@duetso/agent 0.1.201 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +43 -9
  2. package/dist/package.json +1 -1
  3. package/dist/src/cli/help.d.ts +1 -0
  4. package/dist/src/cli/help.d.ts.map +1 -1
  5. package/dist/src/cli/help.js +73 -26
  6. package/dist/src/cli/help.js.map +1 -1
  7. package/dist/src/cli/inline-slash.js +1 -1
  8. package/dist/src/cli/login.d.ts +2 -3
  9. package/dist/src/cli/login.d.ts.map +1 -1
  10. package/dist/src/cli/login.js +17 -32
  11. package/dist/src/cli/login.js.map +1 -1
  12. package/dist/src/cli/memory-add.d.ts +8 -1
  13. package/dist/src/cli/memory-add.d.ts.map +1 -1
  14. package/dist/src/cli/memory-add.js +49 -53
  15. package/dist/src/cli/memory-add.js.map +1 -1
  16. package/dist/src/cli/memory-db.d.ts +23 -0
  17. package/dist/src/cli/memory-db.d.ts.map +1 -1
  18. package/dist/src/cli/memory-db.js +48 -1
  19. package/dist/src/cli/memory-db.js.map +1 -1
  20. package/dist/src/cli/memory-json.d.ts +67 -0
  21. package/dist/src/cli/memory-json.d.ts.map +1 -0
  22. package/dist/src/cli/memory-json.js +28 -0
  23. package/dist/src/cli/memory-json.js.map +1 -0
  24. package/dist/src/cli/memory-query.d.ts +20 -1
  25. package/dist/src/cli/memory-query.d.ts.map +1 -1
  26. package/dist/src/cli/memory-query.js +45 -20
  27. package/dist/src/cli/memory-query.js.map +1 -1
  28. package/dist/src/cli/memory-recall.d.ts +53 -0
  29. package/dist/src/cli/memory-recall.d.ts.map +1 -0
  30. package/dist/src/cli/memory-recall.js +217 -0
  31. package/dist/src/cli/memory-recall.js.map +1 -0
  32. package/dist/src/cli/memory.d.ts +3 -1
  33. package/dist/src/cli/memory.d.ts.map +1 -1
  34. package/dist/src/cli/memory.js +10 -4
  35. package/dist/src/cli/memory.js.map +1 -1
  36. package/dist/src/cli/model-gateway.d.ts +3 -3
  37. package/dist/src/cli/model-gateway.js +3 -3
  38. package/dist/src/cli/rpc.d.ts +19 -5
  39. package/dist/src/cli/rpc.d.ts.map +1 -1
  40. package/dist/src/cli/rpc.js +20 -19
  41. package/dist/src/cli/rpc.js.map +1 -1
  42. package/dist/src/cli/run.d.ts +8 -0
  43. package/dist/src/cli/run.d.ts.map +1 -1
  44. package/dist/src/cli/run.js +7 -20
  45. package/dist/src/cli/run.js.map +1 -1
  46. package/dist/src/cli/send-feedback.d.ts +1 -1
  47. package/dist/src/cli/send-feedback.js +1 -1
  48. package/dist/src/cli/shared.d.ts +16 -3
  49. package/dist/src/cli/shared.d.ts.map +1 -1
  50. package/dist/src/cli/shared.js +19 -4
  51. package/dist/src/cli/shared.js.map +1 -1
  52. package/dist/src/cli/train.d.ts.map +1 -1
  53. package/dist/src/cli/train.js +40 -23
  54. package/dist/src/cli/train.js.map +1 -1
  55. package/dist/src/cli.d.ts +1 -0
  56. package/dist/src/cli.d.ts.map +1 -1
  57. package/dist/src/cli.js +1 -0
  58. package/dist/src/cli.js.map +1 -1
  59. package/dist/src/lib/duet-api-url.d.ts +9 -0
  60. package/dist/src/lib/duet-api-url.d.ts.map +1 -0
  61. package/dist/src/lib/duet-api-url.js +18 -0
  62. package/dist/src/lib/duet-api-url.js.map +1 -0
  63. package/dist/src/lib/feedback.d.ts +1 -1
  64. package/dist/src/lib/feedback.js +4 -4
  65. package/dist/src/lib/feedback.js.map +1 -1
  66. package/dist/src/lib/login.d.ts +24 -21
  67. package/dist/src/lib/login.d.ts.map +1 -1
  68. package/dist/src/lib/login.js +50 -114
  69. package/dist/src/lib/login.js.map +1 -1
  70. package/dist/src/memory/embedding.d.ts +20 -15
  71. package/dist/src/memory/embedding.d.ts.map +1 -1
  72. package/dist/src/memory/embedding.js +26 -20
  73. package/dist/src/memory/embedding.js.map +1 -1
  74. package/dist/src/memory/recall.d.ts +44 -0
  75. package/dist/src/memory/recall.d.ts.map +1 -1
  76. package/dist/src/memory/recall.js +92 -6
  77. package/dist/src/memory/recall.js.map +1 -1
  78. package/dist/src/model-resolution/duet-gateway.d.ts +4 -3
  79. package/dist/src/model-resolution/duet-gateway.d.ts.map +1 -1
  80. package/dist/src/model-resolution/duet-gateway.js +12 -6
  81. package/dist/src/model-resolution/duet-gateway.js.map +1 -1
  82. package/dist/src/tui/app.d.ts +2 -2
  83. package/dist/src/tui/app.d.ts.map +1 -1
  84. package/dist/src/tui/app.js +20 -2
  85. package/dist/src/tui/app.js.map +1 -1
  86. package/dist/src/tui/paste-controller.d.ts +3 -0
  87. package/dist/src/tui/paste-controller.d.ts.map +1 -1
  88. package/dist/src/tui/paste-controller.js +25 -0
  89. package/dist/src/tui/paste-controller.js.map +1 -1
  90. package/dist/src/tui/session-subscription.d.ts +10 -0
  91. package/dist/src/tui/session-subscription.d.ts.map +1 -1
  92. package/dist/src/tui/session-subscription.js +22 -5
  93. package/dist/src/tui/session-subscription.js.map +1 -1
  94. package/dist/src/tui/slash-commands.d.ts +4 -4
  95. package/dist/src/tui/slash-commands.js +4 -4
  96. package/dist/src/tui/step-renderer.d.ts +4 -0
  97. package/dist/src/tui/step-renderer.d.ts.map +1 -1
  98. package/dist/src/tui/step-renderer.js +41 -37
  99. package/dist/src/tui/step-renderer.js.map +1 -1
  100. package/dist/src/tui/tool-formatters.d.ts +2 -2
  101. package/dist/src/tui/tool-formatters.d.ts.map +1 -1
  102. package/dist/src/turn-runner/agent-events.d.ts +12 -1
  103. package/dist/src/turn-runner/agent-events.d.ts.map +1 -1
  104. package/dist/src/turn-runner/agent-events.js +60 -42
  105. package/dist/src/turn-runner/agent-events.js.map +1 -1
  106. package/dist/src/turn-runner/tools.d.ts.map +1 -1
  107. package/dist/src/turn-runner/tools.js +15 -54
  108. package/dist/src/turn-runner/tools.js.map +1 -1
  109. package/dist/src/turn-runner/turn-runner.d.ts +2 -0
  110. package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
  111. package/dist/src/turn-runner/turn-runner.js +4 -2
  112. package/dist/src/turn-runner/turn-runner.js.map +1 -1
  113. package/dist/src/types/memory.d.ts +11 -0
  114. package/dist/src/types/memory.d.ts.map +1 -1
  115. package/dist/src/types/protocol.d.ts +22 -3
  116. package/dist/src/types/protocol.d.ts.map +1 -1
  117. package/package.json +1 -1
  118. package/dist/src/lib/duet-app-url.d.ts +0 -10
  119. package/dist/src/lib/duet-app-url.d.ts.map +0 -1
  120. package/dist/src/lib/duet-app-url.js +0 -19
  121. package/dist/src/lib/duet-app-url.js.map +0 -1
  122. package/dist/src/lib/sync-skills.d.ts +0 -54
  123. package/dist/src/lib/sync-skills.d.ts.map +0 -1
  124. package/dist/src/lib/sync-skills.js +0 -215
  125. package/dist/src/lib/sync-skills.js.map +0 -1
