@sublang/playbook 0.9.0 → 1.3.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 (51) hide show
  1. package/README.md +190 -151
  2. package/package.json +50 -6
  3. package/reference/sdlc/captain.md +102 -0
  4. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +227 -0
  5. package/reference/sdlc/captain.playbook/captain.fsm.js +628 -0
  6. package/reference/sdlc/captain.playbook/captain.fsm.ts +851 -0
  7. package/reference/sdlc/captain.playbook/captain.gears.md +60 -0
  8. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +23 -0
  9. package/reference/sdlc/captain.playbook/captain.playbook.js +1053 -0
  10. package/reference/sdlc/captain.playbook/captain.playbook.ts +1144 -0
  11. package/reference/sdlc/code.playbook/bin/playbook.js +158 -12
  12. package/reference/sdlc/code.playbook/bin/run.js +999 -0
  13. package/reference/sdlc/code.playbook/code.fsm.d.ts +11 -4
  14. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +2 -2
  15. package/reference/sdlc/code.playbook/code.fsm.introspect.js +1 -1
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +6 -6
  17. package/reference/sdlc/code.playbook/code.fsm.js +334 -102
  18. package/reference/sdlc/code.playbook/code.fsm.ts +467 -180
  19. package/reference/sdlc/code.playbook/code.gears.md +11 -10
  20. package/reference/sdlc/code.playbook/code.playbook.d.ts +16 -19
  21. package/reference/sdlc/code.playbook/code.playbook.js +199 -488
  22. package/reference/sdlc/code.playbook/code.playbook.ts +327 -566
  23. package/reference/sdlc/code.playbook/code.registry.d.ts +0 -3
  24. package/reference/sdlc/code.playbook/code.registry.js +0 -3
  25. package/reference/sdlc/code.playbook/code.registry.ts +0 -6
  26. package/reference/sdlc/code.playbook/playbook-captain.d.ts +9 -4
  27. package/reference/sdlc/code.playbook/playbook-captain.js +889 -210
  28. package/reference/sdlc/code.playbook/playbook-captain.ts +1136 -257
  29. package/reference/sdlc/code.playbook/playbook.config.template.yaml +21 -0
  30. package/reference/sdlc/discuss.playbook/discuss.fsm.d.ts +396 -0
  31. package/reference/sdlc/discuss.playbook/discuss.fsm.js +2066 -0
  32. package/reference/sdlc/discuss.playbook/discuss.fsm.ts +2464 -0
  33. package/reference/sdlc/discuss.playbook/discuss.gears.md +251 -0
  34. package/reference/sdlc/discuss.playbook/discuss.playbook.d.ts +113 -0
  35. package/reference/sdlc/discuss.playbook/discuss.playbook.js +1514 -0
  36. package/reference/sdlc/discuss.playbook/discuss.playbook.ts +1926 -0
  37. package/reference/sdlc/discuss.playbook/discuss.registry.d.ts +58 -0
  38. package/reference/sdlc/discuss.playbook/discuss.registry.js +97 -0
  39. package/reference/sdlc/discuss.playbook/discuss.registry.ts +153 -0
  40. package/slc/gears2fsm.md +557 -57
  41. package/slc/link.md +1165 -89
  42. package/slc/optimize.md +92 -0
  43. package/slc/text2gears.md +255 -7
  44. package/src/runtime.d.ts +146 -3
  45. package/src/runtime.ts +201 -2
  46. package/src/xstate-playbook-runtime.d.ts +201 -0
  47. package/src/xstate-playbook-runtime.js +2058 -0
  48. package/src/xstate-playbook-runtime.ts +2792 -0
  49. package/src/xstate-runtime.d.ts +95 -0
  50. package/src/xstate-runtime.js +1258 -0
  51. package/src/xstate-runtime.ts +1816 -0
@@ -56,3 +56,24 @@ playbooks:
56
56
  coder: claude-opus-1m
57
57
  reviewer: codex-gpt
58
58
  committer: coder
