@skrr-ai/cli 0.1.108 → 0.1.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +10 -0
  2. package/dist/base-command.d.ts +59 -0
  3. package/dist/base-command.js +118 -7
  4. package/dist/commands/agents/update.d.ts +14 -0
  5. package/dist/commands/agents/update.js +40 -1
  6. package/dist/commands/commitments/accounting.js +7 -2
  7. package/dist/commands/commitments/cost.d.ts +11 -0
  8. package/dist/commands/commitments/cost.js +26 -3
  9. package/dist/commands/commitments/create.js +2 -1
  10. package/dist/commands/commitments/operating-review.d.ts +15 -0
  11. package/dist/commands/commitments/operating-review.js +103 -50
  12. package/dist/commands/commitments/update.js +12 -5
  13. package/dist/commands/doctor.js +9 -0
  14. package/dist/commands/goals/list.js +6 -1
  15. package/dist/commands/grants/rotate.js +4 -0
  16. package/dist/commands/login.js +42 -14
  17. package/dist/commands/machines/list.js +28 -6
  18. package/dist/commands/projects/show.js +1 -1
  19. package/dist/commands/revoke-daemon.js +2 -1
  20. package/dist/commands/spaces/workflows/archive.d.ts +1 -0
  21. package/dist/commands/spaces/workflows/archive.js +1 -0
  22. package/dist/commands/spaces/workflows/artifact.d.ts +1 -0
  23. package/dist/commands/spaces/workflows/artifact.js +1 -0
  24. package/dist/commands/spaces/workflows/cancel-node.d.ts +1 -0
  25. package/dist/commands/spaces/workflows/cancel-node.js +1 -0
  26. package/dist/commands/spaces/workflows/cancel.d.ts +1 -0
  27. package/dist/commands/spaces/workflows/cancel.js +6 -2
  28. package/dist/commands/spaces/workflows/create.d.ts +1 -0
  29. package/dist/commands/spaces/workflows/create.js +7 -1
  30. package/dist/commands/spaces/workflows/events.d.ts +1 -0
  31. package/dist/commands/spaces/workflows/events.js +1 -0
  32. package/dist/commands/spaces/workflows/fixtures/create.d.ts +1 -0
  33. package/dist/commands/spaces/workflows/fixtures/create.js +1 -0
  34. package/dist/commands/spaces/workflows/fixtures/list.d.ts +1 -0
  35. package/dist/commands/spaces/workflows/fixtures/list.js +1 -0
  36. package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +1 -0
  37. package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +1 -0
  38. package/dist/commands/spaces/workflows/list.d.ts +1 -0
  39. package/dist/commands/spaces/workflows/list.js +1 -0
  40. package/dist/commands/spaces/workflows/node-types.d.ts +2 -0
  41. package/dist/commands/spaces/workflows/node-types.js +24 -6
  42. package/dist/commands/spaces/workflows/pause.d.ts +1 -0
  43. package/dist/commands/spaces/workflows/pause.js +1 -0
  44. package/dist/commands/spaces/workflows/plan/show.d.ts +1 -0
  45. package/dist/commands/spaces/workflows/plan/show.js +1 -0
  46. package/dist/commands/spaces/workflows/plan/update.d.ts +1 -0
  47. package/dist/commands/spaces/workflows/plan/update.js +1 -0
  48. package/dist/commands/spaces/workflows/proposals/apply.d.ts +1 -0
  49. package/dist/commands/spaces/workflows/proposals/apply.js +1 -0
  50. package/dist/commands/spaces/workflows/proposals/confirm.d.ts +1 -0
  51. package/dist/commands/spaces/workflows/proposals/confirm.js +1 -0
  52. package/dist/commands/spaces/workflows/proposals/create.d.ts +1 -0
  53. package/dist/commands/spaces/workflows/proposals/create.js +1 -0
  54. package/dist/commands/spaces/workflows/proposals/dismiss.d.ts +1 -0
  55. package/dist/commands/spaces/workflows/proposals/dismiss.js +1 -0
  56. package/dist/commands/spaces/workflows/proposals/list.d.ts +1 -0
  57. package/dist/commands/spaces/workflows/proposals/list.js +1 -0
  58. package/dist/commands/spaces/workflows/publish.d.ts +1 -0
  59. package/dist/commands/spaces/workflows/publish.js +9 -0
  60. package/dist/commands/spaces/workflows/reconcile.d.ts +1 -0
  61. package/dist/commands/spaces/workflows/reconcile.js +1 -0
  62. package/dist/commands/spaces/workflows/resume.d.ts +1 -0
  63. package/dist/commands/spaces/workflows/resume.js +1 -0
  64. package/dist/commands/spaces/workflows/retry.d.ts +1 -0
  65. package/dist/commands/spaces/workflows/retry.js +1 -0
  66. package/dist/commands/spaces/workflows/run.d.ts +1 -0
  67. package/dist/commands/spaces/workflows/run.js +14 -7
  68. package/dist/commands/spaces/workflows/runs.d.ts +1 -0
  69. package/dist/commands/spaces/workflows/runs.js +1 -0
  70. package/dist/commands/spaces/workflows/show.d.ts +25 -0
  71. package/dist/commands/spaces/workflows/show.js +42 -4
  72. package/dist/commands/spaces/workflows/signal.d.ts +12 -0
  73. package/dist/commands/spaces/workflows/signal.js +40 -2
  74. package/dist/commands/spaces/workflows/start.d.ts +1 -0
  75. package/dist/commands/spaces/workflows/start.js +1 -0
  76. package/dist/commands/spaces/workflows/task-execution/create.d.ts +1 -0
  77. package/dist/commands/spaces/workflows/task-execution/create.js +1 -0
  78. package/dist/commands/spaces/workflows/test.d.ts +1 -0
  79. package/dist/commands/spaces/workflows/test.js +1 -0
  80. package/dist/commands/spaces/workflows/triggers/create.d.ts +1 -0
  81. package/dist/commands/spaces/workflows/triggers/create.js +1 -0
  82. package/dist/commands/spaces/workflows/triggers/fire.d.ts +1 -0
  83. package/dist/commands/spaces/workflows/triggers/fire.js +1 -0
  84. package/dist/commands/spaces/workflows/triggers/list.d.ts +1 -0
  85. package/dist/commands/spaces/workflows/triggers/list.js +1 -0
  86. package/dist/commands/spaces/workflows/triggers/update.d.ts +1 -0
  87. package/dist/commands/spaces/workflows/triggers/update.js +1 -0
  88. package/dist/commands/spaces/workflows/update.d.ts +1 -0
  89. package/dist/commands/spaces/workflows/update.js +4 -0
  90. package/dist/commands/spaces/workflows/validate.d.ts +1 -0
  91. package/dist/commands/spaces/workflows/validate.js +15 -0
  92. package/dist/commands/tasks/activity.js +6 -2
  93. package/dist/commands/tasks/bulk-update.d.ts +1 -0
  94. package/dist/commands/tasks/bulk-update.js +7 -0
  95. package/dist/commands/tasks/complete.js +2 -1
  96. package/dist/commands/tasks/create-tree.d.ts +69 -0
  97. package/dist/commands/tasks/create-tree.js +413 -47
  98. package/dist/commands/tasks/list.d.ts +2 -0
  99. package/dist/commands/tasks/list.js +19 -1
  100. package/dist/commands/tasks/rearm-recurrence.d.ts +22 -0
  101. package/dist/commands/tasks/rearm-recurrence.js +68 -0
  102. package/dist/commands/tasks/show.d.ts +1 -0
  103. package/dist/commands/tasks/show.js +17 -3
  104. package/dist/commands/tasks/timeline.js +4 -0
  105. package/dist/commands/tasks/update.d.ts +1 -0
  106. package/dist/commands/tasks/update.js +6 -1
  107. package/dist/commands/triggers/create.js +8 -2
  108. package/dist/commands/triggers/parse-intent.d.ts +7 -0
  109. package/dist/commands/triggers/parse-intent.js +31 -9
  110. package/dist/commands/workspaces/grants.js +23 -3
  111. package/dist/commands/workspaces/members.d.ts +20 -0
  112. package/dist/commands/workspaces/members.js +64 -0
  113. package/dist/commands/workspaces/stewardship.js +14 -2
  114. package/dist/help.js +12 -0
  115. package/dist/hooks/command-not-found.js +27 -1
  116. package/dist/lib/command-miss.d.ts +52 -2
  117. package/dist/lib/command-miss.js +187 -18
  118. package/dist/lib/commitment-loop-status.d.ts +8 -0
  119. package/dist/lib/commitment-loop-status.js +45 -0
  120. package/dist/lib/commitments.d.ts +16 -2
  121. package/dist/lib/commitments.js +48 -8
  122. package/dist/lib/daemon-command-hint.d.ts +15 -0
  123. package/dist/lib/daemon-command-hint.js +21 -0
  124. package/dist/lib/daemon-setup.js +10 -1
  125. package/dist/lib/daemonBrokerRefusal.js +3 -2
  126. package/dist/lib/daemonHandoff.js +2 -1
  127. package/dist/lib/deployed-build.d.ts +43 -0
  128. package/dist/lib/deployed-build.js +66 -0
  129. package/dist/lib/grants.d.ts +27 -1
  130. package/dist/lib/grants.js +39 -21
  131. package/dist/lib/json-mode.d.ts +11 -0
  132. package/dist/lib/json-mode.js +19 -0
  133. package/dist/lib/json-output.d.ts +25 -0
  134. package/dist/lib/json-output.js +30 -0
  135. package/dist/lib/list-output.d.ts +9 -0
  136. package/dist/lib/list-output.js +20 -1
  137. package/dist/lib/local-daemon-readiness.d.ts +90 -0
  138. package/dist/lib/local-daemon-readiness.js +143 -0
  139. package/dist/lib/machines.d.ts +117 -0
  140. package/dist/lib/machines.js +139 -0
  141. package/dist/lib/managed-instruction-local.d.ts +2 -0
  142. package/dist/lib/managed-instruction-local.js +2 -0
  143. package/dist/lib/profile-machine-identity-guard.d.ts +18 -0
  144. package/dist/lib/profile-machine-identity-guard.js +29 -0
  145. package/dist/lib/request-field-flags.d.ts +20 -0
  146. package/dist/lib/request-field-flags.js +34 -0
  147. package/dist/lib/stewardship-output.d.ts +1 -1
  148. package/dist/lib/stewardship-output.js +26 -30
  149. package/dist/lib/task-batch.d.ts +61 -4
  150. package/dist/lib/task-batch.js +316 -80
  151. package/dist/lib/task-economics.d.ts +5 -0
  152. package/dist/lib/task-economics.js +15 -0
  153. package/dist/lib/task-recurrence-outcome.d.ts +6 -6
  154. package/dist/lib/task-recurrence-outcome.js +27 -3
  155. package/dist/lib/tasks.d.ts +39 -0
  156. package/dist/lib/tasks.js +132 -0
  157. package/dist/lib/triggers.d.ts +31 -1
  158. package/dist/lib/triggers.js +55 -1
  159. package/dist/lib/workflow-issues.d.ts +14 -0
  160. package/dist/lib/workflow-issues.js +32 -0
  161. package/dist/lib/workflow-run-view.d.ts +55 -0
  162. package/dist/lib/workflow-run-view.js +105 -0
  163. package/dist/lib/workspaces.d.ts +31 -4
  164. package/dist/lib/workspaces.js +43 -0
  165. package/dist/lib/write-target.d.ts +29 -0
  166. package/dist/lib/write-target.js +72 -0
  167. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/workspaceIsolationProbeWire.d.ts +51 -0
  168. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/workspaceIsolationProbeWire.js +50 -0
  169. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/workspaceIsolationProbeWire.d.ts +51 -0
  170. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/workspaceIsolationProbeWire.js +46 -0
  171. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  172. package/dist/node_modules/@skrr-ai/data-provider/index.js +6718 -6370
  173. package/oclif.manifest.json +376 -52
  174. package/package.json +19 -1
