nolo-cli 0.1.32 → 0.1.33

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 (230) hide show
  1. package/README.md +0 -6
  2. package/agent-runtime/agentRecordConfig.ts +2 -0
  3. package/agent-runtime/hostAdapter.ts +1 -0
  4. package/agent-runtime/index.ts +0 -21
  5. package/agent-runtime/localToolPolicy.ts +6 -13
  6. package/agent-runtime/localWorkspaceTools.ts +30 -333
  7. package/agent-runtime/platformChatProvider.ts +1 -4
  8. package/agent-runtime/runtimeToolPolicy.ts +47 -32
  9. package/agentAliases.ts +14 -83
  10. package/agentCommandSupport.ts +3 -6
  11. package/agentInternalCommandEntries.ts +2 -13
  12. package/agentListCommands.ts +19 -28
  13. package/agentMachineCommands.ts +40 -336
  14. package/agentPullCommand.ts +36 -56
  15. package/agentRecordCommands.ts +3 -5
  16. package/agentRecordHelpers.ts +22 -189
  17. package/agentRunCommand.ts +438 -107
  18. package/agentRuntimeLocal.ts +0 -10
  19. package/ai/agent/cliExecutor.ts +19 -323
  20. package/authCommands.ts +2 -36
  21. package/cli/agentAliases.ts +14 -83
  22. package/cli/agentCommandSupport.ts +3 -6
  23. package/cli/agentInternalCommandEntries.ts +2 -13
  24. package/cli/agentListCommands.ts +19 -28
  25. package/cli/agentMachineCommands.ts +40 -336
  26. package/cli/agentPullCommand.ts +36 -56
  27. package/cli/agentRecordCommands.ts +3 -5
  28. package/cli/agentRecordHelpers.ts +22 -189
  29. package/cli/agentRunCommand.ts +438 -107
  30. package/cli/agentRuntimeLocal.ts +0 -10
  31. package/cli/authCommands.ts +2 -36
  32. package/cli/cliEnvHelpers.ts +21 -162
  33. package/cli/client/agentRun.ts +853 -57
  34. package/cli/client/localRuntimeAdapter.ts +22 -159
  35. package/cli/client/streamingOutput.ts +3 -1
  36. package/cli/client/taskRunPrompt.ts +24 -7
  37. package/cli/commandRegistry.ts +2 -3
  38. package/cli/connectorRunArtifact.ts +10 -34
  39. package/cli/connectorWebSocketTarget.ts +6 -10
  40. package/cli/internalCommandEntries.ts +0 -8
  41. package/cli/localRuntimeDb.ts +2 -39
  42. package/cli/machineCommands.ts +189 -190
  43. package/cli/machineDaemonCommands.ts +165 -9
  44. package/cli/machineHeartbeatCommands.ts +2 -1
  45. package/cli/machineStatusCommands.ts +13 -5
  46. package/cli/machineWatchCommands.ts +1 -1
  47. package/cli/machineWsRunDispatch.ts +14 -48
  48. package/cli/machineWsSession.ts +0 -2
  49. package/cli/offlineMarxistsAgentCommand.ts +314 -0
  50. package/cli/runtimeDoctorCommands.ts +69 -18
  51. package/cli/scriptCommandEntries.ts +45 -5
  52. package/cli/tableCommands.ts +133 -33
  53. package/cli/taskRunCommand.ts +211 -16
  54. package/cli/tui/session.ts +372 -43
  55. package/cli/workflowInternalCommandEntries.ts +0 -20
  56. package/cliEnvHelpers.ts +21 -162
  57. package/client/agentConfigResolver.test.ts +2 -0
  58. package/client/agentRun.test.ts +12 -208
  59. package/client/agentRun.ts +853 -57
  60. package/client/localRuntimeAdapter.test.ts +9 -168
  61. package/client/localRuntimeAdapter.ts +22 -159
  62. package/client/localToolPolicy.test.ts +4 -28
  63. package/client/streamingOutput.ts +3 -1
  64. package/client/taskRunPrompt.ts +24 -7
  65. package/commandRegistry.ts +2 -3
  66. package/connectorRunArtifact.ts +10 -34
  67. package/connectorWebSocketTarget.ts +6 -10
  68. package/database/server/db.ts +34 -15
  69. package/internalCommandEntries.ts +0 -8
  70. package/localRuntimeDb.ts +2 -39
  71. package/machineCommands.ts +189 -190
  72. package/machineDaemonCommands.ts +165 -9
  73. package/machineHeartbeatCommands.ts +2 -1
  74. package/machineStatusCommands.ts +13 -5
  75. package/machineWatchCommands.ts +1 -1
  76. package/machineWsRunDispatch.ts +14 -48
  77. package/machineWsSession.ts +0 -2
  78. package/offlineMarxistsAgentCommand.ts +314 -0
  79. package/package.json +49 -193
  80. package/runtimeDoctorCommands.ts +69 -18
  81. package/scriptCommandEntries.ts +45 -5
  82. package/tableCommands.ts +133 -33
  83. package/taskRunCommand.ts +211 -16
  84. package/tui/session.ts +372 -43
  85. package/workflowInternalCommandEntries.ts +0 -20
  86. package/agent-runtime/dialogStatus.ts +0 -139
  87. package/agent-runtime/hostRuntimeConfig.ts +0 -86
  88. package/agentCreateCustomCommands.ts +0 -278
  89. package/agentDialogsCommands.ts +0 -227
  90. package/agentDoctorCommands.ts +0 -203
  91. package/agentRunLocalWorkspace.ts +0 -182
  92. package/agentRunParsing.ts +0 -298
  93. package/agentSuperviseCommands.ts +0 -8
  94. package/agentUnpublishCommands.ts +0 -113
  95. package/ai/agent/agentRunDialogLineage.ts +0 -56
  96. package/ai/policy/types.ts +0 -64
  97. package/ai/skills/skillSummaryMarker.ts +0 -26
  98. package/app/types.ts +0 -358
  99. package/build.ts +0 -16
  100. package/buildPublish.ts +0 -138
  101. package/buildPublishArtifactAssembly.ts +0 -724
  102. package/buildPublishImportAnalysis.ts +0 -242
  103. package/chat/messages/fetchMessages.ts +0 -84
  104. package/chat/messages/types.ts +0 -185
  105. package/cli/agentCreateCustomCommands.ts +0 -278
  106. package/cli/agentDialogsCommands.ts +0 -227
  107. package/cli/agentDoctorCommands.ts +0 -203
  108. package/cli/agentRunLocalWorkspace.ts +0 -182
  109. package/cli/agentRunParsing.ts +0 -298
  110. package/cli/agentSuperviseCommands.ts +0 -8
  111. package/cli/agentUnpublishCommands.ts +0 -113
  112. package/cli/buildPublish.ts +0 -138
  113. package/cli/buildPublishArtifactAssembly.ts +0 -724
  114. package/cli/buildPublishImportAnalysis.ts +0 -242
  115. package/cli/cliIoTypes.ts +0 -3
  116. package/cli/cliRuntimeDoctorReport.ts +0 -193
  117. package/cli/client/agentRunInput.ts +0 -10
  118. package/cli/client/agentRunLocalExecution.ts +0 -124
  119. package/cli/client/agentRunLocalExecutor.ts +0 -179
  120. package/cli/client/agentRunRuntimeSelection.ts +0 -145
  121. package/cli/client/agentRunServerTransport.ts +0 -397
  122. package/cli/client/agentRunTaskRunRecorder.ts +0 -176
  123. package/cli/customCodingAgentFlow.ts +0 -208
  124. package/cli/customCodingAgentRecord.ts +0 -179
  125. package/cli/dialogDataAccess.ts +0 -186
  126. package/cli/dialogInternalCommandEntries.ts +0 -11
  127. package/cli/dialogReadCommands.ts +0 -180
  128. package/cli/dialogReadHelpers.ts +0 -226
  129. package/cli/dialogStatusCommands.ts +0 -123
  130. package/cli/docInternalCommandEntries.ts +0 -20
  131. package/cli/hybridReadHelpers.ts +0 -109
  132. package/cli/machineCommandPrompts.ts +0 -79
  133. package/cli/machineCommandResolution.ts +0 -43
  134. package/cli/noloReadBridgePrompt.ts +0 -16
  135. package/cli/pageCreateCommands.ts +0 -219
  136. package/cli/pageDeleteCommands.ts +0 -167
  137. package/cli/pageReadCommands.ts +0 -151
  138. package/cli/pageUpdateCommands.ts +0 -249
  139. package/cli/pageWriteHelpers.ts +0 -209
  140. package/cli/publishPackage.ts +0 -36
  141. package/cli/runtimeInternalCommandEntries.ts +0 -15
  142. package/cli/runtimePassthroughCommands.ts +0 -22
  143. package/cli/scriptPassthroughHelpers.ts +0 -28
  144. package/cli/secretScanHelpers.ts +0 -31
  145. package/cli/spaceAttachCommands.ts +0 -134
  146. package/cli/spaceCategoryCommands.ts +0 -263
  147. package/cli/spaceCommands.ts +0 -295
  148. package/cli/spaceDeleteCommands.ts +0 -312
  149. package/cli/spaceInternalCommandEntries.ts +0 -21
  150. package/cli/spaceMutationHelpers.ts +0 -135
  151. package/cli/spaceReadCommands.ts +0 -323
  152. package/cli/tableDataOutput.ts +0 -41
  153. package/cli/tableDataSafety.ts +0 -26
  154. package/cli/tableMetaCommands.ts +0 -307
  155. package/cli/tableMutationCommands.ts +0 -266
  156. package/cli/tableQueryParsing.ts +0 -90
  157. package/cli/tableQueryRequest.ts +0 -53
  158. package/cli/taskRunActions.ts +0 -122
  159. package/cli/taskRunParsing.ts +0 -86
  160. package/cli/taskRunPromptShared.ts +0 -55
  161. package/cli/tui/tuiCatalog.ts +0 -22
  162. package/cli/tui/tuiCommandInterpreter.ts +0 -253
  163. package/cli/tui/tuiPresentation.ts +0 -146
  164. package/cliIoTypes.ts +0 -3
  165. package/cliRuntimeDoctorReport.ts +0 -193
  166. package/client/agentRunInput.ts +0 -10
  167. package/client/agentRunLocalExecution.test.ts +0 -123
  168. package/client/agentRunLocalExecution.ts +0 -124
  169. package/client/agentRunLocalExecutor.ts +0 -179
  170. package/client/agentRunRuntimeSelection.test.ts +0 -159
  171. package/client/agentRunRuntimeSelection.ts +0 -145
  172. package/client/agentRunServerTransport.ts +0 -397
  173. package/client/agentRunTaskRunRecorder.ts +0 -176
  174. package/connector-experimental/daemonLauncher.ts +0 -223
  175. package/create/space/spaceKeys.ts +0 -65
  176. package/create/types.ts +0 -21
  177. package/customCodingAgentFlow.ts +0 -208
  178. package/customCodingAgentRecord.ts +0 -179
  179. package/database/keys.ts +0 -765
  180. package/database/server/authorityStoreTypes.ts +0 -31
  181. package/database/server/legacyServerDb.ts +0 -58
  182. package/database/server/levelAuthorityStore.ts +0 -75
  183. package/database/server/memoryAuthorityStore.ts +0 -133
  184. package/database/server/serverStoreFactory.ts +0 -124
  185. package/database/tombstones.ts +0 -52
  186. package/database/utils/ulid.ts +0 -1
  187. package/dialogDataAccess.ts +0 -186
  188. package/dialogInternalCommandEntries.ts +0 -11
  189. package/dialogReadCommands.ts +0 -180
  190. package/dialogReadHelpers.ts +0 -226
  191. package/dialogStatusCommands.ts +0 -123
  192. package/docInternalCommandEntries.ts +0 -20
  193. package/hybridReadHelpers.ts +0 -109
  194. package/machineCommandPrompts.ts +0 -79
  195. package/machineCommandResolution.ts +0 -43
  196. package/noloReadBridgePrompt.ts +0 -16
  197. package/pageCreateCommands.ts +0 -219
  198. package/pageDeleteCommands.ts +0 -167
  199. package/pageReadCommands.ts +0 -151
  200. package/pageUpdateCommands.ts +0 -249
  201. package/pageWriteHelpers.ts +0 -209
  202. package/publishPackage.ts +0 -36
  203. package/runtimeInternalCommandEntries.ts +0 -15
  204. package/runtimePassthroughCommands.ts +0 -22
  205. package/scriptPassthroughHelpers.ts +0 -28
  206. package/secretScanHelpers.ts +0 -31
  207. package/share/helpers.ts +0 -302
  208. package/share/keys.ts +0 -243
  209. package/share/types.ts +0 -100
  210. package/spaceAttachCommands.ts +0 -134
  211. package/spaceCategoryCommands.ts +0 -263
  212. package/spaceCommands.ts +0 -295
  213. package/spaceDeleteCommands.ts +0 -312
  214. package/spaceInternalCommandEntries.ts +0 -21
  215. package/spaceMutationHelpers.ts +0 -135
  216. package/spaceReadCommands.ts +0 -323
  217. package/tableDataOutput.ts +0 -41
  218. package/tableDataSafety.ts +0 -26
  219. package/tableMetaCommands.ts +0 -307
  220. package/tableMutationCommands.ts +0 -266
  221. package/tableQueryParsing.ts +0 -90
  222. package/tableQueryRequest.ts +0 -53
  223. package/taskRunActions.ts +0 -122
  224. package/taskRunParsing.ts +0 -86
  225. package/taskRunPromptShared.ts +0 -55
  226. package/tui/tuiCatalog.ts +0 -22
  227. package/tui/tuiCommandInterpreter.test.ts +0 -169
  228. package/tui/tuiCommandInterpreter.ts +0 -253
  229. package/tui/tuiPresentation.test.ts +0 -154
  230. package/tui/tuiPresentation.ts +0 -146
