overlord-cli 4.14.0 → 4.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/_cli/protocol.mjs
CHANGED
|
@@ -69,7 +69,7 @@ function resolveProtocolMetadata(flags = {}, base = {}) {
|
|
|
69
69
|
const metadata = { ...base };
|
|
70
70
|
|
|
71
71
|
if (flags['metadata-json']) {
|
|
72
|
-
const parsed =
|
|
72
|
+
const parsed = parseJsonFlag('--metadata-json', flags['metadata-json']);
|
|
73
73
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
74
74
|
throw new Error('--metadata-json must be a JSON object');
|
|
75
75
|
}
|
|
@@ -215,6 +215,15 @@ function requireFlag(flags, name, envAlias) {
|
|
|
215
215
|
return String(value);
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
function parseJsonFlag(flagName, rawValue) {
|
|
219
|
+
try {
|
|
220
|
+
return JSON.parse(String(rawValue));
|
|
221
|
+
} catch (err) {
|
|
222
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
223
|
+
throw new Error(`${flagName} must be valid JSON: ${detail}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
218
227
|
function readTextFile(filePath, label) {
|
|
219
228
|
try {
|
|
220
229
|
return fs.readFileSync(filePath, 'utf8');
|
|
@@ -286,11 +295,7 @@ async function resolveChangeRationales(flags) {
|
|
|
286
295
|
);
|
|
287
296
|
}
|
|
288
297
|
if (flags['change-rationales-json']) {
|
|
289
|
-
|
|
290
|
-
return JSON.parse(String(flags['change-rationales-json']));
|
|
291
|
-
} catch {
|
|
292
|
-
throw new Error('--change-rationales-json must be valid JSON');
|
|
293
|
-
}
|
|
298
|
+
return parseJsonFlag('--change-rationales-json', flags['change-rationales-json']);
|
|
294
299
|
}
|
|
295
300
|
return [];
|
|
296
301
|
}
|
|
@@ -534,7 +539,7 @@ async function protocolUpdate(args) {
|
|
|
534
539
|
: {}),
|
|
535
540
|
...(flags.phase ? { phase: String(flags.phase) } : {}),
|
|
536
541
|
...(flags['event-type'] ? { eventType: String(flags['event-type']) } : {}),
|
|
537
|
-
...(flags['payload-json'] ? { payload:
|
|
542
|
+
...(flags['payload-json'] ? { payload: parseJsonFlag('--payload-json', flags['payload-json']) } : {}),
|
|
538
543
|
...(changeRationales.length > 0 ? { changeRationales } : {})
|
|
539
544
|
};
|
|
540
545
|
|
|
@@ -613,7 +618,7 @@ async function protocolAsk(args) {
|
|
|
613
618
|
ticketId,
|
|
614
619
|
question,
|
|
615
620
|
...(flags.phase ? { phase: String(flags.phase) } : {}),
|
|
616
|
-
...(flags['payload-json'] ? { payload:
|
|
621
|
+
...(flags['payload-json'] ? { payload: parseJsonFlag('--payload-json', flags['payload-json']) } : {})
|
|
617
622
|
};
|
|
618
623
|
|
|
619
624
|
const data = await apiPost(platformUrl, agentToken, localSecret, '/api/protocol/ask', body, timeoutMs);
|
|
@@ -750,11 +755,7 @@ async function protocolDeliver(args) {
|
|
|
750
755
|
if (flags['artifacts-file']) {
|
|
751
756
|
artifacts = await readJsonFileOrStdin(String(flags['artifacts-file']), '--artifacts-file');
|
|
752
757
|
} else if (flags['artifacts-json']) {
|
|
753
|
-
|
|
754
|
-
artifacts = JSON.parse(String(flags['artifacts-json']));
|
|
755
|
-
} catch {
|
|
756
|
-
throw new Error('--artifacts-json must be valid JSON');
|
|
757
|
-
}
|
|
758
|
+
artifacts = parseJsonFlag('--artifacts-json', flags['artifacts-json']);
|
|
758
759
|
}
|
|
759
760
|
|
|
760
761
|
if (deliverPayload && (flags['change-rationales-file'] || flags['change-rationales-json'])) {
|
|
@@ -805,7 +806,7 @@ async function protocolArtifactPrepareUpload(args) {
|
|
|
805
806
|
...(flags['artifact-type'] ? { artifactType: String(flags['artifact-type']) } : {}),
|
|
806
807
|
...(flags['content-type'] ? { contentType: String(flags['content-type']) } : {}),
|
|
807
808
|
...(flags['file-size'] ? { fileSize: parseInt(String(flags['file-size']), 10) } : {}),
|
|
808
|
-
...(flags['metadata-json'] ? { metadata:
|
|
809
|
+
...(flags['metadata-json'] ? { metadata: parseJsonFlag('--metadata-json', flags['metadata-json']) } : {})
|
|
809
810
|
};
|
|
810
811
|
|
|
811
812
|
const data = await apiPost(
|
|
@@ -838,7 +839,7 @@ async function protocolArtifactFinalizeUpload(args) {
|
|
|
838
839
|
...(flags['artifact-type'] ? { artifactType: String(flags['artifact-type']) } : {}),
|
|
839
840
|
...(flags['content-type'] ? { contentType: String(flags['content-type']) } : {}),
|
|
840
841
|
...(flags['file-size'] ? { fileSize: parseInt(String(flags['file-size']), 10) } : {}),
|
|
841
|
-
...(flags['metadata-json'] ? { metadata:
|
|
842
|
+
...(flags['metadata-json'] ? { metadata: parseJsonFlag('--metadata-json', flags['metadata-json']) } : {})
|
|
842
843
|
};
|
|
843
844
|
|
|
844
845
|
const data = await apiPost(
|
|
@@ -915,7 +916,7 @@ async function protocolArtifactUploadFile(args) {
|
|
|
915
916
|
artifactType: String(flags['artifact-type'] ?? 'document'),
|
|
916
917
|
contentType,
|
|
917
918
|
fileSize: fileStats.size,
|
|
918
|
-
...(flags['metadata-json'] ? { metadata:
|
|
919
|
+
...(flags['metadata-json'] ? { metadata: parseJsonFlag('--metadata-json', flags['metadata-json']) } : {})
|
|
919
920
|
},
|
|
920
921
|
timeoutMs
|
|
921
922
|
);
|
|
@@ -941,7 +942,7 @@ async function protocolArtifactUploadFile(args) {
|
|
|
941
942
|
artifactType: String(flags['artifact-type'] ?? 'document'),
|
|
942
943
|
contentType,
|
|
943
944
|
fileSize: fileStats.size,
|
|
944
|
-
...(flags['metadata-json'] ? { metadata:
|
|
945
|
+
...(flags['metadata-json'] ? { metadata: parseJsonFlag('--metadata-json', flags['metadata-json']) } : {})
|
|
945
946
|
},
|
|
946
947
|
timeoutMs
|
|
947
948
|
);
|
|
@@ -1044,8 +1045,9 @@ async function protocolSpawn(args) {
|
|
|
1044
1045
|
const agentIdentifier = resolveProtocolAgentIdentifier(flags);
|
|
1045
1046
|
const modelIdentifier = resolveProtocolModelIdentifier(flags);
|
|
1046
1047
|
|
|
1047
|
-
// When --project-id is not provided, auto-send cwd as workingDirectory
|
|
1048
|
-
//
|
|
1048
|
+
// When --project-id is not provided, auto-send cwd as workingDirectory so
|
|
1049
|
+
// the server can resolve the project from the caller's project_user
|
|
1050
|
+
// local_working_directory setting.
|
|
1049
1051
|
const workingDirectory = flags['working-directory'] ?? (!flags['project-id'] ? process.cwd() : undefined);
|
|
1050
1052
|
|
|
1051
1053
|
const body = {
|
|
@@ -1147,7 +1149,7 @@ async function protocolCreateTicket(args) {
|
|
|
1147
1149
|
const projectId = discovered?.project?.id;
|
|
1148
1150
|
if (!projectId) {
|
|
1149
1151
|
throw new Error(
|
|
1150
|
-
|
|
1152
|
+
"Could not resolve project from working directory. Set your local working directory for this project in Overlord or pass --working-directory."
|
|
1151
1153
|
);
|
|
1152
1154
|
}
|
|
1153
1155
|
|
|
@@ -1215,8 +1217,8 @@ or attach to an existing ticket with \`ovld protocol attach --ticket-id <id>\`.
|
|
|
1215
1217
|
|
|
1216
1218
|
Project discovery:
|
|
1217
1219
|
When spawning or creating tickets, the CLI automatically resolves the correct
|
|
1218
|
-
project by matching your current working directory against
|
|
1219
|
-
|
|
1220
|
+
project by matching your current working directory against your configured
|
|
1221
|
+
"Local working directory" for that project (stored per user in Overlord).
|
|
1220
1222
|
You can also discover the project explicitly:
|
|
1221
1223
|
|
|
1222
1224
|
ovld protocol discover-project
|
|
@@ -1267,13 +1269,13 @@ auth-status:
|
|
|
1267
1269
|
discover-project:
|
|
1268
1270
|
Purpose:
|
|
1269
1271
|
Resolve the Overlord project that corresponds to the current (or given) working directory.
|
|
1270
|
-
Uses
|
|
1272
|
+
Uses the caller's configured "Local working directory" for matching.
|
|
1271
1273
|
Optional:
|
|
1272
1274
|
--working-directory <path> Directory to match (default: current working directory)
|
|
1273
1275
|
Returns:
|
|
1274
1276
|
Project JSON with id, name, organizationId. Prints PROJECT_ID=<id> on stderr.
|
|
1275
1277
|
Notes:
|
|
1276
|
-
Set
|
|
1278
|
+
Set your local working directory for a project in the Overlord UI under Project Settings.
|
|
1277
1279
|
When no match is found, returns a 404 with a hint.
|
|
1278
1280
|
|
|
1279
1281
|
attach:
|
|
@@ -1406,7 +1408,7 @@ spawn:
|
|
|
1406
1408
|
Purpose:
|
|
1407
1409
|
Create a follow-up ticket and attach to it in one call.
|
|
1408
1410
|
When --project-id is omitted, automatically resolves the project from the
|
|
1409
|
-
current working directory (matching against
|
|
1411
|
+
current working directory (matching against the caller's project_user.local_working_directory).
|
|
1410
1412
|
Required:
|
|
1411
1413
|
--objective <text>
|
|
1412
1414
|
Optional:
|
|
@@ -1437,7 +1439,7 @@ create:
|
|
|
1437
1439
|
Optional:
|
|
1438
1440
|
--session-key <key>
|
|
1439
1441
|
--ticket-id <id>
|
|
1440
|
-
--working-directory <path> Resolve project by local working directory (default: cwd)
|
|
1442
|
+
--working-directory <path> Resolve project by your configured local working directory (default: cwd)
|
|
1441
1443
|
--title <text>
|
|
1442
1444
|
--priority <level> low | medium | high | urgent
|
|
1443
1445
|
--acceptance-criteria <text>
|
package/package.json
CHANGED
|
@@ -73,7 +73,7 @@ Use this mode when the conversation starts normally and the user asks Claude to
|
|
|
73
73
|
|
|
74
74
|
1. If the user wants to create tickets (and does not ask to start execution), run `ovld protocol create --agent claude-code --objective "..."`.
|
|
75
75
|
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
76
|
-
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to Overlord `local_working_directory`, then creates a standalone draft.
|
|
76
|
+
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to the caller's configured Overlord `project_user.local_working_directory`, then creates a standalone draft.
|
|
77
77
|
2. Default to `create` for new tickets. Only use `/overlord:spawn` or `ovld protocol spawn --agent claude-code --objective "..."` when the user explicitly asks to create and execute immediately.
|
|
78
78
|
`spawn` creates the ticket in `execute` status and attaches immediately.
|
|
79
79
|
3. If the user already has a ticket ID and only wants to inspect it, use `/overlord:load` or run `ovld protocol load-context --ticket-id <ticket-id>`.
|