perttool 0.4.0 → 0.5.1
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 +63 -1
- package/README.md +107 -34
- package/dist/actuals/lifecycle.d.ts +101 -0
- package/dist/actuals/lifecycle.d.ts.map +1 -0
- package/dist/actuals/lifecycle.js +329 -0
- package/dist/actuals/lifecycle.js.map +1 -0
- package/dist/actuals/source.d.ts +36 -0
- package/dist/actuals/source.d.ts.map +1 -0
- package/dist/actuals/source.js +119 -0
- package/dist/actuals/source.js.map +1 -0
- package/dist/analysis/temporal-deadline.d.ts +2 -2
- package/dist/analysis/temporal-deadline.d.ts.map +1 -1
- package/dist/analysis/temporal-deadline.js.map +1 -1
- package/dist/analysis/temporal-precedence.d.ts +2 -2
- package/dist/analysis/temporal-precedence.d.ts.map +1 -1
- package/dist/analysis/temporal-precedence.js +2 -0
- package/dist/analysis/temporal-precedence.js.map +1 -1
- package/dist/analysis/temporal-resource.d.ts +2 -2
- package/dist/analysis/temporal-resource.d.ts.map +1 -1
- package/dist/analysis/temporal-resource.js +2 -0
- package/dist/analysis/temporal-resource.js.map +1 -1
- package/dist/application/analyze.d.ts +1 -0
- package/dist/application/analyze.d.ts.map +1 -1
- package/dist/application/analyze.js +38 -29
- package/dist/application/analyze.js.map +1 -1
- package/dist/application/check.d.ts +3 -0
- package/dist/application/check.d.ts.map +1 -1
- package/dist/application/check.js +17 -1
- package/dist/application/check.js.map +1 -1
- package/dist/application/contract6-actuals.d.ts +24 -0
- package/dist/application/contract6-actuals.d.ts.map +1 -0
- package/dist/application/contract6-actuals.js +51 -0
- package/dist/application/contract6-actuals.js.map +1 -0
- package/dist/application/contract6-mutation.d.ts +18 -0
- package/dist/application/contract6-mutation.d.ts.map +1 -0
- package/dist/application/contract6-mutation.js +173 -0
- package/dist/application/contract6-mutation.js.map +1 -0
- package/dist/application/contract6-projection.d.ts +9 -0
- package/dist/application/contract6-projection.d.ts.map +1 -0
- package/dist/application/contract6-projection.js +105 -0
- package/dist/application/contract6-projection.js.map +1 -0
- package/dist/application/init.d.ts +1 -1
- package/dist/application/init.js +3 -3
- package/dist/application/project.js +2 -2
- package/dist/application/target-actuals-advance.d.ts +12 -0
- package/dist/application/target-actuals-advance.d.ts.map +1 -0
- package/dist/application/target-actuals-advance.js +113 -0
- package/dist/application/target-actuals-advance.js.map +1 -0
- package/dist/application/target-actuals-analysis.d.ts +76 -0
- package/dist/application/target-actuals-analysis.d.ts.map +1 -0
- package/dist/application/target-actuals-analysis.js +250 -0
- package/dist/application/target-actuals-analysis.js.map +1 -0
- package/dist/application/target-actuals-mutation.d.ts +28 -0
- package/dist/application/target-actuals-mutation.d.ts.map +1 -0
- package/dist/application/target-actuals-mutation.js +404 -0
- package/dist/application/target-actuals-mutation.js.map +1 -0
- package/dist/application/target-actuals-write.d.ts +7 -0
- package/dist/application/target-actuals-write.d.ts.map +1 -0
- package/dist/application/target-actuals-write.js +37 -0
- package/dist/application/target-actuals-write.js.map +1 -0
- package/dist/application/target-governance-init.d.ts +3 -3
- package/dist/application/target-governance-init.d.ts.map +1 -1
- package/dist/application/target-governance-init.js +20 -10
- package/dist/application/target-governance-init.js.map +1 -1
- package/dist/application/target-governance-project.d.ts +4 -4
- package/dist/application/target-governance-project.d.ts.map +1 -1
- package/dist/application/target-governance-project.js +4 -2
- package/dist/application/target-governance-project.js.map +1 -1
- package/dist/application/target-governance-write.d.ts +8 -0
- package/dist/application/target-governance-write.d.ts.map +1 -1
- package/dist/application/target-governance-write.js +1 -1
- package/dist/application/target-governance-write.js.map +1 -1
- package/dist/application/target-mutate.d.ts +3 -1
- package/dist/application/target-mutate.d.ts.map +1 -1
- package/dist/application/target-mutate.js +34 -2
- package/dist/application/target-mutate.js.map +1 -1
- package/dist/application/target-project-history.d.ts +18 -0
- package/dist/application/target-project-history.d.ts.map +1 -0
- package/dist/application/target-project-history.js +279 -0
- package/dist/application/target-project-history.js.map +1 -0
- package/dist/application/target-temporal-analysis.d.ts +7 -1
- package/dist/application/target-temporal-analysis.d.ts.map +1 -1
- package/dist/application/target-temporal-analysis.js +10 -8
- package/dist/application/target-temporal-analysis.js.map +1 -1
- package/dist/application/target-temporal-input.d.ts +6 -4
- package/dist/application/target-temporal-input.d.ts.map +1 -1
- package/dist/application/target-temporal-input.js +10 -1
- package/dist/application/target-temporal-input.js.map +1 -1
- package/dist/application/target-unit-migration-candidate.d.ts +2 -2
- package/dist/application/target-unit-migration-candidate.d.ts.map +1 -1
- package/dist/application/target-unit-migration-candidate.js +21 -10
- package/dist/application/target-unit-migration-candidate.js.map +1 -1
- package/dist/application/target-unit-migration-request.d.ts +4 -4
- package/dist/application/target-unit-migration-request.d.ts.map +1 -1
- package/dist/application/target-unit-migration-request.js +6 -4
- package/dist/application/target-unit-migration-request.js.map +1 -1
- package/dist/application/target-unit-migration-result.d.ts +5 -5
- package/dist/application/target-unit-migration-result.d.ts.map +1 -1
- package/dist/application/target-unit-migration-result.js +1 -1
- package/dist/application/target-unit-migration-result.js.map +1 -1
- package/dist/application/target-velocity-observation.d.ts +11 -0
- package/dist/application/target-velocity-observation.d.ts.map +1 -0
- package/dist/application/target-velocity-observation.js +201 -0
- package/dist/application/target-velocity-observation.js.map +1 -0
- package/dist/application/unit-migration.d.ts +2 -2
- package/dist/application/unit-migration.d.ts.map +1 -1
- package/dist/application/unit-migration.js +2 -2
- package/dist/cli.js +309 -45
- package/dist/cli.js.map +1 -1
- package/dist/command/actuals-discovery.d.ts +26 -0
- package/dist/command/actuals-discovery.d.ts.map +1 -0
- package/dist/command/actuals-discovery.js +328 -0
- package/dist/command/actuals-discovery.js.map +1 -0
- package/dist/command/actuals-usage.d.ts +22 -0
- package/dist/command/actuals-usage.d.ts.map +1 -0
- package/dist/command/actuals-usage.js +122 -0
- package/dist/command/actuals-usage.js.map +1 -0
- package/dist/formatter/source-formatter.d.ts +3 -3
- package/dist/formatter/source-formatter.d.ts.map +1 -1
- package/dist/formatter/source-formatter.js +53 -5
- package/dist/formatter/source-formatter.js.map +1 -1
- package/dist/formatter/target-source-formatter.d.ts +2 -1
- package/dist/formatter/target-source-formatter.d.ts.map +1 -1
- package/dist/formatter/target-source-formatter.js +18 -2
- package/dist/formatter/target-source-formatter.js.map +1 -1
- package/dist/governance/authority.d.ts +7 -3
- package/dist/governance/authority.d.ts.map +1 -1
- package/dist/governance/authority.js.map +1 -1
- package/dist/governance/source.d.ts +2 -2
- package/dist/governance/source.d.ts.map +1 -1
- package/dist/governance/source.js.map +1 -1
- package/dist/help/actuals-guide.d.ts +10 -0
- package/dist/help/actuals-guide.d.ts.map +1 -0
- package/dist/help/actuals-guide.js +23 -0
- package/dist/help/actuals-guide.js.map +1 -0
- package/dist/help/guide.d.ts +1 -1
- package/dist/help/guide.d.ts.map +1 -1
- package/dist/help/registry.d.ts.map +1 -1
- package/dist/help/registry.js +97 -7
- package/dist/help/registry.js.map +1 -1
- package/dist/history/git-probe.d.ts +56 -0
- package/dist/history/git-probe.d.ts.map +1 -0
- package/dist/history/git-probe.js +574 -0
- package/dist/history/git-probe.js.map +1 -0
- package/dist/history/project-history.d.ts +112 -0
- package/dist/history/project-history.d.ts.map +1 -0
- package/dist/history/project-history.js +786 -0
- package/dist/history/project-history.js.map +1 -0
- package/dist/history/velocity-observation.d.ts +69 -0
- package/dist/history/velocity-observation.d.ts.map +1 -0
- package/dist/history/velocity-observation.js +604 -0
- package/dist/history/velocity-observation.js.map +1 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/io/target-safe-write.d.ts +4 -1
- package/dist/io/target-safe-write.d.ts.map +1 -1
- package/dist/io/target-safe-write.js +19 -1
- package/dist/io/target-safe-write.js.map +1 -1
- package/dist/migration/conversion.d.ts +1 -1
- package/dist/migration/conversion.d.ts.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 +11 -3
- package/dist/migration/grammar-boundary.js.map +1 -1
- package/dist/migration/request.d.ts +5 -5
- package/dist/migration/request.d.ts.map +1 -1
- package/dist/migration/request.js +15 -2
- package/dist/migration/request.js.map +1 -1
- package/dist/model/calendar.d.ts +2 -0
- package/dist/model/calendar.d.ts.map +1 -1
- package/dist/model/calendar.js +19 -0
- package/dist/model/calendar.js.map +1 -1
- package/dist/model/declaration-fields.d.ts +8 -0
- package/dist/model/declaration-fields.d.ts.map +1 -1
- package/dist/model/declaration-fields.js +13 -0
- package/dist/model/declaration-fields.js.map +1 -1
- package/dist/model/exact-person-hours-source.d.ts +2 -0
- package/dist/model/exact-person-hours-source.d.ts.map +1 -0
- package/dist/model/exact-person-hours-source.js +10 -0
- package/dist/model/exact-person-hours-source.js.map +1 -0
- package/dist/model/syntax.d.ts +23 -8
- package/dist/model/syntax.d.ts.map +1 -1
- package/dist/model/syntax.js.map +1 -1
- package/dist/mutation/actuals.d.ts +17 -0
- package/dist/mutation/actuals.d.ts.map +1 -0
- package/dist/mutation/actuals.js +90 -0
- package/dist/mutation/actuals.js.map +1 -0
- package/dist/mutation/advance.d.ts +9 -3
- package/dist/mutation/advance.d.ts.map +1 -1
- package/dist/mutation/advance.js +41 -12
- package/dist/mutation/advance.js.map +1 -1
- package/dist/mutation/entity-editor.d.ts +2 -2
- package/dist/mutation/entity-editor.d.ts.map +1 -1
- package/dist/mutation/entity-editor.js.map +1 -1
- package/dist/mutation/project.d.ts +2 -0
- package/dist/mutation/project.d.ts.map +1 -1
- package/dist/mutation/project.js +13 -4
- package/dist/mutation/project.js.map +1 -1
- package/dist/mutation/source.d.ts +3 -3
- package/dist/mutation/source.d.ts.map +1 -1
- package/dist/mutation/source.js.map +1 -1
- package/dist/parser/document-parser.d.ts +8 -1
- package/dist/parser/document-parser.d.ts.map +1 -1
- package/dist/parser/document-parser.js +151 -23
- package/dist/parser/document-parser.js.map +1 -1
- package/dist/recommendation/override-types.d.ts +2 -2
- package/dist/recommendation/override.d.ts +2 -2
- package/dist/recommendation/override.d.ts.map +1 -1
- package/dist/recommendation/override.js +2 -2
- package/dist/recommendation/override.js.map +1 -1
- package/dist/schema/registry.d.ts +36 -0
- package/dist/schema/registry.d.ts.map +1 -0
- package/dist/schema/registry.js +156 -0
- package/dist/schema/registry.js.map +1 -0
- package/dist/semantic/target-validator.d.ts +13 -2
- package/dist/semantic/target-validator.d.ts.map +1 -1
- package/dist/semantic/target-validator.js +46 -2
- package/dist/semantic/target-validator.js.map +1 -1
- package/dist/semantic/validator.d.ts +4 -1
- package/dist/semantic/validator.d.ts.map +1 -1
- package/dist/semantic/validator.js +152 -6
- package/dist/semantic/validator.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
- package/schemas/Perttool.AgentGuidanceResult.v1.schema.json +152 -0
- package/schemas/Perttool.AnalysisResult.v4.schema.json +124 -0
- package/schemas/Perttool.CheckResult.v3.schema.json +159 -0
- package/schemas/Perttool.CliError.v1.schema.json +83 -0
- package/schemas/Perttool.CommandHelpResult.v1.schema.json +165 -0
- package/schemas/Perttool.Common.v1.schema.json +508 -0
- package/schemas/Perttool.ExportResult.v1.schema.json +96 -0
- package/schemas/Perttool.FormatResult.v1.schema.json +82 -0
- package/schemas/Perttool.GuideResult.v1.schema.json +104 -0
- package/schemas/Perttool.ImportResult.v1.schema.json +111 -0
- package/schemas/Perttool.InitResult.v1.schema.json +70 -0
- package/schemas/Perttool.MutationResult.v3.schema.json +143 -0
- package/schemas/Perttool.NextResult.v5.schema.json +139 -0
- package/schemas/Perttool.OverrideDecision.v1.schema.json +170 -0
- package/schemas/Perttool.ProjectHistoryResult.v1.schema.json +139 -0
- package/schemas/Perttool.ProjectResult.v3.schema.json +144 -0
- package/schemas/Perttool.SchemaResult.v1.schema.json +84 -0
- package/schemas/Perttool.UnitMigrationResult.v3.schema.json +205 -0
- package/schemas/Perttool.VelocityObservationResult.v1.schema.json +102 -0
package/dist/cli.js
CHANGED
|
@@ -2,23 +2,26 @@
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { TextDecoder } from "node:util";
|
|
5
|
-
import { analyzeDocument, selectNextTasks, } from "./application/
|
|
5
|
+
import { analyzeDocument, selectNextTasks, } from "./application/contract6-actuals.js";
|
|
6
6
|
import { checkDocument } from "./application/check.js";
|
|
7
7
|
import { planFormat } from "./application/format.js";
|
|
8
8
|
import { planProjectInit, projectInitResultToJson, renderProjectInitResult, withProjectInitOutput, } from "./application/init.js";
|
|
9
9
|
import { planUnitMigration, withUnitMigrationWrite, } from "./application/unit-migration.js";
|
|
10
10
|
import { getProjectMetadata, } from "./application/project.js";
|
|
11
|
-
import {
|
|
12
|
-
import { renderTargetGovernanceDecision, renderTargetGovernanceProjectText,
|
|
13
|
-
import {
|
|
11
|
+
import { planAdvance, planBatchMutation, planFinishActuals, planLifecycle, planMutation, } from "./application/contract6-mutation.js";
|
|
12
|
+
import { renderTargetGovernanceDecision, renderTargetGovernanceProjectText, } from "./application/target-governance-projection.js";
|
|
13
|
+
import { contract6MutationResultToJson, contract6ProjectResultToJson, contract6WorkEventToJson, } from "./application/contract6-projection.js";
|
|
14
|
+
import { persistTargetActualsResult, } from "./application/target-actuals-write.js";
|
|
15
|
+
import { inspectTargetProjectHistoryFile, renderTargetProjectHistoryText, targetProjectHistoryResultToJson, } from "./application/target-project-history.js";
|
|
16
|
+
import { observeTargetProjectVelocity, renderTargetVelocityObservationText, targetVelocityObservationResultToJson, } from "./application/target-velocity-observation.js";
|
|
14
17
|
import { getAgentHelp } from "./application/agent-help.js";
|
|
15
18
|
import { exportMermaid, } from "./conversion/mermaid.js";
|
|
16
19
|
import { importMermaid } from "./conversion/mermaid-import.js";
|
|
17
|
-
import {
|
|
20
|
+
import { getActualsGuide, renderActualsGuideResult, serializeActualsGuideResult, } from "./help/actuals-guide.js";
|
|
18
21
|
import { commandOptionSets, } from "./command/registry.js";
|
|
19
|
-
import {
|
|
22
|
+
import { ACTUALS_COMMAND_REGISTRY, getActualsCommandDiscovery, renderActualsCommandHelpResult, serializeActualsCommandHelpResult, } from "./command/actuals-discovery.js";
|
|
20
23
|
import { handlerCommandUsageError, } from "./command/usage.js";
|
|
21
|
-
import {
|
|
24
|
+
import { renderActualsCommandUsageError, serializeActualsCommandUsageError, validateActualsCommandInvocation, } from "./command/actuals-usage.js";
|
|
22
25
|
import { agentGuidanceResultToJson } from "./guidance/projection.js";
|
|
23
26
|
import { agentGuidanceExitCode, renderAgentGuidanceText, } from "./guidance/text.js";
|
|
24
27
|
import { documentContentFromBytes, readDocumentFile, } from "./io/document-file.js";
|
|
@@ -27,7 +30,8 @@ import { formatDecimal } from "./model/rational.js";
|
|
|
27
30
|
import { convertWithVelocity, durationSuffix } from "./model/units.js";
|
|
28
31
|
import { recommendationInvariantExitCode } from "./recommendation/failure.js";
|
|
29
32
|
import { recommendationAnalysisToJson } from "./recommendation/json.js";
|
|
30
|
-
import {
|
|
33
|
+
import { TARGET_GRAMMAR_5_CAPABILITY, } from "./parser/document-parser.js";
|
|
34
|
+
import { getJsonSchemaResult, renderJsonSchemaResult, serializeJsonSchemaResult, } from "./schema/registry.js";
|
|
31
35
|
import { TOOL_VERSION } from "./version.js";
|
|
32
36
|
class UsageError extends Error {
|
|
33
37
|
code = "PTCLI-001";
|
|
@@ -82,7 +86,7 @@ function parseOptions(args, valueOptions, flagOptions, repeatableOptions = new S
|
|
|
82
86
|
return { positionals, values, repeatedValues, flags };
|
|
83
87
|
}
|
|
84
88
|
function parseCommandOptions(operation, args) {
|
|
85
|
-
const descriptor =
|
|
89
|
+
const descriptor = ACTUALS_COMMAND_REGISTRY.find((candidate) => candidate.operation === operation);
|
|
86
90
|
if (descriptor === undefined) {
|
|
87
91
|
throw new Error(`command descriptor is missing for ${operation}`);
|
|
88
92
|
}
|
|
@@ -220,7 +224,7 @@ function cliError(error, exitCode, operation, json) {
|
|
|
220
224
|
if (json) {
|
|
221
225
|
writeJson({
|
|
222
226
|
schema_version: "Perttool.CliError.v1",
|
|
223
|
-
cli_contract_version:
|
|
227
|
+
cli_contract_version: 6,
|
|
224
228
|
tool_version: TOOL_VERSION,
|
|
225
229
|
operation,
|
|
226
230
|
ok: false,
|
|
@@ -255,8 +259,8 @@ async function runCheck(args) {
|
|
|
255
259
|
const ok = result.ok && !warningFailure;
|
|
256
260
|
if (format === "json") {
|
|
257
261
|
writeJson({
|
|
258
|
-
schema_version:
|
|
259
|
-
cli_contract_version:
|
|
262
|
+
schema_version: result.schemaVersion,
|
|
263
|
+
cli_contract_version: 6,
|
|
260
264
|
tool_version: TOOL_VERSION,
|
|
261
265
|
operation: "document.check",
|
|
262
266
|
ok,
|
|
@@ -268,6 +272,12 @@ async function runCheck(args) {
|
|
|
268
272
|
grammar_version: result.grammarVersion,
|
|
269
273
|
summary: result.summary,
|
|
270
274
|
temporal_inputs: snakeJson(result.temporalInputs),
|
|
275
|
+
actuals_inputs: result.actualsInputs === null
|
|
276
|
+
? null
|
|
277
|
+
: {
|
|
278
|
+
model_version: result.actualsInputs.modelVersion,
|
|
279
|
+
events: result.actualsInputs.events.map(contract6WorkEventToJson),
|
|
280
|
+
},
|
|
271
281
|
});
|
|
272
282
|
}
|
|
273
283
|
else {
|
|
@@ -306,7 +316,7 @@ async function runProjectShow(args) {
|
|
|
306
316
|
result.diagnostics.some((diagnostic) => diagnostic.severity === "warning"));
|
|
307
317
|
const ok = result.ok && !warningFailure;
|
|
308
318
|
if (format === "json") {
|
|
309
|
-
writeJson(
|
|
319
|
+
writeJson(contract6ProjectResultToJson(result, source, input.digest, ok));
|
|
310
320
|
}
|
|
311
321
|
else {
|
|
312
322
|
if (ok && result.project !== null) {
|
|
@@ -484,7 +494,7 @@ async function persistGovernedResult(result, request, sourceOperand) {
|
|
|
484
494
|
written: false,
|
|
485
495
|
});
|
|
486
496
|
}
|
|
487
|
-
return
|
|
497
|
+
return persistTargetActualsResult(result, TARGET_GRAMMAR_5_CAPABILITY, request.mode === "in_place"
|
|
488
498
|
? {
|
|
489
499
|
mode: "in_place",
|
|
490
500
|
target: request.target,
|
|
@@ -576,7 +586,7 @@ async function runFormat(args) {
|
|
|
576
586
|
if (format === "json") {
|
|
577
587
|
writeJson({
|
|
578
588
|
schema_version: "Perttool.FormatResult.v1",
|
|
579
|
-
cli_contract_version:
|
|
589
|
+
cli_contract_version: 6,
|
|
580
590
|
tool_version: TOOL_VERSION,
|
|
581
591
|
operation: "document.format",
|
|
582
592
|
ok,
|
|
@@ -620,6 +630,11 @@ function requiredOption(parsed, name) {
|
|
|
620
630
|
throw new UsageError(`option --${name} is required`);
|
|
621
631
|
return value;
|
|
622
632
|
}
|
|
633
|
+
function exactMeasurementToken(value, suffix) {
|
|
634
|
+
return /^(?:[0-9]+(?:\.[0-9]+)?|[0-9]+\/[1-9][0-9]*)$/.test(value)
|
|
635
|
+
? `${value}${suffix}`
|
|
636
|
+
: value;
|
|
637
|
+
}
|
|
623
638
|
function optionalInteger(parsed, name, minimum, maximum) {
|
|
624
639
|
const raw = parsed.values.get(name);
|
|
625
640
|
return raw === undefined
|
|
@@ -1074,6 +1089,7 @@ async function runMutation(resource, action, args) {
|
|
|
1074
1089
|
let sourceOperand;
|
|
1075
1090
|
let writeRequest;
|
|
1076
1091
|
let mutation;
|
|
1092
|
+
let lifecycleMutation = null;
|
|
1077
1093
|
if (resource === "batch") {
|
|
1078
1094
|
if (parsed.positionals.length !== 1) {
|
|
1079
1095
|
throw new UsageError("batch apply requires exactly one <file>");
|
|
@@ -1108,6 +1124,37 @@ async function runMutation(resource, action, args) {
|
|
|
1108
1124
|
: resourceMutationFromOptions(action, parsed);
|
|
1109
1125
|
sourceOperand = parsed.positionals[0];
|
|
1110
1126
|
writeRequest = editingWriteRequest(parsed, sourceOperand);
|
|
1127
|
+
if (resource === "task" &&
|
|
1128
|
+
action === "finish" &&
|
|
1129
|
+
parsed.values.has("at")) {
|
|
1130
|
+
lifecycleMutation = {
|
|
1131
|
+
kind: "task.finish.actual",
|
|
1132
|
+
taskId: parsed.positionals[1],
|
|
1133
|
+
event: {
|
|
1134
|
+
occurredAt: parsed.values.get("at"),
|
|
1135
|
+
...(parsed.values.get("event-id") === undefined
|
|
1136
|
+
? {}
|
|
1137
|
+
: { id: parsed.values.get("event-id") }),
|
|
1138
|
+
...(parsed.values.get("active-time") === undefined
|
|
1139
|
+
? {}
|
|
1140
|
+
: {
|
|
1141
|
+
activeTime: exactMeasurementToken(parsed.values.get("active-time"), "h"),
|
|
1142
|
+
}),
|
|
1143
|
+
...(parsed.values.get("effort") === undefined
|
|
1144
|
+
? {}
|
|
1145
|
+
: {
|
|
1146
|
+
effort: exactMeasurementToken(parsed.values.get("effort"), "ph"),
|
|
1147
|
+
}),
|
|
1148
|
+
},
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
else if (resource === "task" &&
|
|
1152
|
+
action === "finish" &&
|
|
1153
|
+
(parsed.values.has("event-id") ||
|
|
1154
|
+
parsed.values.has("active-time") ||
|
|
1155
|
+
parsed.values.has("effort"))) {
|
|
1156
|
+
throw new UsageError("--event-id, --active-time, and --effort require --at");
|
|
1157
|
+
}
|
|
1111
1158
|
}
|
|
1112
1159
|
const source = sourceOperand === "-" ? "<stdin>" : sourceOperand;
|
|
1113
1160
|
let input;
|
|
@@ -1123,9 +1170,11 @@ async function runMutation(resource, action, args) {
|
|
|
1123
1170
|
updatedLabel: "candidate",
|
|
1124
1171
|
governance: governanceRequest(parsed, writeRequest),
|
|
1125
1172
|
};
|
|
1126
|
-
const result =
|
|
1127
|
-
?
|
|
1128
|
-
:
|
|
1173
|
+
const result = lifecycleMutation !== null
|
|
1174
|
+
? planFinishActuals(input.text, lifecycleMutation, mutationOptions)
|
|
1175
|
+
: resource === "batch"
|
|
1176
|
+
? planBatchMutation(input.text, mutation, mutationOptions)
|
|
1177
|
+
: planMutation(input.text, mutation, mutationOptions);
|
|
1129
1178
|
const warningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
1130
1179
|
(result.diagnosticsTruncated ||
|
|
1131
1180
|
result.diagnostics.some((diagnostic) => diagnostic.severity === "warning"));
|
|
@@ -1146,7 +1195,7 @@ async function runMutation(resource, action, args) {
|
|
|
1146
1195
|
}
|
|
1147
1196
|
}
|
|
1148
1197
|
if (format === "json") {
|
|
1149
|
-
writeJson(
|
|
1198
|
+
writeJson(contract6MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
|
|
1150
1199
|
}
|
|
1151
1200
|
else {
|
|
1152
1201
|
if (ok) {
|
|
@@ -1172,6 +1221,94 @@ async function runMutation(resource, action, args) {
|
|
|
1172
1221
|
}
|
|
1173
1222
|
return ok ? 0 : 1;
|
|
1174
1223
|
}
|
|
1224
|
+
async function runLifecycleMutation(action, args) {
|
|
1225
|
+
const operation = `task.${action}`;
|
|
1226
|
+
const parsed = parseCommandOptions(operation, args);
|
|
1227
|
+
if (parsed.positionals.length !== 2) {
|
|
1228
|
+
throw new UsageError(`task ${action} requires <file> <task-id>`);
|
|
1229
|
+
}
|
|
1230
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
1231
|
+
const color = colorMode(parsed.values.get("color"), format);
|
|
1232
|
+
const maxDiagnostics = boundedInteger(parsed.values.get("max-diagnostics"), "max-diagnostics", 100, 1, 1000);
|
|
1233
|
+
const sourceOperand = parsed.positionals[0];
|
|
1234
|
+
const source = sourceOperand === "-" ? "<stdin>" : sourceOperand;
|
|
1235
|
+
const writeRequest = editingWriteRequest(parsed, sourceOperand);
|
|
1236
|
+
const event = {
|
|
1237
|
+
occurredAt: requiredOption(parsed, "at"),
|
|
1238
|
+
...(parsed.values.get("event-id") === undefined
|
|
1239
|
+
? {}
|
|
1240
|
+
: { id: parsed.values.get("event-id") }),
|
|
1241
|
+
...(action !== "suspend" || parsed.values.get("reason") === undefined
|
|
1242
|
+
? {}
|
|
1243
|
+
: { reason: parsed.values.get("reason") }),
|
|
1244
|
+
};
|
|
1245
|
+
const mutation = action === "start"
|
|
1246
|
+
? { kind: "task.start", taskId: parsed.positionals[1], event }
|
|
1247
|
+
: action === "suspend"
|
|
1248
|
+
? { kind: "task.suspend", taskId: parsed.positionals[1], event }
|
|
1249
|
+
: { kind: "task.resume", taskId: parsed.positionals[1], event };
|
|
1250
|
+
let input;
|
|
1251
|
+
try {
|
|
1252
|
+
input = await readDocument(sourceOperand);
|
|
1253
|
+
}
|
|
1254
|
+
catch (error) {
|
|
1255
|
+
return cliError(error instanceof Error ? error : new Error(String(error)), 3, operation, format === "json");
|
|
1256
|
+
}
|
|
1257
|
+
const result = planLifecycle(input.text, mutation, {
|
|
1258
|
+
maxDiagnostics,
|
|
1259
|
+
originalLabel: source,
|
|
1260
|
+
updatedLabel: "candidate",
|
|
1261
|
+
governance: governanceRequest(parsed, writeRequest),
|
|
1262
|
+
});
|
|
1263
|
+
const warningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
1264
|
+
(result.diagnosticsTruncated ||
|
|
1265
|
+
result.diagnostics.some((diagnostic) => diagnostic.severity === "warning"));
|
|
1266
|
+
const ok = result.ok && !warningFailure;
|
|
1267
|
+
let writeResult = Object.freeze({
|
|
1268
|
+
mode: writeRequest.mode,
|
|
1269
|
+
target: writeRequest.target,
|
|
1270
|
+
written: false,
|
|
1271
|
+
});
|
|
1272
|
+
if (result.ok && ok && writeRequest.mode !== "preview") {
|
|
1273
|
+
try {
|
|
1274
|
+
writeResult = await persistGovernedResult(result, writeRequest, sourceOperand);
|
|
1275
|
+
}
|
|
1276
|
+
catch (error) {
|
|
1277
|
+
return writeFailureExit(error, operation, format === "json");
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
if (format === "json") {
|
|
1281
|
+
writeJson(contract6MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
|
|
1282
|
+
}
|
|
1283
|
+
else {
|
|
1284
|
+
if (ok) {
|
|
1285
|
+
if (writeRequest.mode !== "preview") {
|
|
1286
|
+
process.stderr.write(renderGovernanceWriteSummary(operation, writeResult, result.updatedDigest));
|
|
1287
|
+
}
|
|
1288
|
+
else {
|
|
1289
|
+
process.stdout.write(parsed.flags.has("diff")
|
|
1290
|
+
? (result.diff ?? "")
|
|
1291
|
+
: (result.updatedText ?? ""));
|
|
1292
|
+
if (!parsed.flags.has("diff")) {
|
|
1293
|
+
process.stderr.write(`PREVIEW ${operation} changed=${result.changed} original_digest=${result.originalDigest} updated_digest=${result.updatedDigest}\n`);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
if (result.lifecycle !== null) {
|
|
1298
|
+
process.stderr.write(`LIFECYCLE task=${result.lifecycle.taskId} from=${result.lifecycle.fromState} to=${result.lifecycle.toState} event=${result.lifecycle.event.id} coverage=${result.lifecycle.coverage}\n`);
|
|
1299
|
+
}
|
|
1300
|
+
if (result.governance !== null) {
|
|
1301
|
+
process.stderr.write(renderTargetGovernanceDecision(result.governance));
|
|
1302
|
+
}
|
|
1303
|
+
for (const diagnostic of result.diagnostics) {
|
|
1304
|
+
process.stderr.write(`${renderDiagnostic(diagnostic, source, color)}\n`);
|
|
1305
|
+
}
|
|
1306
|
+
if (result.diagnosticsTruncated) {
|
|
1307
|
+
process.stderr.write(`DIAGNOSTICS_TRUNCATED true limit=${maxDiagnostics}\n`);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
return ok ? 0 : 1;
|
|
1311
|
+
}
|
|
1175
1312
|
function unitMigrationJson(result, source, sourceDigest, ok) {
|
|
1176
1313
|
const exact = (value) => ({
|
|
1177
1314
|
numerator: value.numerator.toString(),
|
|
@@ -1180,7 +1317,7 @@ function unitMigrationJson(result, source, sourceDigest, ok) {
|
|
|
1180
1317
|
});
|
|
1181
1318
|
return {
|
|
1182
1319
|
schema_version: result.schemaVersion,
|
|
1183
|
-
cli_contract_version:
|
|
1320
|
+
cli_contract_version: 6,
|
|
1184
1321
|
tool_version: TOOL_VERSION,
|
|
1185
1322
|
operation: "project.migrate-unit",
|
|
1186
1323
|
ok,
|
|
@@ -1308,10 +1445,90 @@ async function runUnitMigration(args) {
|
|
|
1308
1445
|
}
|
|
1309
1446
|
return ok ? 0 : 1;
|
|
1310
1447
|
}
|
|
1448
|
+
async function readHistoryForCommand(operation, parsed, format) {
|
|
1449
|
+
if (parsed.positionals.length !== 1) {
|
|
1450
|
+
throw new UsageError(`${operation.replace(".", " ")} requires exactly one <file>`);
|
|
1451
|
+
}
|
|
1452
|
+
const source = parsed.positionals[0];
|
|
1453
|
+
if (source === "-") {
|
|
1454
|
+
throw new UsageError(`${operation.replace(".", " ")} requires an on-disk file`);
|
|
1455
|
+
}
|
|
1456
|
+
try {
|
|
1457
|
+
return await inspectTargetProjectHistoryFile({
|
|
1458
|
+
targetPath: source,
|
|
1459
|
+
...(parsed.values.get("rev") === undefined
|
|
1460
|
+
? {}
|
|
1461
|
+
: { revision: parsed.values.get("rev") }),
|
|
1462
|
+
...(parsed.repeatedValues.get("task") === undefined
|
|
1463
|
+
? {}
|
|
1464
|
+
: { taskIds: parsed.repeatedValues.get("task") }),
|
|
1465
|
+
}, TARGET_GRAMMAR_5_CAPABILITY);
|
|
1466
|
+
}
|
|
1467
|
+
catch (error) {
|
|
1468
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
async function runProjectHistory(args) {
|
|
1472
|
+
const parsed = parseCommandOptions("project.history", args);
|
|
1473
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
1474
|
+
const color = colorMode(parsed.values.get("color"), format);
|
|
1475
|
+
const result = await readHistoryForCommand("project.history", parsed, format);
|
|
1476
|
+
if (result instanceof Error) {
|
|
1477
|
+
return cliError(result, 3, "project.history", format === "json");
|
|
1478
|
+
}
|
|
1479
|
+
const warningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
1480
|
+
result.diagnostics.some((diagnostic) => diagnostic.severity === "warning");
|
|
1481
|
+
const ok = result.ok && !warningFailure;
|
|
1482
|
+
if (format === "json") {
|
|
1483
|
+
writeJson(targetProjectHistoryResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), parsed.positionals[0]));
|
|
1484
|
+
}
|
|
1485
|
+
else {
|
|
1486
|
+
if (ok)
|
|
1487
|
+
process.stdout.write(renderTargetProjectHistoryText(result));
|
|
1488
|
+
for (const diagnostic of result.diagnostics) {
|
|
1489
|
+
process.stderr.write(`${renderDiagnostic(diagnostic, parsed.positionals[0], color)}\n`);
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
return ok ? 0 : 1;
|
|
1493
|
+
}
|
|
1494
|
+
async function runProjectVelocityObservation(args) {
|
|
1495
|
+
const parsed = parseCommandOptions("project.observe-velocity", args);
|
|
1496
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
1497
|
+
const color = colorMode(parsed.values.get("color"), format);
|
|
1498
|
+
const history = await readHistoryForCommand("project.observe-velocity", parsed, format);
|
|
1499
|
+
if (history instanceof Error) {
|
|
1500
|
+
return cliError(history, 3, "project.observe-velocity", format === "json");
|
|
1501
|
+
}
|
|
1502
|
+
const evidenceValue = parsed.values.get("evidence") ?? "declared";
|
|
1503
|
+
const evidence = evidenceValue === "git-recorded"
|
|
1504
|
+
? "git_recorded"
|
|
1505
|
+
: evidenceValue;
|
|
1506
|
+
const result = observeTargetProjectVelocity(history, {
|
|
1507
|
+
...(parsed.repeatedValues.get("task") === undefined
|
|
1508
|
+
? {}
|
|
1509
|
+
: { taskIds: parsed.repeatedValues.get("task") }),
|
|
1510
|
+
evidence,
|
|
1511
|
+
});
|
|
1512
|
+
const warningFailure = parsed.flags.has("warnings-as-errors") &&
|
|
1513
|
+
result.diagnostics.some((diagnostic) => diagnostic.severity === "warning");
|
|
1514
|
+
const ok = result.ok && !warningFailure;
|
|
1515
|
+
if (format === "json") {
|
|
1516
|
+
writeJson(targetVelocityObservationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), parsed.positionals[0]));
|
|
1517
|
+
}
|
|
1518
|
+
else {
|
|
1519
|
+
if (ok) {
|
|
1520
|
+
process.stdout.write(renderTargetVelocityObservationText(result));
|
|
1521
|
+
}
|
|
1522
|
+
for (const diagnostic of result.diagnostics) {
|
|
1523
|
+
process.stderr.write(`${renderDiagnostic(diagnostic, parsed.positionals[0], color)}\n`);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
return ok ? 0 : 1;
|
|
1527
|
+
}
|
|
1311
1528
|
function renderAdvanceSummary(details) {
|
|
1312
1529
|
const list = (ids) => ids.join(",") || "-";
|
|
1313
1530
|
return [
|
|
1314
|
-
`ADVANCE removed_tasks=${list(details.removedTaskIds)} removed_gates=${list(details.removedGateIds)} removed_milestones=${list(details.removedMilestoneIds)}`,
|
|
1531
|
+
`ADVANCE removed_tasks=${list(details.removedTaskIds)} removed_gates=${list(details.removedGateIds)} removed_milestones=${list(details.removedMilestoneIds)} removed_work_events=${list("removedWorkEventIds" in details ? details.removedWorkEventIds : [])}`,
|
|
1315
1532
|
`ADVANCE frontier_before=${list(details.frontierBefore)} frontier_after=${list(details.frontierAfter)} ready_before=${list(details.readyBefore)} ready_after=${list(details.readyAfter)}`,
|
|
1316
1533
|
"",
|
|
1317
1534
|
].join("\n");
|
|
@@ -1334,7 +1551,7 @@ async function runAdvance(args) {
|
|
|
1334
1551
|
catch (error) {
|
|
1335
1552
|
return cliError(error instanceof Error ? error : new Error(String(error)), 3, "dag.advance", format === "json");
|
|
1336
1553
|
}
|
|
1337
|
-
const result =
|
|
1554
|
+
const result = planAdvance(input.text, {
|
|
1338
1555
|
maxDiagnostics,
|
|
1339
1556
|
originalLabel: source,
|
|
1340
1557
|
updatedLabel: "candidate",
|
|
@@ -1360,7 +1577,7 @@ async function runAdvance(args) {
|
|
|
1360
1577
|
}
|
|
1361
1578
|
}
|
|
1362
1579
|
if (format === "json") {
|
|
1363
|
-
writeJson(
|
|
1580
|
+
writeJson(contract6MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), "dag.advance", source, writeResult));
|
|
1364
1581
|
}
|
|
1365
1582
|
else {
|
|
1366
1583
|
if (ok && result.advance !== null) {
|
|
@@ -1407,6 +1624,8 @@ function precedenceJson(result, unit, precision) {
|
|
|
1407
1624
|
makespan: rationalJson(result.makespan, unit, precision),
|
|
1408
1625
|
conditional_on_blocks_resolved: result.conditionalOnBlocksResolved,
|
|
1409
1626
|
blocked_task_ids: result.blockedTaskIds,
|
|
1627
|
+
conditional_on_suspensions_resumed: result.conditionalOnSuspensionsResumed,
|
|
1628
|
+
suspended_task_ids: result.suspendedTaskIds,
|
|
1410
1629
|
milestones: result.milestones.map((milestone) => ({
|
|
1411
1630
|
id: milestone.id,
|
|
1412
1631
|
earliest: rationalJson(milestone.earliest, unit, precision),
|
|
@@ -1458,6 +1677,8 @@ function resourceJson(result, unit, precision) {
|
|
|
1458
1677
|
algorithm: result.algorithm,
|
|
1459
1678
|
conditional_on_blocks_resolved: result.conditionalOnBlocksResolved,
|
|
1460
1679
|
blocked_task_ids: result.blockedTaskIds,
|
|
1680
|
+
conditional_on_suspensions_resumed: result.conditionalOnSuspensionsResumed,
|
|
1681
|
+
suspended_task_ids: result.suspendedTaskIds,
|
|
1461
1682
|
capacities: result.capacities.map((capacity) => ({
|
|
1462
1683
|
id: capacity.id,
|
|
1463
1684
|
declared: capacity.declared,
|
|
@@ -1566,11 +1787,14 @@ function renderAnalysisText(result) {
|
|
|
1566
1787
|
const conditional = result.precedence?.conditionalOnBlocksResolved === true ||
|
|
1567
1788
|
result.resource?.conditionalOnBlocksResolved === true;
|
|
1568
1789
|
const blockedTaskIds = result.precedence?.blockedTaskIds ?? result.resource?.blockedTaskIds ?? [];
|
|
1790
|
+
const suspendedTaskIds = result.precedence?.suspendedTaskIds ??
|
|
1791
|
+
result.resource?.suspendedTaskIds ??
|
|
1792
|
+
[];
|
|
1569
1793
|
const pathsTruncated = result.precedence?.critical.pathsTruncated === true ||
|
|
1570
1794
|
result.resource?.scheduleCritical.pathsTruncated === true;
|
|
1571
1795
|
const overrides = [...result.capacityOverrides]
|
|
1572
1796
|
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));
|
|
1573
|
-
lines.push(`CONDITIONAL_ON_BLOCKS_RESOLVED ${conditional}`, `BLOCKED_TASKS ${blockedTaskIds.join(", ") || "-"}`, `PATHS_TRUNCATED ${pathsTruncated}`, `CAPACITY_OVERRIDES ${overrides.map(([id, capacity]) => `${id}=${capacity}`).join(", ") || "-"}`, `VELOCITY ${result.velocity === null ? "-" : velocityText(result.velocity, result.precision)}`, `VELOCITY_FORECAST_UNIT ${result.velocityForecast?.targetUnit ?? "-"}`);
|
|
1797
|
+
lines.push(`CONDITIONAL_ON_BLOCKS_RESOLVED ${conditional}`, `BLOCKED_TASKS ${blockedTaskIds.join(", ") || "-"}`, `CONDITIONAL_ON_SUSPENSIONS_RESUMED ${suspendedTaskIds.length > 0}`, `SUSPENDED_TASKS ${suspendedTaskIds.join(", ") || "-"}`, `PATHS_TRUNCATED ${pathsTruncated}`, `CAPACITY_OVERRIDES ${overrides.map(([id, capacity]) => `${id}=${capacity}`).join(", ") || "-"}`, `VELOCITY ${result.velocity === null ? "-" : velocityText(result.velocity, result.precision)}`, `VELOCITY_FORECAST_UNIT ${result.velocityForecast?.targetUnit ?? "-"}`);
|
|
1574
1798
|
if (result.precedence !== null) {
|
|
1575
1799
|
const precedence = result.precedence;
|
|
1576
1800
|
lines.push("", "PRECEDENCE", `MAKESPAN ${durationText(precedence.makespan, unit, result.precision)}`, ...(result.velocityForecast === null
|
|
@@ -1646,7 +1870,7 @@ function renderAnalysisText(result) {
|
|
|
1646
1870
|
["TEMPORAL PRECEDENCE", result.temporal.precedence],
|
|
1647
1871
|
["TEMPORAL RESOURCE", result.temporal.resource],
|
|
1648
1872
|
]) {
|
|
1649
|
-
lines.push("", title, `STATE ${projection.state}`, `ALGORITHM ${projection.algorithm === null ? "-" : `${projection.algorithm.id}@${projection.algorithm.version} optimal=${projection.algorithm.optimal}`}`, `CONDITIONAL_ON_BLOCKS_RESOLVED ${projection.conditionalOnBlocksResolved}`, `BLOCKED_TASKS ${projection.blockedTaskIds.join(",") || "-"}`);
|
|
1873
|
+
lines.push("", title, `STATE ${projection.state}`, `ALGORITHM ${projection.algorithm === null ? "-" : `${projection.algorithm.id}@${projection.algorithm.version} optimal=${projection.algorithm.optimal}`}`, `CONDITIONAL_ON_BLOCKS_RESOLVED ${projection.conditionalOnBlocksResolved}`, `BLOCKED_TASKS ${projection.blockedTaskIds.join(",") || "-"}`, `CONDITIONAL_ON_SUSPENSIONS_RESUMED ${projection.conditionalOnSuspensionsResumed}`, `SUSPENDED_TASKS ${projection.suspendedTaskIds.join(",") || "-"}`);
|
|
1650
1874
|
for (const task of projection.tasks) {
|
|
1651
1875
|
lines.push(`${task.taskId} START ${temporalPoint(task.start)} FINISH ${temporalPoint(task.finish)}`);
|
|
1652
1876
|
}
|
|
@@ -1701,8 +1925,8 @@ async function runAnalyze(args) {
|
|
|
1701
1925
|
const ok = result.ok && !warningFailure;
|
|
1702
1926
|
if (format === "json") {
|
|
1703
1927
|
writeJson({
|
|
1704
|
-
schema_version: "Perttool.AnalysisResult.
|
|
1705
|
-
cli_contract_version:
|
|
1928
|
+
schema_version: "Perttool.AnalysisResult.v4",
|
|
1929
|
+
cli_contract_version: 6,
|
|
1706
1930
|
tool_version: TOOL_VERSION,
|
|
1707
1931
|
operation: "dag.analyze",
|
|
1708
1932
|
ok,
|
|
@@ -1712,6 +1936,11 @@ async function runAnalyze(args) {
|
|
|
1712
1936
|
diagnostics: result.diagnostics.map(jsonDiagnostic),
|
|
1713
1937
|
diagnostics_truncated: result.diagnosticsTruncated,
|
|
1714
1938
|
grammar_version: result.grammarVersion,
|
|
1939
|
+
task_actuals: result.taskActuals.map((actuals) => ({
|
|
1940
|
+
task_id: actuals.taskId,
|
|
1941
|
+
status: actuals.status,
|
|
1942
|
+
coverage: actuals.coverage,
|
|
1943
|
+
})),
|
|
1715
1944
|
mode: result.mode,
|
|
1716
1945
|
precision: result.precision,
|
|
1717
1946
|
...(result.durationUnit === null
|
|
@@ -1816,7 +2045,7 @@ async function runRender(args) {
|
|
|
1816
2045
|
if (format === "json") {
|
|
1817
2046
|
writeJson({
|
|
1818
2047
|
schema_version: "Perttool.ExportResult.v1",
|
|
1819
|
-
cli_contract_version:
|
|
2048
|
+
cli_contract_version: 6,
|
|
1820
2049
|
tool_version: TOOL_VERSION,
|
|
1821
2050
|
operation: "dag.render",
|
|
1822
2051
|
ok,
|
|
@@ -1908,7 +2137,7 @@ async function runImport(args) {
|
|
|
1908
2137
|
if (format === "json") {
|
|
1909
2138
|
writeJson({
|
|
1910
2139
|
schema_version: "Perttool.ImportResult.v1",
|
|
1911
|
-
cli_contract_version:
|
|
2140
|
+
cli_contract_version: 6,
|
|
1912
2141
|
tool_version: TOOL_VERSION,
|
|
1913
2142
|
operation: "dag.import",
|
|
1914
2143
|
ok,
|
|
@@ -1999,6 +2228,7 @@ function nextJson(result) {
|
|
|
1999
2228
|
runnable_now: result.groups.runnableNow,
|
|
2000
2229
|
blocked_now: result.groups.blockedNow,
|
|
2001
2230
|
upcoming: result.groups.upcoming,
|
|
2231
|
+
suspended: result.groups.suspended,
|
|
2002
2232
|
},
|
|
2003
2233
|
tasks: result.tasks.map((task) => ({
|
|
2004
2234
|
id: task.id,
|
|
@@ -2171,6 +2401,7 @@ function renderNextText(result) {
|
|
|
2171
2401
|
section("RUNNABLE NOW", result.groups.runnableNow);
|
|
2172
2402
|
section("READY / WAITING RESOURCE", result.groups.ready.filter((id) => !result.groups.runnableNow.includes(id)), "rejection");
|
|
2173
2403
|
section("BLOCKED NOW", result.groups.blockedNow, "blocked");
|
|
2404
|
+
section("SUSPENDED", result.groups.suspended);
|
|
2174
2405
|
section("UPCOMING", result.groups.upcoming, "explanation");
|
|
2175
2406
|
lines.push("", "TEMPORAL CONTEXT");
|
|
2176
2407
|
for (const temporal of result.temporal.tasks) {
|
|
@@ -2215,7 +2446,7 @@ async function runNext(args) {
|
|
|
2215
2446
|
if (format === "json") {
|
|
2216
2447
|
writeJson({
|
|
2217
2448
|
schema_version: "Perttool.CliError.v1",
|
|
2218
|
-
cli_contract_version:
|
|
2449
|
+
cli_contract_version: 6,
|
|
2219
2450
|
tool_version: TOOL_VERSION,
|
|
2220
2451
|
operation: "dag.next",
|
|
2221
2452
|
ok: false,
|
|
@@ -2235,8 +2466,8 @@ async function runNext(args) {
|
|
|
2235
2466
|
const ok = result.ok && !warningFailure;
|
|
2236
2467
|
if (format === "json") {
|
|
2237
2468
|
writeJson({
|
|
2238
|
-
schema_version: "Perttool.NextResult.
|
|
2239
|
-
cli_contract_version:
|
|
2469
|
+
schema_version: "Perttool.NextResult.v5",
|
|
2470
|
+
cli_contract_version: 6,
|
|
2240
2471
|
recommendation_interface_version: 1,
|
|
2241
2472
|
tool_version: TOOL_VERSION,
|
|
2242
2473
|
operation: "dag.next",
|
|
@@ -2272,12 +2503,12 @@ function runGuide(args) {
|
|
|
2272
2503
|
colorMode(parsed.values.get("color"), format);
|
|
2273
2504
|
const topicId = parsed.positionals.length === 0 ? null : parsed.positionals.join(".");
|
|
2274
2505
|
const level = helpLevel(parsed.values.get("level"), topicId !== null);
|
|
2275
|
-
const result =
|
|
2506
|
+
const result = getActualsGuide(topicId, level);
|
|
2276
2507
|
if (format === "json") {
|
|
2277
|
-
process.stdout.write(
|
|
2508
|
+
process.stdout.write(serializeActualsGuideResult(result));
|
|
2278
2509
|
}
|
|
2279
2510
|
else {
|
|
2280
|
-
const rendered =
|
|
2511
|
+
const rendered = renderActualsGuideResult(result);
|
|
2281
2512
|
if (result.ok) {
|
|
2282
2513
|
process.stdout.write(rendered);
|
|
2283
2514
|
}
|
|
@@ -2293,15 +2524,36 @@ function runCommandHelp(args) {
|
|
|
2293
2524
|
throw new UsageError("help accepts at most <resource> <action>");
|
|
2294
2525
|
}
|
|
2295
2526
|
const format = outputFormat(parsed.values.get("format"));
|
|
2296
|
-
const result =
|
|
2527
|
+
const result = getActualsCommandDiscovery({
|
|
2297
2528
|
resource: parsed.positionals[0] ?? null,
|
|
2298
2529
|
action: parsed.positionals[1] ?? null,
|
|
2299
2530
|
});
|
|
2300
2531
|
if (format === "json") {
|
|
2301
|
-
process.stdout.write(
|
|
2532
|
+
process.stdout.write(serializeActualsCommandHelpResult(result));
|
|
2533
|
+
}
|
|
2534
|
+
else {
|
|
2535
|
+
const rendered = renderActualsCommandHelpResult(result);
|
|
2536
|
+
if (result.ok) {
|
|
2537
|
+
process.stdout.write(rendered);
|
|
2538
|
+
}
|
|
2539
|
+
else {
|
|
2540
|
+
process.stderr.write(rendered);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
return result.ok ? 0 : 1;
|
|
2544
|
+
}
|
|
2545
|
+
function runJsonSchema(args) {
|
|
2546
|
+
const parsed = parseCommandOptions("schema", args);
|
|
2547
|
+
if (parsed.positionals.length > 1) {
|
|
2548
|
+
throw new UsageError("schema accepts at most one <schema-id>");
|
|
2549
|
+
}
|
|
2550
|
+
const format = outputFormat(parsed.values.get("format"));
|
|
2551
|
+
const result = getJsonSchemaResult(parsed.positionals[0] ?? null);
|
|
2552
|
+
if (format === "json") {
|
|
2553
|
+
process.stdout.write(serializeJsonSchemaResult(result));
|
|
2302
2554
|
}
|
|
2303
2555
|
else {
|
|
2304
|
-
const rendered =
|
|
2556
|
+
const rendered = renderJsonSchemaResult(result);
|
|
2305
2557
|
if (result.ok) {
|
|
2306
2558
|
process.stdout.write(rendered);
|
|
2307
2559
|
}
|
|
@@ -2331,7 +2583,7 @@ function runAgentHelp(args) {
|
|
|
2331
2583
|
const { schema_version: schemaVersion, ...payload } = projected;
|
|
2332
2584
|
writeJson({
|
|
2333
2585
|
schema_version: schemaVersion,
|
|
2334
|
-
cli_contract_version:
|
|
2586
|
+
cli_contract_version: 6,
|
|
2335
2587
|
...payload,
|
|
2336
2588
|
});
|
|
2337
2589
|
}
|
|
@@ -2357,6 +2609,8 @@ async function dispatchCommand(descriptor, args) {
|
|
|
2357
2609
|
switch (descriptor.operation) {
|
|
2358
2610
|
case "help":
|
|
2359
2611
|
return runCommandHelp(args);
|
|
2612
|
+
case "schema":
|
|
2613
|
+
return runJsonSchema(args);
|
|
2360
2614
|
case "guide":
|
|
2361
2615
|
return runGuide(args);
|
|
2362
2616
|
case "document.check":
|
|
@@ -2369,6 +2623,10 @@ async function dispatchCommand(descriptor, args) {
|
|
|
2369
2623
|
return runProjectInit(args);
|
|
2370
2624
|
case "project.show":
|
|
2371
2625
|
return runProjectShow(args);
|
|
2626
|
+
case "project.history":
|
|
2627
|
+
return runProjectHistory(args);
|
|
2628
|
+
case "project.observe-velocity":
|
|
2629
|
+
return runProjectVelocityObservation(args);
|
|
2372
2630
|
case "project.migrate-unit":
|
|
2373
2631
|
return runUnitMigration(args);
|
|
2374
2632
|
case "dag.analyze":
|
|
@@ -2381,6 +2639,12 @@ async function dispatchCommand(descriptor, args) {
|
|
|
2381
2639
|
return runRender(args);
|
|
2382
2640
|
case "dag.import":
|
|
2383
2641
|
return runImport(args);
|
|
2642
|
+
case "task.start":
|
|
2643
|
+
return runLifecycleMutation("start", args);
|
|
2644
|
+
case "task.suspend":
|
|
2645
|
+
return runLifecycleMutation("suspend", args);
|
|
2646
|
+
case "task.resume":
|
|
2647
|
+
return runLifecycleMutation("resume", args);
|
|
2384
2648
|
}
|
|
2385
2649
|
if (descriptor.path.length === 2
|
|
2386
2650
|
&& (descriptor.operation === "project.set"
|
|
@@ -2389,14 +2653,14 @@ async function dispatchCommand(descriptor, args) {
|
|
|
2389
2653
|
const [resource, action] = descriptor.path;
|
|
2390
2654
|
return runMutation(resource, action, args);
|
|
2391
2655
|
}
|
|
2392
|
-
throw new Error(`no Contract
|
|
2656
|
+
throw new Error(`no Contract 6 handler for ${descriptor.operation}`);
|
|
2393
2657
|
}
|
|
2394
2658
|
function emitCommandUsage(error, json) {
|
|
2395
2659
|
if (json) {
|
|
2396
|
-
process.stdout.write(
|
|
2660
|
+
process.stdout.write(serializeActualsCommandUsageError(error));
|
|
2397
2661
|
}
|
|
2398
2662
|
else {
|
|
2399
|
-
process.stderr.write(
|
|
2663
|
+
process.stderr.write(renderActualsCommandUsageError(error));
|
|
2400
2664
|
}
|
|
2401
2665
|
return 2;
|
|
2402
2666
|
}
|
|
@@ -2408,13 +2672,13 @@ async function main(argv) {
|
|
|
2408
2672
|
if (argv.length === 1 && argv[0] === "--help") {
|
|
2409
2673
|
return runCommandHelp([]);
|
|
2410
2674
|
}
|
|
2411
|
-
const validation =
|
|
2675
|
+
const validation = validateActualsCommandInvocation(argv);
|
|
2412
2676
|
if (!validation.ok) {
|
|
2413
2677
|
if (jsonRequested(argv)) {
|
|
2414
|
-
process.stdout.write(
|
|
2678
|
+
process.stdout.write(serializeActualsCommandUsageError(validation.error));
|
|
2415
2679
|
}
|
|
2416
2680
|
else {
|
|
2417
|
-
process.stderr.write(
|
|
2681
|
+
process.stderr.write(renderActualsCommandUsageError(validation.error));
|
|
2418
2682
|
}
|
|
2419
2683
|
return 2;
|
|
2420
2684
|
}
|