@sublang/playbook 15.1.0 → 17.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 (102) hide show
  1. package/README.md +2 -0
  2. package/docs/cli.md +36 -18
  3. package/docs/configuration.md +7 -5
  4. package/docs/embedding.md +28 -7
  5. package/package.json +4 -4
  6. package/reference/sdlc/branch.playbook/branch.fsm.d.ts +63 -33
  7. package/reference/sdlc/branch.playbook/branch.fsm.js +190 -108
  8. package/reference/sdlc/branch.playbook/branch.fsm.ts +269 -147
  9. package/reference/sdlc/branch.playbook/branch.gears.md +7 -17
  10. package/reference/sdlc/branch.playbook/branch.playbook.d.ts +12 -16
  11. package/reference/sdlc/branch.playbook/branch.playbook.js +112 -101
  12. package/reference/sdlc/branch.playbook/branch.playbook.ts +128 -171
  13. package/reference/sdlc/branch.playbook/branch.registry.d.ts +3 -2
  14. package/reference/sdlc/branch.playbook/branch.registry.ts +6 -2
  15. package/reference/sdlc/captain.md +19 -10
  16. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +6 -2
  17. package/reference/sdlc/captain.playbook/captain.fsm.js +19 -7
  18. package/reference/sdlc/captain.playbook/captain.fsm.ts +25 -10
  19. package/reference/sdlc/captain.playbook/captain.gears.md +16 -8
  20. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +1 -1
  21. package/reference/sdlc/captain.playbook/captain.playbook.js +3 -2
  22. package/reference/sdlc/captain.playbook/captain.playbook.ts +4 -3
  23. package/reference/sdlc/code.playbook/bin/interactive-session.js +14 -1
  24. package/reference/sdlc/code.playbook/bin/portable-codec.js +3 -0
  25. package/reference/sdlc/code.playbook/bin/repository-effects.js +1 -0
  26. package/reference/sdlc/code.playbook/bin/run.js +128 -85
  27. package/reference/sdlc/code.playbook/bin/session-host.js +40 -8
  28. package/reference/sdlc/code.playbook/bin/session-store.js +162 -34
  29. package/reference/sdlc/code.playbook/code.fsm.d.ts +146 -93
  30. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +8 -8
  31. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +13 -13
  32. package/reference/sdlc/code.playbook/code.fsm.js +609 -649
  33. package/reference/sdlc/code.playbook/code.fsm.ts +890 -821
  34. package/reference/sdlc/code.playbook/code.gears.md +39 -29
  35. package/reference/sdlc/code.playbook/code.playbook.d.ts +13 -16
  36. package/reference/sdlc/code.playbook/code.playbook.js +166 -147
  37. package/reference/sdlc/code.playbook/code.playbook.ts +180 -229
  38. package/reference/sdlc/code.playbook/code.registry.d.ts +3 -2
  39. package/reference/sdlc/code.playbook/code.registry.ts +6 -2
  40. package/reference/sdlc/code.playbook/host-capabilities.d.ts +3 -0
  41. package/reference/sdlc/code.playbook/playbook-captain.d.ts +74 -2
  42. package/reference/sdlc/code.playbook/playbook-captain.js +1548 -468
  43. package/reference/sdlc/code.playbook/playbook-captain.ts +1993 -573
  44. package/reference/sdlc/code.playbook/session-host.d.ts +4 -1
  45. package/reference/sdlc/code.playbook/session-store.d.ts +17 -0
  46. package/reference/sdlc/code.playbook/session-store.js +1 -0
  47. package/reference/sdlc/decide.md +1 -0
  48. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +273 -157
  49. package/reference/sdlc/decide.playbook/decide.fsm.js +765 -732
  50. package/reference/sdlc/decide.playbook/decide.fsm.ts +1167 -945
  51. package/reference/sdlc/decide.playbook/decide.gears.md +28 -21
  52. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -59
  53. package/reference/sdlc/decide.playbook/decide.playbook.js +155 -3696
  54. package/reference/sdlc/decide.playbook/decide.playbook.ts +186 -5244
  55. package/reference/sdlc/decide.playbook/decide.registry.d.ts +8 -4
  56. package/reference/sdlc/decide.playbook/decide.registry.js +2 -2
  57. package/reference/sdlc/decide.playbook/decide.registry.ts +13 -6
  58. package/reference/sdlc/dev.playbook/dev.fsm.d.ts +116 -134
  59. package/reference/sdlc/dev.playbook/dev.fsm.js +517 -575
  60. package/reference/sdlc/dev.playbook/dev.fsm.ts +667 -787
  61. package/reference/sdlc/dev.playbook/dev.gears.md +52 -54
  62. package/reference/sdlc/dev.playbook/dev.playbook.d.ts +13 -10
  63. package/reference/sdlc/dev.playbook/dev.playbook.js +128 -120
  64. package/reference/sdlc/dev.playbook/dev.playbook.ts +143 -193
  65. package/reference/sdlc/dev.playbook/dev.registry.d.ts +3 -2
  66. package/reference/sdlc/dev.playbook/dev.registry.ts +6 -2
  67. package/reference/sdlc/pr.playbook/pr.fsm.d.ts +95 -88
  68. package/reference/sdlc/pr.playbook/pr.fsm.js +461 -518
  69. package/reference/sdlc/pr.playbook/pr.fsm.ts +533 -663
  70. package/reference/sdlc/pr.playbook/pr.gears.md +47 -63
  71. package/reference/sdlc/pr.playbook/pr.playbook.d.ts +13 -23
  72. package/reference/sdlc/pr.playbook/pr.playbook.js +118 -112
  73. package/reference/sdlc/pr.playbook/pr.playbook.ts +136 -190
  74. package/reference/sdlc/pr.playbook/pr.registry.d.ts +3 -2
  75. package/reference/sdlc/pr.playbook/pr.registry.ts +4 -2
  76. package/reference/sdlc/review.md +3 -3
  77. package/reference/sdlc/review.playbook/review.fsm.d.ts +150 -116
  78. package/reference/sdlc/review.playbook/review.fsm.js +479 -550
  79. package/reference/sdlc/review.playbook/review.fsm.ts +717 -662
  80. package/reference/sdlc/review.playbook/review.gears.md +32 -29
  81. package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -12
  82. package/reference/sdlc/review.playbook/review.playbook.js +180 -155
  83. package/reference/sdlc/review.playbook/review.playbook.ts +190 -230
  84. package/reference/sdlc/review.playbook/review.registry.d.ts +6 -5
  85. package/reference/sdlc/review.playbook/review.registry.js +3 -3
  86. package/reference/sdlc/review.playbook/review.registry.ts +9 -5
  87. package/slc/gears2fsm.md +77 -8
  88. package/slc/link.md +127 -60
  89. package/slc/materialize-link.mjs +51 -13
  90. package/slc/optimize.md +4 -1
  91. package/slc/prefix-prompts.mjs +29 -28
  92. package/slc/prefix.md +27 -24
  93. package/slc/slc.pin-inputs.json +11 -2
  94. package/slc/text2gears.md +71 -11
  95. package/src/runtime.d.ts +46 -2
  96. package/src/runtime.ts +42 -2
  97. package/src/xstate-playbook-runtime.d.ts +63 -23
  98. package/src/xstate-playbook-runtime.js +1637 -475
  99. package/src/xstate-playbook-runtime.ts +2105 -532
  100. package/src/xstate-runtime.d.ts +3 -4
  101. package/src/xstate-runtime.js +52 -0
  102. package/src/xstate-runtime.ts +59 -4
