@sublang/playbook 12.3.0 → 13.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/docs/cli.md +56 -52
- package/docs/configuration.md +2 -2
- package/docs/embedding.md +68 -32
- package/package.json +11 -3
- package/reference/sdlc/code.playbook/bin/interactive-session.js +1 -0
- package/reference/sdlc/code.playbook/bin/launch-config.js +2 -0
- package/reference/sdlc/code.playbook/bin/playbook.js +42 -4
- package/reference/sdlc/code.playbook/bin/portable-codec.js +190 -0
- package/reference/sdlc/code.playbook/bin/replay-observer.js +18 -2
- package/reference/sdlc/code.playbook/bin/run.js +62 -18
- package/reference/sdlc/code.playbook/bin/session-host.js +104 -0
- package/reference/sdlc/code.playbook/bin/session-store.js +622 -65
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +5 -0
- package/reference/sdlc/code.playbook/playbook-captain.js +53 -14
- package/reference/sdlc/code.playbook/playbook-captain.ts +68 -21
- package/reference/sdlc/code.playbook/session-host.d.ts +75 -0
- package/reference/sdlc/code.playbook/session-host.js +18 -0
- package/reference/sdlc/code.playbook/session-store.d.ts +176 -1
- package/reference/sdlc/code.playbook/session-store.js +22 -6
- package/src/xstate-playbook-runtime.js +12 -13
- package/src/xstate-playbook-runtime.ts +14 -21
|
@@ -21,14 +21,17 @@ export function openSessionStore(sessionsDir) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function wrapStore(store) {
|
|
24
|
+
let preparation;
|
|
25
|
+
const prepared = async (operation) => {
|
|
26
|
+
await (preparation ??= store.prepare());
|
|
27
|
+
return operation();
|
|
28
|
+
};
|
|
24
29
|
return Object.freeze({
|
|
25
30
|
sessionsDir: store.sessionsDir,
|
|
26
|
-
list: async () => projectListResult(await store.listSummaries()),
|
|
27
|
-
read: async (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
projectReadResult(await store.readStream(sessionId, options)),
|
|
31
|
-
acquire: async (sessionId) => wrapLease(await store.acquire(sessionId)),
|
|
31
|
+
list: () => prepared(async () => projectListResult(await store.listSummaries())),
|
|
32
|
+
read: (sessionId) => prepared(async () => projectSummary(await store.readSummary(sessionId))),
|
|
33
|
+
readStream: (sessionId, options) => prepared(async () => projectReadResult(await store.readStream(sessionId, options))),
|
|
34
|
+
acquire: (sessionId) => prepared(async () => wrapLease(await store.acquire(sessionId))),
|
|
32
35
|
});
|
|
33
36
|
}
|
|
34
37
|
|
|
@@ -111,3 +114,16 @@ function projectStatus(status) {
|
|
|
111
114
|
incomplete: status.incomplete,
|
|
112
115
|
});
|
|
113
116
|
}
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
createCaptainSessionStore as createSessionStore,
|
|
120
|
+
projectCaptainSessionStructure,
|
|
121
|
+
validateCaptainSessionExecutionProjection,
|
|
122
|
+
validateCaptainSessionStructuralProjection,
|
|
123
|
+
assertCaptainSessionExecutionCompatible,
|
|
124
|
+
} from './bin/session-store.js';
|
|
125
|
+
export {
|
|
126
|
+
validateSessionManifest,
|
|
127
|
+
validateSessionContext,
|
|
128
|
+
attachSessionHints,
|
|
129
|
+
} from './bin/portable-codec.js';
|
|
@@ -2847,7 +2847,7 @@ export function createXStatePlaybookRuntime(machine, spec) {
|
|
|
2847
2847
|
};
|
|
2848
2848
|
}
|
|
2849
2849
|
function detachedPlayerContinuation(roleId, playerId) {
|
|
2850
|
-
return snapshotJsonValue(
|
|
2850
|
+
return snapshotJsonValue({ v: 1, playerId: playerId ?? roleId }, `${label} deferred player continuation`);
|
|
2851
2851
|
}
|
|
2852
2852
|
function completionEvidenceFor(input, roleId, playerId, signal, operationId) {
|
|
2853
2853
|
return async (completion) => {
|
|
@@ -4979,6 +4979,15 @@ export function createXStatePlaybookRuntime(machine, spec) {
|
|
|
4979
4979
|
throw new Error(`${label} deferred continuation requires repository.runDeferred`);
|
|
4980
4980
|
}
|
|
4981
4981
|
const effectBoundary = continuationBoundarySeed(operation, turnId);
|
|
4982
|
+
const boundPlayerId = resolvedPlayerId(effectBoundary.roleId);
|
|
4983
|
+
const validateBinding = (value) => {
|
|
4984
|
+
if (!isPlainObject(value) || Object.keys(value).length !== 2 ||
|
|
4985
|
+
value.v !== 1 ||
|
|
4986
|
+
value.playerId !== (boundPlayerId ?? effectBoundary.roleId)) {
|
|
4987
|
+
throw new TypeError(`${label} bound deferred player continuation is invalid`);
|
|
4988
|
+
}
|
|
4989
|
+
};
|
|
4990
|
+
validateBinding(operation.playerContinuation);
|
|
4982
4991
|
const continuation = {
|
|
4983
4992
|
operationId: operation.operationId,
|
|
4984
4993
|
effectBoundary,
|
|
@@ -5004,18 +5013,8 @@ export function createXStatePlaybookRuntime(machine, spec) {
|
|
|
5004
5013
|
operationId: operation.operationId,
|
|
5005
5014
|
effectBoundary,
|
|
5006
5015
|
operation: async ({ playerContinuation }) => {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
: selectPlayerResume(effectBoundary.roleId, resolvedPlayerId(effectBoundary.roleId));
|
|
5010
|
-
if (selectedContinuation !== false &&
|
|
5011
|
-
(typeof selectedContinuation !== 'string' ||
|
|
5012
|
-
selectedContinuation.trim().length === 0)) {
|
|
5013
|
-
throw new TypeError(`${label} bound deferred player continuation is invalid`);
|
|
5014
|
-
}
|
|
5015
|
-
// Retained adoption owns a fresh Captain-session player ledger;
|
|
5016
|
-
// no source token becomes target ownership. Same-engagement
|
|
5017
|
-
// continuation still uses the exact durable binding.
|
|
5018
|
-
continuation.playerContinuation = selectedContinuation;
|
|
5016
|
+
validateBinding(playerContinuation);
|
|
5017
|
+
continuation.playerContinuation = selectPlayerResume(effectBoundary.roleId, boundPlayerId);
|
|
5019
5018
|
continuationStarted = true;
|
|
5020
5019
|
actor.send(event);
|
|
5021
5020
|
// The host has durably started this boundary and the FSM has
|
|
@@ -4523,7 +4523,7 @@ export function createXStatePlaybookRuntime<
|
|
|
4523
4523
|
playerId: string | undefined,
|
|
4524
4524
|
): JsonValue {
|
|
4525
4525
|
return snapshotJsonValue(
|
|
4526
|
-
|
|
4526
|
+
{ v: 1, playerId: playerId ?? roleId },
|
|
4527
4527
|
`${label} deferred player continuation`,
|
|
4528
4528
|
);
|
|
4529
4529
|
}
|
|
@@ -7324,6 +7324,15 @@ export function createXStatePlaybookRuntime<
|
|
|
7324
7324
|
);
|
|
7325
7325
|
}
|
|
7326
7326
|
const effectBoundary = continuationBoundarySeed(operation, turnId);
|
|
7327
|
+
const boundPlayerId = resolvedPlayerId(effectBoundary.roleId);
|
|
7328
|
+
const validateBinding = (value: unknown): void => {
|
|
7329
|
+
if (!isPlainObject(value) || Object.keys(value).length !== 2 ||
|
|
7330
|
+
value.v !== 1 ||
|
|
7331
|
+
value.playerId !== (boundPlayerId ?? effectBoundary.roleId)) {
|
|
7332
|
+
throw new TypeError(`${label} bound deferred player continuation is invalid`);
|
|
7333
|
+
}
|
|
7334
|
+
};
|
|
7335
|
+
validateBinding(operation.playerContinuation);
|
|
7327
7336
|
const continuation: NonNullable<typeof activeDeferredContinuation> = {
|
|
7328
7337
|
operationId: operation.operationId,
|
|
7329
7338
|
effectBoundary,
|
|
@@ -7349,26 +7358,10 @@ export function createXStatePlaybookRuntime<
|
|
|
7349
7358
|
operationId: operation.operationId,
|
|
7350
7359
|
effectBoundary,
|
|
7351
7360
|
operation: async ({ playerContinuation }) => {
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
effectBoundary.roleId,
|
|
7357
|
-
resolvedPlayerId(effectBoundary.roleId),
|
|
7358
|
-
);
|
|
7359
|
-
if (
|
|
7360
|
-
selectedContinuation !== false &&
|
|
7361
|
-
(typeof selectedContinuation !== 'string' ||
|
|
7362
|
-
selectedContinuation.trim().length === 0)
|
|
7363
|
-
) {
|
|
7364
|
-
throw new TypeError(
|
|
7365
|
-
`${label} bound deferred player continuation is invalid`,
|
|
7366
|
-
);
|
|
7367
|
-
}
|
|
7368
|
-
// Retained adoption owns a fresh Captain-session player ledger;
|
|
7369
|
-
// no source token becomes target ownership. Same-engagement
|
|
7370
|
-
// continuation still uses the exact durable binding.
|
|
7371
|
-
continuation.playerContinuation = selectedContinuation;
|
|
7361
|
+
validateBinding(playerContinuation);
|
|
7362
|
+
continuation.playerContinuation = selectPlayerResume(
|
|
7363
|
+
effectBoundary.roleId, boundPlayerId,
|
|
7364
|
+
);
|
|
7372
7365
|
continuationStarted = true;
|
|
7373
7366
|
actor!.send(event);
|
|
7374
7367
|
// The host has durably started this boundary and the FSM has
|