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
@@ -2,6 +2,7 @@ import { resolveCliAgentKeyInput } from "./agentAliases";
2
2
  import { getReadableCliDb, type AgentCommandDeps } from "./agentCommandSupport";
3
3
  import {
4
4
  buildUpdatedAgentRecord,
5
+ buildCreatedAgentRecord,
5
6
  normalizeAgentRecordForOutput,
6
7
  parseAgentUpdateArgs,
7
8
  resolveAgentRecordFromHybridStore,
@@ -17,7 +18,7 @@ export async function runAgentReadCommand(
17
18
  const output = deps.output ?? process.stdout;
18
19
  const agentInput = args[0]?.trim();
19
20
  if (!agentInput || agentInput === "--help" || agentInput === "-h") {
20
- output.write("Usage: nolo agent read <agent> [--server <url>]\n");
21
+ output.write("Usage: nolo agent read <agent>\n");
21
22
  return agentInput ? 0 : 1;
22
23
  }
23
24
 
@@ -141,3 +142,85 @@ export async function runAgentUpdateCommand(
141
142
  return 1;
142
143
  }
143
144
  }
145
+
146
+ export async function runAgentCreateCommand(
147
+ args: string[],
148
+ deps: AgentCommandDeps = {}
149
+ ) {
150
+ const env = deps.env ?? process.env;
151
+ const output = deps.output ?? process.stdout;
152
+ let parsed;
153
+ try {
154
+ parsed = parseAgentUpdateArgs(args);
155
+ } catch (error) {
156
+ output.write(`[nolo] agent create failed: ${error instanceof Error ? error.message : String(error)}\n`);
157
+ return 1;
158
+ }
159
+ if (!parsed) {
160
+ output.write(
161
+ "Usage: nolo agent create <agent> [--model <id>] [--cli-provider <provider>] [--api-source <source>] [--prompt <text> | --prompt-file <path> | --prompt-doc <pageKey>] [--tools <json>] [--copy-provider-from <agent>] [--name <name>] [--custom-provider-url <url>] [--provider-api-key <key>] [--field key=value]\n"
162
+ );
163
+ return args[0] ? 0 : 1;
164
+ }
165
+
166
+ const authToken = resolveAuthToken(args, env);
167
+ if (!authToken) {
168
+ output.write("[nolo] agent create requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
169
+ return 1;
170
+ }
171
+
172
+ const userId = parseUserIdFromAuthToken(authToken);
173
+ if (!userId) {
174
+ output.write("[nolo] agent create could not read userId from AUTH_TOKEN.\n");
175
+ return 1;
176
+ }
177
+
178
+ const db = deps.db ?? await getReadableCliDb(output);
179
+ const fetchImpl = deps.fetchImpl ?? fetch;
180
+ const fallbackFetchImpl = deps.fallbackFetchImpl;
181
+
182
+ try {
183
+ const built = await buildCreatedAgentRecord({
184
+ cliArgs: args,
185
+ parsed,
186
+ env,
187
+ db,
188
+ fetchImpl,
189
+ fallbackFetchImpl,
190
+ authToken,
191
+ });
192
+
193
+ await writeAgentRecord({
194
+ agentKey: built.agentKey,
195
+ authToken,
196
+ fallbackFetchImpl,
197
+ fetchImpl,
198
+ serverUrl: built.serverUrl,
199
+ userId,
200
+ record: built.nextRecord,
201
+ });
202
+ await db.put(built.agentKey, {
203
+ ...built.nextRecord,
204
+ dbKey: built.agentKey,
205
+ key: built.nextRecord?.key || built.agentKey,
206
+ serverOrigin: built.serverUrl,
207
+ });
208
+
209
+ output.write(JSON.stringify({
210
+ ok: true,
211
+ agentKey: built.agentKey,
212
+ baseUrl: built.serverUrl,
213
+ updates: built.updates,
214
+ record: built.nextRecord,
215
+ }, null, 2));
216
+ output.write("\n");
217
+ return 0;
218
+ } catch (error) {
219
+ output.write(
220
+ `[nolo] agent create failed: ${
221
+ error instanceof Error ? error.message : String(error)
222
+ }\n`
223
+ );
224
+ return 1;
225
+ }
226
+ }
@@ -1,14 +1,8 @@
1
1
  import { readFileSync } from "node:fs";
2
- import {
3
- buildPrivateAgentKey,
4
- buildCurrentUserPlatformAgentCandidateKeys,
5
- resolveCliAgentKeyInput,
6
- resolvePlatformAgentAliasSpec,
7
- } from "./agentAliases";
2
+ import { resolveCliAgentKeyInput } from "./agentAliases";
8
3
  import type { CliKvDb } from "./client/hybridRecordStore";
9
4
  import { buildLocalAgentLookupKeys, shouldReadAgentKeyRemotely } from "./client/localAgentRecords";
10
5
  import {
11
- hasExplicitServerOverride,
12
6
  parseUserIdFromAuthToken,
13
7
  readOption,
14
8
  resolveAuthToken,
@@ -16,7 +10,6 @@ import {
16
10
  resolveServerUrl,
17
11
  type EnvLike,
18
12
  } from "./cliEnvHelpers";
19
- import { parseSpaceIdFromInput, readSpaceRecordWithFallback } from "./spaceMutationHelpers";
20
13
 
21
14
  const PROVIDER_COPY_FIELDS = [
22
15
  "apiSource",
@@ -155,13 +148,10 @@ export async function queryUserRecords(args: {
155
148
  fetchImpl: typeof fetch;
156
149
  serverUrl: string;
157
150
  userId: string;
158
- type: "agent" | "cybot" | "dialog";
159
- limit?: number;
151
+ type: "agent" | "cybot";
160
152
  }) {
161
153
  const res = await fetchWithTransportFallback(
162
- `${args.serverUrl}/api/v1/db/query/${encodeURIComponent(args.userId)}${
163
- typeof args.limit === "number" && Number.isFinite(args.limit) ? `?limit=${args.limit}` : ""
164
- }`,
154
+ `${args.serverUrl}/api/v1/db/query/${encodeURIComponent(args.userId)}`,
165
155
  {
166
156
  method: "POST",
167
157
  headers: {
@@ -191,26 +181,6 @@ export async function writeAgentRecord(args: {
191
181
  serverUrl: string;
192
182
  userId: string;
193
183
  record: Record<string, any>;
194
- }) {
195
- return writeDbRecord({
196
- authToken: args.authToken,
197
- dbKey: args.agentKey,
198
- fallbackFetchImpl: args.fallbackFetchImpl,
199
- fetchImpl: args.fetchImpl,
200
- record: args.record,
201
- serverUrl: args.serverUrl,
202
- userId: args.userId,
203
- });
204
- }
205
-
206
- export async function writeDbRecord(args: {
207
- authToken: string;
208
- dbKey: string;
209
- fallbackFetchImpl?: typeof fetch;
210
- fetchImpl: typeof fetch;
211
- serverUrl: string;
212
- userId: string;
213
- record: Record<string, any>;
214
184
  }) {
215
185
  const res = await fetchWithTransportFallback(`${args.serverUrl}/api/v1/db/write/`, {
216
186
  method: "POST",
@@ -219,11 +189,11 @@ export async function writeDbRecord(args: {
219
189
  "Content-Type": "application/json",
220
190
  },
221
191
  body: JSON.stringify({
222
- customKey: args.dbKey,
192
+ customKey: args.agentKey,
223
193
  userId: args.userId,
224
194
  data: {
225
195
  ...args.record,
226
- dbKey: args.dbKey,
196
+ dbKey: args.agentKey,
227
197
  },
228
198
  }),
229
199
  }, args);
@@ -233,40 +203,6 @@ export async function writeDbRecord(args: {
233
203
  }
234
204
  }
235
205
 
236
- export async function deleteDbRecord(args: {
237
- authToken: string;
238
- dbKey: string;
239
- fallbackFetchImpl?: typeof fetch;
240
- fetchImpl: typeof fetch;
241
- serverUrl: string;
242
- userId: string;
243
- }) {
244
- const res = await fetchWithTransportFallback(
245
- `${args.serverUrl}/api/v1/db/delete/${encodeURIComponent(args.dbKey)}?userId=${encodeURIComponent(args.userId)}`,
246
- {
247
- method: "DELETE",
248
- headers: {
249
- Authorization: `Bearer ${args.authToken}`,
250
- },
251
- },
252
- args
253
- );
254
- const text = await res.text();
255
- let data: any = {};
256
- if (text) {
257
- try {
258
- data = JSON.parse(text);
259
- } catch {
260
- data = {};
261
- }
262
- }
263
- if (res.status === 404) return "missing" as const;
264
- if (!res.ok && res.status !== 204) {
265
- throw new Error(`delete failed: HTTP ${res.status} ${JSON.stringify(data)}`);
266
- }
267
- return "deleted" as const;
268
- }
269
-
270
206
  export async function resolveAgentRecordFromHybridStore(args: {
271
207
  agentInput: string;
272
208
  cliArgs?: string[];
@@ -276,102 +212,36 @@ export async function resolveAgentRecordFromHybridStore(args: {
276
212
  fallbackFetchImpl?: typeof fetch;
277
213
  }) {
278
214
  const agentKey = resolveCliAgentKeyInput(args.agentInput);
279
- const authToken = resolveAuthToken(args.cliArgs ?? [], args.env);
280
- const currentUserId = parseUserIdFromAuthToken(authToken);
281
- const cliArgs = args.cliArgs ?? [];
282
- const defaultServerUrl = resolveServerUrl(cliArgs, args.env);
283
- const serverCandidates = resolveServerCandidates(cliArgs, args.env, defaultServerUrl);
284
- const preferRemote = hasExplicitServerOverride(cliArgs);
285
- const aliasSpec = resolvePlatformAgentAliasSpec(args.agentInput);
286
- const rawSpaceInput = readOption(cliArgs, "--space");
287
- const preferredLookupKeys = buildCurrentUserPlatformAgentCandidateKeys(
288
- args.agentInput,
289
- currentUserId
290
- );
291
- const collectSpaceAttachedCandidateKeys = (spaceRecord: any) => {
292
- const contents = spaceRecord?.contents;
293
- if (!contents || typeof contents !== "object") return [];
294
-
295
- const currentUserPrivateKey =
296
- currentUserId ? buildPrivateAgentKey(currentUserId, aliasSpec!.agentId) : null;
297
- const canonicalMatches: string[] = [];
298
- const otherMatches: string[] = [];
299
- const currentUserMatches: string[] = [];
300
-
301
- for (const [entryKey, value] of Object.entries(contents)) {
302
- if (!value || typeof value !== "object") continue;
303
- const contentKey =
304
- typeof (value as any).contentKey === "string" && (value as any).contentKey.trim()
305
- ? (value as any).contentKey.trim()
306
- : entryKey.trim();
307
- if (!contentKey || !contentKey.endsWith(`-${aliasSpec!.agentId}`)) continue;
308
- if (contentKey === aliasSpec!.canonicalKey) {
309
- canonicalMatches.push(contentKey);
310
- continue;
311
- }
312
- if (currentUserPrivateKey && contentKey === currentUserPrivateKey) {
313
- currentUserMatches.push(contentKey);
314
- continue;
315
- }
316
- otherMatches.push(contentKey);
317
- }
318
-
319
- return Array.from(
320
- new Set([
321
- ...canonicalMatches.sort(),
322
- ...otherMatches.sort(),
323
- ...currentUserMatches.sort(),
324
- ])
325
- );
326
- };
327
- const resolveSpaceAttachedCandidateKeys = async () => {
328
- if (!aliasSpec || !rawSpaceInput || !authToken) return [];
215
+ const authToken = args.cliArgs
216
+ ? resolveAuthToken(args.cliArgs, args.env)
217
+ : resolveAuthToken(args.env);
218
+ const defaultServerUrl = args.cliArgs
219
+ ? resolveServerUrl(args.cliArgs, args.env)
220
+ : resolveServerUrl(args.env);
221
+
222
+ for (const key of buildLocalAgentLookupKeys({
223
+ agentRef: agentKey,
224
+ userId: parseUserIdFromAuthToken(authToken) || "local",
225
+ })) {
329
226
  try {
330
- const spaceId = parseSpaceIdFromInput(rawSpaceInput);
331
- let localSpaceRecord: any = null;
332
- try {
333
- localSpaceRecord = await args.db.get(`space-${spaceId}`);
334
- } catch {
335
- localSpaceRecord = null;
336
- }
337
-
338
- const localMatches = collectSpaceAttachedCandidateKeys(localSpaceRecord);
339
- if (localMatches.length > 0) return localMatches;
340
-
341
- const spaceRecord = await readSpaceRecordWithFallback({
342
- authToken,
343
- db: {
344
- ...args.db,
345
- get: async () => {
346
- throw new Error("force remote refresh for shared space alias resolution");
347
- },
348
- },
349
- fallbackFetchImpl: args.fallbackFetchImpl,
350
- fetchImpl: args.fetchImpl,
351
- serverCandidates,
352
- spaceId,
353
- });
354
- if (spaceRecord && typeof args.db.put === "function") {
355
- await args.db.put(`space-${spaceId}`, spaceRecord);
227
+ const record = await args.db.get(key);
228
+ if (record && typeof record === "object") {
229
+ return {
230
+ agentKey: key,
231
+ record,
232
+ source: record?.serverOrigin ? "remote-cache" : "local-cache",
233
+ } as const;
356
234
  }
357
- return collectSpaceAttachedCandidateKeys(spaceRecord);
358
235
  } catch {
359
- return [];
236
+ // local miss
360
237
  }
361
- };
362
- const spaceAttachedLookupKeys = await resolveSpaceAttachedCandidateKeys();
363
- const lookupKeys =
364
- spaceAttachedLookupKeys.length > 0
365
- ? Array.from(new Set([...spaceAttachedLookupKeys, ...preferredLookupKeys]))
366
- : preferredLookupKeys.length > 0
367
- ? preferredLookupKeys
368
- : buildLocalAgentLookupKeys({
369
- agentRef: agentKey,
370
- userId: currentUserId || "local",
371
- });
372
238
 
373
- const readRemoteRecord = async (key: string) => {
374
- for (const serverUrl of serverCandidates) {
239
+ if (!shouldReadAgentKeyRemotely(key)) continue;
240
+ for (const serverUrl of (
241
+ args.cliArgs
242
+ ? resolveServerCandidates(args.cliArgs, args.env, defaultServerUrl)
243
+ : resolveServerCandidates(args.env, defaultServerUrl)
244
+ )) {
375
245
  try {
376
246
  const remoteRecord = await readAgentRecord({
377
247
  agentKey: key,
@@ -391,31 +261,6 @@ export async function resolveAgentRecordFromHybridStore(args: {
391
261
  // try next
392
262
  }
393
263
  }
394
- return null;
395
- };
396
-
397
- for (const key of lookupKeys) {
398
- if (preferRemote && shouldReadAgentKeyRemotely(key)) {
399
- const remoteFirst = await readRemoteRecord(key);
400
- if (remoteFirst) return remoteFirst;
401
- }
402
-
403
- try {
404
- const record = await args.db.get(key);
405
- if (record && typeof record === "object") {
406
- return {
407
- agentKey: key,
408
- record,
409
- source: record?.serverOrigin ? "remote-cache" : "local-cache",
410
- } as const;
411
- }
412
- } catch {
413
- // local miss
414
- }
415
-
416
- if (!shouldReadAgentKeyRemotely(key)) continue;
417
- const remoteFallback = await readRemoteRecord(key);
418
- if (remoteFallback) return remoteFallback;
419
264
  }
420
265
 
421
266
  return null;
@@ -454,6 +299,8 @@ export function parseAgentUpdateArgs(args: string[]) {
454
299
  const tools = readOption(args, "--tools");
455
300
  const copyProviderFrom = readOption(args, "--copy-provider-from");
456
301
  const name = readOption(args, "--name");
302
+ const customProviderUrl = readOption(args, "--custom-provider-url");
303
+ const apiKey = readOption(args, "--api-key");
457
304
 
458
305
  const promptSources = [prompt, promptFile, promptDoc].filter(Boolean);
459
306
  if (promptSources.length > 1) {
@@ -468,6 +315,8 @@ export function parseAgentUpdateArgs(args: string[]) {
468
315
  if (promptFile) updates.prompt = readFileSync(promptFile, "utf8");
469
316
  if (tools) updates.tools = parseJsonishValue(tools);
470
317
  if (name) updates.name = name;
318
+ if (customProviderUrl) updates.customProviderUrl = customProviderUrl;
319
+ if (apiKey) updates.apiKey = apiKey;
471
320
 
472
321
  for (const entry of readRepeatedOption(args, "--field")) {
473
322
  const index = entry.indexOf("=");
@@ -486,6 +335,71 @@ export function parseAgentUpdateArgs(args: string[]) {
486
335
  return { agentInput, updates, promptDoc, copyProviderFrom };
487
336
  }
488
337
 
338
+ export async function buildCreatedAgentRecord(args: {
339
+ cliArgs?: string[];
340
+ parsed: NonNullable<ReturnType<typeof parseAgentUpdateArgs>>;
341
+ env: EnvLike;
342
+ db: CliKvDb;
343
+ fetchImpl: typeof fetch;
344
+ fallbackFetchImpl?: typeof fetch;
345
+ authToken: string;
346
+ }) {
347
+ const agentKey = resolveCliAgentKeyInput(args.parsed.agentInput);
348
+ const serverUrl = args.cliArgs ? resolveServerUrl(args.cliArgs, args.env) : resolveServerUrl(args.env);
349
+
350
+ if (args.parsed.copyProviderFrom) {
351
+ const providerSource = await resolveAgentRecordFromHybridStore({
352
+ agentInput: args.parsed.copyProviderFrom,
353
+ cliArgs: args.cliArgs,
354
+ env: args.env,
355
+ db: args.db,
356
+ fetchImpl: args.fetchImpl,
357
+ fallbackFetchImpl: args.fallbackFetchImpl,
358
+ });
359
+ if (!providerSource) {
360
+ throw new Error(`provider source agent not found: ${args.parsed.copyProviderFrom}`);
361
+ }
362
+ for (const field of PROVIDER_COPY_FIELDS) {
363
+ if (field in providerSource.record) {
364
+ args.parsed.updates[field] = providerSource.record[field];
365
+ }
366
+ }
367
+ }
368
+
369
+ if (args.parsed.promptDoc) {
370
+ const promptDoc = await readDbRecord({
371
+ dbKey: args.parsed.promptDoc,
372
+ authToken: args.authToken,
373
+ fallbackFetchImpl: args.fallbackFetchImpl,
374
+ fetchImpl: args.fetchImpl,
375
+ serverUrl,
376
+ });
377
+ const promptBody = typeof promptDoc?.content === "string" ? promptDoc.content : "";
378
+ if (!promptBody.trim()) {
379
+ throw new Error(`prompt doc is empty or unreadable: ${args.parsed.promptDoc}`);
380
+ }
381
+ args.parsed.updates.prompt = promptBody;
382
+ }
383
+
384
+ const userId = parseUserIdFromAuthToken(args.authToken);
385
+
386
+ const nextRecord = {
387
+ ...args.parsed.updates,
388
+ dbKey: agentKey,
389
+ key: agentKey,
390
+ createdAt: Date.now(),
391
+ updatedAt: Date.now(),
392
+ userId,
393
+ };
394
+
395
+ return {
396
+ agentKey,
397
+ serverUrl,
398
+ nextRecord,
399
+ updates: args.parsed.updates,
400
+ };
401
+ }
402
+
489
403
  export async function buildUpdatedAgentRecord(args: {
490
404
  cliArgs?: string[];
491
405
  parsed: NonNullable<ReturnType<typeof parseAgentUpdateArgs>>;
@@ -504,7 +418,9 @@ export async function buildUpdatedAgentRecord(args: {
504
418
  fallbackFetchImpl: args.fallbackFetchImpl,
505
419
  });
506
420
  const agentKey = cached?.agentKey ?? resolveCliAgentKeyInput(args.parsed.agentInput);
507
- const serverUrl = cached?.record?.serverOrigin ?? resolveServerUrl(args.cliArgs ?? [], args.env);
421
+ const serverUrl = cached?.record?.serverOrigin ?? (
422
+ args.cliArgs ? resolveServerUrl(args.cliArgs, args.env) : resolveServerUrl(args.env)
423
+ );
508
424
  const currentRecord = await readAgentRecord({
509
425
  agentKey,
510
426
  authToken: args.authToken,