@@ -14,8 +14,8 @@
14
14
  */
15
15
 
16
16
  import { exec, execSync, spawn } from "child_process";
17
- import { createHash, randomUUID } from "node:crypto";
18
- import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
17
+ import { randomUUID } from "node:crypto";
18
+ import { mkdtempSync, readFileSync, rmSync } from "node:fs";
19
19
  import { join } from "node:path";
20
20
  import { tmpdir } from "node:os";
21
21
  import { resolveLaunchableCodexCommand } from "../../connector-experimental/codexBinary";
@@ -50,25 +50,6 @@ export interface CliExecuteResult {
50
50
  warnings?: string[];
51
51
  }
52
52
 
53
- type AgyDebugArtifact = {
54
- dir: string;
55
- promptHash: string;
56
- promptBytes: number;
57
- writeResult: (args: {
58
- startedAt: string;
59
- finishedAt: string;
60
- elapsedMs: number;
61
- cwd: string;
62
- timeoutMs: number;
63
- args: string[];
64
- stdout: string;
65
- stderr: string;
66
- exitCode: number | null;
67
- outcome: "succeeded" | "timed_out" | "spawn_error" | "failed";
68
- errorMessage?: string;
69
- }) => void;
70
- };
71
-
72
53
  type CliSessionMessage = {
73
54
  role: "user" | "assistant";
74
55
  content: string;
@@ -190,18 +171,15 @@ function supportsNativeSystemPrompt(provider: CliProvider): boolean {
190
171
  }
191
172
 
192
173
  function supportsModel(provider: CliProvider): boolean {
193
- // Antigravity CLI does not expose a model selection flag.
194
- // Codex is handled separately so explicit opt-in can still pass --model through.
195
- return provider !== "agy";
174
+ // Codex accepts --model syntactically, but real desktop/subscription installs
175
+ // can fail with plan-gating errors. Keep model routing out of Codex CLI.
176
+ return provider !== "agy" && provider !== "codex";
196
177
  }
197
178
 
198
179
  function supportsReasoningEffort(provider: CliProvider): boolean {
199
180
  return provider === "claude" || provider === "copilot";
200
181
  }
201
182
 
202
- function shouldPassCodexModel(options: CliExecuteOptions): boolean {
203
- return (options.env?.NOLO_CODEX_CLI_ALLOW_MODEL ?? process.env.NOLO_CODEX_CLI_ALLOW_MODEL) === "1";
204
- }
205
183
  function shouldPassClaudeModel(options: CliExecuteOptions): boolean {
206
184
  return (options.env?.NOLO_CLAUDE_CLI_ALLOW_MODEL ?? process.env.NOLO_CLAUDE_CLI_ALLOW_MODEL) === "1";
207
185
  }
@@ -217,11 +195,7 @@ function collectCliCapabilityWarnings(
217
195
  warnings.push(`${label} does not support reasoning_effort; ignored.`);
218
196
  }
219
197
 
220
- if (provider === "codex" && options.model !== undefined && !shouldPassCodexModel(options)) {
221
- warnings.push(
222
- "Codex CLI model selection is disabled by default because real Codex installs can reject --model with subscription/plan errors; set NOLO_CODEX_CLI_ALLOW_MODEL=1 to pass it through."
223
- );
224
- } else if (provider === "claude" && options.model !== undefined && !shouldPassClaudeModel(options)) {
198
+ if (provider === "claude" && options.model !== undefined && !shouldPassClaudeModel(options)) {
225
199
  warnings.push(
226
200
  "Claude CLI model selection is disabled by default because current installs can reject --model; set NOLO_CLAUDE_CLI_ALLOW_MODEL=1 to pass it through."
227
201
  );
@@ -254,121 +228,16 @@ function resolveCliExecution(
254
228
  options: CliExecuteOptions
255
229
  ): { prompt: string; options: CliExecuteOptions; warnings: string[] } {
256
230
  const warnings = collectCliCapabilityWarnings(provider, options);
257
- const resolvedPrompt =
258
- supportsNativeSystemPrompt(provider) || !options.systemPrompt?.trim()
259
- ? prompt
260
- : buildCliPrompt(options.systemPrompt, prompt);
261
- const resolvedOptions =
262
- supportsNativeSystemPrompt(provider) || !options.systemPrompt?.trim()
263
- ? options
264
- : {
265
- ...options,
266
- systemPrompt: undefined,
267
- };
268
- const agyPrompt = provider === "agy" ? compactAgyPrompt(resolvedPrompt) : null;
269
- return {
270
- prompt: agyPrompt?.prompt ?? resolvedPrompt,
271
- options: resolvedOptions,
272
- warnings: [...warnings, ...(agyPrompt?.warnings ?? [])],
273
- };
274
- }
275
-
276
- const AGY_PRESERVED_PROMPT_BLOCK_HEADERS = [
277
- "--- Nolo read-only CLI bridge ---",
278
- "--- Nolo task-run tool bridge ---",
279
- ] as const;
280
- const AGY_OPTIONAL_TASKRUN_GUIDANCE_HEADERS = [
281
- "## TaskRun tool guidance (2026-05-17)",
282
- "## TaskRun tool strictness (2026-05-17)",
283
- "## TaskRun delegation boundary (2026-05-17)",
284
- ] as const;
285
-
286
- function escapeRegExp(value: string) {
287
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
288
- }
289
-
290
- function extractPromptBlock(source: string, header: string) {
291
- const pattern = new RegExp(
292
- `(?:^|\\n)(${escapeRegExp(header)}\\n[\\s\\S]*?)(?=\\n{2,}--- [^\\n]+ ---|\\n{2,}User task:|\\n{2,}--- User task ---|$)`,
293
- );
294
- const match = source.match(pattern);
295
- if (!match) return null;
296
- return {
297
- block: match[1].trim(),
298
- remaining: source.replace(pattern, "\n\n"),
299
- };
300
- }
301
-
302
- function stripMarkdownSection(source: string, header: string) {
303
- const pattern = new RegExp(
304
- `(?:^|\\n)${escapeRegExp(header)}\\n[\\s\\S]*?(?=\\n{2,}## [^\\n]+|\\n{2,}--- [^\\n]+ ---|\\n{2,}User task:|\\n{2,}--- User task ---|$)`,
305
- );
306
- return source.replace(pattern, "\n\n");
307
- }
308
-
309
- function compactAgyPrompt(prompt: string): { prompt: string; warnings: string[] } {
310
- let next = prompt;
311
- let changed = false;
312
- const preservedBlocks: string[] = [];
313
-
314
- const stripBlock = (pattern: RegExp) => {
315
- const updated = next.replace(pattern, "\n\n");
316
- if (updated !== next) {
317
- next = updated;
318
- changed = true;
319
- }
320
- };
321
-
322
- for (const header of AGY_PRESERVED_PROMPT_BLOCK_HEADERS) {
323
- const extracted = extractPromptBlock(next, header);
324
- if (!extracted) continue;
325
- next = extracted.remaining;
326
- preservedBlocks.push(extracted.block);
327
- changed = true;
328
- }
329
-
330
- // Antigravity intermittently stalls on long runtime metadata tails. The
331
- // connector already enforces permissions and owns dialog context, so trim
332
- // these blocks before handing the prompt to agy.
333
- stripBlock(/(?:^|\n)Conversation Reference:\n[\s\S]*?(?=\n{2,}--- Machine permission policy ---|\n{2,}--- User task ---|\n{2,}User task:|$)/);
334
- stripBlock(/(?:^|\n)--- Machine permission policy ---\n[\s\S]*?(?=\n{2,}--- User task ---|\n{2,}User task:|$)/);
335
- if (!preservedBlocks.some((block) => block.startsWith("--- Nolo task-run tool bridge ---"))) {
336
- for (const header of AGY_OPTIONAL_TASKRUN_GUIDANCE_HEADERS) {
337
- const updated = stripMarkdownSection(next, header);
338
- if (updated !== next) {
339
- next = updated;
340
- changed = true;
341
- }
342
- }
231
+ if (supportsNativeSystemPrompt(provider) || !options.systemPrompt?.trim()) {
232
+ return { prompt, options, warnings };
343
233
  }
344
-
345
- let normalized = next
346
- .replace(/\n\n--- User task ---\n/g, "\n\nUser task:\n")
347
- .replace(/\n{3,}/g, "\n\n")
348
- .trim();
349
- if (preservedBlocks.length > 0) {
350
- const reinjected = preservedBlocks.join("\n\n");
351
- if (/^User task:\n/.test(normalized)) {
352
- normalized = `${reinjected}\n\n${normalized}`;
353
- } else if (/\n\nUser task:\n/.test(normalized)) {
354
- normalized = normalized.replace(/\n\nUser task:\n/, `\n\n${reinjected}\n\nUser task:\n`);
355
- } else {
356
- normalized = `${normalized}\n\n${reinjected}`.trim();
357
- }
358
- }
359
- if (normalized !== prompt) {
360
- changed = true;
361
- }
362
-
363
- if (!changed) {
364
- return { prompt, warnings: [] };
365
- }
366
-
367
234
  return {
368
- prompt: normalized,
369
- warnings: [
370
- "Antigravity CLI prompt was compacted to avoid known timeout patterns in conversation-reference and machine-permission runtime blocks.",
371
- ],
235
+ prompt: buildCliPrompt(options.systemPrompt, prompt),
236
+ options: {
237
+ ...options,
238
+ systemPrompt: undefined,
239
+ },
240
+ warnings,
372
241
  };
373
242
  }
374
243
 
@@ -536,7 +405,6 @@ function executeCodex(
536
405
  options: CliExecuteOptions
537
406
  ): Promise<CliExecuteResult> {
538
407
  const {
539
- model,
540
408
  timeout = 120_000,
541
409
  cwd = process.cwd(),
542
410
  yolo = true,
@@ -557,12 +425,6 @@ function executeCodex(
557
425
  "--cd",
558
426
  cwd,
559
427
  ];
560
- // Codex CLI accepts --model syntactically, but real desktop/subscription
561
- // installs can fail with plan-gating errors. Keep default execution stable.
562
- if (model && shouldPassCodexModel(options)) {
563
- args.push("--model");
564
- args.push(model);
565
- }
566
428
  if (yolo) {
567
429
  args.push("--sandbox");
568
430
  args.push("danger-full-access");
@@ -707,82 +569,9 @@ function formatCliTimeout(timeoutMs: number) {
707
569
  return `${Math.max(1, Math.ceil(timeoutMs / 1000))}s`;
708
570
  }
709
571
 
710
- function shortHash(value: string) {
711
- return createHash("sha256").update(value).digest("hex").slice(0, 12);
712
- }
713
-
714
- function resolveAgyDebugDir(env?: Record<string, string | undefined>) {
715
- const raw = env?.NOLO_AGY_DEBUG_DIR ?? process.env.NOLO_AGY_DEBUG_DIR ?? "";
716
- return raw.trim();
717
- }
718
-
719
- function createAgyDebugArtifact(args: {
720
- prompt: string;
721
- attempt: number;
722
- timeoutMs: number;
723
- cwd: string;
724
- env?: Record<string, string | undefined>;
725
- }): AgyDebugArtifact | null {
726
- const debugRoot = resolveAgyDebugDir(args.env);
727
- if (!debugRoot) return null;
728
-
729
- const promptHash = shortHash(args.prompt);
730
- const promptBytes = Buffer.byteLength(args.prompt, "utf8");
731
- const dir = join(debugRoot, `${Date.now()}-agy-${promptHash}-attempt-${args.attempt + 1}`);
732
- mkdirSync(dir, { recursive: true });
733
- writeFileSync(join(dir, "prompt.txt"), args.prompt, "utf8");
734
-
735
- return {
736
- dir,
737
- promptHash,
738
- promptBytes,
739
- writeResult: (result) => {
740
- writeFileSync(join(dir, "stdout.txt"), result.stdout, "utf8");
741
- writeFileSync(join(dir, "stderr.txt"), result.stderr, "utf8");
742
- writeFileSync(
743
- join(dir, "meta.json"),
744
- `${JSON.stringify({
745
- promptHash,
746
- promptBytes,
747
- attempt: args.attempt + 1,
748
- startedAt: result.startedAt,
749
- finishedAt: result.finishedAt,
750
- elapsedMs: result.elapsedMs,
751
- cwd: result.cwd,
752
- timeoutMs: result.timeoutMs,
753
- args: result.args,
754
- exitCode: result.exitCode,
755
- outcome: result.outcome,
756
- errorMessage: result.errorMessage ?? null,
757
- stdoutBytes: Buffer.byteLength(result.stdout, "utf8"),
758
- stderrBytes: Buffer.byteLength(result.stderr, "utf8"),
759
- }, null, 2)}\n`,
760
- "utf8"
761
- );
762
- },
763
- };
764
- }
765
-
766
- function isAgyTimeoutError(error: unknown) {
767
- return error instanceof Error && /Antigravity CLI timed out after \d+ms/.test(error.message);
768
- }
769
-
770
- function resolveAgyTimeoutRetryCount(env?: Record<string, string | undefined>) {
771
- const raw = env?.NOLO_AGY_TIMEOUT_RETRIES ?? process.env.NOLO_AGY_TIMEOUT_RETRIES ?? "2";
772
- const parsed = Number.parseInt(raw, 10);
773
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : 2;
774
- }
775
-
776
- const AGY_PROCESS_TIMEOUT_BUFFER_MS = 10_000;
777
-
778
- function isAgyUpstreamTimeoutText(stdout: string) {
779
- return /^Error:\s+timed out waiting for response\b/i.test(stdout.trim());
780
- }
781
-
782
- function executeAgyOnce(
572
+ function executeAgy(
783
573
  prompt: string,
784
- options: CliExecuteOptions,
785
- attempt = 0
574
+ options: CliExecuteOptions
786
575
  ): Promise<CliExecuteResult> {
787
576
  const {
788
577
  timeout = 120_000,
@@ -804,14 +593,6 @@ function executeAgyOnce(
804
593
  }
805
594
 
806
595
  const start = Date.now();
807
- const startedAt = new Date(start).toISOString();
808
- const debugArtifact = createAgyDebugArtifact({
809
- prompt,
810
- attempt,
811
- timeoutMs: timeout,
812
- cwd,
813
- env: options.env,
814
- });
815
596
  const proc = spawn("agy", args, {
816
597
  cwd,
817
598
  env: buildCliProcessEnv(options.env),
@@ -820,40 +601,12 @@ function executeAgyOnce(
820
601
  let stdout = "";
821
602
  let stderr = "";
822
603
  let timer: ReturnType<typeof setTimeout> | undefined;
823
- let timedOut = false;
824
-
825
- const flushDebug = (result: {
826
- exitCode: number | null;
827
- outcome: "succeeded" | "timed_out" | "spawn_error" | "failed";
828
- errorMessage?: string;
829
- }) => {
830
- debugArtifact?.writeResult({
831
- startedAt,
832
- finishedAt: new Date().toISOString(),
833
- elapsedMs: Date.now() - start,
834
- cwd,
835
- timeoutMs: timeout,
836
- args,
837
- stdout,
838
- stderr,
839
- exitCode: result.exitCode,
840
- outcome: result.outcome,
841
- ...(result.errorMessage ? { errorMessage: result.errorMessage } : {}),
842
- });
843
- };
844
604
 
845
605
  if (timeout > 0) {
846
606
  timer = setTimeout(() => {
847
- timedOut = true;
848
607
  proc.kill("SIGTERM");
849
- const error = new Error(`Antigravity CLI timed out after ${timeout}ms`);
850
- flushDebug({
851
- exitCode: null,
852
- outcome: "timed_out",
853
- errorMessage: error.message,
854
- });
855
- reject(error);
856
- }, timeout + AGY_PROCESS_TIMEOUT_BUFFER_MS);
608
+ reject(new Error(`Antigravity CLI timed out after ${timeout}ms`));
609
+ }, timeout + 1_000);
857
610
  }
858
611
 
859
612
  proc.stdout.on("data", (data: Buffer) => {
@@ -866,32 +619,11 @@ function executeAgyOnce(
866
619
 
867
620
  proc.on("close", (code) => {
868
621
  if (timer) clearTimeout(timer);
869
- if (timedOut) return;
870
622
  if (code !== 0 && code !== null) {
871
- const error = new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderr}`);
872
- flushDebug({
873
- exitCode: code,
874
- outcome: "failed",
875
- errorMessage: error.message,
876
- });
877
- reject(error);
878
- return;
879
- }
880
- if (isAgyUpstreamTimeoutText(stdout)) {
881
- const error = new Error(`Antigravity CLI timed out after ${timeout}ms`);
882
- flushDebug({
883
- exitCode: code,
884
- outcome: "timed_out",
885
- errorMessage: error.message,
886
- });
887
- reject(error);
623
+ reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderr}`));
888
624
  return;
889
625
  }
890
626
 
891
- flushDebug({
892
- exitCode: code,
893
- outcome: "succeeded",
894
- });
895
627
  resolve({
896
628
  text: stdout.trim(),
897
629
  raw: stdout,
@@ -901,47 +633,11 @@ function executeAgyOnce(
901
633
 
902
634
  proc.on("error", (err) => {
903
635
  if (timer) clearTimeout(timer);
904
- flushDebug({
905
- exitCode: null,
906
- outcome: "spawn_error",
907
- errorMessage: err instanceof Error ? err.message : String(err),
908
- });
909
636
  reject(err);
910
637
  });
911
638
  });
912
639
  }
913
640
 
914
- async function executeAgy(
915
- prompt: string,
916
- options: CliExecuteOptions
917
- ): Promise<CliExecuteResult> {
918
- const maxRetries = resolveAgyTimeoutRetryCount(options.env);
919
- let attempt = 0;
920
- let lastError: unknown;
921
-
922
- while (attempt <= maxRetries) {
923
- try {
924
- const result = await executeAgyOnce(prompt, options, attempt);
925
- if (attempt === 0) return result;
926
- return {
927
- ...result,
928
- warnings: [
929
- ...(result.warnings ?? []),
930
- `Antigravity CLI succeeded after ${attempt} timeout retr${attempt === 1 ? "y" : "ies"}.`,
931
- ],
932
- };
933
- } catch (error) {
934
- lastError = error;
935
- if (!isAgyTimeoutError(error) || attempt >= maxRetries) {
936
- throw error;
937
- }
938
- attempt += 1;
939
- }
940
- }
941
-
942
- throw lastError instanceof Error ? lastError : new Error(String(lastError));
943
- }
944
-
945
641
  // ── 注册表(新增 CLI 工具时在这里加) ────────────────────────────────────────
946
642
 
947
643
  const EXECUTORS: Record<
package/authCommands.ts CHANGED
@@ -9,7 +9,6 @@ import {
9
9
  loadProfileConfig,
10
10
  saveDefaultProfile,
11
11
  } from "./client/profileConfig";
12
- import { parseUserIdFromAuthToken } from "./cliEnvHelpers";
13
12
  import { DEFAULT_NOLO_SERVER_URL } from "./defaultServer";
14
13
 
15
14
  function getArg(args: string[], flag: string) {
@@ -68,47 +67,17 @@ async function saveTokenLogin(args: {
68
67
  configPath: string;
69
68
  serverUrl: string;
70
69
  authToken: string;
71
- fetchImpl: typeof fetch;
72
70
  output: Pick<Console, "log">;
73
71
  error: Pick<Console, "error">;
74
72
  }) {
75
- const authToken = args.authToken.trim();
76
- if (!authToken) {
73
+ if (!args.authToken.trim()) {
77
74
  args.error.error("No auth token provided.");
78
75
  return 1;
79
76
  }
80
77
 
81
- const userId = parseUserIdFromAuthToken(authToken);
82
- if (!userId) {
83
- args.error.error("Auth token payload is missing userId.");
84
- return 1;
85
- }
86
-
87
- try {
88
- const res = await args.fetchImpl(
89
- `${args.serverUrl}/api/v1/db/query/${encodeURIComponent(userId)}?limit=1`,
90
- {
91
- method: "POST",
92
- headers: {
93
- Authorization: `Bearer ${authToken}`,
94
- "Content-Type": "application/json",
95
- },
96
- body: JSON.stringify({ type: "agent" }),
97
- }
98
- );
99
- if (res.status === 401 || res.status === 403) {
100
- args.error.error(
101
- `Auth token is not valid for ${args.serverUrl}. Log in against the matching server or use a token issued by that server.`
102
- );
103
- return 1;
104
- }
105
- } catch {
106
- // Allow saving when the server is temporarily unreachable.
107
- }
108
-
109
78
  saveDefaultProfile(args.configPath, {
110
79
  serverUrl: args.serverUrl,
111
- authToken,
80
+ authToken: args.authToken.trim(),
112
81
  });
113
82
  args.output.log(`Saved profile default -> ${args.serverUrl}`);
114
83
  return 0;
@@ -175,7 +144,6 @@ async function runWebLogin(args: {
175
144
  configPath: args.configPath,
176
145
  serverUrl: approvedServer,
177
146
  authToken: poll.token,
178
- fetchImpl: args.fetchImpl,
179
147
  output: args.output,
180
148
  error: args.error,
181
149
  });
@@ -205,7 +173,6 @@ export async function runLoginCommand(args: string[], deps: LoginCommandDeps = {
205
173
  configPath,
206
174
  serverUrl,
207
175
  authToken: tokenArg,
208
- fetchImpl: deps.fetchImpl ?? fetch,
209
176
  output: outputTarget,
210
177
  error: errorTarget,
211
178
  });
@@ -220,7 +187,6 @@ export async function runLoginCommand(args: string[], deps: LoginCommandDeps = {
220
187
  configPath,
221
188
  serverUrl,
222
189
  authToken,
223
- fetchImpl: deps.fetchImpl ?? fetch,
224
190
  output: outputTarget,
225
191
  error: errorTarget,
226
192
  });
@@ -10,17 +10,13 @@ export const NOLO_PROJECT_MANAGER_AGENT_KEY =
10
10
  export const NOLO_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000001J740Q";
11
11
  export const NOLO_FULLSTACK_AGENT_KEY =
12
12
  `agent-${PLATFORM_DEMO_USER_ID}-${NOLO_FULLSTACK_AGENT_ID}`;
13
+ export const NOLO_SENIOR_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000000T3XR4";
14
+ export const NOLO_SENIOR_FULLSTACK_AGENT_KEY =
15
+ `agent-${PLATFORM_DEMO_USER_ID}-${NOLO_SENIOR_FULLSTACK_AGENT_ID}`;
13
16
  export const NOLO_REVIEW_AGENT_ID = "01CODEXCLIMAIN00000001OK";
14
17
  export const NOLO_REVIEW_AGENT_KEY =
15
18
  `agent-${PLATFORM_DEMO_USER_ID}-${NOLO_REVIEW_AGENT_ID}`;
16
19
 
17
- type PlatformAgentAliasSpec = {
18
- agentId: string;
19
- canonicalKey: string;
20
- aliases: string[];
21
- preferCurrentUserCopy?: boolean;
22
- };
23
-
24
20
  const AGENT_ALIAS_TO_KEY: Record<string, string> = {
25
21
  "nolo-frontend": FRONTEND_IMPLEMENTER_AGENT_KEY,
26
22
  "frontend-implementer": FRONTEND_IMPLEMENTER_AGENT_KEY,
@@ -29,11 +25,21 @@ const AGENT_ALIAS_TO_KEY: Record<string, string> = {
29
25
  "front-end": FRONTEND_IMPLEMENTER_AGENT_KEY,
30
26
  "前端": FRONTEND_IMPLEMENTER_AGENT_KEY,
31
27
  "前端实现员": FRONTEND_IMPLEMENTER_AGENT_KEY,
28
+ "nolo-project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
29
+ "project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
30
+ "nolo-pm": NOLO_PROJECT_MANAGER_AGENT_KEY,
31
+ pm: NOLO_PROJECT_MANAGER_AGENT_KEY,
32
+ "项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
33
+ "nolo 项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
32
34
  "nolo-fullstack": NOLO_FULLSTACK_AGENT_KEY,
33
35
  fullstack: NOLO_FULLSTACK_AGENT_KEY,
34
36
  "full-stack": NOLO_FULLSTACK_AGENT_KEY,
35
37
  "全栈": NOLO_FULLSTACK_AGENT_KEY,
36
38
  "nolo 全栈工程师": NOLO_FULLSTACK_AGENT_KEY,
39
+ "senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
40
+ "nolo-senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
41
+ "高级全栈": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
42
+ "nolo 高级全栈工程师": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
37
43
  "nolo-reviewer": NOLO_REVIEW_AGENT_KEY,
38
44
  reviewer: NOLO_REVIEW_AGENT_KEY,
39
45
  "nolo-code-review": NOLO_REVIEW_AGENT_KEY,
@@ -43,45 +49,6 @@ const AGENT_ALIAS_TO_KEY: Record<string, string> = {
43
49
  "nolo 代码审查": NOLO_REVIEW_AGENT_KEY,
44
50
  };
45
51
 
46
- const PLATFORM_AGENT_ALIAS_SPECS: PlatformAgentAliasSpec[] = [
47
- {
48
- agentId: FRONTEND_IMPLEMENTER_AGENT_ID,
49
- canonicalKey: FRONTEND_IMPLEMENTER_AGENT_KEY,
50
- aliases: [
51
- "nolo-frontend",
52
- "frontend-implementer",
53
- "frontend-agent",
54
- "frontend",
55
- "front-end",
56
- "前端",
57
- "前端实现员",
58
- ],
59
- preferCurrentUserCopy: true,
60
- },
61
- {
62
- agentId: NOLO_FULLSTACK_AGENT_ID,
63
- canonicalKey: NOLO_FULLSTACK_AGENT_KEY,
64
- aliases: ["nolo-fullstack", "fullstack", "full-stack", "全栈", "nolo 全栈工程师"],
65
- },
66
- {
67
- agentId: NOLO_REVIEW_AGENT_ID,
68
- canonicalKey: NOLO_REVIEW_AGENT_KEY,
69
- aliases: [
70
- "nolo-reviewer",
71
- "reviewer",
72
- "nolo-code-review",
73
- "code-review",
74
- "review",
75
- "代码审查",
76
- "nolo 代码审查",
77
- ],
78
- },
79
- ];
80
-
81
- function normalizeAlias(raw: string) {
82
- return raw.trim().toLowerCase();
83
- }
84
-
85
52
  function parseAgentKeyFromInput(raw: string): string {
86
53
  const trimmed = raw.trim();
87
54
  if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
@@ -91,42 +58,6 @@ function parseAgentKeyFromInput(raw: string): string {
91
58
  return trimmed;
92
59
  }
93
60
 
94
- export function resolveAgentKeyAlias(raw: string): string | undefined {
95
- return AGENT_ALIAS_TO_KEY[normalizeAlias(raw)];
96
- }
97
-
98
- export function buildPrivateAgentKey(userId: string, agentId: string) {
99
- return `agent-${userId}-${agentId}`;
100
- }
101
-
102
- export function resolvePlatformAgentAliasSpec(raw: string): PlatformAgentAliasSpec | undefined {
103
- const normalized = normalizeAlias(raw);
104
- return PLATFORM_AGENT_ALIAS_SPECS.find((spec) => spec.aliases.includes(normalized));
105
- }
106
-
107
- export function buildCurrentUserPlatformAgentCandidateKeys(raw: string, userId?: string) {
108
- const spec = resolvePlatformAgentAliasSpec(raw);
109
- if (!spec) return [];
110
-
111
- const keys: string[] = [];
112
- const normalizedUserId = userId?.trim();
113
- if (spec.preferCurrentUserCopy && normalizedUserId) {
114
- keys.push(buildPrivateAgentKey(normalizedUserId, spec.agentId));
115
- }
116
- keys.push(spec.canonicalKey);
117
- return Array.from(new Set(keys));
118
- }
119
-
120
- export function isKnownPlatformAgentKey(raw?: string) {
121
- const trimmed = raw?.trim();
122
- if (!trimmed) return false;
123
- return PLATFORM_AGENT_ALIAS_SPECS.some(
124
- (spec) => trimmed === spec.agentId || trimmed.endsWith(`-${spec.agentId}`)
125
- );
126
- }
127
-
128
61
  export function resolveCliAgentKeyInput(raw: string): string {
129
- return resolveAgentKeyAlias(raw) ?? parseAgentKeyFromInput(raw);
62
+ return AGENT_ALIAS_TO_KEY[raw.trim().toLowerCase()] ?? parseAgentKeyFromInput(raw);
130
63
  }
131
-
132
- export const resolveAgentKeyInput = resolveCliAgentKeyInput;
@@ -1,9 +1,8 @@
1
1
  import type { MachineHeartbeat } from "../connector-experimental/protocol";
2
2
  import type { CliKvDb } from "./client/hybridRecordStore";
3
3
  import type { EnvLike } from "./cliEnvHelpers";
4
- import type { OutputLike } from "./cliIoTypes";
5
- import type { MachineWsRunDispatchDeps } from "./machineWsRunDispatch";
6
- export type { OutputLike } from "./cliIoTypes";
4
+
5
+ export type OutputLike = { write(chunk: string): unknown };
7
6
 
8
7
  export type SmokeWebSocketOptions = {
9
8
  headers: Record<string, string>;
@@ -41,10 +40,8 @@ export type AgentCommandDeps = {
41
40
  pushMessage: (response: string) => void,
42
41
  executeCli: LocalCliExecutor,
43
42
  env: EnvLike,
44
- fetchImpl: typeof fetch,
45
- dispatchDeps?: MachineWsRunDispatchDeps,
43
+ fetchImpl: typeof fetch
46
44
  ) => Promise<void>;
47
- connectorRunDispatchDeps?: MachineWsRunDispatchDeps;
48
45
  localRuntimeProbe?: (env: EnvLike) => Promise<LocalRuntimeProbeResult>;
49
46
  };
50
47