## Context The kb client currently overloads the root Cobra command to handle both command dispatch and implicit note ingestion. Any unrecognized multi-word input is silently submitted as a note via `POST /api/v1/jobs`. This was introduced to reduce friction for note-taking but has proven error-prone — typos in commands create unwanted notes. A single-word guard was added but multi-word typos still slip through. The root command has: custom `ArbitraryArgs` validation, a `RunE` with arg-count branching, a `--tags` flag for the note shorthand, a custom usage template with `isRootCmd` template function, and `submitNote()` living in `add.go`. ## Goals / Non-Goals **Goals:** - Eliminate accidental note creation from mistyped commands - Provide a clean, explicit `addnote` command that pairs with existing `addfile` - Revert root command to standard Cobra behaviour (no custom args, no custom template) - Keep the same API contract — `POST /api/v1/jobs` with `note` field unchanged **Non-Goals:** - Changing the engine API - Modifying `addfile` behaviour - Adding new content types (url, bookmark, etc.) - Backward compatibility shim for `kb "text"` syntax ## Decisions ### 1. New `addnote` command in its own file Create `client/cmd/addnote.go` with a `cobra.Command` that takes `ExactArgs(1)` — a single quoted string. This mirrors `addfile` which also takes `ExactArgs(1)`. **Rationale**: Keeps each command in its own file (consistent with the existing pattern). `ExactArgs(1)` means the user must quote multi-word notes, which is unambiguous and avoids the flag-parsing edge cases that plagued the implicit shorthand. **Alternative considered**: Joining `ArbitraryArgs` like the old shorthand. Rejected — this is exactly the ambiguity we're removing. ### 2. Move `submitNote()` from `add.go` to `addnote.go` The function is only used by the addnote command, so it belongs in the same file. **Rationale**: `add.go` becomes purely about file operations (it already is, aside from hosting `submitNote()`). Clean separation. ### 3. Fully revert root command to Cobra defaults Remove: `ArbitraryArgs`, custom `RunE` (replace with nil — Cobra shows help by default), `--tags` flag on root, custom usage template, `isRootCmd` template function. **Rationale**: The root command should do one thing — dispatch to subcommands. All the custom logic was there to support the implicit shorthand which is being removed. ### 4. `addnote` gets its own `--tags` flag The `--tags` flag moves from the root command to `addnote`, matching how `addfile` already has its own `--tags` flag. ## Risks / Trade-offs - **Breaking change for existing users** → Mitigated by clear error messaging. If someone types `kb "some text"`, Cobra will say "unknown command". The `examples` command will show the new syntax. - **Slightly more typing for notes** (`kb addnote "text"` vs `kb "text"`) → Acceptable trade-off for eliminating accidental ingestion. Tab-completion helps. - **Scripts using old syntax will break** → This is intentional. The old syntax was a foot-gun.