@@ -1,26 +1,30 @@
1
1
  <!-- SPDX-License-Identifier: Apache-2.0 -->
2
2
  <!-- SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai> -->
3
3
 
4
- # DEV: Development Planning Workflow
4
+ # Dev
5
5
 
6
6
  Roles:
7
7
 
8
8
  - Analyst
9
9
 
10
+ The caller supplies a development request including any desired outcome, scope, and context.
11
+
10
12
  `dev` is an optional repository-aware planner for a development request that needs more analysis before choosing a development path.
11
13
  It coordinates existing playbooks and owns no repository commit itself.
12
- Analyst chooses the path and states why in a short planning note; analysis, design, and implementation belong to the playbooks `dev` calls, and a question to Boss serves only the choice of path.
13
14
 
14
- ## Analyst
15
+ ## Planning
15
16
 
16
17
  ### DEV-1
17
18
 
19
+ Analyst chooses the path and states why in a short planning note; analysis, design, and implementation belong to the playbooks `dev` calls, and a question to Boss serves only the choice of path.
20
+ The planning result has six semantic outcomes: needs Boss reply, discussion complete, code, decide then code, code via pull request, and decide then code via pull request.
21
+ Each outcome requires affirmative support in Analyst's result; absence of a reason to choose another outcome is not support.
22
+ No outcome depends on a fixed presentation format of Analyst's reply.
23
+ `dev` shall act on the accepted outcome itself and shall not return to the session Captain for another routing decision.
24
+ For needs Boss reply, `dev` shall use the standard Boss-question suspension with Analyst's complete response; the session Captain shall present that response to Boss and, after Boss replies, resume `dev` with the answer in the same Analyst conversation, including the previous question only when that conversation must start fresh.
25
+
18
26
  At the start of `dev` and after each Boss reply, Captain shall relay the development request, relevant discussion context, and any relevant run results to Analyst in quotes (`>`), along with the planning instruction:
