overlord-cli 4.15.0 → 4.17.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 +34 -36
- package/package.json +1 -1
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
|
);
|
|
@@ -1047,7 +1048,9 @@ async function protocolSpawn(args) {
|
|
|
1047
1048
|
// When --project-id is not provided, auto-send cwd as workingDirectory so
|
|
1048
1049
|
// the server can resolve the project from the caller's project_user
|
|
1049
1050
|
// local_working_directory setting.
|
|
1050
|
-
const
|
|
1051
|
+
const personal = Boolean(flags.personal);
|
|
1052
|
+
const workingDirectory =
|
|
1053
|
+
flags['working-directory'] ?? (!flags['project-id'] && !personal ? process.cwd() : undefined);
|
|
1051
1054
|
|
|
1052
1055
|
const body = {
|
|
1053
1056
|
objective,
|
|
@@ -1057,6 +1060,7 @@ async function protocolSpawn(args) {
|
|
|
1057
1060
|
...(flags.title ? { title: String(flags.title) } : {}),
|
|
1058
1061
|
...(flags.priority ? { priority: String(flags.priority) } : {}),
|
|
1059
1062
|
...(flags['project-id'] ? { projectId: String(flags['project-id']) } : {}),
|
|
1063
|
+
...(personal ? { personal: true } : {}),
|
|
1060
1064
|
...(workingDirectory ? { workingDirectory: String(workingDirectory) } : {}),
|
|
1061
1065
|
...(flags['acceptance-criteria'] ? { acceptanceCriteria: String(flags['acceptance-criteria']) } : {}),
|
|
1062
1066
|
...(flags['available-tools'] ? { availableTools: String(flags['available-tools']) } : {}),
|
|
@@ -1135,26 +1139,16 @@ async function protocolCreateTicket(args) {
|
|
|
1135
1139
|
);
|
|
1136
1140
|
}
|
|
1137
1141
|
|
|
1138
|
-
const
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
localSecret,
|
|
1143
|
-
'/api/protocol/discover-project',
|
|
1144
|
-
{ workingDirectory },
|
|
1145
|
-
timeoutMs
|
|
1146
|
-
);
|
|
1147
|
-
|
|
1148
|
-
const projectId = discovered?.project?.id;
|
|
1149
|
-
if (!projectId) {
|
|
1150
|
-
throw new Error(
|
|
1151
|
-
"Could not resolve project from working directory. Set your local working directory for this project in Overlord or pass --working-directory."
|
|
1152
|
-
);
|
|
1153
|
-
}
|
|
1142
|
+
const standaloneWorkingDirectory =
|
|
1143
|
+
!flags.personal && !flags['project-id']
|
|
1144
|
+
? String(flags['working-directory'] ?? process.cwd())
|
|
1145
|
+
: undefined;
|
|
1154
1146
|
|
|
1155
1147
|
const standaloneBody = {
|
|
1156
1148
|
objective,
|
|
1157
|
-
|
|
1149
|
+
...(flags.personal ? { personal: true } : {}),
|
|
1150
|
+
...(!flags.personal && flags['project-id'] ? { projectId: String(flags['project-id']) } : {}),
|
|
1151
|
+
...(standaloneWorkingDirectory ? { workingDirectory: standaloneWorkingDirectory } : {}),
|
|
1158
1152
|
...(flags.title ? { title: String(flags.title) } : {}),
|
|
1159
1153
|
...(flags.priority ? { priority: String(flags.priority) } : {}),
|
|
1160
1154
|
...(flags['acceptance-criteria'] ? { acceptanceCriteria: String(flags['acceptance-criteria']) } : {}),
|
|
@@ -1224,6 +1218,7 @@ Project discovery:
|
|
|
1224
1218
|
ovld protocol discover-project --working-directory /path/to/repo
|
|
1225
1219
|
|
|
1226
1220
|
Use --project-id to override automatic resolution on spawn or ticket creation.
|
|
1221
|
+
Use --personal to create a private ticket without assigning any project.
|
|
1227
1222
|
|
|
1228
1223
|
Subcommands:
|
|
1229
1224
|
auth-status Return machine-readable auth status for agent runtimes
|
|
@@ -1414,6 +1409,7 @@ spawn:
|
|
|
1414
1409
|
--title <text>
|
|
1415
1410
|
--priority <level> low | medium | high | urgent
|
|
1416
1411
|
--project-id <id> Explicit project; skips working-directory resolution
|
|
1412
|
+
--personal Create the ticket without assigning a project
|
|
1417
1413
|
--working-directory <path> Override cwd for project resolution (default: cwd)
|
|
1418
1414
|
--acceptance-criteria <text>
|
|
1419
1415
|
--available-tools <text>
|
|
@@ -1439,6 +1435,8 @@ create:
|
|
|
1439
1435
|
--session-key <key>
|
|
1440
1436
|
--ticket-id <id>
|
|
1441
1437
|
--working-directory <path> Resolve project by your configured local working directory (default: cwd)
|
|
1438
|
+
--project-id <id> Explicit project for standalone draft creation
|
|
1439
|
+
--personal Create a private standalone draft without a project
|
|
1442
1440
|
--title <text>
|
|
1443
1441
|
--priority <level> low | medium | high | urgent
|
|
1444
1442
|
--acceptance-criteria <text>
|
|
@@ -1450,7 +1448,7 @@ create:
|
|
|
1450
1448
|
Returns:
|
|
1451
1449
|
New draft ticket JSON (follow-up draft when session flags are provided)
|
|
1452
1450
|
Notes:
|
|
1453
|
-
Standalone create auto-discovers the project from the current working directory.
|
|
1451
|
+
Standalone create auto-discovers the project from the current working directory unless --personal is set.
|
|
1454
1452
|
Follow-up create requires both --session-key and --ticket-id.
|
|
1455
1453
|
|
|
1456
1454
|
artifact-prepare-upload:
|