package/README.md CHANGED
@@ -49,7 +49,7 @@ None of this makes Claude Code or Codex worse at what they do. It makes duet-age
49
49
 
50
50
  Two things that don't get a section of their own below, but that follow from the same shape:
51
51
 
52
- - **One login, every frontier model.** `duet login` is the whole setup. Claude, GPT, Gemini, image, video, web — all behind one key, with default skills auto-synced and kept fresh.
52
+ - **One login, every frontier model.** `duet login` is the whole setup. Claude, GPT, Gemini, image, video, web — all behind one key.
53
53
  - **Open source.** No black box. If we made a wrong call about how memory ranks or how relays route, you can read the code and tell us we're wrong.
54
54
 
55
55
  ## What we do differently
@@ -251,7 +251,7 @@ The pre-commit hook runs `format`, `check-types`, and `lint`.
251
251
 
252
252
  ## CLI Quick Start
253
253
 
254
- The recommended path is `duet login`. One sign-in writes `DUET_API_KEY` to `~/.duet/.env`, syncs the default skills, and gives you access to every frontier language, image, and video model on the Duet AI Gateway plus the bundled web-scraping skills — no other API keys required.
254
+ The recommended path is `duet login`. One sign-in writes `DUET_API_KEY` to `~/.duet/.env` and gives you access to every frontier language, image, and video model on the Duet AI Gateway plus the bundled web-scraping skills — no other API keys required.
255
255
 