19
27
 
20
- > > Original request: <development-request>
21
- > > Prior discussion: <discussion-context>
22
- > > Run results: <run-results>
23
- >
24
28
  > Plan which playbooks run for this request; the playbooks do the work.
25
29
  > Read the request, then the specs and the repository only as far as choosing the path requires.
26
30
  > Do not change files or commit while planning or discussing the request.
@@ -39,55 +43,52 @@ At the start of `dev` and after each Boss reply, Captain shall relay the develop
39
43
  > A question or exploratory discussion is not by itself authorization to create a durable decision or implement changes.
40
44
  > Do not choose `decide then code` merely because the work is large, nor `code` merely because it is small.
41
45
  > Consult @specs/map.md for relevant context and @specs/meta.md for spec requirements, if needed.
46
+ >
47
+ > > Original request: <development-request>
48
+ > > Prior discussion: <discussion-context>
49
+ > > Run results: <run-results>
42
50
 
43
51
  Results:
44
- - `discussionComplete`: Analyst concluded the discussion after a Boss reply, with no repository work to follow.
45
- - `code`: Analyst chose `code`: the existing decisions and spec items settle how the work is done. Output shall include `planningResult: <verbatim final text>`.
46
- - `decideThenCode`: Analyst chose `decide then code`: the work turns on a point the specs leave open or contradict. Output shall include `planningResult: <verbatim final text>`.
47
- - `codeViaPullRequest`: Analyst chose `code via pull request`: the existing decisions settle the work, and the request names a GitHub issue or explicitly asks for pull-request delivery. Output shall include `planningResult: <verbatim final text>`.
48
- - `decideThenCodeViaPullRequest`: Analyst chose `decide then code via pull request`: the work turns on a point the specs leave open or contradict, and the request names a GitHub issue or explicitly asks for pull-request delivery. Output shall include `planningResult: <verbatim final text>`.
49
-
50
- Workflow outcomes:
51
- - The planning result has six semantic outcomes: needs Boss reply, discussion complete, code, decide then code, code via pull request, and decide then code via pull request.
52
- - Each outcome requires affirmative support in Analyst's result; absence of a reason to choose another outcome is not support, and no outcome depends on a fixed presentation format of Analyst's reply.
53
- - Needs Boss reply uses the standard Boss-question suspension with Analyst's complete response; after Boss replies, `dev` resumes with the answer in the same Analyst conversation; the previous question is included only when that conversation must start fresh.
54
- - Discussion complete is available only after a Boss reply, when that reply settles that no repository work should follow; it completes `dev` without a child call or repository change.
55
- - `dev` acts on the accepted outcome itself and does not return to the session Captain for another routing decision.
52
+ - `discussionComplete`: After a Boss reply that settles that no repository work should follow, Analyst concluded the discussion; dev completes without a child call or repository change.
53
+ - `code`: Analyst chose the code path because the existing decisions and spec items settle how the work is done. Output shall include `planningResult: <verbatim final text>`.
54
+ - `decideThenCode`: Analyst chose the decide then code path because the work turns on a rule, concept, term, shape, or trade-off the specs leave open or contradict. Output shall include `planningResult: <verbatim final text>`.
55
+ - `codeViaPullRequest`: Analyst chose the code via pull request path because the existing decisions and spec items settle how the work is done and the request names a GitHub issue or explicitly asks for pull-request delivery. Output shall include `planningResult: <verbatim final text>`.
56
+ - `decideThenCodeViaPullRequest`: Analyst chose the decide then code via pull request path because the work turns on a rule, concept, term, shape, or trade-off the specs leave open or contradict and the request names a GitHub issue or explicitly asks for pull-request delivery. Output shall include `planningResult: <verbatim final text>`.
56
57
 
57
- ## Nested development paths
58
+ ## Development paths
58
59
 
59
60
  ### DEV-2
60
61
 
61
- When the accepted planning result selects `code`, or `branch` succeeds for `code via pull request`, Captain shall call playbook `code`:
62
+ When the accepted planning result is code, or when `branch` has succeeded on the code via pull request path, Captain shall call playbook `code`:
62
63
 
63
64
  > > Original request: <development-request>
64
65
  > > Prior discussion: <discussion-context>
65
66
  > > Planning result: <planning-result>
66
67
 
