nolo-cli 0.1.32 → 0.1.34

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 (234) hide show
  1. package/README.md +4 -10
  2. package/agent-runtime/agentRecordConfig.ts +10 -0
  3. package/agent-runtime/hostAdapter.ts +10 -1
  4. package/agent-runtime/index.ts +9 -20
  5. package/agent-runtime/localLoop.ts +49 -2
  6. package/agent-runtime/localToolPolicy.ts +76 -34
  7. package/agent-runtime/localWorkspaceTools.ts +30 -333
  8. package/agent-runtime/openAiCompatibleProvider.ts +7 -3
  9. package/agent-runtime/openAiCompatibleProviderConfig.ts +15 -26
  10. package/agent-runtime/platformChatProvider.ts +47 -73
  11. package/agent-runtime/providerResolution.ts +244 -0
  12. package/agent-runtime/runtimeToolPolicy.ts +77 -29
  13. package/agent-runtime/shellCommandPolicy.ts +120 -0
  14. package/agentAliases.ts +14 -83
  15. package/agentCommandSupport.ts +3 -6
  16. package/agentInternalCommandEntries.ts +4 -13
  17. package/agentListCommands.ts +18 -27
  18. package/agentMachineCommands.ts +40 -336
  19. package/agentPullCommand.ts +30 -55
  20. package/agentRecordCommands.ts +84 -1
  21. package/agentRecordHelpers.ts +102 -186
  22. package/agentRunCommand.ts +438 -107
  23. package/agentRuntimeLocal.ts +2 -9
  24. package/ai/agent/cliExecutor.ts +19 -323
  25. package/ai/tools/toolNameAliases.ts +70 -0
  26. package/authCommands.ts +2 -36
  27. package/cli/agentAliases.ts +14 -83
  28. package/cli/agentCommandSupport.ts +3 -6
  29. package/cli/agentInternalCommandEntries.ts +4 -13
  30. package/cli/agentListCommands.ts +18 -27
  31. package/cli/agentMachineCommands.ts +40 -336
  32. package/cli/agentPullCommand.ts +30 -55
  33. package/cli/agentRecordCommands.ts +84 -1
  34. package/cli/agentRecordHelpers.ts +102 -186
  35. package/cli/agentRunCommand.ts +438 -107
  36. package/cli/agentRuntimeLocal.ts +2 -9
  37. package/cli/authCommands.ts +2 -36
  38. package/cli/cliCommandDispatch.ts +2 -2
  39. package/cli/cliEnvHelpers.ts +34 -107
  40. package/cli/client/agentRun.ts +854 -57
  41. package/cli/client/localRuntimeAdapter.ts +59 -159
  42. package/cli/client/streamingOutput.ts +3 -1
  43. package/cli/client/taskRunPrompt.ts +24 -7
  44. package/cli/commandRegistry.ts +4 -5
  45. package/cli/connectorRunArtifact.ts +10 -34
  46. package/cli/connectorWebSocketTarget.ts +6 -10
  47. package/cli/internalCommandEntries.ts +0 -8
  48. package/cli/localRuntimeDb.ts +2 -39
  49. package/cli/machineCommands.ts +189 -190
  50. package/cli/machineDaemonCommands.ts +165 -9
  51. package/cli/machineHeartbeatCommands.ts +2 -1
  52. package/cli/machineStatusCommands.ts +13 -5
  53. package/cli/machineWatchCommands.ts +1 -1
  54. package/cli/machineWsRunDispatch.ts +30 -44
  55. package/cli/machineWsSession.ts +0 -2
  56. package/cli/offlineMarxistsAgentCommand.ts +314 -0
  57. package/cli/runtimeDoctorCommands.ts +72 -15
  58. package/cli/scriptCommandEntries.ts +45 -5
  59. package/cli/tableCommands.ts +133 -33
  60. package/cli/taskRunCommand.ts +211 -16
  61. package/cli/tui/session.ts +372 -43
  62. package/cli/workflowInternalCommandEntries.ts +0 -20
  63. package/cliCommandDispatch.ts +2 -2
  64. package/cliEnvHelpers.ts +34 -107
  65. package/client/agentConfigResolver.test.ts +2 -0
  66. package/client/agentRun.test.ts +12 -208
  67. package/client/agentRun.ts +854 -57
  68. package/client/localProviderResolver.test.ts +26 -2
  69. package/client/localRuntimeAdapter.test.ts +296 -171
  70. package/client/localRuntimeAdapter.ts +59 -159
  71. package/client/localToolPolicy.test.ts +4 -28
  72. package/client/streamingOutput.ts +3 -1
  73. package/client/taskRunPrompt.ts +24 -7
  74. package/commandRegistry.ts +4 -5
  75. package/connectorRunArtifact.ts +10 -34
  76. package/connectorWebSocketTarget.ts +6 -10
  77. package/database/server/serverStoreFactory.ts +2 -8
  78. package/internalCommandEntries.ts +0 -8
  79. package/localRuntimeDb.ts +2 -39
  80. package/machineCommands.ts +189 -190
  81. package/machineDaemonCommands.ts +165 -9
  82. package/machineHeartbeatCommands.ts +2 -1
  83. package/machineStatusCommands.ts +13 -5
  84. package/machineWatchCommands.ts +1 -1
  85. package/machineWsRunDispatch.ts +30 -44
  86. package/machineWsSession.ts +0 -2
  87. package/offlineMarxistsAgentCommand.ts +314 -0
  88. package/package.json +52 -188
  89. package/runtimeDoctorCommands.ts +72 -15
  90. package/scriptCommandEntries.ts +45 -5
  91. package/tableCommands.ts +133 -33
  92. package/taskRunCommand.ts +211 -16
  93. package/tui/session.ts +372 -43
  94. package/workflowInternalCommandEntries.ts +0 -20
  95. package/agent-runtime/dialogStatus.ts +0 -139
  96. package/agent-runtime/hostRuntimeConfig.ts +0 -86
  97. package/agentCreateCustomCommands.ts +0 -278
  98. package/agentDialogsCommands.ts +0 -227
  99. package/agentDoctorCommands.ts +0 -203
  100. package/agentRunLocalWorkspace.ts +0 -182
  101. package/agentRunParsing.ts +0 -298
  102. package/agentSuperviseCommands.ts +0 -8
  103. package/agentUnpublishCommands.ts +0 -113
  104. package/ai/agent/agentRunDialogLineage.ts +0 -56
  105. package/ai/policy/types.ts +0 -64
  106. package/ai/skills/skillSummaryMarker.ts +0 -26
  107. package/app/types.ts +0 -358
  108. package/build.ts +0 -16
  109. package/buildPublish.ts +0 -138
  110. package/buildPublishArtifactAssembly.ts +0 -724
  111. package/buildPublishImportAnalysis.ts +0 -242
  112. package/chat/messages/fetchMessages.ts +0 -84
  113. package/chat/messages/types.ts +0 -185
  114. package/cli/agentCreateCustomCommands.ts +0 -278
  115. package/cli/agentDialogsCommands.ts +0 -227
  116. package/cli/agentDoctorCommands.ts +0 -203
  117. package/cli/agentRunLocalWorkspace.ts +0 -182
  118. package/cli/agentRunParsing.ts +0 -298
  119. package/cli/agentSuperviseCommands.ts +0 -8
  120. package/cli/agentUnpublishCommands.ts +0 -113
  121. package/cli/buildPublish.ts +0 -138
  122. package/cli/buildPublishArtifactAssembly.ts +0 -724
  123. package/cli/buildPublishImportAnalysis.ts +0 -242
  124. package/cli/cliIoTypes.ts +0 -3
  125. package/cli/cliRuntimeDoctorReport.ts +0 -193
  126. package/cli/client/agentRunInput.ts +0 -10
  127. package/cli/client/agentRunLocalExecution.ts +0 -124
  128. package/cli/client/agentRunLocalExecutor.ts +0 -179
  129. package/cli/client/agentRunRuntimeSelection.ts +0 -145
  130. package/cli/client/agentRunServerTransport.ts +0 -397
  131. package/cli/client/agentRunTaskRunRecorder.ts +0 -176
  132. package/cli/customCodingAgentFlow.ts +0 -208
  133. package/cli/customCodingAgentRecord.ts +0 -179
  134. package/cli/dialogDataAccess.ts +0 -186
  135. package/cli/dialogInternalCommandEntries.ts +0 -11
  136. package/cli/dialogReadCommands.ts +0 -180
  137. package/cli/dialogReadHelpers.ts +0 -226
  138. package/cli/dialogStatusCommands.ts +0 -123
  139. package/cli/docInternalCommandEntries.ts +0 -20
  140. package/cli/hybridReadHelpers.ts +0 -109
  141. package/cli/machineCommandPrompts.ts +0 -79
  142. package/cli/machineCommandResolution.ts +0 -43
  143. package/cli/noloReadBridgePrompt.ts +0 -16
  144. package/cli/pageCreateCommands.ts +0 -219
  145. package/cli/pageDeleteCommands.ts +0 -167
  146. package/cli/pageReadCommands.ts +0 -151
  147. package/cli/pageUpdateCommands.ts +0 -249
  148. package/cli/pageWriteHelpers.ts +0 -209
  149. package/cli/publishPackage.ts +0 -36
  150. package/cli/runtimeInternalCommandEntries.ts +0 -15
  151. package/cli/runtimePassthroughCommands.ts +0 -22
  152. package/cli/scriptPassthroughHelpers.ts +0 -28
  153. package/cli/secretScanHelpers.ts +0 -31
  154. package/cli/spaceAttachCommands.ts +0 -134
  155. package/cli/spaceCategoryCommands.ts +0 -263
  156. package/cli/spaceCommands.ts +0 -295
  157. package/cli/spaceDeleteCommands.ts +0 -312
  158. package/cli/spaceInternalCommandEntries.ts +0 -21
  159. package/cli/spaceMutationHelpers.ts +0 -135
  160. package/cli/spaceReadCommands.ts +0 -323
  161. package/cli/tableDataOutput.ts +0 -41
  162. package/cli/tableDataSafety.ts +0 -26
  163. package/cli/tableMetaCommands.ts +0 -307
  164. package/cli/tableMutationCommands.ts +0 -266
  165. package/cli/tableQueryParsing.ts +0 -90
  166. package/cli/tableQueryRequest.ts +0 -53
  167. package/cli/taskRunActions.ts +0 -122
  168. package/cli/taskRunParsing.ts +0 -86
  169. package/cli/taskRunPromptShared.ts +0 -55
  170. package/cli/tui/tuiCatalog.ts +0 -22
  171. package/cli/tui/tuiCommandInterpreter.ts +0 -253
  172. package/cli/tui/tuiPresentation.ts +0 -146
  173. package/cliIoTypes.ts +0 -3
  174. package/cliRuntimeDoctorReport.ts +0 -193
  175. package/client/agentRunInput.ts +0 -10
  176. package/client/agentRunLocalExecution.test.ts +0 -123
  177. package/client/agentRunLocalExecution.ts +0 -124
  178. package/client/agentRunLocalExecutor.ts +0 -179
  179. package/client/agentRunRuntimeSelection.test.ts +0 -159
  180. package/client/agentRunRuntimeSelection.ts +0 -145
  181. package/client/agentRunServerTransport.ts +0 -397
  182. package/client/agentRunTaskRunRecorder.ts +0 -176
  183. package/connector-experimental/daemonLauncher.ts +0 -223
  184. package/create/space/spaceKeys.ts +0 -65
  185. package/create/types.ts +0 -21
  186. package/customCodingAgentFlow.ts +0 -208
  187. package/customCodingAgentRecord.ts +0 -179
  188. package/database/keys.ts +0 -765
  189. package/database/tombstones.ts +0 -52
  190. package/database/utils/ulid.ts +0 -1
  191. package/dialogDataAccess.ts +0 -186
  192. package/dialogInternalCommandEntries.ts +0 -11
  193. package/dialogReadCommands.ts +0 -180
  194. package/dialogReadHelpers.ts +0 -226
  195. package/dialogStatusCommands.ts +0 -123
  196. package/docInternalCommandEntries.ts +0 -20
  197. package/hybridReadHelpers.ts +0 -109
  198. package/machineCommandPrompts.ts +0 -79
  199. package/machineCommandResolution.ts +0 -43
  200. package/noloReadBridgePrompt.ts +0 -16
  201. package/pageCreateCommands.ts +0 -219
  202. package/pageDeleteCommands.ts +0 -167
  203. package/pageReadCommands.ts +0 -151
  204. package/pageUpdateCommands.ts +0 -249
  205. package/pageWriteHelpers.ts +0 -209
  206. package/publishPackage.ts +0 -36
  207. package/runtimeInternalCommandEntries.ts +0 -15
  208. package/runtimePassthroughCommands.ts +0 -22
  209. package/scriptPassthroughHelpers.ts +0 -28
  210. package/secretScanHelpers.ts +0 -31
  211. package/share/helpers.ts +0 -302
  212. package/share/keys.ts +0 -243
  213. package/share/types.ts +0 -100
  214. package/spaceAttachCommands.ts +0 -134
  215. package/spaceCategoryCommands.ts +0 -263
  216. package/spaceCommands.ts +0 -295
  217. package/spaceDeleteCommands.ts +0 -312
  218. package/spaceInternalCommandEntries.ts +0 -21
  219. package/spaceMutationHelpers.ts +0 -135
  220. package/spaceReadCommands.ts +0 -323
  221. package/tableDataOutput.ts +0 -41
  222. package/tableDataSafety.ts +0 -26
  223. package/tableMetaCommands.ts +0 -307
  224. package/tableMutationCommands.ts +0 -266
  225. package/tableQueryParsing.ts +0 -90
  226. package/tableQueryRequest.ts +0 -53
  227. package/taskRunActions.ts +0 -122
  228. package/taskRunParsing.ts +0 -86
  229. package/taskRunPromptShared.ts +0 -55
  230. package/tui/tuiCatalog.ts +0 -22
  231. package/tui/tuiCommandInterpreter.test.ts +0 -169
  232. package/tui/tuiCommandInterpreter.ts +0 -253
  233. package/tui/tuiPresentation.test.ts +0 -154
  234. package/tui/tuiPresentation.ts +0 -146