256
256
  ```bash
257
257
  duet login
@@ -327,12 +327,12 @@ Type `/` in the composer to open the command picker, or send any of these as a m
327
327
  - **`/model <name>`** — switch the model used for **subsequent** turns. Accepts the same shorthands and `provider:modelId` forms as the `--model` flag (e.g. `/model sonnet-4.6`, `/model anthropic:claude-opus-4-7`). Unknown shorthands or missing provider credentials surface an error and leave the current model in place. The in-flight turn (if any) keeps the model it started with.
328
328
  - **`/thinking <level>`** — switch the thinking level for the **next** turn. One of `minimal`, `low`, `medium`, `high`, `xhigh`. The runner clamps to the active model's supported range at use-time. The in-flight turn (if any) keeps its level.
329
329
  - **`/feedback <message>`** — send free-form feedback to the Duet team.
330
- - **`/reset`** — dispose the current session and start a fresh one.
330
+ - **`/clear`** — dispose the current session and start a fresh one.
331
331
  - **`/copy [last|all|<N>]`** — copy transcript text to the system clipboard (default: last agent reply).
332
332
  - **`/paste`**, **`/image <path>`**, **`/clear-images`** — image-attachment helpers, covered in the next section.
333
333
  - **`/diag`** — toggle key and selection event logging when triaging terminal-specific issues.
334
334
 
335
- `/model`, `/thinking`, `/reset`, `/paste`, `/clear-images`, and `/diag` also work **anywhere inside a longer prompt**. `hey can you review this /model gpt-5.5` swaps the model for the very turn that delivers the message; the slash form is stripped from what the agent sees, so the model receives `hey can you review this`. When the whole prompt is just slash commands, no agent turn runs at all. Commands that take rest-of-line arguments (`/feedback`, `/copy`, `/image`) only fire when they own the whole message.
335
+ `/model`, `/thinking`, `/clear`, `/paste`, `/clear-images`, and `/diag` also work **anywhere inside a longer prompt**. `hey can you review this /model gpt-5.5` swaps the model for the very turn that delivers the message; the slash form is stripped from what the agent sees, so the model receives `hey can you review this`. When the whole prompt is just slash commands, no agent turn runs at all. Commands that take rest-of-line arguments (`/feedback`, `/copy`, `/image`) only fire when they own the whole message.
336
336
 
337
337
  The inline form also works for the non-TUI one-shot CLI: `duet "hey can you review this /model gpt-5.5"` swaps the model and dispatches the stripped prompt to the agent; `duet "/model gpt-5.5"` applies the swap and exits without dispatching a turn.
338
338
 
@@ -353,6 +353,43 @@ The interactive TUI accepts image attachments (PNG, JPEG, GIF, WebP):
353
353
 
354
354
  </details>
355
355
 
356
+ <details>
357
+ <summary><b>Query, recall, and add durable memory from the CLI</b></summary>
358
+
359
+ The same `~/.duet/memory.db` the runner reads is scriptable from the CLI. Bare `duet memory` opens the interactive TUI; adding `--json` or any filter turns the same invocation into a non-interactive query. Three subcommands cover the write and search paths:
360
+
361
+ ```bash
362
+ # Filter/query mode — bare array of canonical memory objects
363
+ duet memory --json --type reflection --from 2026-06-26
364
+ duet memory --json --source user --session sess_abc123 # rows authored by one session
365
+
366
+ # Recall — hybrid semantic + keyword search, same pipeline as the recall_memory tool
367
+ duet memory recall wire byte budget cap # positional query
368
+ duet memory recall --query "how does the gateway race resolve" --expand
369
+ duet memory recall --scope global --session sess_abc123 --json qwiklabs
370
+
371
+ # Add — write a single user-authored note
372
+ duet memory add --priority high --tag billing "Enterprise discounts cap at 20%"
373
+ echo "note from a pipe" | duet memory add --source import --session sess_abc123 --json
374
+ ```
375
+
376
+ All three share one **canonical memory JSON object** (`--json`), so a consumer parses one shape everywhere:
377
+
378
+ - Timestamps are ISO 8601 strings (e.g. `2026-07-06T00:00:00.000Z`); date-only fields (`observedDate`, `referencedDate`) stay `YYYY-MM-DD`.
379
+ - `source` is a flat string — one of `user | agent | system | api | import` (`system` is the training-origin value).
380
+ - `sessionId` is the session that authored the row: writable on `add` via `--session <id>`, filterable on `memory`/`recall` via `--session`, and echoed on output (absent on legacy rows).
381
+ - Two ranking scores are always named explicitly, never a generic `score`: `packScore` (recency × priority × kind bias, present everywhere) and `relevanceScore` (query-relevance, RRF-fused — present only in `memory recall` results).
382
+
383
+ Command-specific notes:
384
+
385
+ - **`duet memory` (query):** `--json` emits a bare array ordered by pack score; `--source` and `--session` narrow the set alongside `--type`, `--priority`, `--from`, and `--to`.
386
+ - **`duet memory recall`:** query text comes from `--query <q>` or positional args. `--scope session|global` requires `--session <id>` to compare against; `all` (default) ignores it. `--json` emits a bare array ordered best-first, each row carrying both `packScore` and `relevanceScore`.
387
+ - **`duet memory add`:** added rows are always `note` kind. `--source` defaults to `user`; `--session <id>` stamps the row (omit to leave it global). Content comes from positional args or stdin, and empty input is a usage error. `--json` emits one canonical object (`packScore` and `lastUsedAt` present, `relevanceScore` absent).
388
+
389
+ Every memory command accepts `--db <absolute-path>` (default `~/.duet/memory.db`) and `--wait <seconds>` (lock-wait budget, default 30; `0` fails immediately). Exit codes are stable for scripting: `0` success, `64` usage or validation error (unknown flag, bad value, empty input), `75` memory-DB lock-wait budget exhausted, and `1` for anything else.
390
+
391
+ </details>
392
+
356
393
  <details>
357
394
  <summary><b>Train a folder of docs into durable memory</b></summary>
358
395
 
@@ -383,16 +420,13 @@ The CLI also prints the observation content to stdout, so it's pipeable: `duet t
383
420
  <details>