67
- Workflow outcomes:
68
- - On a plain path, `code` success completes `dev` with the successful `code` result.
69
- - On a pull-request path, `code` success provides the exact last `code`-owned commit and the exact final evaluated repository revision from `code`'s canonical structured result and continues with the `pr` call.
70
- - An authored `code` abort or failure, or a terminal `code` result that does not prove the success required for the selected path, terminates `dev` with that canonical result relayed and no later child call.
71
- - Any other nested-call error parks `dev` as failed and retains the control-plane error.
72
- - `dev` consumes commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
68
+ On the code path, `code` success completes `dev` with that successful `code` result; a plain request calls neither `branch` nor `pr`.
69
+ On the code via pull request path, only after `code` succeeds shall `dev` call playbook `pr`.
70
+ If `code` returns an authored abort or failure, or a terminal result that does not prove the success required for the selected path, `dev` shall start no later child and shall relay that canonical result.
71
+ If the `code` call fails outside its authored result contract, `dev` shall park as failed and retain the control-plane error.
72
+ `dev` shall consume commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
73
73
 
74
74
  ### DEV-3
75
75
 
76
- When the accepted planning result selects `decide then code`, or `branch` succeeds for `decide then code via pull request`, Captain shall call playbook `decide`:
76
+ When the accepted planning result is decide then code, or when `branch` has succeeded on the decide then code via pull request path, Captain shall call playbook `decide`:
77
77
 
78
78
  > > Original request: <development-request>
79
79
  > > Prior discussion: <discussion-context>
80
80
  > > Planning result: <planning-result>
81
81
 
82
- Workflow outcomes:
83
- - `decide` success provides the `decide`-owned commit and the exact evaluated repository revision from `decide`'s canonical structured result and continues with the `code` call.
84
- - An authored `decide` abort or failure, or a terminal `decide` result that does not prove that success, terminates `dev` with that canonical result relayed and no later child call.
85
- - Any other nested-call error parks `dev` as failed and retains the control-plane error.
86
- - `dev` does not separately call `review` for the design scope already reviewed by `decide`.
82
+ Only after `decide` succeeds shall `dev` call playbook `code` with the `decide`-owned commit and exact evaluated repository revision from `decide`'s canonical structured result.
83
+ `dev` shall not separately call `review` for the design scope already reviewed by `decide`.
84
+ On the decide then code path, a plain request calls neither `branch` nor `pr`.
85
+ If `decide` returns an authored abort or failure, or a terminal result that does not prove the success required for the selected path, `dev` shall start no later child and shall relay that canonical result.
86
+ If the `decide` call fails outside its authored result contract, `dev` shall park as failed and retain the control-plane error.
87
+ `dev` shall consume commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
87
88
 
88
89
  ### DEV-4
89
90
 
90
- When `decide` succeeds, Captain shall call playbook `code`:
91
+ When `decide` has succeeded on the decide then code path or the decide then code via pull request path, Captain shall call playbook `code`:
91
92
 
92
93
  > > Original request: <development-request>
93
94
  > > Prior discussion: <discussion-context>
@@ -95,32 +96,29 @@ When `decide` succeeds, Captain shall call playbook `code`:
95
96
  > > DECIDE commit: <decide-commit>
96
97
  > > Evaluated revision: <evaluated-revision>
97
98
 
98
- Workflow outcomes:
99
- - On a plain path, `code` success completes `dev` with the successful `code` result.
100
- - On a pull-request path, `code` success provides the exact last `code`-owned commit and the exact final evaluated repository revision from `code`'s canonical structured result and continues with the `pr` call.
101
- - An authored `code` abort or failure, or a terminal `code` result that does not prove the success required for the selected path, terminates `dev` with that canonical result relayed and no later child call.
102
- - Any other nested-call error parks `dev` as failed and retains the control-plane error.
103
- - `dev` consumes commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
104
-
105
- ## Pull-request delivery
99
+ `dev` shall not separately call `review` for the design scope already reviewed by `decide`.
100
+ On the decide then code path, `code` success completes `dev` with that successful `code` result; a plain request calls neither `branch` nor `pr`.
101
+ On the decide then code via pull request path, only after `code` succeeds shall `dev` call playbook `pr`.
102
+ If `code` returns an authored abort or failure, or a terminal result that does not prove the success required for the selected path, `dev` shall start no later child and shall relay that canonical result.
103
+ If the `code` call fails outside its authored result contract, `dev` shall park as failed and retain the control-plane error.
104
+ `dev` shall consume commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
106
105
 
107
106
  ### DEV-5
108
107
 
109
- When the accepted planning result selects `code via pull request` or `decide then code via pull request`, Captain shall call playbook `branch`:
108
+ When the accepted planning result is code via pull request or decide then code via pull request and no child call has started yet, Captain shall call playbook `branch`:
110
109
 
111
110
  > > Original request: <development-request>
112
111
  > > Prior discussion: <discussion-context>
113
112
  > > Planning result: <planning-result>
114
113
 
