perttool 0.8.0 → 0.9.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/CHANGELOG.md +37 -1
- package/README.md +90 -39
- package/dist/application/cli-facade.d.ts +10 -6
- package/dist/application/cli-facade.d.ts.map +1 -1
- package/dist/application/cli-facade.js +14 -6
- package/dist/application/cli-facade.js.map +1 -1
- package/dist/application/contract8-milestone-acceptance.d.ts +74 -0
- package/dist/application/contract8-milestone-acceptance.d.ts.map +1 -0
- package/dist/application/contract8-milestone-acceptance.js +185 -0
- package/dist/application/contract8-milestone-acceptance.js.map +1 -0
- package/dist/application/editor-milestone-acceptance.d.ts +75 -0
- package/dist/application/editor-milestone-acceptance.d.ts.map +1 -0
- package/dist/application/editor-milestone-acceptance.js +161 -0
- package/dist/application/editor-milestone-acceptance.js.map +1 -0
- package/dist/application/target-governance-init.d.ts +1 -1
- package/dist/application/target-governance-init.d.ts.map +1 -1
- package/dist/application/target-governance-init.js +3 -5
- package/dist/application/target-governance-init.js.map +1 -1
- package/dist/application/target-governance-project.d.ts +2 -2
- package/dist/application/target-governance-project.d.ts.map +1 -1
- package/dist/application/target-historical-graph.d.ts +3 -1
- package/dist/application/target-historical-graph.d.ts.map +1 -1
- package/dist/application/target-historical-graph.js +85 -2
- package/dist/application/target-historical-graph.js.map +1 -1
- package/dist/assurance/advance.d.ts.map +1 -1
- package/dist/assurance/advance.js +13 -3
- package/dist/assurance/advance.js.map +1 -1
- package/dist/cli.js +348 -28
- package/dist/cli.js.map +1 -1
- package/dist/command/assurance-discovery.d.ts +4 -3
- package/dist/command/assurance-discovery.d.ts.map +1 -1
- package/dist/command/assurance-discovery.js +96 -9
- package/dist/command/assurance-discovery.js.map +1 -1
- package/dist/command/assurance-usage.js +2 -2
- package/dist/command/assurance-usage.js.map +1 -1
- package/dist/command/discovery.js +4 -4
- package/dist/command/discovery.js.map +1 -1
- package/dist/command/registry.d.ts +1 -1
- package/dist/command/registry.d.ts.map +1 -1
- package/dist/command/registry.js +2 -2
- package/dist/command/registry.js.map +1 -1
- package/dist/command/usage.d.ts.map +1 -1
- package/dist/command/usage.js +12 -4
- package/dist/command/usage.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/help/assurance-guide.d.ts +1 -1
- package/dist/help/assurance-guide.d.ts.map +1 -1
- package/dist/help/assurance-guide.js +45 -19
- package/dist/help/assurance-guide.js.map +1 -1
- package/dist/help/guide.d.ts +1 -1
- package/dist/help/guide.d.ts.map +1 -1
- package/dist/help/registry.js +4 -4
- package/dist/help/registry.js.map +1 -1
- package/dist/history/historical-graph.d.ts +2 -0
- package/dist/history/historical-graph.d.ts.map +1 -1
- package/dist/history/historical-graph.js +98 -24
- package/dist/history/historical-graph.js.map +1 -1
- package/dist/history/milestone-acceptance-history.d.ts +59 -0
- package/dist/history/milestone-acceptance-history.d.ts.map +1 -0
- package/dist/history/milestone-acceptance-history.js +332 -0
- package/dist/history/milestone-acceptance-history.js.map +1 -0
- package/dist/index.d.ts +10 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/migration/grammar-boundary.d.ts +1 -1
- package/dist/migration/grammar-boundary.d.ts.map +1 -1
- package/dist/migration/grammar-boundary.js +7 -3
- package/dist/migration/grammar-boundary.js.map +1 -1
- package/dist/milestone-acceptance/advance.d.ts +39 -0
- package/dist/milestone-acceptance/advance.d.ts.map +1 -0
- package/dist/milestone-acceptance/advance.js +112 -0
- package/dist/milestone-acceptance/advance.js.map +1 -0
- package/dist/milestone-acceptance/evaluate.d.ts +51 -0
- package/dist/milestone-acceptance/evaluate.d.ts.map +1 -0
- package/dist/milestone-acceptance/evaluate.js +114 -0
- package/dist/milestone-acceptance/evaluate.js.map +1 -0
- package/dist/milestone-acceptance/migration.d.ts +25 -0
- package/dist/milestone-acceptance/migration.d.ts.map +1 -0
- package/dist/milestone-acceptance/migration.js +76 -0
- package/dist/milestone-acceptance/migration.js.map +1 -0
- package/dist/milestone-acceptance/mutation.d.ts +49 -0
- package/dist/milestone-acceptance/mutation.d.ts.map +1 -0
- package/dist/milestone-acceptance/mutation.js +136 -0
- package/dist/milestone-acceptance/mutation.js.map +1 -0
- package/dist/milestone-acceptance/source.d.ts +83 -0
- package/dist/milestone-acceptance/source.d.ts.map +1 -0
- package/dist/milestone-acceptance/source.js +301 -0
- package/dist/milestone-acceptance/source.js.map +1 -0
- package/dist/mutation/advance-deletion.d.ts.map +1 -1
- package/dist/mutation/advance-deletion.js +6 -1
- package/dist/mutation/advance-deletion.js.map +1 -1
- package/dist/recommendation/override-types.d.ts +2 -2
- package/dist/recommendation/override.d.ts +1 -1
- package/dist/recommendation/override.js +2 -2
- package/dist/schema/registry.d.ts +1 -1
- package/dist/schema/registry.d.ts.map +1 -1
- package/dist/schema/registry.js +8 -6
- package/dist/schema/registry.js.map +1 -1
- package/dist/semantic/validator.d.ts.map +1 -1
- package/dist/semantic/validator.js +14 -3
- package/dist/semantic/validator.js.map +1 -1
- package/dist/session/document-session.d.ts +5 -0
- package/dist/session/document-session.d.ts.map +1 -1
- package/dist/session/document-session.js +25 -2
- package/dist/session/document-session.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schemas/{Perttool.AdvanceResult.v2.schema.json → Perttool.AdvanceResult.v3.schema.json} +36 -5
- package/schemas/Perttool.AgentGuidanceResult.v1.schema.json +1 -1
- package/schemas/{Perttool.AnalysisResult.v5.schema.json → Perttool.AnalysisResult.v6.schema.json} +12 -5
- package/schemas/{Perttool.CheckResult.v4.schema.json → Perttool.CheckResult.v5.schema.json} +12 -5
- package/schemas/Perttool.CliError.v1.schema.json +1 -1
- package/schemas/Perttool.CommandHelpResult.v1.schema.json +3 -3
- package/schemas/Perttool.ExportResult.v1.schema.json +1 -1
- package/schemas/Perttool.FormatResult.v1.schema.json +1 -1
- package/schemas/Perttool.GuideResult.v1.schema.json +1 -1
- package/schemas/Perttool.HistoricalGraphResult.v1.schema.json +100 -2
- package/schemas/Perttool.ImportResult.v1.schema.json +1 -1
- package/schemas/Perttool.InitResult.v1.schema.json +1 -1
- package/schemas/Perttool.MilestoneAcceptanceMigrationResult.v1.schema.json +24 -0
- package/schemas/Perttool.MilestoneAcceptanceResult.v1.schema.json +79 -0
- package/schemas/{Perttool.MutationResult.v4.schema.json → Perttool.MutationResult.v5.schema.json} +4 -4
- package/schemas/{Perttool.NextResult.v6.schema.json → Perttool.NextResult.v7.schema.json} +12 -5
- package/schemas/Perttool.OverrideDecision.v1.schema.json +1 -1
- package/schemas/Perttool.PlanAssuranceResult.v1.schema.json +1 -1
- package/schemas/Perttool.ProjectHistoryResult.v1.schema.json +1 -1
- package/schemas/Perttool.ProjectResult.v4.schema.json +2 -2
- package/schemas/Perttool.SchemaResult.v1.schema.json +1 -1
- package/schemas/Perttool.UnitMigrationResult.v3.schema.json +5 -3
- package/schemas/Perttool.VelocityObservationResult.v1.schema.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -19,11 +19,29 @@ import { formatDecimal } from "./model/rational.js";
|
|
|
19
19
|
import { convertWithVelocity, durationSuffix } from "./model/units.js";
|
|
20
20
|
import { recommendationInvariantExitCode } from "./recommendation/failure.js";
|
|
21
21
|
import { recommendationAnalysisToJson } from "./recommendation/json.js";
|
|
22
|
+
import { applyTextEdits, normalizeTextEdits } from "./mutation/text-edits.js";
|
|
23
|
+
import { createUnifiedDiff } from "./editing/unified-diff.js";
|
|
24
|
+
import { sha256DigestUtf8 } from "./model/sha256.js";
|
|
22
25
|
import { TARGET_GRAMMAR_6_CAPABILITY, } from "./parser/document-parser.js";
|
|
23
26
|
import { exportPlanAssuranceMermaid, importPlanAssuranceMermaid, } from "./assurance/mermaid.js";
|
|
24
27
|
import { getJsonSchemaResult, renderJsonSchemaResult, serializeJsonSchemaResult, } from "./schema/registry.js";
|
|
25
28
|
import { TOOL_VERSION } from "./version.js";
|
|
26
|
-
|
|
29
|
+
import { analyzeDocument as analyzeContract8Document, checkDocument as checkContract8Document, selectNextTasks as selectContract8NextTasks, } from "./application/contract8-milestone-acceptance.js";
|
|
30
|
+
import { persistMilestoneAcceptanceMutation, planAcceptanceReceiptMutation, planCriterionSetReplacement, showMilestoneAcceptance, } from "./milestone-acceptance/mutation.js";
|
|
31
|
+
import { planMilestoneAcceptanceMigration, recheckCommittedMigrationProof, } from "./milestone-acceptance/migration.js";
|
|
32
|
+
import { MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY, milestoneAcceptanceBaseText, parseMilestoneAcceptanceSource } from "./milestone-acceptance/source.js";
|
|
33
|
+
import { planMilestoneAcceptanceAdvance } from "./milestone-acceptance/advance.js";
|
|
34
|
+
const { analyzeDocument: _analyzeContract7Document, checkDocument: _checkContract7Document, selectNextTasks: _selectContract7NextTasks, planFormat, planProjectInit, projectInitResultToJson, renderProjectInitResult, withProjectInitOutput, planUnitMigration, withUnitMigrationWrite, getProjectMetadata, contract7ProjectResultToJson, renderContract7ProjectText, planAdvance, planBatchMutation, planFinishActuals, planLifecycle, planMutation, planAssuranceMutation, renderTargetGovernanceDecision, contract7InspectionResultToJson, contract7MutationResultToJson, contract7SnakeJson, contract6WorkEventToJson, renderAdvanceHistoryGuard, prepareTargetPlanAssuranceAdvanceHistory, prepareAdvanceHistory, withAdvanceHistoryRace, withTargetPlanAssuranceAdvanceHistoryRace, persistTargetPlanAssuranceResult, inspectTargetPlanAssurance, inspectTargetProjectHistoryFile, renderTargetProjectHistoryText, targetProjectHistoryResultToJson, observeTargetProjectVelocity, renderTargetVelocityObservationText, targetVelocityObservationResultToJson, getAgentHelp, documentContentFromBytes, readDocumentContent, readBytes, recheckAdvanceHistoryBaseline, captureAdvanceHistoryBaseline, createArtifactFile, createValidatedDocumentFile, createTargetGrammar6DocumentFile, replaceTargetGrammar6DocumentFile, replaceValidatedDocumentFile, inspectTargetHistoricalGraphFile, renderTargetHistoricalGraphText, targetHistoricalGraphResultToJson, } = createCliApplicationFacade(createNodeHost(), createHistoricalGraphGitEvidenceHost());
|
|
35
|
+
const analyzeDocument = analyzeContract8Document;
|
|
36
|
+
const checkDocument = checkContract8Document;
|
|
37
|
+
const selectNextTasks = selectContract8NextTasks;
|
|
38
|
+
function contract8MutationResultToJson(result, ...args) {
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
...contract7MutationResultToJson(result, ...args),
|
|
41
|
+
schema_version: "Perttool.MutationResult.v5",
|
|
42
|
+
cli_contract_version: 8,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
27
45
|
class UsageError extends Error {
|
|
28
46
|
code = "PTCLI-001";
|
|
29
47
|
}
|
|
@@ -195,7 +213,11 @@ async function readStdin() {
|
|
|
195
213
|
return Buffer.concat(chunks);
|
|
196
214
|
}
|
|
197
215
|
function writeJson(value) {
|
|
198
|
-
|
|
216
|
+
const contract8Value = typeof value === "object" && value !== null && !Array.isArray(value) &&
|
|
217
|
+
"cli_contract_version" in value
|
|
218
|
+
? { ...value, cli_contract_version: 8 }
|
|
219
|
+
: value;
|
|
220
|
+
process.stdout.write(`${JSON.stringify(contract8Value)}\n`);
|
|
199
221
|
}
|
|
200
222
|
function snakeJson(value) {
|
|
201
223
|
if (typeof value === "bigint")
|
|
@@ -232,7 +254,7 @@ function cliError(error, exitCode, operation, json) {
|
|
|
232
254
|
if (json) {
|
|
233
255
|
writeJson({
|
|
234
256
|
schema_version: "Perttool.CliError.v1",
|
|
235
|
-
cli_contract_version:
|
|
257
|
+
cli_contract_version: 8,
|
|
236
258
|
tool_version: TOOL_VERSION,
|
|
237
259
|
operation,
|
|
238
260
|
ok: false,
|
|
@@ -268,7 +290,7 @@ async function runCheck(args) {
|
|
|
268
290
|
if (format === "json") {
|
|
269
291
|
writeJson({
|
|
270
292
|
schema_version: result.schemaVersion,
|
|
271
|
-
cli_contract_version:
|
|
293
|
+
cli_contract_version: 8,
|
|
272
294
|
tool_version: TOOL_VERSION,
|
|
273
295
|
operation: "document.check",
|
|
274
296
|
ok,
|
|
@@ -288,6 +310,7 @@ async function runCheck(args) {
|
|
|
288
310
|
},
|
|
289
311
|
assurance: contract7SnakeJson(result.assurance),
|
|
290
312
|
assurance_state_counts: contract7SnakeJson(result.assuranceStateCounts),
|
|
313
|
+
acceptance: snakeJson(result.acceptance),
|
|
291
314
|
});
|
|
292
315
|
}
|
|
293
316
|
else {
|
|
@@ -345,7 +368,7 @@ async function runProjectInit(args) {
|
|
|
345
368
|
const parsed = parseCommandOptions("project.init", args);
|
|
346
369
|
const format = outputFormat(parsed.values.get("format"));
|
|
347
370
|
const color = colorMode(parsed.values.get("color"), format);
|
|
348
|
-
const durationUnit = enumOption(
|
|
371
|
+
const durationUnit = enumOption(parsed.values.get("duration-unit") ?? "point", "duration-unit", new Set(["day", "hour", "point"]));
|
|
349
372
|
const version = optionalInteger(parsed, "version", 0, 2_147_483_647);
|
|
350
373
|
let result = planProjectInit({
|
|
351
374
|
projectId: parsed.positionals[0],
|
|
@@ -518,6 +541,28 @@ async function persistGovernedResult(result, request, sourceOperand) {
|
|
|
518
541
|
target: request.target,
|
|
519
542
|
});
|
|
520
543
|
}
|
|
544
|
+
async function persistContract8CandidateResult(result, request) {
|
|
545
|
+
if (request.mode === "preview" || !result.changed) {
|
|
546
|
+
return Object.freeze({ mode: request.mode, target: request.target, written: false });
|
|
547
|
+
}
|
|
548
|
+
if (!result.ok || !result.governance?.writeAuthorized || result.updatedText === null) {
|
|
549
|
+
throw new TypeError("authorized Contract 8 result does not contain a digest-bound candidate");
|
|
550
|
+
}
|
|
551
|
+
const validator = (candidate) => {
|
|
552
|
+
const parsed = parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
|
|
553
|
+
return { ok: parsed.ok, diagnostics: [] };
|
|
554
|
+
};
|
|
555
|
+
if (request.mode === "in_place") {
|
|
556
|
+
await replaceValidatedDocumentFile(request.target, result.updatedText, {
|
|
557
|
+
initialDigest: result.originalDigest,
|
|
558
|
+
...(request.expectedDigest === undefined ? {} : { expectedDigest: request.expectedDigest }),
|
|
559
|
+
}, validator);
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
await createValidatedDocumentFile(request.target, result.updatedText, validator);
|
|
563
|
+
}
|
|
564
|
+
return Object.freeze({ mode: request.mode, target: request.target, written: true });
|
|
565
|
+
}
|
|
521
566
|
function assertExpectedDigest(request, initialDigest) {
|
|
522
567
|
if (request.mode === "in_place" &&
|
|
523
568
|
request.expectedDigest !== undefined &&
|
|
@@ -529,6 +574,21 @@ async function commitCandidate(request, candidateText, initialDigest) {
|
|
|
529
574
|
if (candidateText === null) {
|
|
530
575
|
throw new SafeWriteVerificationError("invalid_candidate", "successful editing result has no candidate text");
|
|
531
576
|
}
|
|
577
|
+
const acceptanceSource = parseMilestoneAcceptanceSource(candidateText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
|
|
578
|
+
if (acceptanceSource.grammarVersion === 7) {
|
|
579
|
+
const validator = (candidate) => {
|
|
580
|
+
const parsed = parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
|
|
581
|
+
return { ok: parsed.ok, diagnostics: [] };
|
|
582
|
+
};
|
|
583
|
+
return request.mode === "in_place"
|
|
584
|
+
? replaceValidatedDocumentFile(request.target, candidateText, {
|
|
585
|
+
initialDigest,
|
|
586
|
+
...(request.expectedDigest === undefined
|
|
587
|
+
? {}
|
|
588
|
+
: { expectedDigest: request.expectedDigest }),
|
|
589
|
+
}, validator)
|
|
590
|
+
: createValidatedDocumentFile(request.target, candidateText, validator);
|
|
591
|
+
}
|
|
532
592
|
return request.mode === "in_place"
|
|
533
593
|
? replaceTargetGrammar6DocumentFile(request.target, candidateText, TARGET_GRAMMAR_6_CAPABILITY, {
|
|
534
594
|
initialDigest,
|
|
@@ -596,7 +656,7 @@ async function runFormat(args) {
|
|
|
596
656
|
if (format === "json") {
|
|
597
657
|
writeJson({
|
|
598
658
|
schema_version: "Perttool.FormatResult.v1",
|
|
599
|
-
cli_contract_version:
|
|
659
|
+
cli_contract_version: 8,
|
|
600
660
|
tool_version: TOOL_VERSION,
|
|
601
661
|
operation: "document.format",
|
|
602
662
|
ok,
|
|
@@ -1197,7 +1257,7 @@ async function runMutation(resource, action, args) {
|
|
|
1197
1257
|
if (result.ok) {
|
|
1198
1258
|
try {
|
|
1199
1259
|
if (ok && writeRequest.mode !== "preview") {
|
|
1200
|
-
writeResult = await
|
|
1260
|
+
writeResult = await persistContract8CandidateResult(result, writeRequest);
|
|
1201
1261
|
}
|
|
1202
1262
|
}
|
|
1203
1263
|
catch (error) {
|
|
@@ -1205,7 +1265,7 @@ async function runMutation(resource, action, args) {
|
|
|
1205
1265
|
}
|
|
1206
1266
|
}
|
|
1207
1267
|
if (format === "json") {
|
|
1208
|
-
writeJson(
|
|
1268
|
+
writeJson(contract8MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
|
|
1209
1269
|
}
|
|
1210
1270
|
else {
|
|
1211
1271
|
if (ok) {
|
|
@@ -1281,14 +1341,14 @@ async function runLifecycleMutation(action, args) {
|
|
|
1281
1341
|
});
|
|
1282
1342
|
if (result.ok && ok && writeRequest.mode !== "preview") {
|
|
1283
1343
|
try {
|
|
1284
|
-
writeResult = await
|
|
1344
|
+
writeResult = await persistContract8CandidateResult(result, writeRequest);
|
|
1285
1345
|
}
|
|
1286
1346
|
catch (error) {
|
|
1287
1347
|
return writeFailureExit(error, operation, format === "json");
|
|
1288
1348
|
}
|
|
1289
1349
|
}
|
|
1290
1350
|
if (format === "json") {
|
|
1291
|
-
writeJson(
|
|
1351
|
+
writeJson(contract8MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
|
|
1292
1352
|
}
|
|
1293
1353
|
else {
|
|
1294
1354
|
if (ok) {
|
|
@@ -1327,7 +1387,7 @@ function unitMigrationJson(result, source, sourceDigest, ok) {
|
|
|
1327
1387
|
});
|
|
1328
1388
|
return {
|
|
1329
1389
|
schema_version: result.schemaVersion,
|
|
1330
|
-
cli_contract_version:
|
|
1390
|
+
cli_contract_version: 8,
|
|
1331
1391
|
tool_version: TOOL_VERSION,
|
|
1332
1392
|
operation: "project.migrate-unit",
|
|
1333
1393
|
ok,
|
|
@@ -1628,16 +1688,94 @@ async function runAdvance(args) {
|
|
|
1628
1688
|
catch (error) {
|
|
1629
1689
|
return cliError(error instanceof Error ? error : new Error(String(error)), 3, "dag.advance", format === "json");
|
|
1630
1690
|
}
|
|
1631
|
-
const
|
|
1691
|
+
const acceptancePlan = planMilestoneAcceptanceAdvance(input.text, {
|
|
1692
|
+
maxDiagnostics,
|
|
1693
|
+
originalLabel: source,
|
|
1694
|
+
updatedLabel: "candidate",
|
|
1695
|
+
provisionalPlanner: (baseText) => planAdvance(baseText, {
|
|
1696
|
+
maxDiagnostics,
|
|
1697
|
+
originalLabel: source,
|
|
1698
|
+
updatedLabel: "candidate",
|
|
1699
|
+
}),
|
|
1700
|
+
});
|
|
1701
|
+
if (!acceptancePlan.ok) {
|
|
1702
|
+
if (format === "json")
|
|
1703
|
+
writeJson({
|
|
1704
|
+
schema_version: "Perttool.AdvanceResult.v3",
|
|
1705
|
+
cli_contract_version: 8,
|
|
1706
|
+
tool_version: TOOL_VERSION,
|
|
1707
|
+
operation: "dag.advance",
|
|
1708
|
+
ok: false,
|
|
1709
|
+
document_id: /^project ([A-Za-z][A-Za-z0-9_-]*):$/mu.exec(input.text)?.[1] ?? null,
|
|
1710
|
+
source,
|
|
1711
|
+
source_digest: input.digest,
|
|
1712
|
+
diagnostics: acceptancePlan.diagnostics.map(jsonDiagnostic),
|
|
1713
|
+
diagnostics_truncated: false,
|
|
1714
|
+
changed: acceptancePlan.provisional !== null,
|
|
1715
|
+
original_digest: acceptancePlan.originalDigest,
|
|
1716
|
+
updated_digest: acceptancePlan.provisional?.updatedDigest ?? null,
|
|
1717
|
+
updated_text: acceptancePlan.provisional?.updatedText ?? null,
|
|
1718
|
+
diff: acceptancePlan.provisional?.diff ?? null,
|
|
1719
|
+
edits: snakeJson(acceptancePlan.provisional?.edits ?? []),
|
|
1720
|
+
write: { mode: writeRequest.mode, target: writeRequest.target, written: false },
|
|
1721
|
+
governance: null,
|
|
1722
|
+
lifecycle: null,
|
|
1723
|
+
advance: acceptancePlan.provisional === null ? null : snakeJson({
|
|
1724
|
+
...acceptancePlan.provisional.advance,
|
|
1725
|
+
removedWorkEventIds: [],
|
|
1726
|
+
removedAssuranceRecordIds: [],
|
|
1727
|
+
updatedAssuranceReceiptIds: [],
|
|
1728
|
+
}),
|
|
1729
|
+
history_guard: null,
|
|
1730
|
+
assurance_guard: null,
|
|
1731
|
+
acceptance_guard: snakeJson(acceptancePlan.acceptanceGuard),
|
|
1732
|
+
});
|
|
1733
|
+
else {
|
|
1734
|
+
if (acceptancePlan.provisional !== null)
|
|
1735
|
+
process.stdout.write(parsed.flags.has("diff") ? acceptancePlan.provisional.diff : acceptancePlan.provisional.updatedText);
|
|
1736
|
+
for (const diagnostic of acceptancePlan.diagnostics)
|
|
1737
|
+
process.stderr.write(`${renderDiagnostic(diagnostic, source, color)}\n`);
|
|
1738
|
+
}
|
|
1739
|
+
return 1;
|
|
1740
|
+
}
|
|
1741
|
+
const contract7BaseText = milestoneAcceptanceBaseText(input.text);
|
|
1742
|
+
const contract7Planned = planAdvance(contract7BaseText, {
|
|
1632
1743
|
maxDiagnostics,
|
|
1633
1744
|
originalLabel: source,
|
|
1634
1745
|
updatedLabel: "candidate",
|
|
1635
1746
|
governance: governanceRequest(parsed, writeRequest),
|
|
1636
1747
|
});
|
|
1748
|
+
const combinedEdits = contract7Planned.updatedText === null
|
|
1749
|
+
? contract7Planned.edits
|
|
1750
|
+
: normalizeTextEdits(input.text, [...contract7Planned.edits, ...acceptancePlan.provisional.edits].filter((edit, index, values) => values.findIndex((candidate) => candidate.startOffset === edit.startOffset &&
|
|
1751
|
+
candidate.endOffset === edit.endOffset &&
|
|
1752
|
+
candidate.replacement === edit.replacement) === index), "Contract 8 acceptance-aware advance");
|
|
1753
|
+
const combinedText = contract7Planned.updatedText === null
|
|
1754
|
+
? null
|
|
1755
|
+
: applyTextEdits(input.text, combinedEdits);
|
|
1756
|
+
const combinedSource = combinedText === null
|
|
1757
|
+
? null
|
|
1758
|
+
: parseMilestoneAcceptanceSource(combinedText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
|
|
1759
|
+
if (combinedSource !== null && !combinedSource.ok) {
|
|
1760
|
+
throw new Error("acceptance-aware assurance advance lost Grammar 7 validation");
|
|
1761
|
+
}
|
|
1762
|
+
const planned = Object.freeze({
|
|
1763
|
+
...contract7Planned,
|
|
1764
|
+
schemaVersion: "Perttool.AdvanceResult.v3",
|
|
1765
|
+
originalDigest: input.digest,
|
|
1766
|
+
updatedText: combinedText,
|
|
1767
|
+
updatedDigest: combinedText === null ? null : sha256DigestUtf8(combinedText),
|
|
1768
|
+
diff: combinedText === null ? null : createUnifiedDiff(input.text, combinedText, {
|
|
1769
|
+
originalLabel: source,
|
|
1770
|
+
updatedLabel: "candidate",
|
|
1771
|
+
}),
|
|
1772
|
+
edits: combinedEdits,
|
|
1773
|
+
acceptanceGuard: acceptancePlan.acceptanceGuard,
|
|
1774
|
+
});
|
|
1637
1775
|
const initialWarningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
1638
1776
|
(planned.diagnosticsTruncated ||
|
|
1639
1777
|
planned.diagnostics.some((diagnostic) => diagnostic.severity === "warning"));
|
|
1640
|
-
const
|
|
1778
|
+
const preparedBase = await prepareAdvanceHistory(input.text, planned, {
|
|
1641
1779
|
mode: writeRequest.mode === "out"
|
|
1642
1780
|
? "out"
|
|
1643
1781
|
: writeRequest.mode,
|
|
@@ -1649,6 +1787,28 @@ async function runAdvance(args) {
|
|
|
1649
1787
|
forceRequested,
|
|
1650
1788
|
warningDenied: initialWarningFailure,
|
|
1651
1789
|
maxDiagnostics,
|
|
1790
|
+
documentValidator: (candidateText, candidateMaxDiagnostics) => {
|
|
1791
|
+
const acceptanceSource = parseMilestoneAcceptanceSource(candidateText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
|
|
1792
|
+
const checked = checkContract8Document(candidateText, { maxDiagnostics: candidateMaxDiagnostics });
|
|
1793
|
+
return {
|
|
1794
|
+
ok: checked.ok && acceptanceSource.ok,
|
|
1795
|
+
document: checked.document,
|
|
1796
|
+
documentId: checked.documentId,
|
|
1797
|
+
diagnostics: checked.diagnostics,
|
|
1798
|
+
diagnosticsTruncated: checked.diagnosticsTruncated,
|
|
1799
|
+
};
|
|
1800
|
+
},
|
|
1801
|
+
});
|
|
1802
|
+
const prepared = Object.freeze({
|
|
1803
|
+
...preparedBase,
|
|
1804
|
+
result: Object.freeze({
|
|
1805
|
+
...preparedBase.result,
|
|
1806
|
+
schemaVersion: "Perttool.AdvanceResult.v3",
|
|
1807
|
+
governance: planned.governance,
|
|
1808
|
+
assuranceGuard: planned.assuranceGuard,
|
|
1809
|
+
acceptanceGuard: acceptancePlan.acceptanceGuard,
|
|
1810
|
+
advance: planned.advance,
|
|
1811
|
+
}),
|
|
1652
1812
|
});
|
|
1653
1813
|
let result = prepared.result;
|
|
1654
1814
|
const warningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
@@ -1671,13 +1831,20 @@ async function runAdvance(args) {
|
|
|
1671
1831
|
result.historyGuard?.status === "forced")) {
|
|
1672
1832
|
const recheck = await recheckAdvanceHistoryBaseline(prepared.baseline, sourceOperand);
|
|
1673
1833
|
if (!recheck.ok) {
|
|
1674
|
-
result =
|
|
1834
|
+
result = Object.freeze({
|
|
1835
|
+
...withAdvanceHistoryRace(result, recheck, maxDiagnostics),
|
|
1836
|
+
schemaVersion: "Perttool.AdvanceResult.v3",
|
|
1837
|
+
governance: result.governance,
|
|
1838
|
+
assuranceGuard: result.assuranceGuard,
|
|
1839
|
+
acceptanceGuard: result.acceptanceGuard,
|
|
1840
|
+
advance: result.advance,
|
|
1841
|
+
});
|
|
1675
1842
|
ok = false;
|
|
1676
1843
|
historyRace = true;
|
|
1677
1844
|
}
|
|
1678
1845
|
}
|
|
1679
1846
|
if (ok && writeRequest.mode !== "preview") {
|
|
1680
|
-
writeResult = await
|
|
1847
|
+
writeResult = await persistContract8CandidateResult(result, writeRequest);
|
|
1681
1848
|
}
|
|
1682
1849
|
}
|
|
1683
1850
|
catch (error) {
|
|
@@ -1685,7 +1852,12 @@ async function runAdvance(args) {
|
|
|
1685
1852
|
}
|
|
1686
1853
|
}
|
|
1687
1854
|
if (format === "json") {
|
|
1688
|
-
writeJson(
|
|
1855
|
+
writeJson({
|
|
1856
|
+
...contract7MutationResultToJson((ok ? result : Object.freeze({ ...result, ok: false })), "dag.advance", source, writeResult),
|
|
1857
|
+
schema_version: "Perttool.AdvanceResult.v3",
|
|
1858
|
+
cli_contract_version: 8,
|
|
1859
|
+
acceptance_guard: snakeJson(result.acceptanceGuard),
|
|
1860
|
+
});
|
|
1689
1861
|
}
|
|
1690
1862
|
else {
|
|
1691
1863
|
if (result.advance !== null) {
|
|
@@ -2046,7 +2218,7 @@ async function runAnalyze(args) {
|
|
|
2046
2218
|
if (format === "json") {
|
|
2047
2219
|
writeJson({
|
|
2048
2220
|
schema_version: result.schemaVersion,
|
|
2049
|
-
cli_contract_version:
|
|
2221
|
+
cli_contract_version: 8,
|
|
2050
2222
|
tool_version: TOOL_VERSION,
|
|
2051
2223
|
operation: "dag.analyze",
|
|
2052
2224
|
ok,
|
|
@@ -2079,6 +2251,7 @@ async function runAnalyze(args) {
|
|
|
2079
2251
|
: resourceJson(result.resource, result.durationUnit, result.precision),
|
|
2080
2252
|
temporal: snakeJson(result.temporal),
|
|
2081
2253
|
assurance: contract7SnakeJson(result.assurance),
|
|
2254
|
+
acceptance: snakeJson(result.acceptance),
|
|
2082
2255
|
});
|
|
2083
2256
|
}
|
|
2084
2257
|
else {
|
|
@@ -2193,7 +2366,7 @@ async function runRender(args) {
|
|
|
2193
2366
|
if (format === "json") {
|
|
2194
2367
|
writeJson({
|
|
2195
2368
|
schema_version: "Perttool.ExportResult.v1",
|
|
2196
|
-
cli_contract_version:
|
|
2369
|
+
cli_contract_version: 8,
|
|
2197
2370
|
tool_version: TOOL_VERSION,
|
|
2198
2371
|
operation: "dag.render",
|
|
2199
2372
|
ok,
|
|
@@ -2306,7 +2479,7 @@ async function runImport(args) {
|
|
|
2306
2479
|
if (format === "json") {
|
|
2307
2480
|
writeJson({
|
|
2308
2481
|
schema_version: "Perttool.ImportResult.v1",
|
|
2309
|
-
cli_contract_version:
|
|
2482
|
+
cli_contract_version: 8,
|
|
2310
2483
|
tool_version: TOOL_VERSION,
|
|
2311
2484
|
operation: "dag.import",
|
|
2312
2485
|
ok,
|
|
@@ -2615,7 +2788,7 @@ async function runNext(args) {
|
|
|
2615
2788
|
if (format === "json") {
|
|
2616
2789
|
writeJson({
|
|
2617
2790
|
schema_version: "Perttool.CliError.v1",
|
|
2618
|
-
cli_contract_version:
|
|
2791
|
+
cli_contract_version: 8,
|
|
2619
2792
|
tool_version: TOOL_VERSION,
|
|
2620
2793
|
operation: "dag.next",
|
|
2621
2794
|
ok: false,
|
|
@@ -2636,7 +2809,7 @@ async function runNext(args) {
|
|
|
2636
2809
|
if (format === "json") {
|
|
2637
2810
|
writeJson({
|
|
2638
2811
|
schema_version: result.schemaVersion,
|
|
2639
|
-
cli_contract_version:
|
|
2812
|
+
cli_contract_version: 8,
|
|
2640
2813
|
recommendation_interface_version: 1,
|
|
2641
2814
|
tool_version: TOOL_VERSION,
|
|
2642
2815
|
operation: "dag.next",
|
|
@@ -2650,6 +2823,7 @@ async function runNext(args) {
|
|
|
2650
2823
|
...(result.durationUnit === null ? {} : nextJson(result)),
|
|
2651
2824
|
temporal: snakeJson(result.temporal),
|
|
2652
2825
|
assurance: contract7SnakeJson(result.assurance),
|
|
2826
|
+
acceptance: snakeJson(result.acceptance),
|
|
2653
2827
|
});
|
|
2654
2828
|
}
|
|
2655
2829
|
else {
|
|
@@ -2664,6 +2838,142 @@ async function runNext(args) {
|
|
|
2664
2838
|
}
|
|
2665
2839
|
return ok ? 0 : 1;
|
|
2666
2840
|
}
|
|
2841
|
+
async function runMilestoneAcceptance(action, args) {
|
|
2842
|
+
const operation = `milestone-acceptance.${action}`;
|
|
2843
|
+
const parsed = parseCommandOptions(operation, args);
|
|
2844
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
2845
|
+
const sourceOperand = parsed.positionals[0];
|
|
2846
|
+
if (sourceOperand === undefined)
|
|
2847
|
+
throw new UsageError(`${operation} requires <file>`);
|
|
2848
|
+
const input = await readDocument(sourceOperand);
|
|
2849
|
+
if (action === "show") {
|
|
2850
|
+
if (parsed.positionals.length !== 1)
|
|
2851
|
+
throw new UsageError("milestone acceptance show requires exactly one <file>");
|
|
2852
|
+
const result = checkDocument(input.text).acceptance ?? showMilestoneAcceptance(input.text, []);
|
|
2853
|
+
if (format === "json")
|
|
2854
|
+
writeJson({ schema_version: "Perttool.MilestoneAcceptanceResult.v1", cli_contract_version: 8, tool_version: TOOL_VERSION, operation, ok: result.ok, milestones: snakeJson(result.milestones), diagnostics: snakeJson(result.diagnostics) });
|
|
2855
|
+
else
|
|
2856
|
+
process.stdout.write(`${result.milestones.map(({ milestoneId, closure, acceptance }) => `${milestoneId} closure=${closure} acceptance=${acceptance}`).join("\n")}\n`);
|
|
2857
|
+
return result.ok ? 0 : 1;
|
|
2858
|
+
}
|
|
2859
|
+
if (parsed.positionals.length !== 4)
|
|
2860
|
+
throw new UsageError(`${operation} requires four operands`);
|
|
2861
|
+
const request = editingWriteRequest(parsed, sourceOperand);
|
|
2862
|
+
if (request.mode === "out")
|
|
2863
|
+
throw new UsageError(`${operation} does not support --out in Contract 8`);
|
|
2864
|
+
const governance = governanceRequest(parsed, request);
|
|
2865
|
+
let result;
|
|
2866
|
+
if (action === "replace") {
|
|
2867
|
+
const criteria = (parsed.repeatedValues.get("criterion") ?? []).map((value) => {
|
|
2868
|
+
const [criterionId, requiredText, evidenceKind, ...description] = value.split(":");
|
|
2869
|
+
if (criterionId === undefined || !["required", "optional"].includes(requiredText ?? "") || !["test", "command", "artifact", "observation", "owner"].includes(evidenceKind ?? "") || description.length === 0)
|
|
2870
|
+
throw new UsageError("--criterion must be ID:required|optional:kind:description");
|
|
2871
|
+
return { criterionId, required: requiredText === "required", evidenceKind: evidenceKind, description: description.join(":") };
|
|
2872
|
+
});
|
|
2873
|
+
result = planCriterionSetReplacement(input.text, { milestoneId: parsed.positionals[1], setId: parsed.positionals[2], revisionId: parsed.positionals[3], criteria }, { governance });
|
|
2874
|
+
}
|
|
2875
|
+
else {
|
|
2876
|
+
result = planAcceptanceReceiptMutation(input.text, {
|
|
2877
|
+
setId: parsed.positionals[1], criterionId: parsed.positionals[2], receiptId: parsed.positionals[3], action: action,
|
|
2878
|
+
...(parsed.values.get("evidence-kind") === undefined ? {} : { evidenceKind: parsed.values.get("evidence-kind") }),
|
|
2879
|
+
...(parsed.values.get("evidence-reference") === undefined ? {} : { evidenceReference: parsed.values.get("evidence-reference") }),
|
|
2880
|
+
...(parsed.values.get("evidence-revision") === undefined ? {} : { evidenceRevision: parsed.values.get("evidence-revision") }),
|
|
2881
|
+
...(parsed.values.get("verifier") === undefined ? {} : { verifier: parsed.values.get("verifier") }),
|
|
2882
|
+
...(parsed.values.get("occurred-at") === undefined ? {} : { occurredAt: parsed.values.get("occurred-at") }),
|
|
2883
|
+
...(parsed.values.get("reason") === undefined ? {} : { reason: parsed.values.get("reason") }),
|
|
2884
|
+
...(parsed.values.get("revokes") === undefined ? {} : { revokes: parsed.values.get("revokes") }),
|
|
2885
|
+
}, { governance });
|
|
2886
|
+
}
|
|
2887
|
+
let written = false;
|
|
2888
|
+
if (result.ok && request.mode === "in_place" && result.changed) {
|
|
2889
|
+
await persistMilestoneAcceptanceMutation(sourceOperand, result, request.expectedDigest);
|
|
2890
|
+
written = true;
|
|
2891
|
+
}
|
|
2892
|
+
if (format === "json")
|
|
2893
|
+
writeJson({
|
|
2894
|
+
schema_version: "Perttool.MutationResult.v5",
|
|
2895
|
+
cli_contract_version: 8,
|
|
2896
|
+
tool_version: TOOL_VERSION,
|
|
2897
|
+
operation,
|
|
2898
|
+
ok: result.ok,
|
|
2899
|
+
document_id: /^project ([A-Za-z][A-Za-z0-9_-]*):$/mu.exec(input.text)?.[1] ?? null,
|
|
2900
|
+
source: sourceOperand,
|
|
2901
|
+
source_digest: input.digest,
|
|
2902
|
+
diagnostics: result.diagnostics.map((code) => jsonDiagnostic({
|
|
2903
|
+
code,
|
|
2904
|
+
severity: code === "PTGOV-103" || code === "PTGOV-104" ? "warning" : "error",
|
|
2905
|
+
message: code,
|
|
2906
|
+
helpTopic: "editing",
|
|
2907
|
+
})),
|
|
2908
|
+
diagnostics_truncated: false,
|
|
2909
|
+
changed: result.changed,
|
|
2910
|
+
original_digest: result.originalDigest,
|
|
2911
|
+
updated_digest: result.updatedDigest,
|
|
2912
|
+
updated_text: result.updatedText,
|
|
2913
|
+
diff: result.updatedText === null ? null : createUnifiedDiff(input.text, result.updatedText, { originalLabel: sourceOperand, updatedLabel: "candidate" }),
|
|
2914
|
+
edits: result.changed && result.updatedText !== null ? [{ start_offset: 0, end_offset: input.text.length, replacement: result.updatedText }] : [],
|
|
2915
|
+
write: { mode: request.mode, target: request.target, written },
|
|
2916
|
+
governance: result.governance === null ? null : {
|
|
2917
|
+
...snakeJson(result.governance),
|
|
2918
|
+
schema_version: "Perttool.GovernanceDecision.v2",
|
|
2919
|
+
governance_interface_version: 2,
|
|
2920
|
+
governance_semantics_version: 2,
|
|
2921
|
+
},
|
|
2922
|
+
lifecycle: null,
|
|
2923
|
+
assurance_impact: null,
|
|
2924
|
+
});
|
|
2925
|
+
else if (result.updatedText !== null)
|
|
2926
|
+
process.stdout.write(result.updatedText);
|
|
2927
|
+
return result.ok ? 0 : 1;
|
|
2928
|
+
}
|
|
2929
|
+
async function runDocumentMigration(args) {
|
|
2930
|
+
const parsed = parseCommandOptions("document.migrate", args);
|
|
2931
|
+
if (parsed.positionals.length !== 1 || parsed.values.get("target-grammar") !== "7")
|
|
2932
|
+
throw new UsageError("document migrate requires <file> --target-grammar 7");
|
|
2933
|
+
const sourceOperand = parsed.positionals[0];
|
|
2934
|
+
if (sourceOperand === "-")
|
|
2935
|
+
throw new UsageError("document migrate requires a repository file");
|
|
2936
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
2937
|
+
const input = await readDocument(sourceOperand);
|
|
2938
|
+
const baseline = await captureAdvanceHistoryBaseline({ targetPath: sourceOperand, expectedSourceDigest: input.digest });
|
|
2939
|
+
const toProof = (value) => value.status === "complete" && value.repositorySnapshotId !== null &&
|
|
2940
|
+
value.repositoryRelativePath !== null && value.objectFormat !== null &&
|
|
2941
|
+
value.headCommitId !== null && value.headBlobId !== null &&
|
|
2942
|
+
value.indexBlobId !== null && value.currentSourceDigest !== null
|
|
2943
|
+
? {
|
|
2944
|
+
repositoryId: value.repositorySnapshotId,
|
|
2945
|
+
repositoryRelativePath: value.repositoryRelativePath,
|
|
2946
|
+
objectFormat: value.objectFormat,
|
|
2947
|
+
headCommit: value.headCommitId,
|
|
2948
|
+
headBlob: value.headBlobId,
|
|
2949
|
+
stage0Blob: value.indexBlobId,
|
|
2950
|
+
sourceDigest: value.currentSourceDigest,
|
|
2951
|
+
}
|
|
2952
|
+
: null;
|
|
2953
|
+
const proof = toProof(baseline);
|
|
2954
|
+
let result = proof === null
|
|
2955
|
+
? { ok: false, modelVersion: 1, changed: false, sourceGrammarVersion: null, targetGrammarVersion: null, sourceDigest: input.digest, candidateDigest: null, grandfatheredMilestoneIds: Object.freeze([]), candidateText: null, diagnostics: Object.freeze(["PTMAC-109"]) }
|
|
2956
|
+
: planMilestoneAcceptanceMigration(input.text, proof);
|
|
2957
|
+
let race = false;
|
|
2958
|
+
if (result.ok && result.changed && result.candidateText !== null && parsed.flags.has("write")) {
|
|
2959
|
+
const current = toProof(await captureAdvanceHistoryBaseline({
|
|
2960
|
+
targetPath: sourceOperand,
|
|
2961
|
+
expectedSourceDigest: input.digest,
|
|
2962
|
+
}));
|
|
2963
|
+
if (proof === null || current === null || !recheckCommittedMigrationProof(proof, current)) {
|
|
2964
|
+
result = Object.freeze({ ...result, ok: false, diagnostics: Object.freeze(["PTMAC-110"]) });
|
|
2965
|
+
race = true;
|
|
2966
|
+
}
|
|
2967
|
+
else {
|
|
2968
|
+
await replaceValidatedDocumentFile(sourceOperand, result.candidateText, { initialDigest: input.digest, ...(parsed.values.get("expect-digest") === undefined ? {} : { expectedDigest: parsed.values.get("expect-digest") }) }, (candidate) => ({ ok: parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY).ok, diagnostics: [] }));
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
if (format === "json")
|
|
2972
|
+
writeJson({ schema_version: "Perttool.MilestoneAcceptanceMigrationResult.v1", cli_contract_version: 8, tool_version: TOOL_VERSION, operation: "document.migrate", ...snakeJson(result) });
|
|
2973
|
+
else if (result.candidateText !== null)
|
|
2974
|
+
process.stdout.write(result.candidateText);
|
|
2975
|
+
return result.ok ? 0 : race ? 5 : 1;
|
|
2976
|
+
}
|
|
2667
2977
|
function runGuide(args) {
|
|
2668
2978
|
const parsed = parseCommandOptions("guide", args);
|
|
2669
2979
|
if (parsed.positionals.length > 2) {
|
|
@@ -2690,13 +3000,13 @@ function runGuide(args) {
|
|
|
2690
3000
|
}
|
|
2691
3001
|
function runCommandHelp(args) {
|
|
2692
3002
|
const parsed = parseCommandOptions("help", args);
|
|
2693
|
-
if (parsed.positionals.length >
|
|
2694
|
-
throw new UsageError("help accepts at most <resource> <action>");
|
|
3003
|
+
if (parsed.positionals.length > 3) {
|
|
3004
|
+
throw new UsageError("help accepts at most <resource> <group> <action>");
|
|
2695
3005
|
}
|
|
2696
3006
|
const format = outputFormat(parsed.values.get("format"));
|
|
2697
3007
|
const result = getAssuranceCommandDiscovery({
|
|
2698
3008
|
resource: parsed.positionals[0] ?? null,
|
|
2699
|
-
action: parsed.positionals
|
|
3009
|
+
action: parsed.positionals.length < 2 ? null : parsed.positionals.slice(1).join(" "),
|
|
2700
3010
|
});
|
|
2701
3011
|
if (format === "json") {
|
|
2702
3012
|
process.stdout.write(serializeAssuranceCommandHelpResult(result));
|
|
@@ -2770,7 +3080,7 @@ function runAgentHelp(args) {
|
|
|
2770
3080
|
const { schema_version: schemaVersion, ...payload } = projected;
|
|
2771
3081
|
writeJson({
|
|
2772
3082
|
schema_version: schemaVersion,
|
|
2773
|
-
cli_contract_version:
|
|
3083
|
+
cli_contract_version: 8,
|
|
2774
3084
|
...payload,
|
|
2775
3085
|
});
|
|
2776
3086
|
}
|
|
@@ -2974,14 +3284,14 @@ async function runAssuranceMutation(resource, action, args) {
|
|
|
2974
3284
|
});
|
|
2975
3285
|
if (result.ok && writeRequest.mode !== "preview") {
|
|
2976
3286
|
try {
|
|
2977
|
-
writeResult = await
|
|
3287
|
+
writeResult = await persistContract8CandidateResult(result, writeRequest);
|
|
2978
3288
|
}
|
|
2979
3289
|
catch (error) {
|
|
2980
3290
|
return writeFailureExit(error, operation, format === "json");
|
|
2981
3291
|
}
|
|
2982
3292
|
}
|
|
2983
3293
|
if (format === "json") {
|
|
2984
|
-
writeJson(
|
|
3294
|
+
writeJson(contract8MutationResultToJson(result, operation, source, writeResult));
|
|
2985
3295
|
}
|
|
2986
3296
|
else {
|
|
2987
3297
|
if (result.ok) {
|
|
@@ -3021,6 +3331,8 @@ async function dispatchCommand(descriptor, args) {
|
|
|
3021
3331
|
return runCheck(args);
|
|
3022
3332
|
case "document.format":
|
|
3023
3333
|
return runFormat(args);
|
|
3334
|
+
case "document.migrate":
|
|
3335
|
+
return runDocumentMigration(args);
|
|
3024
3336
|
case "agent.help":
|
|
3025
3337
|
return runAgentHelp(args);
|
|
3026
3338
|
case "project.init":
|
|
@@ -3051,6 +3363,14 @@ async function dispatchCommand(descriptor, args) {
|
|
|
3051
3363
|
return runLifecycleMutation("suspend", args);
|
|
3052
3364
|
case "task.resume":
|
|
3053
3365
|
return runLifecycleMutation("resume", args);
|
|
3366
|
+
case "milestone-acceptance.show":
|
|
3367
|
+
case "milestone-acceptance.replace":
|
|
3368
|
+
case "milestone-acceptance.verify":
|
|
3369
|
+
case "milestone-acceptance.fail":
|
|
3370
|
+
case "milestone-acceptance.unavailable":
|
|
3371
|
+
case "milestone-acceptance.revoke":
|
|
3372
|
+
case "milestone-acceptance.waive":
|
|
3373
|
+
return runMilestoneAcceptance(descriptor.path[2], args);
|
|
3054
3374
|
case "plan-assurance.show":
|
|
3055
3375
|
return runPlanAssuranceInspection("show", args);
|
|
3056
3376
|
case "plan-assurance.hash":
|
|
@@ -3069,7 +3389,7 @@ async function dispatchCommand(descriptor, args) {
|
|
|
3069
3389
|
const [resource, action] = descriptor.path;
|
|
3070
3390
|
return runMutation(resource, action, args);
|
|
3071
3391
|
}
|
|
3072
|
-
throw new Error(`no Contract
|
|
3392
|
+
throw new Error(`no Contract 8 handler for ${descriptor.operation}`);
|
|
3073
3393
|
}
|
|
3074
3394
|
function emitCommandUsage(error, json) {
|
|
3075
3395
|
if (json) {
|