@@ -1,11 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeSignalResult = describeSignalResult;
3
4
  exports.parseSignalPayload = parseSignalPayload;
4
5
  const core_1 = require("@oclif/core");
5
6
  const data_provider_1 = require("@skrr-ai/data-provider");
6
7
  const base_command_1 = require("../../../base-command");
7
8
  const prompt_1 = require("../../../lib/prompt");
8
9
  const space_output_1 = require("../../../lib/space-output");
10
+ const workflow_run_view_1 = require("../../../lib/workflow-run-view");
11
+ /**
12
+ * The lines after a signal landed. "run X is succeeded" alone hid a loop item that failed in a
13
+ * run that nonetheless succeeded (OSK-15325), and said nothing about what the run waits on next.
14
+ */
15
+ function describeSignalResult(spaceId, runId, nodeKey, outcome, run, bin = 'skrr') {
16
+ const id = run?.id ?? runId;
17
+ const lines = [`Signalled ${nodeKey} with ${outcome}; run ${id} is ${run?.status ?? 'updated'}.`];
18
+ const nodes = (0, workflow_run_view_1.orderNodesByGraph)((run?.nodes ?? []));
19
+ lines.push(...(0, workflow_run_view_1.describePartialOutcomes)(nodes));
20
+ lines.push(...(0, workflow_run_view_1.describeSignalHints)(spaceId, id, nodes, bin));
21
+ return lines;
22
+ }
9
23
  const OUTCOMES = ['success', 'failure', 'true', 'false'];