115
- Workflow outcomes:
116
- - `branch` success provides the exact branch name, the exact base revision, and the issue summary from `branch`'s canonical structured result and continues with the `code` call for code via pull request, or the `decide` call and then the `code` call for decide then code via pull request, each with the same input as its plain path.
117
- - An authored `branch` abort or failure, or a terminal `branch` result that does not prove that success, terminates `dev` with that canonical result relayed and no later child call.
118
- - Any other nested-call error parks `dev` as failed and retains the control-plane error.
119
- - A plain request calls neither `branch` nor `pr`.
114
+ Only after `branch` succeeds shall `dev` continue with the `code` call for code via pull request, or the `decide` call and then the `code` call for decide then code via pull request, each with the same input as its plain path.
115
+ If `branch` returns an authored abort or failure, or a terminal result that does not prove the success required for the selected path, `dev` shall start no later child and shall relay that canonical result; a `branch` failure ends `dev` under this rule.
116
+ If the `branch` call fails outside its authored result contract, `dev` shall park as failed and retain the control-plane error.
117
+ `dev` shall consume commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
120
118
 
121
119
  ### DEV-6
122
120
 
123
- When `code` succeeds on a pull-request path, Captain shall call playbook `pr`:
121
+ When `code` has succeeded on the code via pull request path or the decide then code via pull request path, Captain shall call playbook `pr`:
124
122
 
125
123
  > > Original request: <development-request>
126
124
  > > Issue summary: <issue-summary>
@@ -129,8 +127,8 @@ When `code` succeeds on a pull-request path, Captain shall call playbook `pr`:
129
127
  > > CODE commit: <last-code-commit>
130
128
  > > Evaluated revision: <final-evaluated-revision>
131
129
 
132
- Workflow outcomes:
133
- - `pr` success completes `dev` with the successful `pr` result.
134
- - An authored `pr` abort or failure, or a terminal `pr` result that does not prove the success required for the selected path, terminates `dev` with that canonical result relayed and no later child call.
135
- - Any other nested-call error parks `dev` as failed and retains the control-plane error.
136
- - `dev` consumes commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
130
+ The branch and base revision come from `branch`'s canonical structured result, and the last `code`-owned commit and exact final evaluated repository revision come from the successful `code` call's canonical structured result.
131
+ `pr` success completes `dev` with that successful `pr` result.
132
+ If `pr` returns an authored abort or failure, or a terminal result that does not prove the success required for the selected path, `dev` shall relay that canonical result; a `pr` failure ends `dev` under this rule.
133
+ If the `pr` call fails outside its authored result contract, `dev` shall park as failed and retain the control-plane error.
134
+ `dev` shall consume commit, revision, branch, and pull-request identities only from each child's canonical structured result, never from player prose.
@@ -1,14 +1,17 @@
1
- import { type PlaybookPlayerInput, type XStatePlaybookRuntimeFactory, type XStatePlaybookRuntimeConstruction } from '@sublang/playbook/xstate-runtime';
2
- import { type DevInput } from './dev.fsm.js';
3
- import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
4
- import type { CaptainCallOptions, CaptainResult, JsonValue, NormalizedError, PlayerCallOptions, PlaybookCallRequest, PlaybookCallResult, PlaybookCallStart, PlaybookControlReceipt, PlaybookControlView, PlaybookPendingCall, PlaybookPorts, PlaybookRunResult, PlaybookRuntime, PlaybookRuntimeFactory, PlaybookRuntimeSnapshot, PlaybookSession, PlaybookState, PlaybookStateValue, PlaybookTraceEvent, PlaybookTraceType, PlayerResult, PlayerSessionStore } from '@sublang/playbook/runtime';
5
- export type { CaptainCallOptions, CaptainResult, JsonValue, NormalizedError, PlayerCallOptions, PlaybookCallRequest, PlaybookCallResult, PlaybookCallStart, PlaybookControlReceipt, PlaybookControlView, PlaybookPendingCall, PlaybookPorts, PlaybookRunResult, PlaybookRuntime, PlaybookRuntimeFactory, PlaybookRuntimeSnapshot, PlaybookSession, PlaybookState, PlaybookStateValue, PlaybookTraceEvent, PlaybookTraceType, PlayerResult, PlayerSessionStore, };
6
- export type DevPlaybookOptions = DevInput;
7
- export type DevPlaybookHostCapabilities = PlaybookHostConstructionCapabilities & XStatePlaybookRuntimeConstruction<DevPlaybookOptions, object>['hostCapabilities'];
1
+ import { type XStatePromptIdentity, type PlaybookPlayerInput, type XStatePlaybookRuntimeConstruction, type XStatePlaybookRuntimeFactory } from '@sublang/playbook/xstate-runtime';
2
+ export type { PlayerResult, PlayerCallOptions, PlayerSessionStore, CaptainResult, CaptainCallOptions, JsonValue, NormalizedError, PlaybookCallRequest, PlaybookCallResult, PlaybookCallStart, PlaybookStateValue, PlaybookState, PlaybookPendingCall, PlaybookRunResult, PlaybookRuntime, PlaybookRuntimeFactory, PlaybookRuntimeSnapshot, PlaybookSession, PlaybookPorts, PlaybookTraceEvent, PlaybookTraceType, PlaybookControlReceipt, PlaybookControlView, } from '@sublang/playbook/runtime';
3
+ export interface PlaybookRuntimeOptions {
4
+ readonly "runResults"?: string;
5
+ }
6
+ export type PlaybookHostCapabilities = XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, {
7
+ readonly authority: object;
8
+ }>['hostCapabilities'];
9
+ export declare function validateOptions(value: unknown): PlaybookRuntimeOptions;
8
10
  export declare const _internal: {
9
- composePlayerPrompt: (input: PlaybookPlayerInput, _identity: import("@sublang/playbook/xstate-runtime").XStatePromptIdentity, resuming?: boolean) => string;
10
- VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string>;
11
+ composePlayerPrompt: (input: PlaybookPlayerInput, promptIdentity: XStatePromptIdentity, resuming?: boolean) => string;
12
+ RESUMABLE_STATE_IDS: ReadonlySet<string>;
11
13
  UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string>;
14
+ VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string>;
12
15
  };