59
+
60
+ # The DISCUSS playbook: two agents converge on spec items or decision
61
+ # records. `committer` picks which player runs Committer commits
62
+ # (default: host).
63
+ # discuss:
64
+ # from: "@sublang/playbook/discuss/registry"
65
+ # players:
66
+ # host: claude-opus
67
+ # participant: codex-gpt
68
+ # committer: host
69
+
70
+ # Non-interactive `playbook run` defaults (optional). Each value is an
71
+ # agent string <adapter>[:<model>][@<effort>]; `player` is the catch-all
72
+ # for any required role without its own `players.<role>` entry, across
73
+ # every playbook. Flags override per role (--player / --captain), and
74
+ # `playbook run resume` keeps the lineup stored with the parked session.
75
+ #run:
76
+ # captain: claude:claude-opus-4-8@high
77
+ # player: claude:claude-opus-4-8@high
78
+ # players:
79
+ # coder: claude:claude-opus-4-8[1m]@xhigh
@@ -0,0 +1,396 @@
1
+ type Player = 'Host' | 'Participant' | 'Committer';
2
+ type ReviewScope = 'specItems' | 'decisionRecords' | 'mixed';
3
+ type JumpableStateId = 'ready' | 'initialProposalRound' | 'reconciliationRound' | 'hostWritesAgreement' | 'commitInitialChanges' | 'reviewSpecInitialCommit' | 'reviewSpecHostChanges' | 'reviewDrInitialCommit' | 'reviewDrHostChanges' | 'reviewMixedInitialCommit' | 'reviewMixedHostChanges' | 'hostAddressesFindings' | 'participantAddressesRebuttals' | 'commitReviewedChanges' | 'failed';
4
+ type ResumableStateId = 'askHostInitial' | 'askParticipantInitial' | 'hostInitialRound' | 'participantInitialRound' | Exclude<JumpableStateId, 'ready' | 'initialProposalRound' | 'reconciliationRound' | 'failed'>;
5
+ export interface PendingBossQuestion {
6
+ questionId: ResumableStateId;
7
+ resumeStateId: ResumableStateId;
8
+ sourceItem: string;
9
+ player: Player;
10
+ question: string;
11
+ }
12
+ type PendingBossQuestions = Partial<Record<ResumableStateId, PendingBossQuestion>>;
13
+ type BossReplies = Partial<Record<ResumableStateId, string>>;
14
+ type PendingBossQuestionParams = Omit<PendingBossQuestion, 'questionId'>;
15
+ export interface DiscussContext {
16
+ hostPlayer?: string;
17
+ participantPlayer?: string;
18
+ committerPlayer?: string;
19
+ topic?: string;
20
+ hostLlm?: string;
21
+ participantLlm?: string;
22
+ hostProposal?: string;
23
+ participantProposal?: string;
24
+ agreement?: string;
25
+ latestChanges?: string;
26
+ reviewScope?: ReviewScope;
27
+ reviewItems?: string;
28
+ rebuttals?: string;
29
+ lastResult?: PlayerOutput;
30
+ lastError?: unknown;
31
+ pendingBossQuestions?: PendingBossQuestions;
32
+ bossReplies?: BossReplies;
33
+ stagedHostResult?: PlayerOutput;
34
+ stagedParticipantResult?: PlayerOutput;
35
+ }
36
+ export type DiscussEvent = {
37
+ type: 'START_DISCUSSION';
38
+ topic: string;
39
+ hostLlm?: string;
40
+ participantLlm?: string;
41
+ } | {
42
+ type: 'START_REVIEW';
43
+ latestChanges: string;
44
+ reviewScope: ReviewScope;
45
+ rebuttals?: string;
46
+ } | {
47
+ type: 'BOSS_INTERRUPT';
48
+ targetId: JumpableStateId;
49
+ } | {
50
+ type: 'BOSS_REPLY';
51
+ questionId?: ResumableStateId;
52
+ answer: string;
53
+ };
54
+ export interface DiscussInput {
55
+ host?: string;
56
+ participant?: string;
57
+ committer?: string;
58
+ }
59
+ export interface PlayerInput {
60
+ stateId: ResumableStateId;
61
+ sourceItem: string;
62
+ prompt: string;
63
+ result: Record<string, string>;
64
+ player: Player;
65
+ topic?: string;
66
+ hostLlm?: string;
67
+ participantLlm?: string;
68
+ hostProposal?: string;
69
+ participantProposal?: string;
70
+ agreement?: string;
71
+ latestChanges?: string;
72
+ reviewScope?: ReviewScope;
73
+ reviewItems?: string;
74
+ rebuttals?: string;
75
+ hostPlayer?: string;
76
+ participantPlayer?: string;
77
+ committerPlayer?: string;
78
+ pendingBossQuestion?: PendingBossQuestion;
79
+ bossReply?: string;
80
+ }
81
+ type AdditionalPlayerFields = {
82
+ proposal?: string;
83
+ agreement?: string;
84
+ latestChanges?: string;
85
+ reviewScope?: ReviewScope;
86
+ reviewItems?: string;
87
+ rebuttals?: string;
88
+ question?: string;
89
+ readonly [key: string]: unknown;
90
+ };
91
+ export type PlayerOutput = ({
92
+ guard: 'proposalMade';
93
+ proposal: string;
94
+ } & AdditionalPlayerFields) | ({
95
+ guard: 'endedInitialDiscussion';
96
+ agreement?: string;
97
+ } & AdditionalPlayerFields) | ({
98
+ guard: 'wroteChanges';
99
+ latestChanges: string;
100
+ reviewScope: ReviewScope;
101
+ } & AdditionalPlayerFields) | ({
102
+ guard: 'committed';
103
+ latestChanges?: string;
104
+ reviewScope?: ReviewScope;
105
+ } & AdditionalPlayerFields) | ({
106
+ guard: 'noFindings';
107
+ } & AdditionalPlayerFields) | ({
108
+ guard: 'findingsRaised';
109
+ reviewItems: string;
110
+ } & AdditionalPlayerFields) | ({
111
+ guard: 'changesMade';
112
+ latestChanges?: string;
113
+ reviewScope?: ReviewScope;
114
+ } & AdditionalPlayerFields) | ({
115
+ guard: 'rebuttalsRaised';
116
+ rebuttals: string;
117
+ } & AdditionalPlayerFields) | ({
118
+ guard: 'rebuttalsAddressed';
119
+ rebuttals?: string;
120
+ } & AdditionalPlayerFields) | ({
121
+ guard: 'needsBossReply';
122
+ question: string;
123
+ } & AdditionalPlayerFields);
124
+ type DiscussActionName = 'copyStartDiscussion' | 'copyStartReview' | 'rememberHostProposal' | 'rememberParticipantProposal' | 'rememberAgreement' | 'rememberWrittenChanges' | 'rememberCommittedChanges' | 'rememberReviewFindings' | 'rememberHostReviewResponse' | 'rememberParticipantRebuttalResponse' | 'rememberCaptainResult' | 'rememberCaptainError' | 'rememberMalformedCaptainOutput' | 'rememberMalformedBossReply' | 'setPendingBossQuestion' | 'rememberBossReply' | 'clearBranchBossReplyContext' | 'clearParallelRoundContext' | 'clearBossReplyContext';
125
+ declare function bossInterrupts(ids: readonly JumpableStateId[], actions?: DiscussActionName | DiscussActionName[]): any[];
126
+ declare function resumableStates(ids: readonly string[]): any[];
127
+ export declare const discussMachine: import("xstate").StateMachine<DiscussContext, {
128
+ type: "START_DISCUSSION";
129
+ topic: string;
130
+ hostLlm?: string;
131
+ participantLlm?: string;
132
+ } | {
133
+ type: "START_REVIEW";
134
+ latestChanges: string;
135
+ reviewScope: ReviewScope;
136
+ rebuttals?: string;
137
+ } | {
138
+ type: "BOSS_INTERRUPT";
139
+ targetId: JumpableStateId;
140
+ } | {
141
+ type: "BOSS_REPLY";
142
+ questionId?: ResumableStateId;
143
+ answer: string;
144
+ }, {
145
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>> | undefined;
146
+ }, {
147
+ src: "player";
148
+ logic: import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>;
149
+ id: string | undefined;
150
+ }, {
151
+ type: "copyStartDiscussion";
152
+ params: import("xstate").NonReducibleUnknown;
153
+ } | {
154
+ type: "copyStartReview";
155
+ params: import("xstate").NonReducibleUnknown;
156
+ } | {
157
+ type: "rememberHostProposal";
158
+ params: import("xstate").NonReducibleUnknown;
159
+ } | {
160
+ type: "rememberParticipantProposal";
161
+ params: import("xstate").NonReducibleUnknown;
162
+ } | {
163
+ type: "rememberAgreement";
164
+ params: import("xstate").NonReducibleUnknown;
165
+ } | {
166
+ type: "rememberWrittenChanges";
167
+ params: import("xstate").NonReducibleUnknown;
168
+ } | {
169
+ type: "rememberCommittedChanges";
170
+ params: import("xstate").NonReducibleUnknown;
171
+ } | {
172
+ type: "rememberReviewFindings";
173
+ params: import("xstate").NonReducibleUnknown;
174
+ } | {
175
+ type: "rememberHostReviewResponse";
176
+ params: import("xstate").NonReducibleUnknown;
177
+ } | {
178
+ type: "rememberParticipantRebuttalResponse";
179
+ params: import("xstate").NonReducibleUnknown;
180
+ } | {
181
+ type: "rememberCaptainResult";
182
+ params: import("xstate").NonReducibleUnknown;
183
+ } | {
184
+ type: "rememberCaptainError";
185
+ params: import("xstate").NonReducibleUnknown;
186
+ } | {
187
+ type: "rememberMalformedCaptainOutput";
188
+ params: import("xstate").NonReducibleUnknown;
189
+ } | {
190
+ type: "rememberMalformedBossReply";
191
+ params: import("xstate").NonReducibleUnknown;
192
+ } | {
193
+ type: "setPendingBossQuestion";
194
+ params: PendingBossQuestionParams;
195
+ } | {
196
+ type: "rememberBossReply";
197
+ params: import("xstate").NonReducibleUnknown;
198
+ } | {
199
+ type: "clearBranchBossReplyContext";
200
+ params: {
201
+ stateId: ResumableStateId;
202
+ };
203
+ } | {
204
+ type: "clearParallelRoundContext";
205
+ params: import("xstate").NonReducibleUnknown;
206
+ } | {
207
+ type: "clearBossReplyContext";
208
+ params: import("xstate").NonReducibleUnknown;
209
+ } | {
210
+ type: "stageHostResult";
211
+ params: import("xstate").NonReducibleUnknown;
212
+ } | {
213
+ type: "stageParticipantResult";
214
+ params: import("xstate").NonReducibleUnknown;
215
+ } | {
216
+ type: "promoteInitialResults";
217
+ params: import("xstate").NonReducibleUnknown;
218
+ } | {
219
+ type: "promoteReconciliationResults";
220
+ params: import("xstate").NonReducibleUnknown;
221
+ }, {
222
+ type: "noFindings";
223
+ params: unknown;
224
+ } | {
225
+ type: "committed";
226
+ params: unknown;
227
+ } | {
228
+ type: "proposalMade";
229
+ params: unknown;
230
+ } | {
231
+ type: "endedInitialDiscussion";
232
+ params: unknown;
233
+ } | {
234
+ type: "wroteChanges";
235
+ params: unknown;
236
+ } | {
237
+ type: "findingsRaised";
238
+ params: unknown;
239
+ } | {
240
+ type: "changesMade";
241
+ params: unknown;
242
+ } | {
243
+ type: "rebuttalsRaised";
244
+ params: unknown;
245
+ } | {
246
+ type: "rebuttalsAddressed";
247
+ params: unknown;
248
+ } | {
249
+ type: "needsBossReplyWithQuestion";
250
+ params: unknown;
251
+ } | {
252
+ type: "needsBossReplyWithoutQuestion";
253
+ params: unknown;
254
+ } | {
255
+ type: "emptyBossReply";
256
+ params: unknown;
257
+ } | {
258
+ type: "bothEndedInitialDiscussion";
259
+ params: unknown;
260
+ } | {
261
+ type: "specReview";
262
+ params: unknown;
263
+ } | {
264
+ type: "drReview";
265
+ params: unknown;
266
+ } | {
267
+ type: "mixedReview";
268
+ params: unknown;
269
+ }, never, "done" | "failed" | "awaitBossReply" | "ready" | "hostWritesAgreement" | "commitInitialChanges" | "reviewSpecInitialCommit" | "reviewSpecHostChanges" | "reviewDrInitialCommit" | "reviewDrHostChanges" | "reviewMixedInitialCommit" | "reviewMixedHostChanges" | "hostAddressesFindings" | "participantAddressesRebuttals" | "commitReviewedChanges" | {
270
+ initialProposalRound: {
271
+ host: "working" | "waiting" | "complete";
272
+ participant: "working" | "waiting" | "complete";
273
+ };
274
+ } | {
275
+ reconciliationRound: {
276
+ host: "working" | "waiting" | "complete";
277
+ participant: "working" | "waiting" | "complete";
278
+ };
279
+ }, string, DiscussInput, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
280
+ id: "discuss";
281
+ states: {
282
+ readonly ready: {
283
+ id: "ready";
284
+ };
285
+ readonly initialProposalRound: {
286
+ id: "initialProposalRound";
287
+ states: {
288
+ readonly host: {
289
+ id: "initialProposalHost";
290
+ states: {
291
+ readonly working: {
292
+ id: "askHostInitial";
293
+ };
294
+ readonly waiting: {
295
+ id: "waitHostInitialReply";
296
+ };
297
+ readonly complete: {
298
+ id: "hostInitialProposalComplete";
299
+ };
300
+ };
301
+ };
302
+ readonly participant: {
303
+ id: "initialProposalParticipant";
304
+ states: {
305
+ readonly working: {
306
+ id: "askParticipantInitial";
307
+ };
308
+ readonly waiting: {
309
+ id: "waitParticipantInitialReply";
310
+ };
311
+ readonly complete: {
312
+ id: "participantInitialProposalComplete";
313
+ };
314
+ };
315
+ };
316
+ };
317
+ };
318
+ readonly reconciliationRound: {
319
+ id: "reconciliationRound";
320
+ states: {
321
+ readonly host: {
322
+ id: "reconciliationHost";
323
+ states: {
324
+ readonly working: {
325
+ id: "hostInitialRound";
326
+ };
327
+ readonly waiting: {
328
+ id: "waitHostReconciliationReply";
329
+ };
330
+ readonly complete: {
331
+ id: "hostReconciliationComplete";
332
+ };
333
+ };
334
+ };
335
+ readonly participant: {
336
+ id: "reconciliationParticipant";
337
+ states: {
338
+ readonly working: {
339
+ id: "participantInitialRound";
340
+ };
341
+ readonly waiting: {
342
+ id: "waitParticipantReconciliationReply";
343
+ };
344
+ readonly complete: {
345
+ id: "participantReconciliationComplete";
346
+ };
347
+ };
348
+ };
349
+ };
350
+ };
351
+ readonly hostWritesAgreement: {
352
+ id: "hostWritesAgreement";
353
+ };
354
+ readonly commitInitialChanges: {
355
+ id: "commitInitialChanges";
356
+ };
357
+ readonly reviewSpecInitialCommit: {
358
+ id: "reviewSpecInitialCommit";
359
+ };
360
+ readonly reviewSpecHostChanges: {
361
+ id: "reviewSpecHostChanges";
362
+ };
363
+ readonly reviewDrInitialCommit: {
364
+ id: "reviewDrInitialCommit";
365
+ };
366
+ readonly reviewDrHostChanges: {
367
+ id: "reviewDrHostChanges";
368
+ };
369
+ readonly reviewMixedInitialCommit: {
370
+ id: "reviewMixedInitialCommit";
371
+ };
372
+ readonly reviewMixedHostChanges: {
373
+ id: "reviewMixedHostChanges";
374
+ };
375
+ readonly hostAddressesFindings: {
376
+ id: "hostAddressesFindings";
377
+ };
378
+ readonly participantAddressesRebuttals: {
379
+ id: "participantAddressesRebuttals";
380
+ };
381
+ readonly commitReviewedChanges: {
382
+ id: "commitReviewedChanges";
383
+ };
384
+ readonly awaitBossReply: {
385
+ id: "awaitBossReply";
386
+ };
387
+ readonly failed: {
388
+ id: "failed";
389
+ };
390
+ readonly done: {
391
+ id: "done";
392
+ };
393
+ };
394
+ }>;
395
+ export { bossInterrupts, resumableStates };
396
+ export default discussMachine;