10
24
  function parseSignalPayload(value) {
11
25
  if (value === undefined)
@@ -18,7 +32,29 @@ function parseSignalPayload(value) {
18
32
  }
19
33
  }
20
34
  class SpacesWorkflowsSignal extends base_command_1.BaseCommand {
21
- static description = 'Resolve a waiting approval or event node in a workflow run';
35
+ static aliases = ['workflows:signal'];
36
+ static summary = 'Resolve a waiting approval or event node in a workflow run';
37
+ /*
38
+ * The two ways to resolve a wait live under different topics — a person
39
+ * signals here, a machine event resolves through a `workflow_signal`
40
+ * trigger — and neither help pointed at the other (OSK-15315).
41
+ */
42
+ static description = [
43
+ 'Needs Space edit access; a token with edit access may call the same signal API.',
44
+ 'The event key a node waits on describes the wait and does not itself authorize a signal.',
45
+ '',
46
+ 'To let a machine event resolve an event wait instead, author a workflow_signal trigger on the Space:',
47
+ ' skrr triggers create --scope space_oracle --ref spaceId=<space-id> --kind event \\',
48
+ ' --entity <entity> --event <event> --mode workflow_signal --workflow-event-key <key>',
49
+ 'It resolves only event waits parked on exactly that key, never an approval.',
50
+ '',
51
+ 'A node that was already resolved, is not waiting yet, or waits on its own work (a loop, a',
52
+ 'child run, a Task) is refused with what the run found, and nothing changes.',
53
+ ].join('\n');
54
+ static examples = [
55
+ '<%= config.bin %> workflows signal <space-id> <run-id> approval_1 --outcome success',
56
+ '<%= config.bin %> workflows signal <space-id> <run-id> wait_event_1 --payload \'{"approved":true}\'',
57
+ ];
22
58
  static args = {
23
59
  spaceId: core_1.Args.string({ description: 'Owning Space ID', required: true, ignoreStdin: true }),
24
60
  runId: core_1.Args.string({ description: 'Workflow run ID', required: true, ignoreStdin: true }),
@@ -70,7 +106,9 @@ class SpacesWorkflowsSignal extends base_command_1.BaseCommand {
70
106
  return;
71
107
  }
72
108
  const run = result.run;
73
- this.log(`Signalled ${args.nodeKey} with ${flags.outcome}; run ${run?.id ?? args.runId} is ${run?.status ?? 'updated'}.`);
109
+ for (const line of describeSignalResult(args.spaceId, args.runId, args.nodeKey, String(flags.outcome), run, this.config.bin)) {
110
+ this.log(line);
111
+ }
74
112
  }
75
113
  }