@@ -1,8 +1,8 @@
1
1
  import type { MachineHeartbeat } from "../connector-experimental/protocol";
2
2
  import type { HeartbeatLoopOptions } from "../connector-experimental/heartbeatLoop";
3
- import type { OutputLike } from "./cliIoTypes";
4
3
 
5
4
  type EnvLike = Record<string, string | undefined>;
5
+ type OutputLike = { write(chunk: string): unknown };
6
6
 
7
7
  function resolveHeartbeatIntervalMs(env: EnvLike) {
8
8
  const raw = Number(env.NOLO_CONNECT_HEARTBEAT_MS ?? "");
@@ -1,6 +1,4 @@
1
1
  import { runLocalAgentTurn, type LocalAgentToolEvent } from "../agent-runtime/localLoop";
2
- import { resolveHostRuntimeConfigFromEnv } from "../agent-runtime/hostRuntimeConfig";
3
- import { normalizeAgentRunDialogLineage } from "../ai/agent/agentRunDialogLineage";
4
2
  import {
5
3
  assertMachineRunAllowed as defaultAssertMachineRunAllowed,
6
4
  resolveMachineRunPermissionPolicy as defaultResolveMachineRunPermissionPolicy,
@@ -58,7 +56,7 @@ type ConnectorRunProgress = {
58
56
 
59
57
  type PermissionPolicy = ReturnType<typeof defaultResolveMachineRunPermissionPolicy>;
60
58
 
61
- export type MachineWsRunDispatchDeps = {
59
+ type MachineWsRunDispatchDeps = {
62
60
  assertMachineRunAllowed?: typeof defaultAssertMachineRunAllowed;
63
61
  resolveMachineRunPermissionPolicy?: typeof defaultResolveMachineRunPermissionPolicy;
64
62
  resolveConnectorRunCwd?: typeof defaultResolveConnectorRunCwd;
@@ -150,7 +148,7 @@ function hasExplicitMachinePermissions(agentConfig: any) {
150
148
 
151
149
  function runtimeWorkspacePermissionPolicy(
152
150
  runtimePolicy: ConnectorRuntimePolicy | undefined,
153
- hostRuntimeConfig: { capabilities: { allowShell: boolean } },
151
+ runtimeEnv: EnvLike,
154
152
  cwd: string
155
153
  ): PermissionPolicy | null {
156
154
  if (!requestsTaskWorktree(runtimePolicy)) return null;
@@ -159,7 +157,7 @@ function runtimeWorkspacePermissionPolicy(
159
157
  allowFilesystemRead: true,
160
158
  allowFilesystemWrite: true,
161
159
  allowShell:
162
- hostRuntimeConfig.capabilities.allowShell &&
160
+ ["worktree", "dangerous", "1", "true"].includes(runtimeEnv.NOLO_LOCAL_SHELL_MODE || "") &&
163
161
  Array.isArray(runtimePolicy?.runtimeTools) &&
164
162
  runtimePolicy.runtimeTools.includes("execShell"),
165
163
  writableRoots: [cwd],
@@ -199,6 +197,9 @@ function mergeToolNames(...values: unknown[]) {
199
197
  function localRuntimeEnvFromPolicy(runtimeEnv: EnvLike, policy?: ConnectorRuntimePolicy): EnvLike {
200
198
  return {
201
199
  ...runtimeEnv,
200
+ ...(policy?.shell?.enabled && policy.shell.mode === "worktree"
201
+ ? { NOLO_LOCAL_SHELL_MODE: "worktree" }
202
+ : {}),
202
203
  ...(policy?.workspace?.cwd ? { NOLO_LOCAL_WORKTREE: policy.workspace.cwd } : {}),
203
204
  };
204
205
  }
@@ -272,12 +273,6 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
272
273
  ? args.parsed.payload.agentConfig
273
274
  : {};
274
275
  const policy = runtimePolicyFromConnectorPayload(args.parsed);
275
- const wantsTaskWorktree = requestsTaskWorktree(policy);
276
- const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
277
- env: args.runtimeEnv,
278
- surface: "connector-local",
279
- workspaceBinding: wantsTaskWorktree ? "default-cwd" : "explicit-cwd",
280
- });
281
276
  const agentRecord = {
282
277
  ...payloadAgentConfig,
283
278
  dbKey: agentKey,
@@ -303,10 +298,11 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
303
298
  withForwardedUserAuthToken(args.runtimeEnv, args.parsed),
304
299
  policy
305
300
  );
301
+ const wantsTaskWorktree = requestsTaskWorktree(policy);
306
302
  const adapter = createCliLocalRuntimeAdapter({
307
303
  env,
308
- hostRuntimeConfig,
309
304
  cwd: args.cwd,
305
+ useCwdAsTaskWorkspaceBase: wantsTaskWorktree,
310
306
  ...(wantsTaskWorktree
311
307
  ? {
312
308
  prepareTaskWorktree: (input) => prepareTaskWorktree({
@@ -389,20 +385,6 @@ function normalizeConnectorRunTimeoutMs(value: unknown): number | undefined {
389
385
  return Math.floor(value);
390
386
  }
391
387
 
392
- function normalizeConnectorRunPayloadContinueDialogId(payload: unknown) {
393
- if (!isRecord(payload)) return payload;
394
- const dialogLineage = normalizeAgentRunDialogLineage({
395
- continueDialogId: payload.continueDialogId,
396
- });
397
- const normalizedPayload = { ...payload };
398
- if (dialogLineage.continueDialogId) {
399
- normalizedPayload.continueDialogId = dialogLineage.continueDialogId;
400
- } else {
401
- delete normalizedPayload.continueDialogId;
402
- }
403
- return normalizedPayload;
404
- }
405
-
406
388
  export async function handleConnectorRunMessage(
407
389
  message: string,
408
390
  send: (message: string) => void,
@@ -418,12 +400,6 @@ export async function handleConnectorRunMessage(
418
400
  return;
419
401
  }
420
402
  if (parsed?.type !== "agent.run" || typeof parsed.requestId !== "string") return;
421
- if (isRecord(parsed)) {
422
- parsed = {
423
- ...parsed,
424
- payload: normalizeConnectorRunPayloadContinueDialogId(parsed.payload),
425
- };
426
- }
427
403
  const agentConfig = parsed.payload?.agentConfig ?? {};
428
404
  const sendProgress = (progress: ConnectorRunProgress) => {
429
405
  send(JSON.stringify({
@@ -451,11 +427,6 @@ export async function handleConnectorRunMessage(
451
427
  try {
452
428
  const machinePermissionPolicy = resolveMachineRunPermissionPolicy(agentConfig);
453
429
  const runtimePolicy = runtimePolicyFromConnectorPayload(parsed);
454
- const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
455
- env: runtimeEnv,
456
- surface: agentConfig.apiSource === "cli" ? "connector-cli" : "connector-local",
457
- workspaceBinding: requestsTaskWorktree(runtimePolicy) ? "default-cwd" : "explicit-cwd",
458
- });
459
430
  const userInput = String(parsed.payload?.userInput ?? "");
460
431
  const timeout = normalizeConnectorRunTimeoutMs(parsed.payload?.timeoutMs);
461
432
  let cwd = resolveConnectorRunCwd({ env: runtimeEnv, policy: machinePermissionPolicy });
@@ -478,7 +449,7 @@ export async function handleConnectorRunMessage(
478
449
  artifactCwd = prepared.path;
479
450
  }
480
451
  const runtimePermissionPolicy = !hasExplicitMachinePermissions(agentConfig)
481
- ? runtimeWorkspacePermissionPolicy(runtimePolicy, hostRuntimeConfig, cwd)
452
+ ? runtimeWorkspacePermissionPolicy(runtimePolicy, runtimeEnv, cwd)
482
453
  : null;
483
454
  const effectivePermissionPolicy = scopePermissionPolicyToRuntimeWorkspace(
484
455
  runtimePermissionPolicy ?? machinePermissionPolicy,
@@ -532,7 +503,7 @@ export async function handleConnectorRunMessage(
532
503
  const heartbeat = setInterval(() => {
533
504
  sendProgress({
534
505
  ...progressBase,
535
- message: "cli-running",
506
+ message: "cli-running",
536
507
  updatedAt: Date.now(),
537
508
  });
538
509
  }, 15_000);
@@ -543,11 +514,26 @@ export async function handleConnectorRunMessage(
543
514
  cwd,
544
515
  yolo: true,
545
516
  env: {
546
- NOLO_SERVER: effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.BASE_URL,
547
- NOLO_SERVER_URL: effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.BASE_URL,
548
- BASE_URL: effectiveRuntimeEnv.BASE_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL,
549
- AUTH_TOKEN: effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH || effectiveRuntimeEnv.NOLO_MACHINE_API_KEY,
550
- NOLO_MACHINE_API_KEY: effectiveRuntimeEnv.NOLO_MACHINE_API_KEY || effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH,
517
+ NOLO_SERVER:
518
+ effectiveRuntimeEnv.NOLO_SERVER ||
519
+ effectiveRuntimeEnv.NOLO_SERVER_URL ||
520
+ effectiveRuntimeEnv.BASE_URL,
521
+ NOLO_SERVER_URL:
522
+ effectiveRuntimeEnv.NOLO_SERVER_URL ||
523
+ effectiveRuntimeEnv.NOLO_SERVER ||
524
+ effectiveRuntimeEnv.BASE_URL,
525
+ BASE_URL:
526
+ effectiveRuntimeEnv.BASE_URL ||
527
+ effectiveRuntimeEnv.NOLO_SERVER ||
528
+ effectiveRuntimeEnv.NOLO_SERVER_URL,
529
+ AUTH_TOKEN:
530
+ effectiveRuntimeEnv.AUTH_TOKEN ||
531
+ effectiveRuntimeEnv.AUTH ||
532
+ effectiveRuntimeEnv.NOLO_MACHINE_API_KEY,
533
+ NOLO_MACHINE_API_KEY:
534
+ effectiveRuntimeEnv.NOLO_MACHINE_API_KEY ||
535
+ effectiveRuntimeEnv.AUTH_TOKEN ||
536
+ effectiveRuntimeEnv.AUTH,
551
537
  },
552
538
  }).finally(() => clearInterval(heartbeat));
553
539
  logConnectorRun("agent.run.cli.result", {
@@ -119,7 +119,6 @@ export async function runMachineWsSession(options: {
119
119
  resolveConnectorWebSocketTarget: (args: {
120
120
  serverUrl: string;
121
121
  machineId: string;
122
- connectorSurface?: string;
123
122
  headers: Record<string, string>;
124
123
  }) => Promise<string>;
125
124
  connectWebSocket: (url: string, options: ConnectorWebSocketOptions) => Promise<void>;
@@ -150,7 +149,6 @@ export async function runMachineWsSession(options: {
150
149
  const wsTarget = await options.resolveConnectorWebSocketTarget({
151
150
  serverUrl: options.serverUrl,
152
151
  machineId: options.machine.machineId,
153
- connectorSurface: "cli",
154
152
  headers: { Authorization: `Bearer ${options.authToken}` },
155
153
  });
156
154
  websocketPromise = options.connectWebSocket(wsTarget, {
@@ -0,0 +1,314 @@
1
+ import { DEFAULT_NOLO_SERVER_URL } from "./defaultServer";
2
+
3
+ type EnvLike = Record<string, string | undefined>;
4
+
5
+ type OutputLike = {
6
+ write(chunk: string): unknown;
7
+ };
8
+
9
+ type SetupOfflineMarxistsAgentDeps = {
10
+ env?: EnvLike;
11
+ output?: OutputLike;
12
+ fetchImpl?: typeof fetch;
13
+ now?: () => number;
14
+ };
15
+
16
+ type ParsedArgs = {
17
+ serverUrl: string;
18
+ authToken: string;
19
+ userId: string;
20
+ sourceAgentKey: string;
21
+ targetAgentId: string;
22
+ targetAgentKey: string;
23
+ spaceId: string;
24
+ name: string;
25
+ publicAgent: boolean;
26
+ json: boolean;
27
+ };
28
+
29
+ const DEFAULT_USER_ID = "b2e06f801f";
30
+ const DEFAULT_SPACE_ID = "01KKY77TT0DA9NY7TNW3R7255N";
31
+ const DEFAULT_SOURCE_AGENT_ID = "01MIMO25MONTH0000000NEW001";
32
+ const DEFAULT_TARGET_AGENT_ID = "01OFFMARXBOOK000000010AHL1";
33
+ const DEFAULT_AGENT_NAME = "离线马克思主义文库书籍转换助手";
34
+ const TOOL_NAME = "convertMarxistsBookToOfflineHtml";
35
+ const AGENT_TOOLS = [TOOL_NAME];
36
+
37
+ function readFlagValue(args: string[], flag: string) {
38
+ const index = args.indexOf(flag);
39
+ return index >= 0 ? args[index + 1] : undefined;
40
+ }
41
+
42
+ function parseUserIdFromToken(token: string) {
43
+ const payload = token.split(".")[0];
44
+ if (!payload) return "";
45
+ try {
46
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
47
+ const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
48
+ const parsed = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
49
+ return typeof parsed?.userId === "string" ? parsed.userId : "";
50
+ } catch {
51
+ return "";
52
+ }
53
+ }
54
+
55
+ function normalizeBaseUrl(value: string) {
56
+ return value.trim().replace(/\/+$/, "");
57
+ }
58
+
59
+ function parseArgs(args: string[], env: EnvLike): ParsedArgs | null {
60
+ if (args.includes("--help") || args.includes("-h")) return null;
61
+ const serverUrl = normalizeBaseUrl(
62
+ readFlagValue(args, "--server") ??
63
+ readFlagValue(args, "--server-url") ??
64
+ env.NOLO_SERVER ??
65
+ env.BASE_URL ??
66
+ DEFAULT_NOLO_SERVER_URL
67
+ );
68
+ const authToken = readFlagValue(args, "--token") ?? env.AUTH_TOKEN ?? env.NOLO_AUTH_TOKEN ?? "";
69
+ const userId =
70
+ readFlagValue(args, "--user-id") ??
71
+ env.NOLO_USER_ID ??
72
+ parseUserIdFromToken(authToken) ??
73
+ DEFAULT_USER_ID;
74
+ const sourceAgentKey =
75
+ readFlagValue(args, "--source-agent") ??
76
+ env.NOLO_MIMO_SOURCE_AGENT_KEY ??
77
+ `agent-${userId}-${DEFAULT_SOURCE_AGENT_ID}`;
78
+ const targetAgentId =
79
+ readFlagValue(args, "--target-agent-id") ??
80
+ env.NOLO_OFFLINE_MARXISTS_AGENT_ID ??
81
+ DEFAULT_TARGET_AGENT_ID;
82
+ const targetAgentKey =
83
+ readFlagValue(args, "--target-agent") ??
84
+ env.NOLO_OFFLINE_MARXISTS_AGENT_KEY ??
85
+ `agent-${userId}-${targetAgentId}`;
86
+ const spaceId =
87
+ readFlagValue(args, "--space") ??
88
+ env.NOLO_OFFLINE_MARXISTS_SPACE_ID ??
89
+ DEFAULT_SPACE_ID;
90
+
91
+ if (!authToken.trim()) return null;
92
+ return {
93
+ serverUrl,
94
+ authToken,
95
+ userId,
96
+ sourceAgentKey,
97
+ targetAgentId,
98
+ targetAgentKey,
99
+ spaceId,
100
+ name: readFlagValue(args, "--name") ?? DEFAULT_AGENT_NAME,
101
+ publicAgent: args.includes("--public"),
102
+ json: args.includes("--json"),
103
+ };
104
+ }
105
+
106
+ async function readDbRecord(args: {
107
+ fetchImpl: typeof fetch;
108
+ serverUrl: string;
109
+ authToken: string;
110
+ dbKey: string;
111
+ }) {
112
+ const res = await args.fetchImpl(
113
+ `${args.serverUrl}/api/v1/db/read/${encodeURIComponent(args.dbKey)}`,
114
+ { headers: { Authorization: `Bearer ${args.authToken}` } }
115
+ );
116
+ const data = await res.json().catch(() => ({}));
117
+ if (!res.ok) {
118
+ throw new Error(`read ${args.dbKey} failed (${res.status}): ${JSON.stringify(data)}`);
119
+ }
120
+ return (data as any)?.data ?? data;
121
+ }
122
+
123
+ async function writeDbRecord(args: {
124
+ fetchImpl: typeof fetch;
125
+ serverUrl: string;
126
+ authToken: string;
127
+ userId: string;
128
+ dbKey: string;
129
+ data: Record<string, any>;
130
+ }) {
131
+ const res = await args.fetchImpl(`${args.serverUrl}/api/v1/db/write/`, {
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ Authorization: `Bearer ${args.authToken}`,
136
+ },
137
+ body: JSON.stringify({
138
+ customKey: args.dbKey,
139
+ userId: args.userId,
140
+ data: { ...args.data, dbKey: args.dbKey },
141
+ }),
142
+ });
143
+ const data = await res.json().catch(() => ({}));
144
+ if (!res.ok) {
145
+ throw new Error(`write ${args.dbKey} failed (${res.status}): ${JSON.stringify(data)}`);
146
+ }
147
+ }
148
+
149
+ function buildTargetAgent(args: {
150
+ parsed: ParsedArgs;
151
+ source: Record<string, any>;
152
+ now: number;
153
+ }) {
154
+ const { parsed, source, now } = args;
155
+ if (!source.apiKey) {
156
+ throw new Error(`source agent ${parsed.sourceAgentKey} has no apiKey`);
157
+ }
158
+ if (!source.customProviderUrl) {
159
+ throw new Error(`source agent ${parsed.sourceAgentKey} has no customProviderUrl`);
160
+ }
161
+ return {
162
+ id: parsed.targetAgentId,
163
+ type: "agent",
164
+ name: parsed.name,
165
+ description:
166
+ "把 Marxists.org 中文旧式书籍页面转换为可离线打开的单文件 HTML,保留原 CSS、表格排版和背景纹理。",
167
+ prompt:
168
+ "你是离线书籍转换助手。用户给出 Marxists.org 中文书籍页面或要求保存离线书籍时,只能调用 convertMarxistsBookToOfflineHtml,不要使用普通网页抓取流程。最终回答必须逐字给出 rawData.fileUrl、rawData.pageCount、rawData.hasNetworkUrls、rawData.byteLength。",
169
+ isPublic: parsed.publicAgent,
170
+ model: source.model ?? "mimo-v2.5-pro",
171
+ provider: source.provider ?? "custom",
172
+ apiSource: source.apiSource ?? "custom",
173
+ apiKey: source.apiKey,
174
+ customProviderUrl: source.customProviderUrl,
175
+ apiKeyHeader: source.apiKeyHeader ?? "api-key",
176
+ tools: AGENT_TOOLS,
177
+ temperature: source.temperature ?? 0.2,
178
+ maxTokens: source.maxTokens ?? 4096,
179
+ category: "document-tools",
180
+ tags: ["offline-book", "marxists", "mimo"],
181
+ userId: parsed.userId,
182
+ createdAt: source.createdAt ?? now,
183
+ updatedAt: now,
184
+ };
185
+ }
186
+
187
+ async function attachAgentToSpace(args: {
188
+ fetchImpl: typeof fetch;
189
+ parsed: ParsedArgs;
190
+ contentKey: string;
191
+ title: string;
192
+ now: number;
193
+ }) {
194
+ const spaceKey = `space-${args.parsed.spaceId}`;
195
+ const space = await readDbRecord({
196
+ fetchImpl: args.fetchImpl,
197
+ serverUrl: args.parsed.serverUrl,
198
+ authToken: args.parsed.authToken,
199
+ dbKey: spaceKey,
200
+ });
201
+ await writeDbRecord({
202
+ fetchImpl: args.fetchImpl,
203
+ serverUrl: args.parsed.serverUrl,
204
+ authToken: args.parsed.authToken,
205
+ userId: args.parsed.userId,
206
+ dbKey: spaceKey,
207
+ data: {
208
+ ...space,
209
+ contents: {
210
+ ...(space.contents ?? {}),
211
+ [args.contentKey]: {
212
+ ...(space.contents?.[args.contentKey] ?? {}),
213
+ title: args.title,
214
+ type: "agent",
215
+ contentKey: args.contentKey,
216
+ createdAt: space.contents?.[args.contentKey]?.createdAt ?? args.now,
217
+ updatedAt: args.now,
218
+ },
219
+ },
220
+ updatedAt: args.now,
221
+ },
222
+ });
223
+ }
224
+
225
+ function writeUsage(output: OutputLike) {
226
+ output.write(
227
+ "Usage: nolo agent setup-offline-marxists [--server https://nolo.chat] [--source-agent <key>] [--space <spaceId>] [--target-agent-id <id>] [--json]\n" +
228
+ "Requires AUTH_TOKEN from `nolo login` or --token.\n"
229
+ );
230
+ }
231
+
232
+ export async function runSetupOfflineMarxistsAgentCommand(
233
+ args: string[],
234
+ deps: SetupOfflineMarxistsAgentDeps = {}
235
+ ) {
236
+ const env = deps.env ?? process.env;
237
+ const output = deps.output ?? process.stdout;
238
+ const parsed = parseArgs(args, env);
239
+ if (!parsed) {
240
+ writeUsage(output);
241
+ return 1;
242
+ }
243
+ const fetchImpl = deps.fetchImpl ?? fetch;
244
+ const now = deps.now?.() ?? Date.now();
245
+
246
+ try {
247
+ const source = await readDbRecord({
248
+ fetchImpl,
249
+ serverUrl: parsed.serverUrl,
250
+ authToken: parsed.authToken,
251
+ dbKey: parsed.sourceAgentKey,
252
+ });
253
+ const target = buildTargetAgent({ parsed, source, now });
254
+ await writeDbRecord({
255
+ fetchImpl,
256
+ serverUrl: parsed.serverUrl,
257
+ authToken: parsed.authToken,
258
+ userId: parsed.userId,
259
+ dbKey: parsed.targetAgentKey,
260
+ data: target,
261
+ });
262
+ const publicKey = `agent-pub-${parsed.targetAgentId}`;
263
+ if (parsed.publicAgent) {
264
+ await writeDbRecord({
265
+ fetchImpl,
266
+ serverUrl: parsed.serverUrl,
267
+ authToken: parsed.authToken,
268
+ userId: parsed.userId,
269
+ dbKey: publicKey,
270
+ data: target,
271
+ });
272
+ }
273
+ await attachAgentToSpace({
274
+ fetchImpl,
275
+ parsed,
276
+ contentKey: parsed.publicAgent ? publicKey : parsed.targetAgentKey,
277
+ title: parsed.name,
278
+ now,
279
+ });
280
+
281
+ const result = {
282
+ serverUrl: parsed.serverUrl,
283
+ sourceAgentKey: parsed.sourceAgentKey,
284
+ agentKey: parsed.targetAgentKey,
285
+ agentUrl: `${parsed.serverUrl}/${parsed.targetAgentKey}`,
286
+ publicKey: parsed.publicAgent ? publicKey : null,
287
+ spaceId: parsed.spaceId,
288
+ model: target.model,
289
+ provider: target.provider,
290
+ customProviderUrl: target.customProviderUrl,
291
+ tools: target.tools,
292
+ };
293
+ if (parsed.json) {
294
+ output.write(`${JSON.stringify(result, null, 2)}\n`);
295
+ } else {
296
+ output.write(
297
+ [
298
+ `created/updated: ${result.agentKey}`,
299
+ `url: ${result.agentUrl}`,
300
+ `space: ${result.spaceId}`,
301
+ `model: ${result.model}`,
302
+ `tools: ${result.tools.join(", ")}`,
303
+ "",
304
+ ].join("\n")
305
+ );
306
+ }
307
+ return 0;
308
+ } catch (error) {
309
+ output.write(
310
+ `setup-offline-marxists failed: ${error instanceof Error ? error.message : String(error)}\n`
311
+ );
312
+ return 1;
313
+ }
314
+ }
@@ -1,22 +1,41 @@
1
+ import { resolveAgentRuntimeDecision } from "../agent-runtime/runtimeDecision";
1
2
  import {
2
3
  type AgentCommandDeps,
3
4
  type LocalRuntimeProbeResult,
4
5
  } from "./agentCommandSupport";
5
- import {
6
- buildCliRuntimeDoctorProbe,
7
- buildCliRuntimeDoctorReport,
8
- formatCliRuntimeDoctorReport,
9
- } from "./cliRuntimeDoctorReport";
10
6
  import {
11
7
  resolveAuthToken,
12
8
  resolveServerUrl,
13
9
  type EnvLike,
14
10
  } from "./cliEnvHelpers";
15
11
 
12
+ function detectLocalAgentConfig(env: EnvLike) {
13
+ return Boolean(readLocalAgentKey(env) || env.NOLO_AGENT_CACHE_READY);
14
+ }
15
+
16
16
  function readLocalAgentKey(env: EnvLike) {
17
17
  return env.NOLO_LOCAL_AGENT_KEY || env.NOLO_AGENT || "";
18
18
  }
19
19
 
20
+ function detectLocalProvider(env: EnvLike) {
21
+ return Boolean(
22
+ env.OPENAI_API_KEY ||
23
+ env.ANTHROPIC_API_KEY ||
24
+ env.GOOGLE_API_KEY ||
25
+ env.NOLO_LOCAL_OPENAI_BASE_URL ||
26
+ env.OLLAMA_BASE_URL
27
+ );
28
+ }
29
+
30
+ function detectProviderLabel(env: EnvLike) {
31
+ if (env.NOLO_LOCAL_OPENAI_BASE_URL) return `openai-compatible endpoint ${env.NOLO_LOCAL_OPENAI_BASE_URL}`;
32
+ if (env.OLLAMA_BASE_URL) return `ollama-compatible endpoint ${env.OLLAMA_BASE_URL}`;
33
+ if (env.OPENAI_API_KEY) return "openai via env OPENAI_API_KEY";
34
+ if (env.ANTHROPIC_API_KEY) return "anthropic via env ANTHROPIC_API_KEY";
35
+ if (env.GOOGLE_API_KEY) return "google via env GOOGLE_API_KEY";
36
+ return "missing";
37
+ }
38
+
20
39
  async function defaultLocalRuntimeProbe(env: EnvLike): Promise<LocalRuntimeProbeResult> {
21
40
  const { resolveCliLocalRuntimeDbPath } = await import("./localRuntimeDb");
22
41
  const dbPath = resolveCliLocalRuntimeDbPath({ env });
@@ -53,15 +72,53 @@ export async function runDoctorRuntimeCommand(
53
72
  const authToken = resolveAuthToken(args, env);
54
73
  const serverUrl = resolveServerUrl(args, env);
55
74
  const localProbe = await (deps.localRuntimeProbe ?? defaultLocalRuntimeProbe)(env);
56
- const report = buildCliRuntimeDoctorReport(
57
- buildCliRuntimeDoctorProbe({
58
- env,
59
- localProbe,
60
- authToken,
61
- serverUrl,
62
- })
63
- );
64
- output.write(formatCliRuntimeDoctorReport(report));
75
+ const hasLocalAgentConfig = detectLocalAgentConfig(env) && localProbe.ok && localProbe.agentFound;
76
+ const hasLocalProvider = detectLocalProvider(env);
77
+ const missingLocalCapabilities = [
78
+ ...(localProbe.ok ? [] : ["leveldb"]),
79
+ ...(hasLocalAgentConfig ? [] : ["agent-config"]),
80
+ ...(hasLocalProvider ? [] : ["provider"]),
81
+ ];
82
+ const decision = resolveAgentRuntimeDecision({
83
+ requestedMode: "auto",
84
+ syncRequested: false,
85
+ host: "cli",
86
+ hasLocalAgentConfig,
87
+ hasLocalProvider,
88
+ hasLocalPersistence: true,
89
+ missingLocalCapabilities,
90
+ requiresServer: false,
91
+ serverFallbackAvailable: Boolean(
92
+ authToken ||
93
+ args.includes("--server") ||
94
+ args.includes("--server-url") ||
95
+ env.NOLO_SERVER ||
96
+ env.BASE_URL
97
+ ),
98
+ });
99
+
100
+ output.write(`Runtime: ${decision.mode}\n`);
101
+ output.write(`Reason: ${decision.reason}\n`);
102
+ output.write(`LevelDB: ${localProbe.ok ? "ok" : "failed"}\n`);
103
+ output.write(`DB path: ${localProbe.dbPath}\n`);
104
+ if (!localProbe.ok && localProbe.error) {
105
+ output.write(`DB error: ${localProbe.error}\n`);
106
+ }
107
+ if (localProbe.agentKey) {
108
+ output.write(`Agent config: ${localProbe.agentFound ? "found" : "missing"} (${localProbe.agentKey})\n`);
109
+ } else {
110
+ output.write("Agent config: missing (no local agent key)\n");
111
+ }
112
+ output.write(`Provider: ${hasLocalProvider ? "available" : "missing"} (${detectProviderLabel(env)})\n`);
113
+ output.write("Persistence: LevelDB local store\n");
114
+ output.write(`Sync: ${authToken ? "available" : "unavailable"}${authToken ? "" : " (not authenticated)"}\n`);
115
+ output.write(`Server fallback: ${decision.runnable && decision.mode === "server" ? serverUrl : authToken || env.NOLO_SERVER || env.BASE_URL ? serverUrl : "unavailable"}\n`);
116
+ if (decision.missingLocalCapabilities.length > 0) {
117
+ output.write("Missing local capabilities:\n");
118
+ for (const capability of decision.missingLocalCapabilities) {
119
+ output.write(`- ${capability}\n`);
120
+ }
121
+ }
65
122
 
66
- return report.decision.runnable ? 0 : 1;
123
+ return decision.runnable ? 0 : 1;
67
124
  }
@@ -1,23 +1,63 @@
1
1
  import { createScriptCommand, type CommandEntry } from "./cliCommandTypes";
2
2
 
3
3
  function getDocScriptCommands(): CommandEntry[] {
4
- return [];
4
+ return [
5
+ createScriptCommand(["doc", "create"], "createDoc.ts", "Create a normal doc"),
6
+ createScriptCommand(["doc", "read"], "readDoc.ts", "Read a normal doc"),
7
+ createScriptCommand(["doc", "update"], "updateDoc.ts", "Update a normal doc"),
8
+ createScriptCommand(["doc", "delete"], "deleteDoc.ts", "Delete a normal doc"),
9
+ createScriptCommand(["skill-doc", "create"], "createSkillDoc.ts", "Create a skill doc"),
10
+ createScriptCommand(["skill-doc", "read"], "readSkillDoc.ts", "Read a skill doc"),
11
+ createScriptCommand(["skill-doc", "update"], "updateSkillDoc.ts", "Update a skill doc"),
12
+ createScriptCommand(["skill-doc", "delete"], "deleteSkillDoc.ts", "Delete a skill doc"),
13
+ createScriptCommand(["skill", "create-doc"], "createSkillDoc.ts", "Create a skill-backed doc"),
14
+ ];
5
15
  }
6
16
 
7
17
  function getSpaceScriptCommands(): CommandEntry[] {
8
- return [];
18
+ return [
19
+ createScriptCommand(["dialog", "read"], "readDialog.ts", "Read a dialog"),
20
+ createScriptCommand(["dialog", "status"], "dialogStatus.ts", "Read compact dialog status"),
21
+ createScriptCommand(["space", "list"], "listSpaces.ts", "List joined spaces"),
22
+ createScriptCommand(["space", "read"], "readSpace.ts", "Read a space"),
23
+ createScriptCommand(["space", "delete"], "deleteSpaces.ts", "Delete spaces by safe filters"),
24
+ createScriptCommand(["space", "category"], "upsertSpaceCategory.ts", "Create or update a space category"),
25
+ createScriptCommand(["space", "content-category"], "setSpaceContentCategory.ts", "Move content into a space category"),
26
+ ];
9
27
  }
10
28
 
11
29
  function getTableScriptCommands(): CommandEntry[] {
12
- return [];
30
+ return [
31
+ createScriptCommand(["table", "add-column"], "tableData.ts", "Add one table column", ["--action", "add-column"]),
32
+ createScriptCommand(["table", "add-row"], "tableData.ts", "Add one table row", ["--action", "add-row"]),
33
+ createScriptCommand(["table", "add-rows"], "tableData.ts", "Add table rows", ["--action", "add-rows"]),
34
+ createScriptCommand(["table", "update-row"], "tableData.ts", "Update one table row", ["--action", "update-row"]),
35
+ createScriptCommand(["table", "update-rows"], "tableData.ts", "Update table rows", ["--action", "update-rows"]),
36
+ createScriptCommand(["table", "delete-row"], "tableData.ts", "Delete one table row", ["--action", "delete-row"]),
37
+ createScriptCommand(["table", "delete-rows"], "tableData.ts", "Delete table rows", ["--action", "delete-rows"]),
38
+ createScriptCommand(["table", "data"], "tableData.ts", "Low-level table row script bridge"),
39
+ createScriptCommand(["table", "meta"], "upsertTableMeta.ts", "Create or update table metadata"),
40
+ ];
13
41
  }
14
42
 
15
43
  function getAgentScriptCommands(): CommandEntry[] {
16
- return [];
44
+ return [
45
+ createScriptCommand(["agent", "unpublish"], "unpublishAgent.ts", "Remove an agent's public record"),
46
+ createScriptCommand(["agent", "dialogs"], "queryAgentDialogs.ts", "Inspect recent dialogs for an agent"),
47
+ createScriptCommand(["agent", "doctor"], "doctorAgentWorkspace.ts", "Audit agent workspace health"),
48
+ createScriptCommand(["agent", "create-custom"], "createCustomCodingAgent.ts", "Create a custom coding agent"),
49
+ createScriptCommand(["agent", "create-space"], "createSpaceAgents.ts", "Create or attach shared-space agents"),
50
+ createScriptCommand(["agent", "setup-demo"], "setupDemoAgent.ts", "Bootstrap demo publisher agents"),
51
+ createScriptCommand(["agent", "supervise"], "runAutonomousAgent.ts", "Run an agent in autonomous cycles"),
52
+ ];
17
53
  }
18
54
 
19
55
  function getRuntimeScriptCommands(): CommandEntry[] {
20
- return [];
56
+ return [
57
+ createScriptCommand(["llama"], "llamaServerSupervisor.ts", "Manage the llama.cpp runtime"),
58
+ createScriptCommand(["model-runtime"], "localModelRuntimeSupervisor.ts", "Manage local model runtime processes"),
59
+ createScriptCommand(["dev"], "devControl.ts", "Manage the local dev environment"),
60
+ ];
21
61
  }
22
62
 
23
63
  export function getScriptCommandEntries(): CommandEntry[] {