@duetso/agent 0.1.33 → 0.1.35

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 (93) hide show
  1. package/README.md +2 -0
  2. package/dist/package.json +1 -1
  3. package/dist/src/cli/env.d.ts +18 -0
  4. package/dist/src/cli/env.d.ts.map +1 -0
  5. package/dist/src/cli/env.js +114 -0
  6. package/dist/src/cli/env.js.map +1 -0
  7. package/dist/src/cli/help.d.ts +8 -0
  8. package/dist/src/cli/help.d.ts.map +1 -0
  9. package/dist/src/cli/help.js +175 -0
  10. package/dist/src/cli/help.js.map +1 -0
  11. package/dist/src/cli/login.d.ts +13 -0
  12. package/dist/src/cli/login.d.ts.map +1 -0
  13. package/dist/src/cli/login.js +61 -0
  14. package/dist/src/cli/login.js.map +1 -0
  15. package/dist/src/cli/memories-db.d.ts +24 -0
  16. package/dist/src/cli/memories-db.d.ts.map +1 -0
  17. package/dist/src/cli/memories-db.js +74 -0
  18. package/dist/src/cli/memories-db.js.map +1 -0
  19. package/dist/src/cli/memories-tui.d.ts +11 -0
  20. package/dist/src/cli/memories-tui.d.ts.map +1 -0
  21. package/dist/src/cli/memories-tui.js +266 -0
  22. package/dist/src/cli/memories-tui.js.map +1 -0
  23. package/dist/src/cli/memories.d.ts +9 -0
  24. package/dist/src/cli/memories.d.ts.map +1 -0
  25. package/dist/src/cli/memories.js +38 -0
  26. package/dist/src/cli/memories.js.map +1 -0
  27. package/dist/src/cli/package-manager.d.ts +38 -0
  28. package/dist/src/cli/package-manager.d.ts.map +1 -0
  29. package/dist/src/cli/package-manager.js +78 -0
  30. package/dist/src/cli/package-manager.js.map +1 -0
  31. package/dist/src/cli/resume-hint.d.ts +22 -0
  32. package/dist/src/cli/resume-hint.d.ts.map +1 -0
  33. package/dist/src/cli/resume-hint.js +61 -0
  34. package/dist/src/cli/resume-hint.js.map +1 -0
  35. package/dist/src/cli/run.d.ts +43 -0
  36. package/dist/src/cli/run.d.ts.map +1 -0
  37. package/dist/src/cli/run.js +273 -0
  38. package/dist/src/cli/run.js.map +1 -0
  39. package/dist/src/cli/shared.d.ts +55 -0
  40. package/dist/src/cli/shared.d.ts.map +1 -0
  41. package/dist/src/cli/shared.js +125 -0
  42. package/dist/src/cli/shared.js.map +1 -0
  43. package/dist/src/cli/skills.d.ts +10 -0
  44. package/dist/src/cli/skills.d.ts.map +1 -0
  45. package/dist/src/cli/skills.js +42 -0
  46. package/dist/src/cli/skills.js.map +1 -0
  47. package/dist/src/cli/upgrade.d.ts +9 -0
  48. package/dist/src/cli/upgrade.d.ts.map +1 -0
  49. package/dist/src/cli/upgrade.js +52 -0
  50. package/dist/src/cli/upgrade.js.map +1 -0
  51. package/dist/src/cli/version-check.d.ts +22 -0
  52. package/dist/src/cli/version-check.d.ts.map +1 -0
  53. package/dist/src/cli/version-check.js +78 -0
  54. package/dist/src/cli/version-check.js.map +1 -0
  55. package/dist/src/cli.d.ts +20 -63
  56. package/dist/src/cli.d.ts.map +1 -1
  57. package/dist/src/cli.js +38 -887
  58. package/dist/src/cli.js.map +1 -1
  59. package/dist/src/memory/observational-prompts.d.ts.map +1 -1
  60. package/dist/src/memory/observational-prompts.js +11 -7
  61. package/dist/src/memory/observational-prompts.js.map +1 -1
  62. package/dist/src/tui/app.d.ts +7 -47
  63. package/dist/src/tui/app.d.ts.map +1 -1
  64. package/dist/src/tui/app.js +279 -396
  65. package/dist/src/tui/app.js.map +1 -1
  66. package/dist/src/tui/autocomplete.d.ts +91 -0
  67. package/dist/src/tui/autocomplete.d.ts.map +1 -0
  68. package/dist/src/tui/autocomplete.js +177 -0
  69. package/dist/src/tui/autocomplete.js.map +1 -0
  70. package/dist/src/tui/file-index.d.ts +11 -0
  71. package/dist/src/tui/file-index.d.ts.map +1 -0
  72. package/dist/src/tui/file-index.js +75 -0
  73. package/dist/src/tui/file-index.js.map +1 -0
  74. package/dist/src/tui/history.d.ts +50 -0
  75. package/dist/src/tui/history.d.ts.map +1 -0
  76. package/dist/src/tui/history.js +132 -0
  77. package/dist/src/tui/history.js.map +1 -0
  78. package/dist/src/tui/sidebar.d.ts +20 -0
  79. package/dist/src/tui/sidebar.d.ts.map +1 -0
  80. package/dist/src/tui/sidebar.js +118 -0
  81. package/dist/src/tui/sidebar.js.map +1 -0
  82. package/dist/src/tui/theme.d.ts +15 -0
  83. package/dist/src/tui/theme.d.ts.map +1 -0
  84. package/dist/src/tui/theme.js +18 -0
  85. package/dist/src/tui/theme.js.map +1 -0
  86. package/dist/src/turn-runner/prompts.d.ts.map +1 -1
  87. package/dist/src/turn-runner/prompts.js +7 -0
  88. package/dist/src/turn-runner/prompts.js.map +1 -1
  89. package/dist/src/turn-runner/tools.d.ts +15 -1
  90. package/dist/src/turn-runner/tools.d.ts.map +1 -1
  91. package/dist/src/turn-runner/tools.js +42 -9
  92. package/dist/src/turn-runner/tools.js.map +1 -1
  93. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # duet-agent