76
114
  exports.default = SpacesWorkflowsSignal;
@@ -17,6 +17,7 @@ export declare function formatStartedRunLine(result: {
17
17
  };
18
18
  }): string;
19
19
  export default class SpacesWorkflowsStart extends BaseCommand {
20
+ static aliases: string[];
20
21
  static description: string;
21
22
  static args: {
22
23
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -21,6 +21,7 @@ function formatStartedRunLine(result) {
21
21
  return `${verb} workflow run ${result.run.id} (${result.run.status})${version}`;
22
22
  }
23
23
  class SpacesWorkflowsStart extends base_command_1.BaseCommand {
24
+ static aliases = ['workflows:start'];
24
25
  static description = 'Start a durable run of a published workflow';
25
26
  static args = {
26
27
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -1,6 +1,7 @@
1
1
  import { BaseCommand } from '../../../../base-command';
2
2
  /** Compile existing Space Tasks into one durable, observable execution run. */
3
3
  export default class SpacesWorkflowsTaskExecutionCreate extends BaseCommand {
4
+ static aliases: string[];
4
5
  static description: string;
5
6
  static args: {
6
7
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -6,6 +6,7 @@ const base_command_1 = require("../../../../base-command");
6
6
  const space_output_1 = require("../../../../lib/space-output");
7
7
  /** Compile existing Space Tasks into one durable, observable execution run. */
8
8
  class SpacesWorkflowsTaskExecutionCreate extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:task-execution:create'];
9
10
  static description = 'Create and start an execution workflow over existing Space Tasks';
10
11
  static args = {
11
12
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../../base-command';
2
2
  export default class SpacesWorkflowsTest extends BaseCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static args: {
5
6
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -6,6 +6,7 @@ const base_command_1 = require("../../../base-command");
6
6
  const prompt_1 = require("../../../lib/prompt");
7
7
  const space_output_1 = require("../../../lib/space-output");
8
8
  class SpacesWorkflowsTest extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:test'];
9
10
  static description = 'Start a test workflow run, optionally using recorded node fixtures';
10
11
  static args = {
11
12
  spaceId: core_1.Args.string({ description: 'Owning Space ID', required: true, ignoreStdin: true }),
@@ -2,6 +2,7 @@ import { type WorkflowTrigger } from '@skrr-ai/data-provider';
2
2
  import { BaseCommand } from '../../../../base-command';
3
3
  declare function readTriggerConfig(inline: string | undefined, file: string | undefined): Promise<WorkflowTrigger['config']>;
4
4
  export default class SpacesWorkflowsTriggersCreate extends BaseCommand {
5
+ static aliases: string[];
5
6
  static description: string;
6
7
  static args: {
7
8
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -15,6 +15,7 @@ async function readTriggerConfig(inline, file) {
15
15
  return value;
16
16
  }
17
17
  class SpacesWorkflowsTriggersCreate extends base_command_1.BaseCommand {
18
+ static aliases = ['workflows:triggers:create'];
18
19
  static description = 'Create a schedule, webhook, or space-event workflow trigger';
19
20
  static args = {
20
21
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../../../base-command';
2
2
  export default class SpacesWorkflowsTriggersFire extends BaseCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static args: {
5
6
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -6,6 +6,7 @@ const base_command_1 = require("../../../../base-command");
6
6
  const prompt_1 = require("../../../../lib/prompt");
7
7
  const space_output_1 = require("../../../../lib/space-output");
8
8
  class SpacesWorkflowsTriggersFire extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:triggers:fire'];
9
10
  static description = 'Manually fire a workflow trigger with an idempotent delivery identity';
10
11
  static args = {
11
12
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../../../base-command';
2
2
  export default class SpacesWorkflowsTriggersList extends BaseCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static args: {
5
6
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -6,6 +6,7 @@ const base_command_1 = require("../../../../base-command");
6
6
  const format_1 = require("../../../../lib/format");
7
7
  const space_output_1 = require("../../../../lib/space-output");
8
8
  class SpacesWorkflowsTriggersList extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:triggers:list'];
9
10
  static description = 'List workflow triggers';
10
11
  static args = {
11
12
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../../../base-command';
2
2
  export default class SpacesWorkflowsTriggersUpdate extends BaseCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static args: {
5
6
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -6,6 +6,7 @@ const base_command_1 = require("../../../../base-command");
6
6
  const create_1 = require("./create");
7
7
  const space_output_1 = require("../../../../lib/space-output");
8
8
  class SpacesWorkflowsTriggersUpdate extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:triggers:update'];
9
10
  static description = 'Update a workflow trigger’s type, state, or configuration';
10
11
  static args = {
11
12
  spaceId: core_1.Args.string({ required: true, ignoreStdin: true }),
@@ -16,6 +16,7 @@ export declare function buildWorkflowUpdatePayload({ body, title, description, c
16
16
  }): WorkflowPatch;
17
17
  /** Update metadata or the mutable draft; executable changes use optimistic concurrency. */
18
18
  export default class SpacesWorkflowsUpdate extends BaseCommand {
19
+ static aliases: string[];
19
20
  static description: string;
20
21
  static examples: string[];
21
22
  static args: {
@@ -7,6 +7,7 @@ const data_provider_1 = require("@skrr-ai/data-provider");
7
7
  const base_command_1 = require("../../../base-command");
8
8
  const prompt_1 = require("../../../lib/prompt");
9
9
  const space_output_1 = require("../../../lib/space-output");
10
+ const workflow_issues_1 = require("../../../lib/workflow-issues");
10
11
  /** `90m`, `4h`, `2d` to milliseconds; null when malformed or outside the shared bounds. */
11
12
  function parseWorkflowDuration(text) {
12
13
  const match = /^(\d+)\s*([mhd])$/i.exec(text.trim());
@@ -29,6 +30,7 @@ function buildWorkflowUpdatePayload({ body, title, description, clearDescription
29
30
  }
30
31
  /** Update metadata or the mutable draft; executable changes use optimistic concurrency. */
31
32
  class SpacesWorkflowsUpdate extends base_command_1.BaseCommand {
33
+ static aliases = ['workflows:update'];
32
34
  static description = 'Update workflow metadata or its mutable graph draft';
33
35
  static examples = [
34
36
  '<%= config.bin %> spaces workflows update <space-id> <workflow-id> --title "Release train"',
@@ -159,6 +161,8 @@ class SpacesWorkflowsUpdate extends base_command_1.BaseCommand {
159
161
  }
160
162
  this.log(`Updated workflow ${workflow.id}: ${workflow.title}`);
161
163
  this.log(`Draft revisions: semantic ${workflow.draft.semanticRevision}, presentation ${workflow.draft.presentationRevision}`);
164
+ for (const line of (0, workflow_issues_1.describeDraftIssues)(workflow.issues))
165
+ this.log(line);
162
166
  }
163
167
  }
164
168
  exports.default = SpacesWorkflowsUpdate;
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../../base-command';
2
2
  export default class SpacesWorkflowsValidate extends BaseCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static args: {
5
6
  spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
@@ -4,7 +4,9 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../../base-command");
6
6
  const space_output_1 = require("../../../lib/space-output");
7
+ const workflow_issues_1 = require("../../../lib/workflow-issues");
7
8
  class SpacesWorkflowsValidate extends base_command_1.BaseCommand {
9
+ static aliases = ['workflows:validate'];
8
10
  static description = 'Validate a workflow draft before publishing';
9
11
  static args = {
10
12
  spaceId: core_1.Args.string({ description: 'Owning Space ID', required: true, ignoreStdin: true }),
@@ -32,11 +34,24 @@ class SpacesWorkflowsValidate extends base_command_1.BaseCommand {
32
34
  this.log(JSON.stringify((0, space_output_1.withSpacePerspectiveUrl)(this.cliConfig.baseURL, args.spaceId, 'workflows', result), null, 2));
33
35
  return;
34
36
  }
37
+ const advisories = (result.issues ?? []).filter((issue) => issue.severity !== 'error');
35
38
  if (result.valid) {
36
39
  this.log('Workflow draft is valid and ready to publish.');
40
+ if (advisories.length) {
41
+ this.log(`${advisories.length} warning${advisories.length === 1 ? '' : 's'} (publishing is allowed):`);
42
+ for (const line of (0, workflow_issues_1.formatWorkflowIssues)(advisories))
43
+ this.log(line);
44
+ }
37
45
  return;
38
46
  }
39
47
  this.log(`Workflow draft is invalid${result.code ? ` (${result.code})` : ''}: ${result.message ?? 'Unknown validation error'}`);
48
+ // Every problem, not only the first one publish would stop at.
49
+ const all = result.issues ?? [];
50
+ if (all.length) {
51
+ this.log('All problems found:');
52
+ for (const line of (0, workflow_issues_1.formatWorkflowIssues)(all))
53
+ this.log(line);
54
+ }
40
55
  this.exit(1);
41
56
  }
42
57
  }
@@ -6,6 +6,7 @@ const core_1 = require("@oclif/core");
6
6
  const data_provider_1 = require("@skrr-ai/data-provider");
7
7
  const base_command_1 = require("../../base-command");
8
8
  const format_1 = require("../../lib/format");
9
+ const task_economics_1 = require("../../lib/task-economics");
9
10
  const task_legacy_1 = require("../../lib/task-legacy");
10
11
  function activityRow(entry) {
11
12
  const actor = entry.actor;
@@ -18,11 +19,14 @@ function activityRow(entry) {
18
19
  ? `integration:${actor.provider}`
19
20
  : `system:${actor.service}`
20
21
  : (entry.userId ?? entry.actorId);
22
+ const type = entry.action ?? entry.event ?? entry.type;
21
23
  return {
22
24
  time: (0, format_1.localTime)(entry.occurredAt ?? entry.timestamp ?? entry.createdAt),
23
- event: (0, format_1.formatCell)(entry.action ?? entry.event ?? entry.type),
25
+ event: (0, format_1.formatCell)(type),
24
26
  actor: (0, format_1.formatCell)(actorText),
25
- details: (0, format_1.formatCell)(entry.data ?? entry.details ?? entry.metadata),
27
+ details: typeof type === 'string' && type.startsWith(data_provider_1.TASK_ECONOMICS_ACTIVITY_TYPE_PREFIX)
28
+ ? (0, task_economics_1.describeEconomicsChange)(entry.data)
29
+ : (0, format_1.formatCell)(entry.data ?? entry.details ?? entry.metadata),
26
30
  };
27
31
  }
28
32
  /**
@@ -3,6 +3,7 @@ export default class TasksBulkUpdate extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ 'expect-target': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
6
7
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
8
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
9
  'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
@@ -7,6 +7,7 @@ const web_url_1 = require("../../lib/web-url");
7
7
  const prompt_1 = require("../../lib/prompt");
8
8
  const dry_run_plans_1 = require("../../lib/dry-run-plans");
9
9
  const task_batch_1 = require("../../lib/task-batch");
10
+ const write_target_1 = require("../../lib/write-target");
10
11
  const tasks_1 = require("../../lib/tasks");
11
12
  class TasksBulkUpdate extends base_command_1.BaseCommand {
12
13
  static description = 'Apply partial updates to many tasks from JSON';
@@ -14,6 +15,7 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
14
15
  '<%= config.bin %> tasks bulk-update --from-json updates.json --json',
15
16
  '<%= config.bin %> tasks bulk-update --from-json updates.json --continue-on-error',
16
17
  '<%= config.bin %> tasks bulk-update --from-json updates.json --dry-run --json',
18
+ '<%= config.bin %> tasks bulk-update --from-json updates.json --expect-target skrr.ai --json',
17
19
  ];
18
20
  static flags = {
19
21
  json: core_1.Flags.boolean({ description: 'Output bulk result as JSON' }),
@@ -27,6 +29,7 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
27
29
  'continue-on-error': core_1.Flags.boolean({
28
30
  description: 'Continue applying later updates after one task fails',
29
31
  }),
32
+ ...write_target_1.expectTargetFlag,
30
33
  };
31
34
  async run() {
32
35
  this.requireAuth();
@@ -80,6 +83,9 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
80
83
  this.exit(1);
81
84
  return;
82
85
  }
86
+ // Everything above only read. Say where the writes land, and honour
87
+ // `--expect-target`, before the first one (OSK-S-440 #10).
88
+ const target = await this.assertWriteTarget(flags['expect-target']);
83
89
  const results = [];
84
90
  const errors = [];
85
91
  const rows = updates.map((update) => {
@@ -180,6 +186,7 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
180
186
  const base = this.cliConfig.baseURL;
181
187
  const enriched = {
182
188
  ...summary,
189
+ target,
183
190
  results: results.map((row) => {
184
191
  const rec = row;
185
192
  // Only link rows that actually updated — a failed row may not exist
@@ -357,7 +357,8 @@ class TasksComplete extends base_command_1.BaseCommand {
357
357
  for (const sentence of (0, task_closure_1.closureSnapshotLines)(result.task?.resolution?.closure)) {
358
358
  this.log(sentence);
359
359
  }
360
- const recurrenceLine = (0, task_recurrence_outcome_1.recurrenceOutcomeLine)(result.recurrence);
360
+ const completedRef = result.task?.identifier || taskId;
361
+ const recurrenceLine = (0, task_recurrence_outcome_1.recurrenceOutcomeLine)(result.recurrence, completedRef, this.config.bin);
361
362
  if (recurrenceLine)
362
363
  this.log(recurrenceLine);
363
364
  for (const advisory of result.advisories || [])
@@ -6,6 +6,14 @@ export type TreeNode = TaskRecord & {
6
6
  export type PlannedNode = {
7
7
  key: string;
8
8
  parentKey?: string;
9
+ /**
10
+ * Keys of other nodes in this file that block this one (`blockedByTempIds`).
11
+ * The ORDER of `planTree`'s result is parents-first only; `orderForCreation`
12
+ * makes it blockers-first too.
13
+ */
14
+ blockerKeys?: string[];
15
+ /** True when `externalKey` was filled in from a key prefix rather than written on the node. */
16
+ keyDerived?: boolean;
9
17
  node: TreeNode;
10
18
  payload: TaskRecord;
11
19
  };
@@ -45,6 +53,12 @@ export type TreeFailure = {
45
53
  /**
46
54
  * What a half-applied tree reports (E4). The ids already created are the only
47
55
  * way to continue or clean up, and the failing call used to print none of them.
56
+ *
57
+ * Every confirmed id is in `mapping` however the run ended, and `summary` counts
58
+ * the three things a failure can leave: confirmed, UNKNOWN (submitted, outcome
59
+ * not established — it may exist) and not attempted. They are different next
60
+ * steps, and a count that folded them together was the thing the first report
61
+ * of OSK-S-440 could not rely on.
48
62
  */
49
63
  export declare function partialFailureResult(args: {
50
64
  results: Array<Record<string, unknown>>;
@@ -55,14 +69,23 @@ export declare function partialFailureResult(args: {
55
69
  keyed?: boolean;
56
70
  warnings: Array<Record<string, unknown>>;
57
71
  failures?: Array<Record<string, unknown>>;
72
+ /** The command to run next, as it should be typed. */
73
+ next?: string;
58
74
  }): {
59
75
  warnings?: Record<string, unknown>[] | undefined;
76
+ next?: string | undefined;
60
77
  rerun: string;
61
78
  failures?: Record<string, unknown>[] | undefined;
62
79
  object: string;
63
80
  ok: boolean;
64
81
  count: number;
65
82
  total: number;
83
+ summary: {
84
+ confirmed: number;
85
+ unknown: number;
86
+ notAttempted: number;
87
+ failed: number;
88
+ };
66
89
  created: {
67
90
  tempId: unknown;
68
91
  parentTempId: unknown;
@@ -74,22 +97,68 @@ export declare function partialFailureResult(args: {
74
97
  mapping: Record<string, string>;
75
98
  failedAt: TreeFailure;
76
99
  };
100
+ /**
101
+ * Order nodes so everything a node depends on — its parent and every blocker —
102
+ * comes BEFORE it, keeping input order otherwise. The batch and the serial path
103
+ * both create in this order, so a parent id and a blocker id exist by the time a
104
+ * node that needs them is written.
105
+ *
106
+ * Also the place a bad `blockedByTempIds` is caught: before any request, naming
107
+ * the node, rather than as a per-row refusal after half the tree exists.
108
+ */
109
+ export declare function orderForCreation(planned: PlannedNode[]): {
110
+ ordered: PlannedNode[];
111
+ errors: string[];
112
+ };
77
113
  export default class TasksCreateTree extends BaseCommand {
78
114
  static description: string;
79
115
  static examples: string[];
80
116
  static flags: {
117
+ 'expect-target': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
81
118
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
82
119
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
83
120
  'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
121
+ verify: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
84
122
  'external-key-prefix': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
85
123
  fresh: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
86
124
  resume: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
125
+ 'no-batch': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
87
126
  'default-agent': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
88
127
  space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
89
128
  goal: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
129
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
90
130
  };
91
131
  run(): Promise<void>;
132
+ /**
133
+ * `--verify`: which nodes of this tree exist, and which do not. Read-only by
134
+ * construction — it is reached before anything that writes — so it is safe to
135
+ * run at any time, as often as wanted, against a tree of any size.
136
+ */
137
+ private verifyTree;
138
+ /**
139
+ * The command that continues this tree, as it should be typed: this
140
+ * invocation's own input and scope, plus `--resume`. Rebuilt from the parsed
141
+ * flags rather than echoed from argv, so it is the same whether the person
142
+ * typed `--space x` or `--space=x`, and so it can say plainly when the input
143
+ * came from stdin and cannot be replayed from a path.
144
+ */
145
+ private nextCommand;
92
146
  }
147
+ /**
148
+ * The note that names an Agent put in charge of nodes by DEFAULT, or undefined
149
+ * when no node was. Sources a person wrote themselves (`explicit-assignee`,
150
+ * `provided` — an operator's own `--default-agent`) are not surprises; the
151
+ * session's agent, a parent's, or the space lead are.
152
+ */
153
+ export declare function describeDefaultAgentAssignment(resolutions: Record<string, unknown>): {
154
+ code: string;
155
+ value: {
156
+ count: number;
157
+ agentIds: string[];
158
+ sources: string[];
159
+ };
160
+ hint: string;
161
+ } | undefined;
93
162
  export declare function normalizeTreeRoots(input: TaskRecord): TreeNode[];
94
163
  export declare function planTree(roots: TreeNode[], opts: {
95
164
  defaults: TaskRecord;