384
421
  <summary><b>CLI Login</b></summary>
385
422
 
386
- `duet login` is the recommended setup path. It opens a browser to sign in, writes `DUET_API_KEY` for the selected org to `~/.duet/.env`, and syncs the latest default skills into `~/.duet/skills`.
423
+ `duet login` is the recommended setup path. It opens a browser to sign in and writes `DUET_API_KEY` for the selected org to `~/.duet/.env`.
387
424
 
388
425
  That single `DUET_API_KEY` is your access token to the Duet AI Gateway: frontier language models (Claude, GPT, Gemini), image generation (GPT Image 2), video generation (Seedance), and the Firecrawl-powered web scraping and search skills, all behind one key.
389
426
 
390
- Once you have synced default skills at least once, every subsequent `duet` invocation refreshes them in the background using a conditional GET against the saved hash. Logging in with `--skip-skill-sync` leaves no hash on disk, so this auto-refresh stays a no-op until you explicitly opt in by syncing once.
391
-
392
427
  ```bash
393
428
  duet login
394
429
  duet login --no-browser # print the auth URL instead of opening a browser
395
- duet login --skip-skill-sync # skip the post-login default skill sync
396
430
  ```
397
431
 
398
432
  </details>
@@ -508,7 +542,7 @@ const turnRunner = new TurnRunner({
508
542
  });
