@sublang/playbook 7.0.0 → 9.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.
- package/README.md +20 -7
- package/docs/cli.md +88 -43
- package/docs/configuration.md +221 -119
- package/docs/embedding.md +78 -27
- package/package.json +4 -3
- package/reference/sdlc/captain.playbook/captain.playbook.js +16 -5
- package/reference/sdlc/captain.playbook/captain.playbook.ts +20 -6
- package/reference/sdlc/code.md +1 -1
- package/reference/sdlc/code.playbook/bin/interactive-session.js +816 -0
- package/reference/sdlc/code.playbook/bin/launch-config.js +1078 -116
- package/reference/sdlc/code.playbook/bin/playbook.js +489 -34
- package/reference/sdlc/code.playbook/bin/run.js +283 -298
- package/reference/sdlc/code.playbook/bin/session-store.js +818 -26
- package/reference/sdlc/code.playbook/code.fsm.d.ts +9 -6
- package/reference/sdlc/code.playbook/code.fsm.introspect.js +2 -2
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +2 -2
- package/reference/sdlc/code.playbook/code.fsm.js +18 -15
- package/reference/sdlc/code.playbook/code.fsm.ts +21 -21
- package/reference/sdlc/code.playbook/code.gears.md +1 -1
- package/reference/sdlc/code.playbook/code.playbook.d.ts +2 -1
- package/reference/sdlc/code.playbook/code.playbook.js +25 -15
- package/reference/sdlc/code.playbook/code.playbook.ts +34 -17
- package/reference/sdlc/code.playbook/code.registry.d.ts +5 -13
- package/reference/sdlc/code.playbook/code.registry.js +3 -10
- package/reference/sdlc/code.playbook/code.registry.ts +7 -32
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +39 -14
- package/reference/sdlc/code.playbook/playbook-captain.js +1014 -299
- package/reference/sdlc/code.playbook/playbook-captain.ts +1450 -406
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +41 -49
- package/reference/sdlc/decide.md +4 -4
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +10 -10
- package/reference/sdlc/decide.playbook/decide.fsm.js +21 -14
- package/reference/sdlc/decide.playbook/decide.fsm.ts +27 -23
- package/reference/sdlc/decide.playbook/decide.gears.md +3 -5
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -13
- package/reference/sdlc/decide.playbook/decide.playbook.js +465 -246
- package/reference/sdlc/decide.playbook/decide.playbook.ts +623 -283
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +5 -13
- package/reference/sdlc/decide.playbook/decide.registry.js +3 -9
- package/reference/sdlc/decide.playbook/decide.registry.ts +7 -31
- package/reference/sdlc/review.md +4 -5
- package/reference/sdlc/review.playbook/review.fsm.d.ts +9 -11
- package/reference/sdlc/review.playbook/review.fsm.js +30 -24
- package/reference/sdlc/review.playbook/review.fsm.ts +39 -35
- package/reference/sdlc/review.playbook/review.gears.md +6 -5
- package/reference/sdlc/review.playbook/review.playbook.d.ts +2 -1
- package/reference/sdlc/review.playbook/review.playbook.js +29 -23
- package/reference/sdlc/review.playbook/review.playbook.ts +38 -28
- package/reference/sdlc/review.playbook/review.registry.d.ts +5 -13
- package/reference/sdlc/review.playbook/review.registry.js +3 -16
- package/reference/sdlc/review.playbook/review.registry.ts +7 -38
- package/slc/gears2fsm.md +45 -24
- package/slc/link.md +297 -135
- package/slc/text2gears.md +19 -18
- package/src/runtime.d.ts +21 -16
- package/src/runtime.ts +20 -23
- package/src/xstate-playbook-runtime.d.ts +34 -20
- package/src/xstate-playbook-runtime.js +973 -400
- package/src/xstate-playbook-runtime.ts +1203 -457
- package/src/xstate-runtime.d.ts +17 -7
- package/src/xstate-runtime.js +198 -81
- package/src/xstate-runtime.ts +339 -112
|
@@ -43,24 +43,17 @@ export function validateCodeOptions(optionSlice) {
|
|
|
43
43
|
}
|
|
44
44
|
return Object.freeze({});
|
|
45
45
|
}
|
|
46
|
-
function playerIdentity(players, id) {
|
|
47
|
-
const player = players.find((entry) => entry.id === id);
|
|
48
|
-
return player?.model ?? player?.adapter;
|
|
49
|
-
}
|
|
50
|
-
export function createCodeRuntimeOptions({ captainOptions, players, }) {
|
|
51
|
-
validateCodeOptions(captainOptions);
|
|
52
|
-
const coderPlayer = playerIdentity(players, 'coder');
|
|
53
|
-
return coderPlayer === undefined ? {} : { coderPlayer };
|
|
54
|
-
}
|
|
55
46
|
export const codePlaybookRegistryEntry = {
|
|
56
47
|
id: 'code',
|
|
57
48
|
command: 'code',
|
|
58
49
|
intent: 'implement a coding intent in reviewed, one-commit phases, using an intent record when needed',
|
|
50
|
+
artifactSchema: 2,
|
|
59
51
|
requiredRoleIds: ['coder'],
|
|
52
|
+
concurrentRoleSets: [],
|
|
60
53
|
summaryPolicy: codeSummaryPolicy,
|
|
61
54
|
validateOptions: validateCodeOptions,
|
|
62
55
|
createRuntime(options) {
|
|
63
|
-
return createPlaybookRuntime(
|
|
56
|
+
return createPlaybookRuntime(options);
|
|
64
57
|
},
|
|
65
58
|
};
|
|
66
59
|
export default codePlaybookRegistryEntry;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
|
|
3
3
|
|
|
4
4
|
import createPlaybookRuntime, {
|
|
5
|
-
type CodePlaybookOptions,
|
|
6
5
|
type PlaybookRuntime,
|
|
7
6
|
} from './code.playbook.js';
|
|
8
7
|
|
|
@@ -15,27 +14,18 @@ export interface PlaybookSummaryPolicy {
|
|
|
15
14
|
): string;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export interface RegistryPlayer {
|
|
19
|
-
id: string;
|
|
20
|
-
adapter?: string;
|
|
21
|
-
model?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface CreateCodeRuntimeOptions {
|
|
25
|
-
captainOptions: unknown;
|
|
26
|
-
players: readonly RegistryPlayer[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
17
|
export type CodeOptions = Readonly<Record<string, never>>;
|
|
30
18
|
|
|
31
19
|
export interface CodePlaybookRegistryEntry {
|
|
32
20
|
id: 'code';
|
|
33
21
|
command: 'code';
|
|
34
22
|
intent: string;
|
|
23
|
+
artifactSchema: 2;
|
|
35
24
|
requiredRoleIds: readonly ['coder'];
|
|
25
|
+
concurrentRoleSets: readonly [];
|
|
36
26
|
summaryPolicy: PlaybookSummaryPolicy;
|
|
37
|
-
validateOptions(
|
|
38
|
-
createRuntime(options:
|
|
27
|
+
validateOptions(optionSlice: unknown): CodeOptions;
|
|
28
|
+
createRuntime(options: CodeOptions): PlaybookRuntime;
|
|
39
29
|
}
|
|
40
30
|
|
|
41
31
|
// REVIEW owns and labels its real review rounds. CODE's two suspended wrapper
|
|
@@ -96,33 +86,18 @@ export function validateCodeOptions(optionSlice: unknown): CodeOptions {
|
|
|
96
86
|
return Object.freeze({});
|
|
97
87
|
}
|
|
98
88
|
|
|
99
|
-
function playerIdentity(
|
|
100
|
-
players: readonly RegistryPlayer[],
|
|
101
|
-
id: string,
|
|
102
|
-
): string | undefined {
|
|
103
|
-
const player = players.find((entry) => entry.id === id);
|
|
104
|
-
return player?.model ?? player?.adapter;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function createCodeRuntimeOptions({
|
|
108
|
-
captainOptions,
|
|
109
|
-
players,
|
|
110
|
-
}: CreateCodeRuntimeOptions): CodePlaybookOptions {
|
|
111
|
-
validateCodeOptions(captainOptions);
|
|
112
|
-
const coderPlayer = playerIdentity(players, 'coder');
|
|
113
|
-
return coderPlayer === undefined ? {} : { coderPlayer };
|
|
114
|
-
}
|
|
115
|
-
|
|
116
89
|
export const codePlaybookRegistryEntry: CodePlaybookRegistryEntry = {
|
|
117
90
|
id: 'code',
|
|
118
91
|
command: 'code',
|
|
119
92
|
intent:
|
|
120
93
|
'implement a coding intent in reviewed, one-commit phases, using an intent record when needed',
|
|
94
|
+
artifactSchema: 2,
|
|
121
95
|
requiredRoleIds: ['coder'],
|
|
96
|
+
concurrentRoleSets: [],
|
|
122
97
|
summaryPolicy: codeSummaryPolicy,
|
|
123
98
|
validateOptions: validateCodeOptions,
|
|
124
99
|
createRuntime(options) {
|
|
125
|
-
return createPlaybookRuntime(
|
|
100
|
+
return createPlaybookRuntime(options);
|
|
126
101
|
},
|
|
127
102
|
};
|
|
128
103
|
|
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Captain, type CaptainSession, type TuningSelection } from '@sublang/cligent/tmux-play';
|
|
2
|
+
import type { Effort, PermissionPolicy } from '@sublang/cligent';
|
|
2
3
|
import type { JsonValue, PlaybookRuntime, PlaybookRuntimeSnapshot } from '@sublang/playbook/runtime';
|
|
3
4
|
import { type CaptainControllerPort } from '../captain.playbook/captain.playbook.js';
|
|
4
|
-
import type { PlaybookSummaryPolicy
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import type { PlaybookSummaryPolicy } from './code.registry.js';
|
|
6
|
+
interface SessionAgent {
|
|
7
|
+
readonly adapter: string;
|
|
8
|
+
readonly model: TuningSelection;
|
|
9
|
+
readonly effort: TuningSelection<Effort>;
|
|
10
|
+
readonly instruction?: string;
|
|
11
|
+
readonly permissions?: PermissionPolicy;
|
|
8
12
|
}
|
|
13
|
+
interface PlayerLedgerEntry {
|
|
14
|
+
readonly adapter: string;
|
|
15
|
+
readonly instruction?: string;
|
|
16
|
+
readonly permissions?: PermissionPolicy;
|
|
17
|
+
resumeToken?: string;
|
|
18
|
+
}
|
|
19
|
+
type DeepReadonly<T> = T extends (...args: never[]) => unknown ? T : T extends readonly (infer Element)[] ? readonly DeepReadonly<Element>[] : T extends object ? {
|
|
20
|
+
readonly [Key in keyof T]: DeepReadonly<T[Key]>;
|
|
21
|
+
} : T;
|
|
22
|
+
type SnapshotAgentEnvelope = DeepReadonly<Omit<SessionAgent, 'model' | 'effort'>>;
|
|
23
|
+
type PlayerLedgerSnapshotEntry = DeepReadonly<PlayerLedgerEntry>;
|
|
9
24
|
export interface PlaybookCaptainDeps {
|
|
10
25
|
loadModule?: (specifier: string) => Promise<unknown>;
|
|
11
26
|
createSessionId?: () => string;
|
|
@@ -22,16 +37,22 @@ export interface PlaybookCaptainRegistryEntry {
|
|
|
22
37
|
id: string;
|
|
23
38
|
command: string;
|
|
24
39
|
intent: string;
|
|
40
|
+
artifactSchema: 2;
|
|
25
41
|
requiredRoleIds: readonly string[];
|
|
42
|
+
concurrentRoleSets: readonly (readonly string[])[];
|
|
26
43
|
summaryPolicy?: PlaybookSummaryPolicy;
|
|
27
|
-
validateOptions(
|
|
28
|
-
createRuntime(options:
|
|
44
|
+
validateOptions(optionSlice: unknown): unknown;
|
|
45
|
+
createRuntime(options: unknown): PlaybookRuntime;
|
|
29
46
|
}
|
|
30
47
|
type PlaybookCaptainConversationSnapshot = {
|
|
31
48
|
readonly kind: 'unopened';
|
|
32
49
|
} | {
|
|
33
50
|
readonly kind: 'pinned';
|
|
34
51
|
readonly token: string;
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: 'needsCatchUp';
|
|
54
|
+
readonly resume: string | false;
|
|
55
|
+
readonly afterJournalSeq: number;
|
|
35
56
|
} | {
|
|
36
57
|
readonly kind: 'needsSeeding';
|
|
37
58
|
};
|
|
@@ -48,15 +69,19 @@ interface PlaybookCaptainFrameSnapshot {
|
|
|
48
69
|
readonly depth: number;
|
|
49
70
|
readonly parentSessionId?: string;
|
|
50
71
|
readonly parentCallId?: string;
|
|
51
|
-
readonly
|
|
72
|
+
readonly options: JsonValue;
|
|
73
|
+
readonly roleBindings: Readonly<Record<string, string>>;
|
|
74
|
+
readonly runtime: DeepReadonly<PlaybookRuntimeSnapshot>;
|
|
52
75
|
}
|
|
53
76
|
interface PlaybookCaptainShellSnapshotFields {
|
|
54
|
-
readonly schemaVersion:
|
|
77
|
+
readonly schemaVersion: 3;
|
|
55
78
|
readonly captain: {
|
|
56
79
|
readonly sessionId: string;
|
|
57
|
-
readonly runtime: PlaybookRuntimeSnapshot
|
|
80
|
+
readonly runtime: DeepReadonly<PlaybookRuntimeSnapshot>;
|
|
81
|
+
readonly agent: SnapshotAgentEnvelope;
|
|
58
82
|
readonly conversation: PlaybookCaptainConversationSnapshot;
|
|
59
83
|
};
|
|
84
|
+
readonly playerSessions: Readonly<Record<string, PlayerLedgerSnapshotEntry>>;
|
|
60
85
|
/** Every Captain and engagement UUID issued during this logical session. */
|
|
61
86
|
readonly issuedSessionIds: readonly string[];
|
|
62
87
|
readonly sequences: {
|
|
@@ -71,28 +96,28 @@ interface PlaybookCaptainShellSnapshotFields {
|
|
|
71
96
|
* Complete JSON-safe durable state for one Captain shell between Boss turns.
|
|
72
97
|
* The discriminated mode keeps chat snapshots free of stale engagement data.
|
|
73
98
|
*/
|
|
74
|
-
|
|
99
|
+
type PlaybookCaptainShellSnapshotValue = PlaybookCaptainShellSnapshotFields & ({
|
|
75
100
|
readonly mode: 'chat';
|
|
76
101
|
readonly frames?: never;
|
|
77
|
-
readonly rootPlayerResumeTokens?: never;
|
|
78
102
|
readonly pendingBossQuestions?: never;
|
|
79
103
|
readonly lastError?: never;
|
|
80
104
|
} | {
|
|
81
105
|
readonly mode: 'engaged.parked';
|
|
82
106
|
/** Root-to-leaf engagement order. */
|
|
83
107
|
readonly frames: readonly PlaybookCaptainFrameSnapshot[];
|
|
84
|
-
/** Root-owned continuation, keyed by effective host-player id. */
|
|
85
|
-
readonly rootPlayerResumeTokens: Readonly<Record<string, string>>;
|
|
86
108
|
readonly pendingBossQuestions?: JsonValue;
|
|
87
109
|
readonly lastError?: {
|
|
88
110
|
readonly name: string;
|
|
89
111
|
readonly message: string;
|
|
90
112
|
};
|
|
91
113
|
});
|
|
114
|
+
export type PlaybookCaptainShellSnapshot = DeepReadonly<PlaybookCaptainShellSnapshotValue>;
|
|
92
115
|
/** tmux and headless front ends share this one durable Captain shell API. */
|
|
93
116
|
export interface PlaybookCaptainShell extends Captain {
|
|
94
117
|
exportSnapshot(): PlaybookCaptainShellSnapshot | undefined;
|
|
95
118
|
restore(session: CaptainSession, snapshot: PlaybookCaptainShellSnapshot): Promise<void>;
|
|
96
119
|
}
|
|
120
|
+
/** Validate, detach, and freeze one untrusted shell snapshot. */
|
|
121
|
+
export declare function assertPlaybookCaptainShellSnapshot(value: unknown): PlaybookCaptainShellSnapshot;
|
|
97
122
|
export declare function createPlaybookCaptainShell(options: unknown, deps?: PlaybookCaptainDeps): PlaybookCaptainShell;
|
|
98
123
|
export default createPlaybookCaptainShell;
|