2
2
 
3
+ ![duet-agent](assets/cover.png)
4
+
3
5
  An opinionated, full-stack agent turn runner. Native multimodal memory. Native interrupts. Multi-agent by default. Serverless-friendly: every turn rehydrates from on-disk state, so a session can pause for minutes or months and resume in a fresh sandbox.
4
6
 
5
7
  ## Get started with one login
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duetso/agent",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "An opinionated full-stack agent turn runner with native memories, interrupts, and multi-agent orchestration",
5
5
  "keywords": [
6
6
  "agent",
@@ -0,0 +1,18 @@
1
+ export interface EnvCommandIO {
2
+ cwd?: string;
3
+ /** Override interactivity detection so tests can drive the paste flow. */
4
+ interactive?: boolean;
5
+ /** Inject a stand-in for the readline-backed key prompt. */
6
+ promptForApiKeys?: () => Promise<Map<string, string>>;
7
+ /** Inject a stand-in for the help-text printer. */
8
+ printHelp?: () => void;
9
+ }
10
+ /**
11
+ * Run `duet env`.
12
+ *
13
+ * Two modes share a target env file: `--import` copies provider keys from a
14
+ * source env file (cwd .env by default), and `--keys` prompts the user for
15
+ * each supported provider key. Without either flag we just print help.
16
+ */
17
+ export declare function runEnvCommand(args: string[], io?: EnvCommandIO): Promise<void>;
18
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/cli/env.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DxF"}
@@ -0,0 +1,114 @@
1
+ import { copyFile, mkdir, readFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { createInterface } from "node:readline/promises";
4
+ import dotenv from "dotenv";
5
+ import { printEnvHelp } from "./help.js";
6
+ import { defaultDuetEnvFilePath, fail, fileExists, mergeEnvEntries, resolveUserPath, SUPPORTED_API_KEYS, } from "./shared.js";
7
+ /**
8
+ * Run `duet env`.
9
+ *
10
+ * Two modes share a target env file: `--import` copies provider keys from a
11
+ * source env file (cwd .env by default), and `--keys` prompts the user for
12
+ * each supported provider key. Without either flag we just print help.
13
+ */
14
+ export async function runEnvCommand(args, io = {}) {
15
+ const cwd = io.cwd ?? process.cwd();
16
+ let envFilePath;
17
+ let importEnvFilePath;
18
+ let pasteKeys = false;
19
+ for (let i = 0; i < args.length; i++) {
20
+ switch (args[i]) {
21
+ case "--env-file":
22
+ if (!args[i + 1] || args[i + 1]?.startsWith("-"))
23
+ fail(`Missing value for ${args[i]}`);
24
+ envFilePath = args[++i];
25
+ break;
26
+ case "--import":
27
+ case "-i":
28
+ importEnvFilePath = args[i + 1]?.startsWith("-") ? "" : (args[++i] ?? "");
29
+ break;
30
+ case "--keys":
31
+ pasteKeys = true;
32
+ break;
33
+ case "--help":
34
+ case "-h":
35
+ printEnvHelp();
36
+ return;
37
+ default:
38
+ fail(`Unknown env option: ${args[i]}`);
39
+ }
40
+ }
41
+ const targetEnvFile = envFilePath ? resolveUserPath(envFilePath, cwd) : defaultDuetEnvFilePath();
42
+ const sourceEnvFile = importEnvFilePath === undefined
43
+ ? undefined
44
+ : importEnvFilePath
45
+ ? resolveUserPath(importEnvFilePath, cwd)
46
+ : join(cwd, ".env");
47
+ const interactive = io.interactive ?? Boolean(process.stdin.isTTY && process.stderr.isTTY);
48
+ if (sourceEnvFile === undefined && !pasteKeys) {
49
+ (io.printHelp ?? printEnvHelp)();
50
+ return;
51
+ }
52
+ if (sourceEnvFile !== undefined) {
53
+ if (!(await fileExists(sourceEnvFile))) {
54
+ fail(`No .env file found at ${sourceEnvFile}`);
55
+ }
56
+ await importEnvFile(sourceEnvFile, targetEnvFile);
57
+ console.error(`Imported ${sourceEnvFile} into ${targetEnvFile}`);
58
+ }
59
+ if (pasteKeys) {
60
+ if (!interactive) {
61
+ fail("duet env --keys requires an interactive terminal");
62
+ }
63
+ const entries = await (io.promptForApiKeys ?? promptForApiKeys)();
64
+ if (entries.size === 0) {
65
+ console.error("No API keys entered.");
66
+ return;
67
+ }
68
+ await mergeEnvEntries(targetEnvFile, entries);
69
+ console.error(`Saved API keys to ${targetEnvFile}`);
70
+ }
71
+ }
72
+ /**
73
+ * Copy a source env file's contents into the target env file. When the
74
+ * target already exists we merge keys (source wins) instead of overwriting,
75
+ * so existing local settings stay intact.
76
+ */
77
+ async function importEnvFile(source, target) {
78
+ if (resolve(source) === resolve(target)) {
79
+ console.error(`${target} is already the shared env file.`);
80
+ return;
81
+ }
82
+ await mkdir(dirname(target), { recursive: true });
83
+ if (!(await fileExists(target))) {
84
+ await copyFile(source, target);
85
+ return;
86
+ }
87
+ const parsed = dotenv.parse(await readFile(source));
88
+ await mergeEnvEntries(target, new Map(Object.entries(parsed)));
89
+ }
90
+ /**
91
+ * Prompt the user for each supported provider key on stderr; blank input
92
+ * skips that key. We use stderr so piping `duet env --keys` does not pollute
93
+ * stdout with prompt text.
94
+ */
95
+ async function promptForApiKeys() {
96
+ const rl = createInterface({
97
+ input: process.stdin,
98
+ output: process.stderr,
99
+ });
100
+ try {
101
+ const entries = new Map();
102
+ console.error("Paste API keys for any providers you want to use. Leave blank to skip.");
103
+ for (const key of SUPPORTED_API_KEYS) {
104
+ const value = (await rl.question(`${key}: `)).trim();
105
+ if (value)
106
+ entries.set(key, value);
107
+ }
108
+ return entries;
109
+ }
110
+ finally {
111
+ rl.close();
112
+ }
113
+ }
114
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/cli/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EACL,sBAAsB,EACtB,IAAI,EACJ,UAAU,EACV,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAYrB;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,KAAmB,EAAE;IACvE,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,WAA+B,CAAC;IACpC,IAAI,iBAAqC,CAAC;IAC1C,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,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,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC;gBACzB,MAAM;YACR,KAAK,UAAU,CAAC;YAChB,KAAK,IAAI;gBACP,iBAAiB,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC1E,MAAM;YACR,KAAK,QAAQ;gBACX,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,YAAY,EAAE,CAAC;gBACf,OAAO;YACT;gBACE,IAAI,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;IACjG,MAAM,aAAa,GACjB,iBAAiB,KAAK,SAAS;QAC7B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,iBAAiB;YACjB,CAAC,CAAC,eAAe,CAAC,iBAAiB,EAAE,GAAG,CAAC;YACzC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1B,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE3F,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9C,CAAC,EAAE,CAAC,SAAS,IAAI,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO;IACT,CAAC;IAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,yBAAyB,aAAa,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,aAAa,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,YAAY,aAAa,SAAS,aAAa,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,EAAE,CAAC;QAClE,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,eAAe,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,qBAAqB,aAAa,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,MAAc;IACzD,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,kCAAkC,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB;IAC7B,MAAM,EAAE,GAAG,eAAe,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;QACxF,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const DEFAULT_RESUME_HISTORY_LINES = 40;
2
+ export declare function printRunHelp(packageName: string): void;
3
+ export declare function printLoginHelp(): void;
4
+ export declare function printEnvHelp(): void;
5
+ export declare function printSkillsHelp(): void;
6
+ export declare function printMemoriesHelp(): void;
7
+ export declare function printUpgradeHelp(packageName: string): void;
8
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAsEtD;AAED,wBAAgB,cAAc,IAAI,IAAI,CA0BrC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAsBnC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAkBtC;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAiBxC;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAa1D"}
@@ -0,0 +1,175 @@
1
+ import { DEFAULT_DUET_ENV_FILE, SUPPORTED_API_KEYS } from "./shared.js";
2
+ export const DEFAULT_RESUME_HISTORY_LINES = 40;
3
+ export function printRunHelp(packageName) {
4
+ console.log(`
5
+ duet — An opinionated full-stack agent runner
6
+
7
+ USAGE
8
+ duet [options] [prompt]
9
+ duet login [--no-browser] [--skip-skill-sync]
10
+ duet env [--env-file <path>] [--import [path]|--keys]
11
+ duet skills [--workdir <path>]
12
+ duet memories [--db <path>]
13
+ duet upgrade [--manager npm|bun|pnpm|yarn]
14
+ echo "prompt" | duet
15
+
16
+ COMMANDS
17
+ login Sign in via browser; saves DUET_API_KEY and syncs default skills (recommended)
18
+ env Manually create or update the shared duet env file with provider API keys
19
+ skills List installed skills as JSON (name, description, path, scope)
20
+ memories Open a TUI to view, edit, and delete observational memories
21
+ upgrade Upgrade the global ${packageName} installation
22
+
23
+ OPTIONS
24
+ -m, --model <name> TurnRunner model override
25
+ --memory-model <name> Observational memory model (default inferred from provider env)
26
+ --no-memory Keep memory in-process; do not read or write durable memory
27
+ -w, --workdir <path> Working directory (default: cwd)
28
+ -r, --resume <id> Resume a saved session
29
+ --resume-history-lines <n>
30
+ Display up to n prior-session lines in the TUI (default: ${DEFAULT_RESUME_HISTORY_LINES})
31
+ --system-prompt <text> Additional system instructions for the runner
32
+ --system-prompt-file <path>
33
+ Load a file into the system prompt; repeatable
34
+ --no-system-prompt-files Disable default AGENTS.md system prompt loading
35
+ --env-file <path> Shared env file to load after <workdir>/.env (default: ${DEFAULT_DUET_ENV_FILE})
36
+ --json Force JSONL event output instead of the TUI
37
+ -v, --version Print the installed duet version and exit
38
+ -h, --help Show this help
39
+
40
+ INTERACTIVE
41
+ In a TTY, duet keeps one local session open after terminal events.
42
+ Type /exit or /quit to end the conversation. Type @ followed by a
43
+ filename to insert a repo-relative path into the prompt.
44
+
45
+ MODELS
46
+ Prefer shorthands like opus-4.7, sonnet-4.6, haiku-4.5, and gpt-5.5.
47
+ They map to the first configured provider that supports that model.
48
+ Full provider:modelId syntax is also supported, e.g. anthropic:claude-opus-4-7.
49
+ If omitted, duet infers a default from ANTHROPIC_API_KEY,
50
+ DUET_API_KEY, AI_GATEWAY_API_KEY, OPENROUTER_API_KEY, or
51
+ OPENAI_API_KEY after loading <workdir>/.env and the shared duet env file.
52
+
53
+ duet-gateway: routes through the Duet gateway proxy
54
+ (https://duet.so/api/v1/ai-gateway by default; override the app origin
55
+ via DUET_APP_BASE_URL). It mirrors vercel-ai-gateway's model catalog
56
+ and authenticates with DUET_API_KEY.
57
+
58
+ EXAMPLES
59
+ duet "build a REST API with Express and TypeScript"
60
+ duet -m gpt-5.5 "analyze the performance of our test suite"
61
+ duet --memory-model sonnet-4.6 "summarize this repo"
62
+ duet -m opus-4.7 "refactor the auth module"
63
+ duet --system-prompt "Prefer concise answers." "review this repo"
64
+ duet --system-prompt-file TEAM.md "review this repo"
65
+ duet --env-file ~/.config/duet/env "review this repo"
66
+ duet --workdir ./my-project "refactor the auth module"
67
+ duet --resume session_abc123 --workdir ./my-project
68
+ duet login
69
+ duet env
70
+ duet memories
71
+ duet upgrade
72
+ `);
73
+ }
74
+ export function printLoginHelp() {
75
+ console.log(`
76
+ duet login — Sign in via browser and sync default skills
77
+
78
+ USAGE
79
+ duet login [--env-file <path>] [--no-browser] [--skip-skill-sync]
80
+
81
+ Opens a browser window pointed at the Duet web app, waits for the user to
82
+ confirm, then writes the org's DUET_API_KEY to the shared env file. After
83
+ auth, fetches and writes the latest default skills to ~/.duet/skills.
84
+
85
+ OPTIONS
86
+ --env-file <path> Env file to write the API key to (default: ${DEFAULT_DUET_ENV_FILE})
87
+ --no-browser Print the auth URL instead of opening a browser
88
+ --skip-skill-sync Skip the post-login default skills sync
89
+ -h, --help Show this help
90
+
91
+ SKILL SYNC
92
+ Mirrors the sandbox protocol: hashes the rendered skill payload and only
93
+ rewrites ~/.duet/skills when the hash differs from ~/.duet/.skills-hash.
94
+
95
+ OVERRIDES
96
+ Set DUET_APP_BASE_URL (e.g. https://staging.duet.so) to re-point both the
97
+ AI gateway provider and the CLI auth/sync endpoints at a non-production
98
+ deployment.
99
+ `);
100
+ }
101
+ export function printEnvHelp() {
102
+ console.log(`
103
+ duet env — Create or update a shared duet env file
104
+
105
+ USAGE
106
+ duet env [--env-file <path>] [--import [path]|--keys]
107
+
108
+ Prefer \`duet login\` for the standard setup flow. Use \`duet env\` when you
109
+ want manual control over which provider API keys land in the shared env file.
110
+
111
+ By default, env only prints this help. Choose --import to copy
112
+ provider keys from cwd .env or a provided env file, or --keys to paste keys interactively.
113
+
114
+ OPTIONS
115
+ --env-file <path> Env file to write (default: ${DEFAULT_DUET_ENV_FILE})
116
+ -i, --import [path] Import cwd .env, or import the provided env file
117
+ --keys Prompt for supported provider API keys
118
+ -h, --help Show this help
119
+
120
+ SUPPORTED KEYS
121
+ ${SUPPORTED_API_KEYS.join(", ")}
122
+ `);
123
+ }
124
+ export function printSkillsHelp() {
125
+ console.log(`
126
+ duet skills — List installed skills as JSON
127
+
128
+ USAGE
129
+ duet skills [--workdir <path>]
130
+
131
+ OPTIONS
132
+ -w, --workdir <path> Working directory for project-local skills (default: cwd)
133
+ -h, --help Show this help
134
+
135
+ OUTPUT
136
+ Prints a JSON array of installed skills. Each entry has:
137
+ name Skill name
138
+ description Skill description (from frontmatter, raw — no shell expansion)
139
+ path Absolute path to the skill directory
140
+ scope "user", "project", or "temporary"
141
+ `);
142
+ }
143
+ export function printMemoriesHelp() {
144
+ console.log(`
145
+ duet memories — Browse, edit, and delete observational memories
146
+
147
+ USAGE
148
+ duet memories [--db <path>]
149
+
150
+ OPTIONS
151
+ --db <path> Memory database path (default: ~/.duet/memory.db)
152
+ -h, --help Show this help
153
+
154
+ KEYS
155
+ ↑ / ↓ Move selection
156
+ e Edit selected memory in $EDITOR
157
+ d Delete selected memory
158
+ q / Esc Quit
159
+ `);
160
+ }
161
+ export function printUpgradeHelp(packageName) {
162
+ console.log(`
163
+ duet upgrade — Upgrade the global ${packageName} installation
164
+
165
+ USAGE
166
+ duet upgrade [--manager npm|bun|pnpm|yarn] [--version <version>]
167
+
168
+ OPTIONS
169
+ --manager <name> Package manager to use (default: detected, fallback: npm)
170
+ --version <version> Install an exact version instead of npm's latest dist-tag
171
+ --dry-run Print the upgrade command without running it
172
+ -h, --help Show this help
173
+ `);
174
+ }
175
+ //# sourceMappingURL=help.js.map
@@ -0,0 +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,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;gDAiBkC,WAAW;;;;;;;;;uFAS4B,4BAA4B;;;;;oFAK/B,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCxG,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;;;;;;;;;;;;;;;;CAgBb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAeb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,CAAC,GAAG,CAAC;oCACsB,WAAW;;;;;;;;;;CAU9C,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface LoginCommandIO {
2
+ cwd?: string;
3
+ envFilePath?: string;
4
+ }
5
+ /**
6
+ * Run `duet login`.
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`.
11
+ */
12
+ export declare function runLoginCommand(args: string[], io?: LoginCommandIO): Promise<void>;
13
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"AAOA,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,CAmD5F"}
@@ -0,0 +1,61 @@
1
+ import { resolveDuetAppBaseUrl } from "../lib/duet-app-url.js";
2
+ import { loginWithBrowser } from "../lib/login.js";
3
+ import { syncDefaultSkills } from "../lib/sync-skills.js";
4
+ import { shimDuetApiKeyToAiGateway } from "../model-resolution/duet-gateway.js";
5
+ import { printLoginHelp } from "./help.js";
6
+ import { defaultDuetEnvFilePath, fail, mergeEnvEntries, resolveUserPath } from "./shared.js";
7
+ /**
8
+ * Run `duet login`.
9
+ *
10
+ * Opens the duet web app in a browser, waits for confirmation, persists the
11
+ * returned `DUET_API_KEY` to the shared env file, then optionally syncs the
12
+ * org's default skills bundle to `~/.duet/skills`.
13
+ */
14
+ export async function runLoginCommand(args, io = {}) {
15
+ const cwd = io.cwd ?? process.cwd();
16
+ let envFilePathOverride = io.envFilePath;
17
+ let noBrowser = false;
18
+ let skipSkillSync = false;
19
+ for (let i = 0; i < args.length; i++) {
20
+ switch (args[i]) {
21
+ case "--env-file":
22
+ if (!args[i + 1] || args[i + 1]?.startsWith("-"))
23
+ fail(`Missing value for ${args[i]}`);
24
+ envFilePathOverride = args[++i];
25
+ break;
26
+ case "--no-browser":
27
+ noBrowser = true;
28
+ break;
29
+ case "--skip-skill-sync":
30
+ skipSkillSync = true;
31
+ break;
32
+ case "--help":
33
+ case "-h":
34
+ printLoginHelp();
35
+ return;
36
+ default:
37
+ fail(`Unknown login option: ${args[i]}`);
38
+ }
39
+ }
40
+ const targetEnvFile = envFilePathOverride
41
+ ? resolveUserPath(envFilePathOverride, cwd)
42
+ : defaultDuetEnvFilePath();
43
+ const result = await loginWithBrowser({ noBrowser });
44
+ await mergeEnvEntries(targetEnvFile, new Map([["DUET_API_KEY", result.apiKey]]));
45
+ console.error(`Saved DUET_API_KEY for ${result.orgName} (${result.orgSlug}) to ${targetEnvFile}`);
46
+ process.env.DUET_API_KEY = result.apiKey;
47
+ shimDuetApiKeyToAiGateway();
48
+ if (skipSkillSync) {
49
+ console.error("Skipping default skill sync (--skip-skill-sync).");
50
+ return;
51
+ }
52
+ console.error(`Checking default skills against ${resolveDuetAppBaseUrl()}...`);
53
+ const syncResult = await syncDefaultSkills({ apiKey: result.apiKey });
54
+ if (syncResult.status === "unchanged") {
55
+ console.error("Default skills already up to date.");
56
+ }
57
+ else {
58
+ console.error(`Synced ${syncResult.count} default skills.`);
59
+ }
60
+ }
61
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Observation } from "../types/memory.js";
2
+ /**
3
+ * Thin read/edit/delete wrapper over the PGlite database `MemoryStore` writes
4
+ * to. The `duet memories` command opens the same on-disk file, so changes
5
+ * made here are visible to subsequent runner sessions.
6
+ */
7
+ export declare class MemoryDb {
8
+ private readonly db;
9
+ private constructor();
10
+ /**
11
+ * Open the memory database at `path`, creating the file and parent
12
+ * directory if needed. The schema matches `memory/storage.ts` so the
13
+ * runner and this CLI command share one source of truth.
14
+ */
15
+ static open(path: string): Promise<MemoryDb>;
16
+ /** Load all observations ordered most recent first. */
17
+ list(): Promise<Observation[]>;
18
+ /** Replace just the `content` of an observation, preserving everything else. */
19
+ updateContent(id: string, content: string): Promise<void>;
20
+ /** Permanently remove an observation. There is no undo. */
21
+ delete(id: string): Promise<void>;
22
+ close(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=memories-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memories-db.d.ts","sourceRoot":"","sources":["../../../src/cli/memories-db.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;GAIG;AACH,qBAAa,QAAQ;IACC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAAvC,OAAO;IAEP;;;;OAIG;WACU,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBlD,uDAAuD;IACjD,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAUpC,gFAAgF;IAC1E,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,2DAA2D;IACrD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,74 @@
1
+ import { PGlite } from "@electric-sql/pglite";
2
+ import { mkdirSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ /**
5
+ * Thin read/edit/delete wrapper over the PGlite database `MemoryStore` writes
6
+ * to. The `duet memories` command opens the same on-disk file, so changes
7
+ * made here are visible to subsequent runner sessions.
8
+ */
9
+ export class MemoryDb {
10
+ db;
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ /**
15
+ * Open the memory database at `path`, creating the file and parent
16
+ * directory if needed. The schema matches `memory/storage.ts` so the
17
+ * runner and this CLI command share one source of truth.
18
+ */
19
+ static async open(path) {
20
+ mkdirSync(dirname(path), { recursive: true });
21
+ const db = new PGlite(path);
22
+ await db.exec(`
23
+ CREATE TABLE IF NOT EXISTS observations (
24
+ id TEXT PRIMARY KEY,
25
+ created_at BIGINT NOT NULL,
26
+ observed_date TEXT NOT NULL,
27
+ referenced_date TEXT,
28
+ relative_date TEXT,
29
+ time_of_day TEXT,
30
+ priority TEXT NOT NULL,
31
+ scope TEXT NOT NULL,
32
+ source_json TEXT NOT NULL,
33
+ content TEXT NOT NULL,
34
+ tags_json TEXT NOT NULL
35
+ );
36
+ `);
37
+ return new MemoryDb(db);
38
+ }
39
+ /** Load all observations ordered most recent first. */
40
+ async list() {
41
+ const result = await this.db.query(`SELECT id, created_at, observed_date, referenced_date, relative_date, time_of_day,
42
+ priority, scope, source_json, content, tags_json
43
+ FROM observations
44
+ ORDER BY created_at DESC`);
45
+ return result.rows.map(rowToObservation);
46
+ }
47
+ /** Replace just the `content` of an observation, preserving everything else. */
48
+ async updateContent(id, content) {
49
+ await this.db.query(`UPDATE observations SET content = $1 WHERE id = $2`, [content, id]);
50
+ }
51
+ /** Permanently remove an observation. There is no undo. */
52
+ async delete(id) {
53
+ await this.db.query(`DELETE FROM observations WHERE id = $1`, [id]);
54
+ }
55
+ async close() {
56
+ await this.db.close();
57
+ }
58
+ }
59
+ function rowToObservation(row) {
60
+ return {
61
+ id: row.id,
62
+ createdAt: row.created_at,
63
+ observedDate: row.observed_date,
64
+ ...(row.referenced_date !== null ? { referencedDate: row.referenced_date } : {}),
65
+ ...(row.relative_date !== null ? { relativeDate: row.relative_date } : {}),
66
+ ...(row.time_of_day !== null ? { timeOfDay: row.time_of_day } : {}),
67
+ priority: row.priority,
68
+ scope: row.scope,
69
+ source: JSON.parse(row.source_json),
70
+ content: row.content,
71
+ tags: JSON.parse(row.tags_json),
72
+ };
73
+ }
74
+ //# sourceMappingURL=memories-db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memories-db.js","sourceRoot":"","sources":["../../../src/cli/memories-db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;GAIG;AACH,MAAM,OAAO,QAAQ;IACkB;IAArC,YAAqC,EAAU;QAAV,OAAE,GAAF,EAAE,CAAQ;IAAG,CAAC;IAEnD;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY;QAC5B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;KAcb,CAAC,CAAC;QACH,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAChC;;;gCAG0B,CAC3B,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC;IAED,gFAAgF;IAChF,KAAK,CAAC,aAAa,CAAC,EAAU,EAAE,OAAe;QAC7C,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,oDAAoD,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF;AAgBD,SAAS,gBAAgB,CAAC,GAAmB;IAC3C,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,YAAY,EAAE,GAAG,CAAC,aAAa;QAC/B,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,GAAG,CAAC,GAAG,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAA0B;QAC5D,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAa;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { MemoryDb } from "./memories-db.js";
2
+ /**
3
+ * Run the interactive memories browser.
4
+ *
5
+ * Renders observations in a scrollable list with metadata per row, lets the
6
+ * user navigate with the arrow keys, edit the selected memory's content via
7
+ * `$EDITOR` (or vi as a fallback), or delete it outright. All edits and
8
+ * deletes hit `db` directly so the runner sees them on its next session.
9
+ */
10
+ export declare function runMemoriesTui(db: MemoryDb, dbPath: string): Promise<void>;
11
+ //# sourceMappingURL=memories-tui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memories-tui.d.ts","sourceRoot":"","sources":["../../../src/cli/memories-tui.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6MhF"}