509
543
  ```
510
544
 
511
- By default, both `duet` (TUI/run) and `duet --rpc` store durable observations in `~/.duet/memory.db`. Override the path with `--db <path>` (the flag is accepted in both modes and is ignored when `--incognito` is also set), or run with `--incognito` (or `-i`) to set `memoryDbPath: false`, which disables observational memory and compaction for that session. Programmatic callers can pass `memoryDbPath: false` or provide a custom `memoryDbPath`. The CLI's `SessionManager` is a convenience layer that stores session snapshots under `~/.duet/sessions`, but the runner owns memory hydration, pi-turn observation/reflection, compaction, and observation persistence.
545
+ By default, both `duet` (TUI/run) and `duet --rpc` store durable observations in `~/.duet/memory.db`. Override the path with `--db <path>` (the flag is accepted in both modes and is ignored when `--incognito` is also set), or run with `--incognito` (or `-i`) to set `memoryDbPath: false`, which disables observational memory and compaction for that session. `duet --rpc` bypasses `SessionManager`, so it has no session of its own; pass `duet --rpc --session <id>` to attribute every observation written during the RPC process to a caller-owned session (one RPC process is one logical session). Omit it to leave those writes unattributed. Programmatic callers can pass `memoryDbPath: false` or provide a custom `memoryDbPath`. The CLI's `SessionManager` is a convenience layer that stores session snapshots under `~/.duet/sessions`, but the runner owns memory hydration, pi-turn observation/reflection, compaction, and observation persistence.
512
546
 
513
547
  > [!WARNING]
514
548
  > We strongly recommend running with a `memoryDbPath` (the default). Compaction is implemented as part of the observational memory pipeline: raw transcript content is replaced by observations/reflections that the observer and reflector write to the durable store. Without a database, the runner skips that pipeline entirely — there is no compaction, the transcript grows unbounded against the raw model context window, and long sessions will eventually hit a provider context-length error. `memoryDbPath: false` is appropriate for short-lived scripts, tests, and incognito runs that stay well under the model window.
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duetso/agent",
3
- "version": "0.1.201",
3
+ "version": "0.2.0",
4
4
  "description": "An opinionated full-stack agent turn runner with native memories, interrupts, and multi-agent orchestration",
5
5
  "keywords": [
6
6
  "agent",
@@ -11,6 +11,7 @@ export declare function printEnvHelp(): void;
11
11
  export declare function printSkillsHelp(): void;
12
12
  export declare function printMemoryHelp(): void;
13
13
  export declare function printMemoryAddHelp(): void;
14
+ export declare function printMemoryRecallHelp(): void;
14
15
  export declare function printMemoryReflectHelp(): void;
15
16
  export declare function printModelHelp(): void;
16
17
  export declare function printTrainHelp(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAyFtD;AAED,wBAAgB,cAAc,IAAI,IAAI,CA0BrC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAsBnC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAqBtC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAuDtC;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAyBzC;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAuC7C;AAED,wBAAgB,cAAc,IAAI,IAAI,CAsCrC;AAED,wBAAgB,cAAc,IAAI,IAAI,CA+DrC;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAiB5C;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAe1D"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CA0FtD;AAED,wBAAgB,cAAc,IAAI,IAAI,CAqBrC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAsBnC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAqBtC;AAED,wBAAgB,eAAe,IAAI,IAAI,CA4DtC;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CA8BzC;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAwC5C;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAuC7C;AAED,wBAAgB,cAAc,IAAI,IAAI,CAsCrC;AAED,wBAAgB,cAAc,IAAI,IAAI,CA+DrC;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAiB5C;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAe1D"}
@@ -12,7 +12,7 @@ duet — An opinionated full-stack agent runner
12
12
 
13
13
  USAGE
14
14
  duet [options] [prompt]
15
- duet login [--no-browser] [--skip-skill-sync]
15
+ duet login --workspace <slug> [--no-browser]
16
16
  duet env [--env-file <path>] [--import [path]|--keys]
17
17
  duet skills [--workdir <path>]
18
18
  duet memory [--db <path>] [--json] [filters]
@@ -22,7 +22,7 @@ USAGE
22
22
  echo "prompt" | duet
23
23
 
24
24
  COMMANDS
25
- login Sign in via browser; saves DUET_API_KEY and syncs default skills (recommended)
25
+ login Sign in via device flow; saves a workspace-scoped DUET_API_KEY (recommended)
26
26
  env Manually create or update the shared duet env file with provider API keys
27
27
  skills List installed skills + collisions as JSON
28
28
  memory Browse memories in a TUI, or query them with --json/filters (alias: memories)
@@ -48,11 +48,12 @@ OPTIONS
48
48
  --no-system-prompt-files Disable default AGENTS.md system prompt loading
49
49
  --env-file <path> Shared env file to load after <workdir>/.env (default: ${DEFAULT_DUET_ENV_FILE})
50
50
  --no-auto-upgrade Skip the auto-upgrade probe for this run (also: DUET_NO_AUTO_UPGRADE=1)
51
- --no-skill-sync Skip the on-load default-skill sync
52
51
  --rpc Bare turn-runner control surface. Reads newline-delimited TurnRunnerCommand
53
52
  JSON from stdin and writes TurnEvent JSON to stdout. The first command must
54
53
  be "start"; the process exits after the single turn reaches its terminal
55
54
  event. Bypasses session persistence entirely.
55
+ --session <id> (--rpc only) Attribute memory written during the process to this caller-owned
56
+ session id. One RPC process is one logical session; omit to write with no id.
56
57
  -v, --version Print the installed duet version and exit
57
58
  -h, --help Show this help
58
59
 
@@ -70,9 +71,9 @@ MODELS
70
71
  OPENAI_API_KEY after loading <workdir>/.env and the shared duet env file.
71
72
 
72
73
  duet-gateway: routes through the Duet gateway proxy
73
- (https://duet.so/api/v1/ai-gateway by default; override the app origin
74
- via DUET_APP_BASE_URL). It mirrors vercel-ai-gateway's model catalog
75
- and authenticates with DUET_API_KEY.
74
+ (https://gateway.duet.so by default; override via DUET_GATEWAY_BASE_URL).
75
+ It mirrors vercel-ai-gateway's model catalog and authenticates with
76
+ DUET_API_KEY.
76
77
 
77
78
  EXAMPLES
78
79
  duet "build a REST API with Express and TypeScript"
@@ -86,7 +87,7 @@ EXAMPLES
86
87
  duet --env-file ~/.config/duet/env "review this repo"
87
88
  duet --workdir ./my-project "refactor the auth module"
88
89
  duet --resume session_abc123 --workdir ./my-project
89
- duet login
90
+ duet login --workspace acme
90
91
  duet env
91
92
  duet memory
92
93
  duet model -m openai/gpt-5.5 "write a haiku about gateways"
@@ -98,29 +99,24 @@ EXAMPLES
98
99
  }
99
100
  export function printLoginHelp() {
100
101
  console.log(`
101
- duet login — Sign in via browser and sync default skills
102
+ duet login — Sign in via device flow
102
103
 
103
104
  USAGE
104
- duet login [--env-file <path>] [--no-browser] [--skip-skill-sync]
105
+ duet login --workspace <slug> [--env-file <path>] [--no-browser]
105
106
 
106
- Opens a browser window pointed at the Duet web app, waits for the user to
107
- confirm, then writes the org's DUET_API_KEY to the shared env file. After
108
- auth, fetches and writes the latest default skills to ~/.duet/skills.
107
+ Requests a workspace-scoped device code, prints the user code and verification
108
+ URL, waits for approval, then writes the workspace's DUET_API_KEY to the shared
109
+ env file.
109
110
 
110
111
  OPTIONS
112
+ --workspace <slug> Workspace slug for the one-workspace API key (or DUET_WORKSPACE)
111
113
  --env-file <path> Env file to write the API key to (default: ${DEFAULT_DUET_ENV_FILE})
112
- --no-browser Print the auth URL instead of opening a browser
113
- --skip-skill-sync Skip the post-login default skills sync
114
+ --no-browser Print the verification URL instead of opening a browser
114
115
  -h, --help Show this help
115
116
 
116
- SKILL SYNC
117
- Mirrors the sandbox protocol: hashes the rendered skill payload and only
118
- rewrites ~/.duet/skills when the hash differs from ~/.duet/.skills-hash.
119
-
120
117
  OVERRIDES
