Skip to content

feat(commands): add inline overrides for slash commands - #1183

Open
MayurK-cmd wants to merge 1 commit into
Nano-Collective:mainfrom
MayurK-cmd:fix/1151-once-scope-config-override
Open

feat(commands): add inline overrides for slash commands#1183
MayurK-cmd wants to merge 1 commit into
Nano-Collective:mainfrom
MayurK-cmd:fix/1151-once-scope-config-override

Conversation

@MayurK-cmd

Copy link
Copy Markdown

Description

Slash commands now accept inline ?key=value overrides that scope a setting to the current command only. Lets users test a value for one command without round-tripping through /settings or otherwise mutating the session state.

/compact ?threshold=80              # session-override key, applied via auto-compact store
/context-max 128k ?once             # session-override key, applied via models.dev store
/compact --mechanical ?preview      # legacy flag (forwarded as --preview)
/some-command ?unknown=1            # ignored; preserved in args so the handler can error normally

How it works

  • parseInlineOverrides(args) (new, pure) splits an args array into {args, overrides}. Only tokens starting with ? are
    considered; bad keys (leading digit, whitespace) are kept in args so the command's own "unknown arg" path runs.
  • expandOverrideArgs(overrides) turns recognised legacy keys (preview, llm, mechanical, aggressive, conservative,
    auto-on, auto-off) into the corresponding --flag value tokens, so existing handlers see them as if the user had typed the
    long form.
  • applyOnceOverrides(overrides) is async and writes recognised session-override keys (threshold, auto-compact, context-max)
    to the existing setAutoCompactThreshold / setAutoCompactEnabled / setSessionContextLimit setters. It returns a restore
    callback that the dispatcher calls in a finally block, so the override only persists for the single command invocation.
  • The slash-command dispatcher in source/app/utils/app-util.ts is wrapped in a try/finally so restore always runs, even if a
    handler throws.

Adding a new inline-override key is a one-line change: add a case in applyOnceOverrides and (if it isn't an existing --flag)
optionally add an entry in LEGACY_FLAG_NAMES.

Why async

applyOnceOverrides defers the heavy auto-compact / models-dev-client imports via dynamic import() so the parser itself is import-free. Without this, the spec timed out under AVA's serial worker because importing @/utils/auto-compact pulls in the chat-handler / config / tokenization init graph.

Files

  • source/utils/inline-overrides.ts (new)
  • source/utils/inline-overrides.spec.ts (new)
  • source/app/utils/app-util.ts (wrap dispatcher in try/finally, rebuild commandParts from parseInlineOverrides +
    expandOverrideArgs)
  • source/app/utils/app-util.spec.ts (4 new dispatcher tests)
  • .changeset/inline-once-overrides.md (minor: new feature)
  • .gitignore (.pnpm-store/)

Out of scope

The pre-existing bash command - queues a completed BashProgress with showOutput test in app-util.spec.ts still fails on this branch (it has been failing since #826 / July 2026). It is unrelated to this change and is not fixed here. Worth a separate issue.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Changeset

  • Added a changeset (pnpm changeset) describing this change for the changelog

.changeset/inline-once-overrides.md is a minor changeset naming @nanocollective/nanocoder and explaining the new ?key=value
syntax. Validated locally with node scripts/validate-changesets.js (72 changesets checked, all resolve).

Docs-only or internal chores need no changeset (or run pnpm changeset --empty to note that intentionally).

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:all completes successfully)
  • Tests cover both success and error scenarios

Verified locally:

  • pnpm test:ava source/utils/inline-overrides.spec.ts16/16 passed
  • pnpm test:ava source/app/utils/app-util.spec.ts → all 4 new inline-override tests passed; one pre-existing unrelated failure
    (bash command - queues a completed BashProgress with showOutput, present since feat: add session-scoped artifact lifecycle across CLI and VS Code #826) — see "Out of scope" above
  • pnpm test:types → clean
  • pnpm test:lint → 516 files, 0 fixes needed

The 16 parser/helper tests cover: empty input, single key=value, mixed positional + override, bare ?flag (no =), ?key=value
with extra = in value, dotted/dashed/underscored keys, invalid keys preserved in args, expandOverrideArgs for both boolean and key=value forms and unknown keys, plus applyOnceOverrides smoke tests for empty input, unknown keys, unparseable threshold values, and unparseable context-max values.

Manual Testing

  • Tested with Ollama
  • Tested with OpenRouter
  • Tested with OpenAI-compatible API
  • Tested MCP integration (if applicable)

This change is provider-agnostic — the override is wired into the slash-command dispatcher, not into any provider's chat pipeline.
Manual end-to-end testing against a real provider was not done as part of this PR; the change was validated via the unit/
integration tests listed above. The session-override stores it writes to (auto-compact, setSessionContextLimit) are already
covered by their own specs and used in production by /compact --threshold and /context-max <n>.

Checklist

  • If this was for an open issue, I was assigned to it
  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (if needed)
  • No breaking changes (or clearly documented)
  • Appropriate logging added using structured logging (see CONTRIBUTING.md)

No documentation update included in this PR — the override syntax is a small extension of existing --flag behaviour and the new docblock on applyOnceOverrides documents the public surface. Happy to add a docs page if reviewers want one.

No logging added: the override is purely a session-override passthrough that uses the existing setter functions. A successful
override is observable via the normal command result (e.g. /compact ?threshold=80 prints the same "Auto-compact threshold set to 80%" success message as /compact --threshold 80). Failures (unparseable values) are silently ignored per the same behaviour the existing --threshold parser already follows (the value simply isn't applied).

@github-actions github-actions Bot added the area:tui Terminal UI label Sep 4, 2026
@MayurK-cmd MayurK-cmd changed the title feat(commands): add inline \?key=value\ overrides for slash commands … feat(commands): add inline overrides for slash commands Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tui Terminal UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant