@sublang/playbook 15.0.0 → 16.0.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.
Files changed (81) hide show
  1. package/README.md +1 -1
  2. package/docs/embedding.md +9 -7
  3. package/package.json +3 -1
  4. package/reference/sdlc/branch.playbook/branch.fsm.d.ts +63 -33
  5. package/reference/sdlc/branch.playbook/branch.fsm.js +190 -108
  6. package/reference/sdlc/branch.playbook/branch.fsm.ts +269 -147
  7. package/reference/sdlc/branch.playbook/branch.gears.md +7 -17
  8. package/reference/sdlc/branch.playbook/branch.playbook.d.ts +12 -16
  9. package/reference/sdlc/branch.playbook/branch.playbook.js +112 -101
  10. package/reference/sdlc/branch.playbook/branch.playbook.ts +128 -171
  11. package/reference/sdlc/branch.playbook/branch.registry.d.ts +3 -2
  12. package/reference/sdlc/branch.playbook/branch.registry.ts +6 -2
  13. package/reference/sdlc/code.playbook/bin/repository-effects.js +54 -13
  14. package/reference/sdlc/code.playbook/code.fsm.d.ts +143 -90
  15. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +8 -8
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +13 -13
  17. package/reference/sdlc/code.playbook/code.fsm.js +609 -649
  18. package/reference/sdlc/code.playbook/code.fsm.ts +890 -821
  19. package/reference/sdlc/code.playbook/code.gears.md +39 -29
  20. package/reference/sdlc/code.playbook/code.playbook.d.ts +13 -16
  21. package/reference/sdlc/code.playbook/code.playbook.js +166 -147
  22. package/reference/sdlc/code.playbook/code.playbook.ts +180 -229
  23. package/reference/sdlc/code.playbook/code.registry.d.ts +3 -2
  24. package/reference/sdlc/code.playbook/code.registry.ts +6 -2
  25. package/reference/sdlc/code.playbook/playbook-captain.d.ts +42 -0
  26. package/reference/sdlc/code.playbook/playbook-captain.js +829 -194
  27. package/reference/sdlc/code.playbook/playbook-captain.ts +1227 -220
  28. package/reference/sdlc/decide.md +1 -0
  29. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +270 -154
  30. package/reference/sdlc/decide.playbook/decide.fsm.js +765 -732
  31. package/reference/sdlc/decide.playbook/decide.fsm.ts +1167 -945
  32. package/reference/sdlc/decide.playbook/decide.gears.md +28 -21
  33. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -67
  34. package/reference/sdlc/decide.playbook/decide.playbook.js +155 -3570
  35. package/reference/sdlc/decide.playbook/decide.playbook.ts +186 -5061
  36. package/reference/sdlc/decide.playbook/decide.registry.d.ts +8 -4
  37. package/reference/sdlc/decide.playbook/decide.registry.js +2 -2
  38. package/reference/sdlc/decide.playbook/decide.registry.ts +13 -6
  39. package/reference/sdlc/dev.playbook/dev.fsm.d.ts +113 -131
  40. package/reference/sdlc/dev.playbook/dev.fsm.js +517 -575
  41. package/reference/sdlc/dev.playbook/dev.fsm.ts +667 -787
  42. package/reference/sdlc/dev.playbook/dev.gears.md +52 -54
  43. package/reference/sdlc/dev.playbook/dev.playbook.d.ts +13 -10
  44. package/reference/sdlc/dev.playbook/dev.playbook.js +128 -120
  45. package/reference/sdlc/dev.playbook/dev.playbook.ts +143 -193
  46. package/reference/sdlc/dev.playbook/dev.registry.d.ts +3 -2
  47. package/reference/sdlc/dev.playbook/dev.registry.ts +6 -2
  48. package/reference/sdlc/pr.playbook/pr.fsm.d.ts +92 -85
  49. package/reference/sdlc/pr.playbook/pr.fsm.js +461 -518
  50. package/reference/sdlc/pr.playbook/pr.fsm.ts +533 -663
  51. package/reference/sdlc/pr.playbook/pr.gears.md +47 -63
  52. package/reference/sdlc/pr.playbook/pr.playbook.d.ts +13 -23
  53. package/reference/sdlc/pr.playbook/pr.playbook.js +118 -112
  54. package/reference/sdlc/pr.playbook/pr.playbook.ts +136 -190
  55. package/reference/sdlc/pr.playbook/pr.registry.d.ts +3 -2
  56. package/reference/sdlc/pr.playbook/pr.registry.ts +4 -2
  57. package/reference/sdlc/review.md +3 -3
  58. package/reference/sdlc/review.playbook/review.fsm.d.ts +150 -116
  59. package/reference/sdlc/review.playbook/review.fsm.js +479 -550
  60. package/reference/sdlc/review.playbook/review.fsm.ts +717 -662
  61. package/reference/sdlc/review.playbook/review.gears.md +32 -29
  62. package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -12
  63. package/reference/sdlc/review.playbook/review.playbook.js +180 -155
  64. package/reference/sdlc/review.playbook/review.playbook.ts +190 -230
  65. package/reference/sdlc/review.playbook/review.registry.d.ts +6 -5
  66. package/reference/sdlc/review.playbook/review.registry.js +3 -3
  67. package/reference/sdlc/review.playbook/review.registry.ts +9 -5
  68. package/slc/gears2fsm.md +72 -3
  69. package/slc/link.md +50 -27
  70. package/slc/materialize-link.mjs +51 -13
  71. package/slc/optimize.md +4 -1
  72. package/slc/prefix-prompts.mjs +191 -0
  73. package/slc/prefix.md +203 -0
  74. package/slc/slc.pin-inputs.json +11 -1
  75. package/slc/text2gears.md +71 -11
  76. package/src/xstate-playbook-runtime.d.ts +82 -9
  77. package/src/xstate-playbook-runtime.js +1224 -283
  78. package/src/xstate-playbook-runtime.ts +1671 -338
  79. package/src/xstate-runtime.d.ts +3 -1
  80. package/src/xstate-runtime.js +9 -2
  81. package/src/xstate-runtime.ts +12 -2
package/README.md CHANGED
@@ -107,7 +107,7 @@ SLC's `playbook` pipeline has three phases:
107
107
  2. **GEARS → FSM** ([slc/gears2fsm.md](slc/gears2fsm.md)) — maps each item to an XState state that invokes the Captain, a player, another playbook, or a local script.
108
108
  3. **FSM → runtime** ([slc/link.md](slc/link.md)) — links the machine to a host-independent interface for user input, agent calls, status, and telemetry.
109
109
 
110
- The default [optimization pass](slc/optimize.md) replaces eligible mechanical steps with local shell scripts; `--no-optimize` skips it.
110
+ The default passes run between the first two phases: the [optimization pass](slc/optimize.md) replaces eligible mechanical steps with local shell scripts, and the [prompt-prefix pass](slc/prefix.md) moves each prompt's relayed runtime values after its instructions so repeated runs share a cacheable prompt prefix; `--no-optimize` skips both.
111
111
  Inspect the complete [Captain](reference/sdlc/captain.md), [CODE](reference/sdlc/code.md), [REVIEW](reference/sdlc/review.md), and [DECIDE](reference/sdlc/decide.md) examples.
112
112
 
113
113
  ## Contributing
package/docs/embedding.md CHANGED
@@ -38,7 +38,7 @@ tree, which pnpm's strict linking will not allow.
38
38
 
39
39
  ```ts
40
40
  import createPlaybookRuntime, {
41
- type ReviewPlaybookHostCapabilities,
41
+ type PlaybookHostCapabilities,
42
42
  } from '@sublang/playbook/review/playbook';
43
43
  import type {
44
44
  CaptainCallOptions,
@@ -156,7 +156,7 @@ const playbookSessionId = randomUUID();
156
156
  // machine input, or a persisted snapshot. A host outside the CLI constructs
157
157
  // the repository and effect-ledger members through the facade described in
158
158
  // "Constructing worktree host capabilities" below.
159
- declare const hostCapabilities: ReviewPlaybookHostCapabilities;
159
+ declare const hostCapabilities: PlaybookHostCapabilities;
160
160
 
161
161
  const runtime = createPlaybookRuntime({
162
162
  configuredOptions: {},
@@ -445,21 +445,23 @@ const url = import.meta.resolve('@sublang/playbook/slc/link.md');
445
445
  const link = await readFile(fileURLToPath(url), 'utf8');
446
446
  ```
447
447
 
448
- The four specs are [`slc/text2gears.md`](../slc/text2gears.md),
448
+ The five specs are [`slc/text2gears.md`](../slc/text2gears.md),
449
449
  [`slc/gears2fsm.md`](../slc/gears2fsm.md),
450
450
  [`slc/link.md`](../slc/link.md) — the FSM-to-runtime contract that
451
- `@sublang/playbook/runtime` projects into TypeScript — and
452
- [`slc/optimize.md`](../slc/optimize.md).
451
+ `@sublang/playbook/runtime` projects into TypeScript —
452
+ [`slc/optimize.md`](../slc/optimize.md), and
453
+ [`slc/prefix.md`](../slc/prefix.md).
453
454
 
454
- Five supporting assets use the same resolution mechanism:
455
+ Six supporting assets use the same resolution mechanism:
455
456
 
456
457
  | Asset | Purpose |
457
458
  | --- | --- |
458
459
  | [`slc/workflow-contracts.json`](../slc/workflow-contracts.json) | Public output schemas and default literal target bindings for the builtin REVIEW, DECIDE, CODE, BRANCH, and PR workflows; compilers and embedders can read them without importing workflow implementations. |
459
460
  | [`slc/materialize-link.mjs`](../slc/materialize-link.mjs) | Optional CLI that emits a thin linked module from a supported FSM and JSON descriptor; see the profiles and invocation in `slc/link.md`. |
460
461
  | [`slc/scaffold-fsm.mjs`](../slc/scaffold-fsm.mjs) | Optional CLI that initializes an incomplete typed FSM from supported GEARS source. |
462
+ | [`slc/prefix-prompts.mjs`](../slc/prefix-prompts.mjs) | CLI that performs the prompt-prefix pass's rewrite of a GEARS package exactly; see the invocation in `slc/prefix.md`. |
461
463
  | [`slc/experiments/fsm-scaffold-guidance.md`](../slc/experiments/fsm-scaffold-guidance.md) | Opt-in compiler guidance for the initializer, outside ordinary phase discovery. |
462
- | [`slc/slc.pin-inputs.json`](../slc/slc.pin-inputs.json) | SLC semantic-input closures for `gears2fsm` and `link`, including the workflow catalog and, for `link`, the materializer. Other phases use SLC's inline-input discovery. |
464
+ | [`slc/slc.pin-inputs.json`](../slc/slc.pin-inputs.json) | SLC semantic-input closures for `gears2fsm`, `prefix`, and `link`, including the workflow catalog, the prefix tool, and, for `link`, the materializer. Other phases use SLC's inline-input discovery. |
463
465
 
464
466
  For example, resolve `@sublang/playbook/slc/workflow-contracts.json`, read it
465
467
  with `readFile`, and parse the result as JSON to inspect the published workflow
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sublang/playbook",
3
- "version": "15.0.0",
3
+ "version": "16.0.0",
4
4
  "type": "module",
5
5
  "description": "Composable XState v5 playbook runtime with compiled Captain, CODE, REVIEW, DECIDE, DEV, BRANCH, and PR workflows driven by GEARS specs.",
6
6
  "license": "Apache-2.0",
@@ -46,6 +46,8 @@
46
46
  "slc/gears2fsm.md",
47
47
  "slc/text2gears.md",
48
48
  "slc/optimize.md",
49
+ "slc/prefix.md",
50
+ "slc/prefix-prompts.mjs",
49
51
  "reference/sdlc/captain.md",
50
52
  "reference/sdlc/code.md",
51
53
  "reference/sdlc/review.md",
@@ -1,34 +1,46 @@
1
1
  export type BranchStateId = 'createBranch';
2
2
  export type BranchSourceItem = 'BRANCH-1';
3
+ /**
4
+ * Stable working-leaf ids that may suspend on a Boss question and be resumed
5
+ * by `BOSS_REPLY`. The machine has at most one active player task, so the
6
+ * scalar Boss-reply form applies.
7
+ */
8
+ declare const RESUMABLE_STATE_IDS: readonly ["createBranch"];
9
+ export type ResumableStateId = (typeof RESUMABLE_STATE_IDS)[number];
10
+ /** JSON-safe normalization of a rejected invocation, retained for inspection. */
11
+ export type NormalizedError = {
12
+ readonly name: string;
13
+ readonly message: string;
14
+ readonly stack?: string;
15
+ };
16
+ /** Question record raised by the suspended Coder working leaf. */
3
17
  export type PendingBossQuestion = {
4
- readonly questionId: 'createBranch';
5
- readonly resumeStateId: 'createBranch';
6
- readonly sourceItem: 'BRANCH-1';
18
+ readonly questionId: ResumableStateId;
19
+ readonly resumeStateId: ResumableStateId;
20
+ readonly sourceItem: BranchSourceItem;
7
21
  readonly asker: {
8
22
  readonly kind: 'role';
9
23
  readonly roleId: 'coder';
10
24
  };
11
25
  readonly question: string;
12
26
  };
27
+ /** Typed input for the delegated `player` actor. */
13
28
  export type PlayerInput = {
14
29
  readonly stateId: 'createBranch';
15
30
  readonly role: 'coder';
16
31
  readonly sourceItem: 'BRANCH-1';
17
32
  readonly prompt: string;
18
33
  readonly result: Readonly<Record<string, string>>;
34
+ /** Backs the prompt's `<caller-input>` placeholder with the exact caller input. */
19
35
  readonly callerInput: string;
20
36
  readonly pendingBossQuestion?: PendingBossQuestion;
21
37
  readonly bossReply?: string;
22
38
  };