13
- declare const createPlaybookRuntime: XStatePlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<DevPlaybookOptions, DevPlaybookHostCapabilities>, 3>;
16
+ declare const createPlaybookRuntime: XStatePlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, PlaybookHostCapabilities>, 3>;
14
17
  export default createPlaybookRuntime;
@@ -1,145 +1,153 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
- //
4
- // Generated by slc/link.md (FSM-to-Runtime linker).
5
- // Source FSM: ./dev.fsm.ts
6
- // Role metadata: Analyst→analyst (canonical local role)
7
- // Boss event: deterministic START_DEV entry; exact Boss text becomes
8
- // developmentRequest; pending Analyst questions retain
9
- // BOSS_REPLY
10
- // Adjudication: LLM judge for the one Analyst state; planningResult is
11
- // carried verbatim
12
- // Nested calls: literal code, decide, branch, and pr targets through the
13
- // shared bridge; branch, revision, commit, and pull-request
14
- // identities enter only from canonical child results
15
- // Compat: artifact schema 3 / runtime ABI 1
16
- import { createXStatePlaybookRuntime, composePlayerContinuation, snapshotJsonValue, } from '@sublang/playbook/xstate-runtime';
17
- import { devMachine, } from './dev.fsm.js';
18
- const OPTION_KEYS = new Set(['runResults']);
19
- const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
20
- const VERBATIM_PAYLOAD_FIELDS = new Set([
21
- 'planningResult',
3
+ // Generated by slc/materialize-link.mjs; governed by the complete slc/link.md.
4
+ // FSM: "./dev.fsm.js"; export: devMachine; strategies: shared defaults with labelled string relays and nested actors.
5
+ import { devMachine as machine } from "./dev.fsm.js";
6
+ import { createXStatePlaybookRuntime, snapshotJsonValue, composePlayerContinuation, } from '@sublang/playbook/xstate-runtime';
7
+ const OPTION_SCHEMA = {
8
+ "runResults": {
9
+ "type": "string",
10
+ "required": false
11
+ }
12
+ };
13
+ const INPUT_MAPPING = {
14
+ "runResults": "runResults"
15
+ };
16
+ const RESUMABLE_STATE_IDS = new Set([
17
+ "planAnalysis"
22
18
  ]);
23
19
  const UNFINISHED_FINAL_STATE_IDS = new Set([
24
- 'reportedChildFailure',
20
+ "reportedChildFailure"
25
21
  ]);
26
- function snapshotDevOptions(value) {
27
- const captured = snapshotJsonValue(value, 'DEV runtime options');
28
- if (captured === null ||
29
- typeof captured !== 'object' ||
30
- Array.isArray(captured)) {
31
- throw new TypeError('DEV runtime options must be an object');
22
+ const VERBATIM_PAYLOAD_FIELDS = new Set([
23
+ "planningResult"
24
+ ]);
25
+ export function validateOptions(value) {
26
+ const captured = snapshotJsonValue(value === undefined ? {} : value, "DEV runtime options");
27
+ if (captured === null || typeof captured !== 'object' || Array.isArray(captured)) {
28
+ throw new TypeError("DEV runtime options must be an object");
29
+ }
30
+ const fields = captured;
31
+ for (const key of Object.keys(captured)) {
32
+ if (!Object.hasOwn(OPTION_SCHEMA, key))
33
+ throw new TypeError("DEV runtime options." + key + ' is not declared');
32
34
  }
33
- const record = captured;
34
- for (const [key, option] of Object.entries(record)) {
35
- if (!OPTION_KEYS.has(key)) {
36
- throw new TypeError(`DEV runtime options.${key} is not declared`);
35
+ for (const [key, schema] of Object.entries(OPTION_SCHEMA)) {
36
+ if (!Object.hasOwn(captured, key)) {
37
+ if (schema.required)
38
+ throw new TypeError("DEV runtime options." + key + ' is required');
37
39
  }
38
- if (typeof option !== 'string') {
39
- throw new TypeError(`DEV runtime options.${key} must be a string`);
40
+ else if (typeof fields[key] !== schema.type || (schema.type === 'number' && !Number.isFinite(fields[key]))) {
41
+ throw new TypeError("DEV runtime options." + key + ' must be a ' + schema.type);
40
42
  }
41
43
  }
42
44
  return captured;
43
45
  }
44
- function placeholderField(token) {
45
- if (token === '#')
46
- return 'irNumber';
47
- return token.replace(/-([A-Za-z0-9_$])/g, (_match, next) => next.toUpperCase());
48
- }
49
- function quotedContinuation(value) {
50
- return value.replaceAll('\n', '\n> ');
51
- }
52
- /**
53
- * Preserve authored Markdown quote markers around every line of relayed
54
- * runtime text. The generic composer preserves the marker itself; DEV's
55
- * override additionally keeps a multiline value inside that quote and drops
56
- * the optional relays that have no value yet.
57
- */
58
- function composePlayerPrompt(input, resuming = false) {
46
+ function renderPlayerPrompt(input, promptIdentity, resuming = false) {
59
47
  const fields = input;
60
- const template = input.prompt
61
- .split('\n')
62
- .filter((line) => !(line === '> Prior discussion: <discussion-context>' &&
63
- input.discussionContext.length === 0) &&
64
- !(line === '> Run results: <run-results>' && input.runResults.length === 0))
65
- .join('\n');
66
- const body = template.replace(PLACEHOLDER, (match, token, offset, source) => {
67
- const value = fields[placeholderField(token)];
68
- if (typeof value !== 'string')
69
- return match;
70
- const lineStart = source.lastIndexOf('\n', offset - 1) + 1;
71
- const literal = source.slice(lineStart, offset);
72
- return literal.startsWith('> ') ? quotedContinuation(value) : value;
73
- });
48
+ const mapping = {};
49
+ const identities = {};
50
+ const omitted = new Set(["> Prior discussion: <discussion-context>", "> Run results: <run-results>"]);
51
+ const fieldFor = (token) => Object.hasOwn(mapping, token) ? mapping[token] : (token === '#' ? 'irNumber' : token.replace(/-([A-Za-z0-9_$])/g, (_match, next) => next.toUpperCase()));
52
+ const parts = input.prompt.split(/(\r?\n)/);
53
+ let body = '';
54
+ for (let index = 0; index < parts.length; index += 2) {
55
+ const line = parts[index];
56
+ if (omitted.has(line)) {
57
+ const token = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>$/.exec(line)[1];
58
+ if (fields[fieldFor(token)] === '')
59
+ continue;
60
+ }
61
+ body += line.replace(/<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g, (match, token) => {
62
+ const value = Object.hasOwn(identities, token) ? promptIdentity(identities[token]) : fields[fieldFor(token)];
63
+ if (typeof value !== 'string')
64
+ return match;
65
+ return line.startsWith('> ') ? value.replace(/\r?\n/g, (ending) => ending + '> ') : value;
66
+ }) + (parts[index + 1] ?? '');
67
+ }
74
68
  return composePlayerContinuation(input, body, resuming);
75
69
  }
70
+ const composePlayerPrompt = (input, promptIdentity, resuming) => renderPlayerPrompt(input, promptIdentity, resuming);
76
71
  const runtimeSpec = {
77
- label: 'DEV',
78
- // DR-022 / slc/link.md: the declaration carries the value current at link
79
- // time — a literal, never the loading engine's RUNTIME_ABI self-report,
80
- // which would follow whatever engine loads the module and make the
81
- // factory's skew check compare that engine with itself.
82
- compat: { artifactSchema: 3, runtimeAbi: 1 },
83
- snapshotOptions: snapshotDevOptions,
84
- entryEvent: {
85
- type: 'START_DEV',
86
- textField: 'developmentRequest',
87
- // `startDev` copies the entry text here, so the failure-state retry
88
- // reads it back from the persisted machine snapshot and survives a
89
- // continued session (DR-034).
90
- contextField: 'developmentRequest',
91
- },
92
- roleStates: {
93
- planAnalysis: {
94
- role: 'analyst',
95
- label: 'Analyst is choosing the development path.',
72
+ composePlayerPrompt,
73
+ ...{
74
+ "label": "DEV",
75
+ "compat": {
76
+ "artifactSchema": 3,
77
+ "runtimeAbi": 1
96
78
  },
97
- },
98
- // DR-044: DEV owns no repository commit — every Analyst outcome is
99
- // governed with the `unchanged` repository disposition, so planning that
100
- // mutates the repository fails authority instead of being adopted.
101
- outcomeAuthority: {
102
- governedPlayerStates: {
103
- planAnalysis: {
104
- discussionComplete: {
105
- fields: {},
106
- repositoryDisposition: 'unchanged',
107
- },
108
- code: {
109
- fields: { planningResult: 'presentation' },
110
- repositoryDisposition: 'unchanged',
111
- },
112
- decideThenCode: {
113
- fields: { planningResult: 'presentation' },
114
- repositoryDisposition: 'unchanged',
115
- },
116
- // DR-050: reading a GitHub issue during planning is not an effect, so
117
- // the two pull-request outcomes stay `unchanged` like the plain ones.
118
- codeViaPullRequest: {
119
- fields: { planningResult: 'presentation' },
120
- repositoryDisposition: 'unchanged',
121
- },
122
- decideThenCodeViaPullRequest: {
123
- fields: { planningResult: 'presentation' },
124
- repositoryDisposition: 'unchanged',
125
- },
126
- needsBossReply: {
127
- fields: { question: 'presentation' },
128
- repositoryDisposition: 'unchanged',
129
- },
130
- },
79
+ "entryEvent": {
80
+ "type": "START_DEV",
81
+ "textField": "developmentRequest",
82
+ "contextField": "developmentRequest"
131
83
  },
84
+ "bossEvents": [],
85
+ "roleStates": {
86
+ "planAnalysis": {
87
+ "role": "analyst",
88
+ "label": "Analyst chooses the development path in a short planning note."
89
+ }
90
+ },
91
+ "outcomeAuthority": {
92
+ "governedPlayerStates": {
93
+ "planAnalysis": {
94
+ "discussionComplete": {
95
+ "fields": {},
96
+ "repositoryDisposition": "unchanged"
97
+ },
98
+ "code": {
99
+ "fields": {
100
+ "planningResult": "presentation"
101
+ },
102
+ "repositoryDisposition": "unchanged"
103
+ },
104
+ "decideThenCode": {
105
+ "fields": {
106
+ "planningResult": "presentation"
107
+ },
108
+ "repositoryDisposition": "unchanged"
109
+ },
110
+ "codeViaPullRequest": {
111
+ "fields": {
112
+ "planningResult": "presentation"
113
+ },
114
+ "repositoryDisposition": "unchanged"
115
+ },
116
+ "decideThenCodeViaPullRequest": {
117
+ "fields": {
118
+ "planningResult": "presentation"
119
+ },
120
+ "repositoryDisposition": "unchanged"
121
+ },
122
+ "needsBossReply": {
123
+ "fields": {
124
+ "question": "presentation"
125
+ },
126
+ "repositoryDisposition": "unchanged"
127
+ }
128
+ }
129
+ }
130
+ },
131
+ "placeholderFields": {},
132
+ "transitionEventFields": [
133
+ "developmentRequest",
134
+ "answer",
135
+ "questionId"
136
+ ],
137
+ "controlContextFields": []
132
138
  },
133
- composePlayerPrompt: (input, _identity, resuming) => composePlayerPrompt(input, resuming),
139
+ snapshotOptions: validateOptions,
140
+ machineInput: (options) => Object.fromEntries(Object.entries(INPUT_MAPPING).filter(([, key]) => options[key] !== undefined)
141
+ .map(([field, key]) => [field, options[key]])),
134
142
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
135
- controlContextFields: [],
143
+ resumableStateIds: RESUMABLE_STATE_IDS,
136
144
  unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
137
- transitionEventFields: ['developmentRequest', 'answer', 'questionId'],
138
145
  };
139
146
  export const _internal = {
140
- composePlayerPrompt: runtimeSpec.composePlayerPrompt,
141
- VERBATIM_PAYLOAD_FIELDS,
147
+ composePlayerPrompt,
148
+ RESUMABLE_STATE_IDS,
142
149
  UNFINISHED_FINAL_STATE_IDS,
150
+ VERBATIM_PAYLOAD_FIELDS,
143
151
  };
144
- const createPlaybookRuntime = createXStatePlaybookRuntime(devMachine, runtimeSpec);
152
+ const createPlaybookRuntime = createXStatePlaybookRuntime(machine, runtimeSpec);
145
153
  export default createPlaybookRuntime;