121
- Set DUET_APP_BASE_URL (e.g. https://staging.duet.so) to re-point both the
122
- AI gateway provider and the CLI auth/sync endpoints at a non-production
123
- deployment.
118
+ Set DUET_API_BASE_URL (e.g. https://api-staging.duet.so) to re-point device
119
+ login. Model traffic uses DUET_GATEWAY_BASE_URL.
124
120
  `);
125
121
  }
126
122
  export function printEnvHelp() {
@@ -175,7 +171,7 @@ duet memory — Browse, query, edit, and delete observational memories
175
171
  USAGE
176
172
  duet memory [--db <path>] [--wait <seconds>]
177
173
  duet memory [--json] [--type <kind>] [--priority <level>] [--source <origin>]
178
- [--from <date>] [--to <date>]
174
+ [--session <id>] [--from <date>] [--to <date>]
179
175
  duet memory reflect [options]
180
176
 
181
177
  ALIASES
@@ -185,9 +181,10 @@ DESCRIPTION
185
181
  Bare \`duet memory\` opens an interactive TUI to browse, edit, and delete
186
182
  durable observations. Passing --json or any filter flag instead runs a
187
183
  non-TUI, scriptable query: it prints a flat, chronological list (newest
188
- createdAt first) of the matching observations, each carrying a computed
189
- \`score\` field matching the runner's global-pack ranking. With --json the
190
- output is a machine-readable array; otherwise an aligned table is printed.
184
+ createdAt first) of the matching observations. In table mode each row shows
185
+ a computed \`score\` matching the runner's global-pack ranking; --json emits
186
+ a machine-readable array of canonical memory objects (ISO timestamps, flat
187
+ \`source\` string, echoed \`sessionId\`, and that score as \`packScore\`).
191
188
 
192
189
  Examples:
193
190
  duet memory
@@ -197,6 +194,9 @@ DESCRIPTION
197
194
  SUBCOMMANDS
198
195
  add Write a single user-added note memory
199
196
  (run \`duet memory add --help\` for add-specific options)
197
+ recall <query> Hybrid semantic + keyword search over durable memory,
198
+ the same pipeline the runner's recall_memory tool uses
199
+ (run \`duet memory recall --help\` for recall-specific options)
200
200
  reflect Condense old global observations into reflection rows
201
201
  (run \`duet memory reflect --help\` for reflect-specific options)
202
202
 
@@ -205,7 +205,8 @@ QUERY OPTIONS
205
205
  --type <kind> Filter by kind: observation | reflection | note | manual
206
206
  --kind <kind> Alias for --type
207
207
  --priority <level> Filter by priority: high | medium | low
208
- --source <origin> Filter by source: user | agent | system
208
+ --source <origin> Filter by source: user | agent | system | api | import
209
+ --session <id> Filter to rows authored by this session id
209
210
  --from <date> Inclusive lower bound on createdAt. Accepts
210
211
  YYYY-MM-DD (start of day UTC) or YYYY-MM-DDTHH:MM:SS (UTC)
211
212
  --to <date> Inclusive upper bound on createdAt. Accepts
@@ -243,8 +244,54 @@ DESCRIPTION
243
244
 
244
245
  OPTIONS
245
246
  --priority <level> high, medium, or low (default: medium)
247
+ --source <origin> user, agent, system, api, or import (default: user)
248
+ --session <id> Stamp the row's authoring session; omit to leave it
249
+ global/unattributed
246
250
  --tag <tag> Attach a label; repeat to add several
247
251
  --db <path> Memory database path (default: ~/.duet/memory.db)
252
+ --json Emit the stored memory as one canonical JSON object
253
+ (with packScore) instead of the confirmation line
254
+ --wait <seconds> Seconds to wait for the cross-process open-lock
255
+ (default: 30; 0 fails immediately)
256
+ -h, --help Show this help
257
+ `);
258
+ }
259
+ export function printMemoryRecallHelp() {
260
+ console.log(`
261
+ duet memory recall — Hybrid semantic + keyword search over durable memory
262
+
263
+ USAGE
264
+ duet memory recall [options] [--query <q> | <query...>]
265
+
266
+ DESCRIPTION
267
+ Searches ~/.duet/memory.db with the exact pipeline the runner's
268
+ recall_memory tool uses: vector (embedding) search and keyword search run
269
+ in parallel and merge via Reciprocal Rank Fusion, so fuzzy paraphrases and
270
+ exact tokens (proper nouns, IDs, code symbols) both match. Results print
271
+ best-match first.
272
+
273
+ Embeddings use the Duet endpoint (DUET_API_KEY). When it is unavailable the
274
+ vector path is skipped and recall falls back to keyword-only, flagged in the
275
+ output. --expand adds model-generated paraphrases before fusion for vague
276
+ queries, at the cost of an extra model call.
277
+
278
+ Examples:
279
+ duet memory recall wire byte budget cap
280
+ duet memory recall --expand "how does the gateway race resolve"
281
+ duet memory recall --scope global --session <id> --json qwiklabs
282
+
283
+ OPTIONS
284
+ --query <q> Search text (alternative to positional <query>;
285
+ both are accepted and combine)
286
+ --scope <scope> session | global | all (default: all).
287
+ session/global require --session <id>
288
+ --session <id> Session id to compare against for --scope session/global
289
+ --limit <n> Maximum fused results to return (default: 8)
290
+ --expand Also run model-generated paraphrases before fusion
291
+ --model <name> Model used for --expand paraphrases (default: cheap CLI memory model)
292
+ --json Emit a bare JSON array of canonical memory objects
293
+ (best-first) with packScore + relevanceScore
294
+ --db <path> Memory database path (default: ~/.duet/memory.db)
248
295
  --wait <seconds> Seconds to wait for the cross-process open-lock
249
296
  (default: 30; 0 fails immediately)
250
297
  -h, --help Show this help
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;gDAqBkC,WAAW;;;;;;;;;;;;;gHAaqD,+BAA+B;;;;;oFAK3D,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDxG,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;wEAW0D,qBAAqB;;;;;;;;;;;;;CAa5F,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;yDAa2C,qBAAqB;;;;;;IAM1E,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;CAChC,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Db,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAeb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,CAAC,GAAG,CAAC;oCACsB,WAAW;;;;;;;;;;;;CAY9C,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;gDAqBkC,WAAW;;;;;;;;;;;;;gHAaqD,+BAA+B;;;;;oFAK3D,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDxG,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;wEAY0D,qBAAqB;;;;;;;CAO5F,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;yDAa2C,qBAAqB;;;;;;IAM1E,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;CAChC,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Db,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Bb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Db,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAeb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,CAAC,GAAG,CAAC;oCACsB,WAAW;;;;;;;;;;;;CAY9C,CAAC,CAAC;AACH,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { resolveModelName } from "../model-resolution/resolver.js";
2
2
  import { validateThinkingLevel } from "../session/thinking-level.js";
3
3
  import { applyInlineSlashCommands } from "../tui/slash-commands.js";
4
- /** Slash commands the non-TUI CLI applies inline. /reset, /paste, /clear-images, /diag
4
+ /** Slash commands the non-TUI CLI applies inline. /clear, /paste, /clear-images, /diag
5
5
  * have no meaning in a one-shot run so the CLI intentionally ignores them. */
6
6
  const CLI_INLINE_COMMANDS = new Set(["model", "thinking"]);
7
7
  /**
@@ -5,9 +5,8 @@ export interface LoginCommandIO {
5
5
  /**
6
6
  * Run `duet login`.
7
7
  *
8
- * Opens the duet web app in a browser, waits for confirmation, persists the
9
- * returned `DUET_API_KEY` to the shared env file, then optionally syncs the
10
- * org's default skills bundle to `~/.duet/skills`.
8
+ * Starts the Duet device flow for a workspace-scoped API key and persists the
9
+ * returned `DUET_API_KEY` to the shared env file.
11
10
  */
12
11
  export declare function runLoginCommand(args: string[], io?: LoginCommandIO): Promise<void>;
13
12
  //# sourceMappingURL=login.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2D5F"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgD5F"}
@@ -1,20 +1,17 @@
1
- import { resolveDuetAppBaseUrl } from "../lib/duet-app-url.js";
2
- import { loginWithBrowser } from "../lib/login.js";
3
- import { syncDefaultSkills } from "../lib/sync-skills.js";
1
+ import { loginWithDeviceFlow } from "../lib/login.js";
4
2
  import { printLoginHelp } from "./help.js";
5
- import { defaultDuetEnvFilePath, fail, mergeEnvEntries, resolveUserPath } from "./shared.js";
3
+ import { defaultDuetEnvFilePath, fail, mergeEnvEntries, resolveUserPath, usageError, } from "./shared.js";
6
4
  /**
7
5
  * Run `duet login`.
8
6
  *
9
- * Opens the duet web app in a browser, waits for confirmation, persists the
10
- * returned `DUET_API_KEY` to the shared env file, then optionally syncs the
11
- * org's default skills bundle to `~/.duet/skills`.
7
+ * Starts the Duet device flow for a workspace-scoped API key and persists the
8
+ * returned `DUET_API_KEY` to the shared env file.
12
9
  */
13
10
  export async function runLoginCommand(args, io = {}) {
14
11
  const cwd = io.cwd ?? process.cwd();
15
12
  let envFilePathOverride = io.envFilePath;
16
13
  let noBrowser = false;
17
- let skipSkillSync = false;
14
+ let workspaceSlug;
18
15
  for (let i = 0; i < args.length; i++) {
19
16
  switch (args[i]) {
20
17
  case "--env-file":
@@ -26,7 +23,12 @@ export async function runLoginCommand(args, io = {}) {
26
23
  noBrowser = true;
27
24
  break;
28
25
  case "--skip-skill-sync":
29
- skipSkillSync = true;
26
+ // Deprecated no-op; tolerated so scripts that pass it do not break.
27
+ break;
28
+ case "--workspace":
29
+ if (!args[i + 1] || args[i + 1]?.startsWith("-"))
30
+ fail(`Missing value for ${args[i]}`);
31
+ workspaceSlug = args[++i];
30
32
  break;
31
33
  case "--help":
32
34
  case "-h":
@@ -36,32 +38,15 @@ export async function runLoginCommand(args, io = {}) {
36
38
  fail(`Unknown login option: ${args[i]}`);
37
39
  }
38
40
  }
41
+ workspaceSlug = workspaceSlug?.trim() || process.env.DUET_WORKSPACE?.trim();
42
+ if (!workspaceSlug) {
43
+ usageError("Missing required workspace. Pass `duet login --workspace <slug>` or set DUET_WORKSPACE; login creates one DUET_API_KEY scoped to one workspace.");
44
+ }
39
45
  const targetEnvFile = envFilePathOverride
40
46
  ? resolveUserPath(envFilePathOverride, cwd)
41
47
  : defaultDuetEnvFilePath();
42
- const result = await loginWithBrowser({ noBrowser });
48
+ const result = await loginWithDeviceFlow({ noBrowser, workspaceSlug });
43
49
  await mergeEnvEntries(targetEnvFile, new Map([["DUET_API_KEY", result.apiKey]]));
44
- console.error(`Saved DUET_API_KEY for ${result.orgName} (${result.orgSlug}) to ${targetEnvFile}`);
45
- process.env.DUET_API_KEY = result.apiKey;
46
- await fetch(`${resolveDuetAppBaseUrl()}/api/v1/analytics/events`, {
47
- method: "POST",
48
- headers: {
49
- Authorization: `Bearer ${result.apiKey}`,
50
- "Content-Type": "application/json",
51
- },
52
- body: JSON.stringify({ name: "cli_login" }),
53
- }).catch(() => { });
54
- if (skipSkillSync) {
55
- console.error("Skipping default skill sync (--skip-skill-sync).");
56
- return;
57
- }
58
- console.error(`Checking default skills against ${resolveDuetAppBaseUrl()}...`);
59
- const syncResult = await syncDefaultSkills({ apiKey: result.apiKey });
60
- if (syncResult.status === "unchanged") {
61
- console.error("Default skills already up to date.");
62
- }
63
- else {
64
- console.error(`Synced default skills (${syncResult.count} total).`);
65
- }
50
+ console.error(`Saved DUET_API_KEY for ${result.workspaceName} (${result.workspaceSlug}) to ${targetEnvFile}`);
66
51
  }
67
52
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,sBAAsB,EACtB,IAAI,EACJ,eAAe,EACf,eAAe,EACf,UAAU,GACX,MAAM,aAAa,CAAC;AAOrB;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAc,EAAE,KAAqB,EAAE;IAC3E,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,mBAAmB,GAAuB,EAAE,CAAC,WAAW,CAAC;IAC7D,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,aAAiC,CAAC;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,YAAY;gBACf,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvF,mBAAmB,GAAG,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC;gBACjC,MAAM;YACR,KAAK,cAAc;gBACjB,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,mBAAmB;gBACtB,oEAAoE;gBACpE,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvF,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC;gBAC3B,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,cAAc,EAAE,CAAC;gBACjB,OAAO;YACT;gBACE,IAAI,CAAC,yBAAyB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,aAAa,GAAG,aAAa,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC5E,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,UAAU,CACR,iJAAiJ,CAClJ,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,mBAAmB;QACvC,CAAC,CAAC,eAAe,CAAC,mBAAmB,EAAE,GAAG,CAAC;QAC3C,CAAC,CAAC,sBAAsB,EAAE,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IAEvE,MAAM,eAAe,CAAC,aAAa,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,OAAO,CAAC,KAAK,CACX,0BAA0B,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,aAAa,QAAQ,aAAa,EAAE,CAC/F,CAAC;AACJ,CAAC"}
@@ -1,10 +1,17 @@
1
- import type { ObservationPriority } from "../types/memory.js";
1
+ import type { ObservationPriority, ObservationSource } from "../types/memory.js";
2
+ type SourceKind = ObservationSource["kind"];
2
3
  interface AddCommandOptions {
3
4
  dbPath: string;
4
5
  /** Positional content joined with spaces; empty when the caller pipes via stdin instead. */
5
6
  content: string;
6
7
  priority: ObservationPriority;
8
+ /** Provenance stamped on the row and echoed back; defaults to `user`. */
9
+ source: SourceKind;
7
10
  tags: string[];
11
+ /** Session that authored the row; omitted leaves the row global/unattributed. */
12
+ sessionId?: string;
13
+ /** Emit one canonical memory JSON object instead of the human line. */
14
+ json: boolean;
8
15
  waitBudgetMs?: number;
9
16
  }
10
17
  interface AddCommandIO {
@@ -1 +1 @@
1
- {"version":3,"file":"memory-add.d.ts","sourceRoot":"","sources":["../../../src/cli/memory-add.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACpD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,GAAE,YAA+D,GAClE,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,GAAG,SAAS,CAoDhF"}
1
+ {"version":3,"file":"memory-add.d.ts","sourceRoot":"","sources":["../../../src/cli/memory-add.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAOjF,KAAK,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE5C,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACpD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,GAAE,YAA+D,GAClE,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,GAAG,SAAS,CA+DhF"}