39
+ /** Discriminated result contract of the delegated `player` actor. */
23
40
  export type PlayerOutput = {
24
41
  readonly guard: 'branched';
25
42
  readonly branch: string;
26
- /**
27
- * Receipt-owned effect evidence (DR-045): the branching call's
28
- * `unchanged` receipt observes the commit the branch was created from
29
- * as HEAD, so the linked runtime injects it and never takes it from
30
- * Coder's prose.
31
- */
43
+ /** Exact base revision from repository authority, not from Coder's prose. */
32
44
  readonly baseRevision: string;
33
45
  readonly issueSummary: string;
34
46
  } | {
@@ -38,47 +50,55 @@ export type PlayerOutput = {
38
50
  readonly guard: 'needsBossReply';
39
51
  readonly question: string;
40
52
  };
53
+ /**
54
+ * Terminal result: exactly the packaged `branch` workflow's public output
55
+ * interface (workflow-contracts.json), derived from typed context.
56
+ */
41
57
  export type BranchPlaybookOutput = {
42
58
  readonly status: 'branched';
43
- /** Exact name of the new branch now checked out. */
59
+ /** Exact new branch name. */
44
60
  readonly branch: string;
45
- /** Exact receipt-observed revision the branch was created from. */
61
+ /** Exact receipt-observed repository revision the branch was created from. */
46
62
  readonly baseRevision: string;
47
- /** Coder's concise summary of the issue and its comments, or of the request. */
63
+ /** Concise issue-and-comments or request summary. */
48
64
  readonly issueSummary: string;
49
65
  } | {
50
66
  readonly status: 'refused';
51
- /** Coder's complete report carrying the reason no branch was created. */
67
+ /** Complete refusal report. */
52
68
  readonly coderOutput: string;
53
69
  };
54
- export type BranchInput = Readonly<Record<string, never>>;
70
+ /** The machine reads no input: the caller input arrives on `START_BRANCH`. */
71
+ export type BranchInput = Readonly<Record<never, never>>;
72
+ export type BranchCompletion = 'branched' | 'refused';
55
73
  export type BranchContext = {
56
74
  readonly callerInput?: string;
57
75
  readonly branch?: string;
58
- /** Observed HEAD of the branching call's unchanged receipt (DR-045). */
59
76
  readonly baseRevision?: string;
60
77
  readonly issueSummary?: string;
61
78
  readonly coderOutput?: string;
62
- readonly completion?: 'branched' | 'refused';
63
- readonly lastError?: unknown;
79
+ readonly completion?: BranchCompletion;
80
+ readonly lastError?: NormalizedError;
64
81
  readonly pendingBossQuestion?: PendingBossQuestion;
65
82
  readonly bossReply?: string;
66
83
  };
84
+ /** Typed Boss surfaces: the caller's entry event and the Boss reply. */
67
85
  export type BranchEvent = {
68
86
  readonly type: 'START_BRANCH';
69
87
  readonly callerInput: string;
70
88
  } | {
71
89
  readonly type: 'BOSS_REPLY';
72
90
  readonly answer: string;
73
- readonly questionId?: 'createBranch';
91
+ readonly questionId?: ResumableStateId;
74
92
  };
93
+ /** No parallel group in this playbook. */
94
+ export declare const concurrentRoleSets: readonly (readonly string[])[];
75
95
  export declare const branchMachine: import("xstate").StateMachine<BranchContext, {
76
96
  readonly type: "START_BRANCH";
77
97
  readonly callerInput: string;
78
98
  } | {
79
99
  readonly type: "BOSS_REPLY";
80
100
  readonly answer: string;
81
- readonly questionId?: "createBranch";
101
+ readonly questionId?: ResumableStateId;
82
102
  }, {
83
103
  [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>> | undefined;
84
104
  }, {
@@ -96,16 +116,22 @@ export declare const branchMachine: import("xstate").StateMachine<BranchContext,
96
116
  type: "rememberActorError";
97
117
  params: import("xstate").NonReducibleUnknown;
98
118
  } | {
99
- type: "rememberPendingQuestion";
119
+ type: "rememberMalformedPlayerOutput";
100
120
  params: import("xstate").NonReducibleUnknown;
101
121
  } | {
102
- type: "rememberBossReply";
122
+ type: "clearBossReplyContext";
103
123
  params: import("xstate").NonReducibleUnknown;
104
124
  } | {
105
- type: "rememberEmptyBossReplyError";
125
+ type: "setPendingBossQuestion";
126
+ params: {
127
+ readonly stateId: ResumableStateId;
128
+ readonly sourceItem: BranchSourceItem;
129
+ };
130
+ } | {
131
+ type: "rememberMalformedBossReply";
106
132
  params: import("xstate").NonReducibleUnknown;
107
133
  } | {
108
- type: "rememberMalformedPlayerOutput";
134
+ type: "acceptBossReply";
109
135
  params: import("xstate").NonReducibleUnknown;
110
136
  } | {
111
137
  type: "startBranch";
@@ -118,9 +144,16 @@ export declare const branchMachine: import("xstate").StateMachine<BranchContext,
118
144
  params: import("xstate").NonReducibleUnknown;
119
145
  }, {
120
146
  type: "needsBossReply";
121
- params: unknown;
147
+ params: {
148
+ readonly stateId: ResumableStateId;
149
+ };
122
150
  } | {
123
- type: "emptyBossReply";
151
+ type: "canResume";
152
+ params: {
153
+ readonly stateId: ResumableStateId;
154
+ };
155
+ } | {
156
+ type: "givesRequest";
124
157
  params: unknown;
125
158
  } | {
126
159
  type: "isBranched";
@@ -128,20 +161,17 @@ export declare const branchMachine: import("xstate").StateMachine<BranchContext,
128
161
  } | {
129
162
  type: "isRefused";
130
163
  params: unknown;
131
- } | {
132
- type: "resumesCreateBranch";
133
- params: unknown;
134
- }, never, "failed" | "ready" | "awaitBossReply" | "refused" | "createBranch" | "branched", string, Readonly<Record<string, never>>, {
164
+ }, never, "failed" | "ready" | "awaitBossReply" | "refused" | "createBranch" | "branched", string, Readonly<Record<never, never>>, {
135
165
  readonly status: "branched";
136
- /** Exact name of the new branch now checked out. */
166
+ /** Exact new branch name. */
137
167
  readonly branch: string;
138
- /** Exact receipt-observed revision the branch was created from. */
168
+ /** Exact receipt-observed repository revision the branch was created from. */
139
169
  readonly baseRevision: string;
140
- /** Coder's concise summary of the issue and its comments, or of the request. */
170
+ /** Concise issue-and-comments or request summary. */
141
171
  readonly issueSummary: string;
142
172
  } | {
143
173
  readonly status: "refused";
144
- /** Coder's complete report carrying the reason no branch was created. */
174
+ /** Complete refusal report. */
145
175
  readonly coderOutput: string;
146
176
  }, import("xstate").EventObject, import("xstate").MetaObject, {
147
177
  id: "branch";