@llblab/pi-kit 0.24.1 → 0.26.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/AGENTS.md +1 -1
- package/BACKLOG.md +5 -1
- package/CHANGELOG.md +12 -0
- package/README.md +11 -8
- package/node_modules/@llblab/pi-actors/AGENTS.md +2 -0
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +4 -1
- package/node_modules/@llblab/pi-actors/LICENSE +21 -0
- package/node_modules/@llblab/pi-actors/README.md +1 -1
- package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +1 -1
- package/node_modules/@llblab/pi-actors/package.json +4 -3
- package/node_modules/@llblab/pi-claude-usage/AGENTS.md +23 -0
- package/node_modules/@llblab/pi-claude-usage/BACKLOG.md +4 -0
- package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +21 -0
- package/node_modules/@llblab/pi-claude-usage/LICENSE +22 -0
- package/node_modules/@llblab/pi-claude-usage/README.md +155 -0
- package/node_modules/@llblab/pi-claude-usage/banner.jpg +0 -0
- package/node_modules/@llblab/pi-claude-usage/index.ts +8 -0
- package/node_modules/@llblab/pi-claude-usage/lib/extension.ts +30 -0
- package/node_modules/@llblab/pi-claude-usage/lib/fast.ts +24 -0
- package/node_modules/@llblab/pi-claude-usage/lib/query.ts +146 -0
- package/node_modules/@llblab/pi-claude-usage/lib/status-format.ts +297 -0
- package/node_modules/@llblab/pi-claude-usage/lib/status.ts +366 -0
- package/node_modules/@llblab/pi-claude-usage/lib/telegram.ts +44 -0
- package/node_modules/@llblab/pi-claude-usage/lib/usage-store.ts +221 -0
- package/node_modules/@llblab/pi-claude-usage/lib/usage.ts +128 -0
- package/node_modules/@llblab/pi-claude-usage/package.json +64 -0
- package/node_modules/@llblab/pi-clean-room/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-clean-room/CHANGELOG.md +5 -0
- package/node_modules/@llblab/pi-clean-room/LICENSE +21 -0
- package/node_modules/@llblab/pi-clean-room/README.md +1 -1
- package/node_modules/@llblab/pi-clean-room/package.json +3 -2
- package/node_modules/@llblab/pi-codex-usage/AGENTS.md +9 -6
- package/node_modules/@llblab/pi-codex-usage/BACKLOG.md +2 -1
- package/node_modules/@llblab/pi-codex-usage/CHANGELOG.md +17 -0
- package/node_modules/@llblab/pi-codex-usage/README.md +75 -17
- package/node_modules/@llblab/pi-codex-usage/index.ts +8 -1602
- package/node_modules/@llblab/pi-codex-usage/lib/extension.ts +25 -0
- package/node_modules/@llblab/pi-codex-usage/lib/fast.ts +23 -0
- package/node_modules/@llblab/pi-codex-usage/lib/query.ts +368 -0
- package/node_modules/@llblab/pi-codex-usage/lib/status-format.ts +347 -0
- package/node_modules/@llblab/pi-codex-usage/lib/status.ts +435 -0
- package/node_modules/@llblab/pi-codex-usage/lib/telegram.ts +45 -0
- package/node_modules/@llblab/pi-codex-usage/lib/usage-store.ts +229 -0
- package/node_modules/@llblab/pi-codex-usage/lib/usage.ts +425 -0
- package/node_modules/@llblab/pi-codex-usage/package.json +11 -6
- package/node_modules/@llblab/pi-command-fast/AGENTS.md +7 -0
- package/node_modules/@llblab/pi-command-fast/BACKLOG.md +9 -0
- package/node_modules/@llblab/pi-command-fast/CHANGELOG.md +7 -0
- package/node_modules/@llblab/pi-command-fast/LICENSE +21 -0
- package/node_modules/@llblab/pi-command-fast/README.md +42 -0
- package/node_modules/@llblab/pi-command-fast/dist/command.d.ts +8 -0
- package/node_modules/@llblab/pi-command-fast/dist/command.js +52 -0
- package/node_modules/@llblab/pi-command-fast/dist/index.d.ts +3 -0
- package/node_modules/@llblab/pi-command-fast/dist/index.js +3 -0
- package/node_modules/@llblab/pi-command-fast/dist/models-json.d.ts +10 -0
- package/node_modules/@llblab/pi-command-fast/dist/models-json.js +81 -0
- package/node_modules/@llblab/pi-command-fast/package.json +49 -0
- package/node_modules/@llblab/pi-grow-loop/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -1
- package/node_modules/@llblab/pi-grow-loop/LICENSE +21 -0
- package/node_modules/@llblab/pi-grow-loop/README.md +1 -1
- package/node_modules/@llblab/pi-grow-loop/package.json +3 -2
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +43 -56
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +17 -3
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +25 -0
- package/node_modules/@llblab/pi-state-flow/LICENSE +21 -0
- package/node_modules/@llblab/pi-state-flow/README.md +18 -15
- package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/index.js +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.js +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.d.ts +7 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.js +16 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +9 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +5 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/continuation.js +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +7 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/episode.d.ts +3 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/episode.js +5 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.d.ts +3 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +503 -235
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.js +16 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.d.ts +11 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.js +6 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.d.ts +4 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +1 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.d.ts +4 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +13 -13
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +7 -6
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.js +9 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +3 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +17 -12
- package/node_modules/@llblab/pi-state-flow/dist/lib/session.d.ts +13 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/session.js +62 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +23 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +52 -20
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.d.ts +22 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.js +30 -10
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +5 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +19 -28
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +17 -15
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +52 -52
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +8 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +34 -18
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.d.ts +5 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +13 -19
- package/node_modules/@llblab/pi-state-flow/dist/package.json +12 -11
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/README.md +2 -1
- package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +72 -0
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +44 -36
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +14 -6
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +7 -5
- package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +6 -6
- package/node_modules/@llblab/pi-state-flow/docs/performance.md +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +13 -12
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +37 -33
- package/node_modules/@llblab/pi-state-flow/index.ts +3 -2
- package/node_modules/@llblab/pi-state-flow/lib/compaction.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/lib/config.ts +20 -10
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +15 -14
- package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/durable.ts +8 -6
- package/node_modules/@llblab/pi-state-flow/lib/episode.ts +6 -6
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +484 -232
- package/node_modules/@llblab/pi-state-flow/lib/git.ts +14 -5
- package/node_modules/@llblab/pi-state-flow/lib/history.ts +16 -11
- package/node_modules/@llblab/pi-state-flow/lib/logging.ts +5 -1
- package/node_modules/@llblab/pi-state-flow/lib/query.ts +16 -16
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +11 -11
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +19 -13
- package/node_modules/@llblab/pi-state-flow/lib/session.ts +57 -3
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +57 -22
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +46 -13
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +23 -32
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +66 -65
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +39 -19
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +19 -27
- package/node_modules/@llblab/pi-state-flow/package.json +12 -11
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +2 -2
- package/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/node_modules/jsonc-parser/LICENSE.md +21 -0
- package/node_modules/jsonc-parser/README.md +364 -0
- package/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/node_modules/jsonc-parser/lib/esm/impl/edit.js +185 -0
- package/node_modules/jsonc-parser/lib/esm/impl/format.js +261 -0
- package/node_modules/jsonc-parser/lib/esm/impl/parser.js +659 -0
- package/node_modules/jsonc-parser/lib/esm/impl/scanner.js +443 -0
- package/node_modules/jsonc-parser/lib/esm/impl/string-intern.js +29 -0
- package/node_modules/jsonc-parser/lib/esm/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/esm/main.js +178 -0
- package/node_modules/jsonc-parser/lib/umd/impl/edit.js +201 -0
- package/node_modules/jsonc-parser/lib/umd/impl/format.js +275 -0
- package/node_modules/jsonc-parser/lib/umd/impl/parser.js +682 -0
- package/node_modules/jsonc-parser/lib/umd/impl/scanner.js +456 -0
- package/node_modules/jsonc-parser/lib/umd/impl/string-intern.js +42 -0
- package/node_modules/jsonc-parser/lib/umd/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/umd/main.js +194 -0
- package/node_modules/jsonc-parser/package.json +37 -0
- package/package.json +10 -6
|
@@ -7,9 +7,19 @@ export declare class RevisionUnavailableError extends Error {
|
|
|
7
7
|
/** Expired history cannot be restored, but explicit activation may use validated current memory. */
|
|
8
8
|
export declare class HistoryBoundaryExpiredError extends RevisionUnavailableError {
|
|
9
9
|
}
|
|
10
|
+
export type StateFlowMode = "active" | "passive" | "off";
|
|
11
|
+
export type InactiveMode = Exclude<StateFlowMode, "active">;
|
|
12
|
+
export declare function isStateFlowMode(value: unknown): value is StateFlowMode;
|
|
13
|
+
/** The session's selected mode is the only serialized behavior switch. */
|
|
10
14
|
export interface SnapshotConfig {
|
|
11
|
-
|
|
15
|
+
mode: StateFlowMode;
|
|
12
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Read only mode policy, without validating or accessing semantic checkpoint metadata.
|
|
19
|
+
* Missing/invalid policy stays undecided; callers must not treat this as restoration proof.
|
|
20
|
+
* Legacy `enabled:false` follows the caller's inactive policy.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readCheckpointMode(value: unknown, inactiveMode?: InactiveMode): StateFlowMode | undefined;
|
|
13
23
|
interface LegacyValidationFeedback {
|
|
14
24
|
attempt: number;
|
|
15
25
|
error: string;
|
|
@@ -52,23 +62,28 @@ export declare function serializeSessionRuntime(runtime: SessionRuntime, cwd: st
|
|
|
52
62
|
config: string;
|
|
53
63
|
runtime: string;
|
|
54
64
|
};
|
|
65
|
+
/** Legacy `enabled:false` decodes as non-active; native checkpoints, not this file, select branch policy. */
|
|
55
66
|
export declare function parseSessionRuntime(config: string | undefined, runtimeSource: string | undefined, cwd: string, sessionId: string): SessionRuntime | undefined;
|
|
56
|
-
export declare function emptySnapshot(
|
|
67
|
+
export declare function emptySnapshot(mode?: StateFlowMode): Snapshot;
|
|
57
68
|
export type RetainedBoundaryCheckpoint = {
|
|
58
69
|
boundary: string;
|
|
59
|
-
|
|
70
|
+
mode: StateFlowMode;
|
|
60
71
|
step: number;
|
|
61
72
|
bootstrap?: true;
|
|
62
73
|
specification?: string;
|
|
63
74
|
};
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
/** A proven pre-runtime branch retains only its explicit inactive choice, never semantic storage. */
|
|
76
|
+
export type PreRuntimeCheckpoint = {
|
|
77
|
+
mode: InactiveMode;
|
|
66
78
|
};
|
|
79
|
+
export type RetainedPiCheckpoint = RetainedBoundaryCheckpoint | PreRuntimeCheckpoint;
|
|
67
80
|
export type FileRevision = `file:${string}`;
|
|
68
81
|
export declare function isFileRevision(value: unknown): value is FileRevision;
|
|
69
82
|
/** Encode branch lifecycle against one retained temporal identity without semantic or backup data. */
|
|
70
83
|
export declare function retainedBoundaryCheckpoint(snapshot: Snapshot, boundary: string): RetainedBoundaryCheckpoint;
|
|
71
|
-
/**
|
|
72
|
-
export declare function
|
|
73
|
-
|
|
84
|
+
/** Encode an explicit inactive choice on a branch that has no accepted runtime. */
|
|
85
|
+
export declare function preRuntimeCheckpoint(mode: StateFlowMode): PreRuntimeCheckpoint;
|
|
86
|
+
/** Decode the retained-window checkpoint contract; legacy `enabled`/`{disabled:true}` markers map through `inactiveMode`. */
|
|
87
|
+
export declare function parseRetainedPiCheckpoint(value: unknown, inactiveMode?: InactiveMode): RetainedPiCheckpoint;
|
|
88
|
+
export declare function migrationFailure(data: JsonObject, error: string, mode?: InactiveMode): Snapshot;
|
|
74
89
|
export {};
|
|
@@ -11,6 +11,21 @@ export class RevisionUnavailableError extends Error {
|
|
|
11
11
|
/** Expired history cannot be restored, but explicit activation may use validated current memory. */
|
|
12
12
|
export class HistoryBoundaryExpiredError extends RevisionUnavailableError {
|
|
13
13
|
}
|
|
14
|
+
export function isStateFlowMode(value) {
|
|
15
|
+
return value === "active" || value === "passive" || value === "off";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Read only mode policy, without validating or accessing semantic checkpoint metadata.
|
|
19
|
+
* Missing/invalid policy stays undecided; callers must not treat this as restoration proof.
|
|
20
|
+
* Legacy `enabled:false` follows the caller's inactive policy.
|
|
21
|
+
*/
|
|
22
|
+
export function readCheckpointMode(value, inactiveMode = "passive") {
|
|
23
|
+
if (!isObject(value))
|
|
24
|
+
return undefined;
|
|
25
|
+
if (Object.hasOwn(value, "mode"))
|
|
26
|
+
return Object.hasOwn(value, "enabled") || !isStateFlowMode(value.mode) ? undefined : value.mode;
|
|
27
|
+
return typeof value.enabled === "boolean" ? value.enabled ? "active" : inactiveMode : undefined;
|
|
28
|
+
}
|
|
14
29
|
export function validateSessionRuntime(value, cwd, sessionId) {
|
|
15
30
|
if (!isJsonValue(value) || !isObject(value) || Object.keys(value).sort().join(",") !== "config,meta"
|
|
16
31
|
|| !isObject(value.config) || !isObject(value.meta))
|
|
@@ -31,7 +46,7 @@ export function validateSessionRuntime(value, cwd, sessionId) {
|
|
|
31
46
|
}
|
|
32
47
|
const runtimeFields = Object.fromEntries(Object.entries(fields).filter(([key]) => known.has(key)));
|
|
33
48
|
const normalized = {
|
|
34
|
-
config: {
|
|
49
|
+
config: { mode: isStateFlowMode(value.config.mode) ? value.config.mode : "off" },
|
|
35
50
|
meta: restoredMeta(runtimeFields),
|
|
36
51
|
};
|
|
37
52
|
if (runtimeFields.bootstrap === false)
|
|
@@ -61,6 +76,7 @@ export function serializeSessionRuntime(runtime, cwd, sessionId) {
|
|
|
61
76
|
const { temporal: _retiredTemporal, artifacts: _legacyArtifacts, ...runtimeMeta } = runtime.meta;
|
|
62
77
|
return { config: `${canonicalJson(runtime.config)}\n`, runtime: `${canonicalJson(runtimeMeta)}\n` };
|
|
63
78
|
}
|
|
79
|
+
/** Legacy `enabled:false` decodes as non-active; native checkpoints, not this file, select branch policy. */
|
|
64
80
|
export function parseSessionRuntime(config, runtimeSource, cwd, sessionId) {
|
|
65
81
|
if (config === undefined && runtimeSource === undefined)
|
|
66
82
|
return undefined;
|
|
@@ -68,14 +84,20 @@ export function parseSessionRuntime(config, runtimeSource, cwd, sessionId) {
|
|
|
68
84
|
throw new Error("Incomplete State Flow config/runtime pair");
|
|
69
85
|
let runtime;
|
|
70
86
|
try {
|
|
71
|
-
|
|
87
|
+
const settings = JSON.parse(config);
|
|
88
|
+
const mode = isObject(settings) && Object.keys(settings).length === 1 ? readCheckpointMode(settings, "passive") : undefined;
|
|
89
|
+
if (mode === undefined)
|
|
90
|
+
throw new Error("Invalid State Flow runtime configuration or counters");
|
|
91
|
+
runtime = { config: { mode }, meta: JSON.parse(runtimeSource) };
|
|
72
92
|
}
|
|
73
|
-
catch {
|
|
74
|
-
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (error instanceof SyntaxError)
|
|
95
|
+
throw new Error("State Flow session runtime contains invalid JSON");
|
|
96
|
+
throw error;
|
|
75
97
|
}
|
|
76
98
|
validateSessionRuntime(runtime, cwd, sessionId);
|
|
77
99
|
const { temporal: _legacyTemporal, ...runtimeMeta } = runtime.meta;
|
|
78
|
-
return { config: {
|
|
100
|
+
return { config: { mode: runtime.config.mode }, meta: runtimeMeta };
|
|
79
101
|
}
|
|
80
102
|
function restoredStep(value) {
|
|
81
103
|
return typeof value === "number"
|
|
@@ -109,11 +131,11 @@ function restoredMeta(value, legacy = {}) {
|
|
|
109
131
|
...(meta.bootstrap === true ? { bootstrap: true } : {}),
|
|
110
132
|
};
|
|
111
133
|
}
|
|
112
|
-
function envelope(
|
|
113
|
-
return { config: {
|
|
134
|
+
function envelope(mode, meta) {
|
|
135
|
+
return { config: { mode }, meta };
|
|
114
136
|
}
|
|
115
|
-
export function emptySnapshot(
|
|
116
|
-
return envelope(
|
|
137
|
+
export function emptySnapshot(mode = "passive") {
|
|
138
|
+
return envelope(mode, { step: 0 });
|
|
117
139
|
}
|
|
118
140
|
export function isFileRevision(value) {
|
|
119
141
|
return typeof value === "string" && /^file:[0-9a-f]{64}$/.test(value);
|
|
@@ -124,23 +146,33 @@ export function retainedBoundaryCheckpoint(snapshot, boundary) {
|
|
|
124
146
|
throw new Error("Checkpoint requires a retained temporal boundary identity");
|
|
125
147
|
const checkpoint = {
|
|
126
148
|
boundary,
|
|
127
|
-
|
|
149
|
+
mode: snapshot.config.mode,
|
|
128
150
|
step: snapshot.meta.step,
|
|
129
151
|
...(snapshot.meta.bootstrap === true ? { bootstrap: true } : {}),
|
|
130
152
|
...(snapshot.meta.specification === undefined ? {} : { specification: snapshot.meta.specification }),
|
|
131
153
|
};
|
|
132
154
|
return parseRetainedPiCheckpoint(checkpoint);
|
|
133
155
|
}
|
|
134
|
-
/**
|
|
135
|
-
export function
|
|
156
|
+
/** Encode an explicit inactive choice on a branch that has no accepted runtime. */
|
|
157
|
+
export function preRuntimeCheckpoint(mode) {
|
|
158
|
+
if (mode === "active")
|
|
159
|
+
throw new Error("An active State Flow branch requires a retained semantic boundary");
|
|
160
|
+
return { mode };
|
|
161
|
+
}
|
|
162
|
+
/** Decode the retained-window checkpoint contract; legacy `enabled`/`{disabled:true}` markers map through `inactiveMode`. */
|
|
163
|
+
export function parseRetainedPiCheckpoint(value, inactiveMode = "passive") {
|
|
136
164
|
if (!isObject(value))
|
|
137
165
|
throw new Error("Invalid State Flow retained-boundary checkpoint");
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (
|
|
166
|
+
const keys = Object.keys(value);
|
|
167
|
+
if (keys.length === 1 && value.disabled === true)
|
|
168
|
+
return { mode: inactiveMode };
|
|
169
|
+
if (keys.length === 1 && (value.mode === "passive" || value.mode === "off"))
|
|
170
|
+
return { mode: value.mode };
|
|
171
|
+
const allowed = new Set(["boundary", "mode", "enabled", "step", "bootstrap", "specification"]);
|
|
172
|
+
const mode = readCheckpointMode(value, inactiveMode);
|
|
173
|
+
if (keys.some((key) => !allowed.has(key))
|
|
142
174
|
|| typeof value.boundary !== "string" || value.boundary.trim().length === 0
|
|
143
|
-
||
|
|
175
|
+
|| mode === undefined
|
|
144
176
|
|| !Number.isSafeInteger(value.step) || value.step < 0 || value.step > MAX_RESTORED_STEP
|
|
145
177
|
|| (value.bootstrap !== undefined && value.bootstrap !== true)
|
|
146
178
|
|| (value.specification !== undefined && typeof value.specification !== "string")) {
|
|
@@ -148,18 +180,18 @@ export function parseRetainedPiCheckpoint(value) {
|
|
|
148
180
|
}
|
|
149
181
|
return {
|
|
150
182
|
boundary: value.boundary,
|
|
151
|
-
|
|
183
|
+
mode,
|
|
152
184
|
step: value.step,
|
|
153
185
|
...(value.bootstrap === true ? { bootstrap: true } : {}),
|
|
154
186
|
...(typeof value.specification === "string" ? { specification: value.specification } : {}),
|
|
155
187
|
};
|
|
156
188
|
}
|
|
157
|
-
export function migrationFailure(data, error) {
|
|
189
|
+
export function migrationFailure(data, error, mode = "passive") {
|
|
158
190
|
const meta = restoredMeta(data.meta, data);
|
|
159
191
|
meta.validation = {
|
|
160
192
|
attempt: 0,
|
|
161
193
|
error,
|
|
162
194
|
instruction: "Start a fresh State Flow episode; null is reserved for patch deletion.",
|
|
163
195
|
};
|
|
164
|
-
return envelope(
|
|
196
|
+
return envelope(mode, meta);
|
|
165
197
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ArtifactCompilationUpdate, type ArtifactModelHints, type ArtifactRegistry } from "./artifact.ts";
|
|
2
2
|
import { type JsonObject } from "./json.ts";
|
|
3
|
-
/**
|
|
3
|
+
/** Runtime defaults for documented semantic planes; stored objects may omit them or retain other fields. */
|
|
4
4
|
export type MaterializedState = JsonObject & {
|
|
5
5
|
intents: JsonObject;
|
|
6
6
|
contract: JsonObject;
|
|
@@ -9,6 +9,16 @@ export type MaterializedState = JsonObject & {
|
|
|
9
9
|
response: string;
|
|
10
10
|
lazy: JsonObject;
|
|
11
11
|
};
|
|
12
|
+
/** Sparse semantic state: documented planes may be absent. Disk codecs select only known fields. */
|
|
13
|
+
export type SemanticState = JsonObject & Partial<{
|
|
14
|
+
intents: JsonObject;
|
|
15
|
+
contract: JsonObject;
|
|
16
|
+
working: JsonObject;
|
|
17
|
+
artifacts: ArtifactRegistry;
|
|
18
|
+
response: string;
|
|
19
|
+
lazy: JsonObject;
|
|
20
|
+
}>;
|
|
21
|
+
export type ScopedSemanticStates = Record<StateScope, SemanticState>;
|
|
12
22
|
/** Compatibility name for callers that still treat materialized state as a document. */
|
|
13
23
|
export type StateDocument = MaterializedState;
|
|
14
24
|
/** Model patch shape; artifact entries may be compiler outputs before trusted metadata is attached. */
|
|
@@ -52,11 +62,14 @@ export interface ScopedStates {
|
|
|
52
62
|
}
|
|
53
63
|
export declare function emptyState(): MaterializedState;
|
|
54
64
|
export declare function isMaterializedState(value: unknown): value is MaterializedState;
|
|
65
|
+
/** Missing planes are valid storage, not missing authority. Present values retain their type checks. */
|
|
66
|
+
export declare function isSemanticState(value: unknown): value is SemanticState;
|
|
55
67
|
export declare const isStateDocument: typeof isMaterializedState;
|
|
56
68
|
/** Atomically replace compiled and removed artifacts inside one materialized scope. */
|
|
57
69
|
export declare function updateMaterializedArtifacts(state: MaterializedState, updates: readonly ArtifactCompilationUpdate[], removed?: readonly string[]): MaterializedState;
|
|
58
70
|
/** Overlay lower-to-higher scopes without mutating any scope document. */
|
|
59
|
-
export declare function overlayStates(...scopes: readonly
|
|
71
|
+
export declare function overlayStates(...scopes: readonly JsonObject[]): MaterializedState;
|
|
72
|
+
/** Default-bearing SDK compatibility view; model transport uses sparse SemanticState instead. */
|
|
60
73
|
export type ModelState = JsonObject & {
|
|
61
74
|
intents: JsonObject;
|
|
62
75
|
contract: JsonObject;
|
|
@@ -64,5 +77,11 @@ export type ModelState = JsonObject & {
|
|
|
64
77
|
artifacts: ArtifactRegistry;
|
|
65
78
|
response: string;
|
|
66
79
|
};
|
|
80
|
+
/** Select only owned top-level fields, preserving nested data and replay deletion markers. */
|
|
81
|
+
export declare function selectSemanticFields(value: JsonObject): JsonObject;
|
|
82
|
+
/** Read only documented, present planes; empty responses carry no semantic value. */
|
|
83
|
+
export declare function projectSemanticState(state: JsonObject): SemanticState;
|
|
84
|
+
/** Preserve deletion meaning in visible history without exposing ignored fields or empty responses. */
|
|
85
|
+
export declare function projectSemanticPatch(patch: JsonObject): JsonObject;
|
|
67
86
|
/** Model-visible projection: lazy bodies and runtime artifact bookkeeping stay out of ordinary context. */
|
|
68
|
-
export declare function projectStateForModel(state:
|
|
87
|
+
export declare function projectStateForModel(state: SemanticState, artifactHints?: ArtifactModelHints): SemanticState;
|
|
@@ -10,8 +10,11 @@ export function isMaterializedState(value) {
|
|
|
10
10
|
&& isObject(value.working)
|
|
11
11
|
&& isObject(value.intents)
|
|
12
12
|
&& typeof value.response === "string"
|
|
13
|
-
&& isObject(value.lazy)
|
|
14
|
-
|
|
13
|
+
&& isObject(value.lazy);
|
|
14
|
+
}
|
|
15
|
+
/** Missing planes are valid storage, not missing authority. Present values retain their type checks. */
|
|
16
|
+
export function isSemanticState(value) {
|
|
17
|
+
return isObject(value) && isMaterializedState({ ...emptyState(), ...value });
|
|
15
18
|
}
|
|
16
19
|
export const isStateDocument = isMaterializedState;
|
|
17
20
|
/** Atomically replace compiled and removed artifacts inside one materialized scope. */
|
|
@@ -27,14 +30,31 @@ export function overlayStates(...scopes) {
|
|
|
27
30
|
return applyPatch(effective, scope);
|
|
28
31
|
}, emptyState());
|
|
29
32
|
}
|
|
33
|
+
/** Select only owned top-level fields, preserving nested data and replay deletion markers. */
|
|
34
|
+
export function selectSemanticFields(value) {
|
|
35
|
+
return structuredClone(Object.fromEntries(Object.keys(emptyState())
|
|
36
|
+
.filter((key) => Object.hasOwn(value, key))
|
|
37
|
+
.map((key) => [key, value[key]])));
|
|
38
|
+
}
|
|
39
|
+
/** Read only documented, present planes; empty responses carry no semantic value. */
|
|
40
|
+
export function projectSemanticState(state) {
|
|
41
|
+
const projected = selectSemanticFields(state);
|
|
42
|
+
if (projected.response === "")
|
|
43
|
+
delete projected.response;
|
|
44
|
+
return projected;
|
|
45
|
+
}
|
|
46
|
+
/** Preserve deletion meaning in visible history without exposing ignored fields or empty responses. */
|
|
47
|
+
export function projectSemanticPatch(patch) {
|
|
48
|
+
const projected = selectSemanticFields(patch);
|
|
49
|
+
if (projected.response === "")
|
|
50
|
+
projected.response = null;
|
|
51
|
+
return projected;
|
|
52
|
+
}
|
|
30
53
|
/** Model-visible projection: lazy bodies and runtime artifact bookkeeping stay out of ordinary context. */
|
|
31
54
|
export function projectStateForModel(state, artifactHints = {}) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
artifacts: projectArtifactsForModel(cloned.artifacts, artifactHints),
|
|
38
|
-
response: cloned.response,
|
|
39
|
-
};
|
|
55
|
+
const { lazy: _hidden, ...visible } = state;
|
|
56
|
+
const projected = projectSemanticState(visible);
|
|
57
|
+
if (projected.artifacts)
|
|
58
|
+
projected.artifacts = projectArtifactsForModel(projected.artifacts, artifactHints);
|
|
59
|
+
return projected;
|
|
40
60
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ArtifactInvalidationReason } from "./artifact.ts";
|
|
2
|
-
import {
|
|
2
|
+
import type { RecentTransitionWindow } from "./history.ts";
|
|
3
3
|
import type { Snapshot } from "./snapshot.ts";
|
|
4
|
-
import { type ScopedStates, type StateScope } from "./state.ts";
|
|
4
|
+
import { type SemanticState, type ScopedStates, type StateScope } from "./state.ts";
|
|
5
5
|
import type { ScopeRevisions, TransitionBoundary } from "./temporal.ts";
|
|
6
6
|
export declare const STATUS_KEY = "state-flow";
|
|
7
7
|
export type Colorize = (color: "accent" | "dim", text: string) => string;
|
|
@@ -16,6 +16,8 @@ export interface StatusDiagnostics {
|
|
|
16
16
|
cwdScopeKey: string;
|
|
17
17
|
sessionScopeKey: string;
|
|
18
18
|
scopeStates: ScopedStates;
|
|
19
|
+
/** Overlay raw scopes before defaults so absent scalar planes cannot mask lower scopes. */
|
|
20
|
+
effectiveState?: SemanticState;
|
|
19
21
|
recent: RecentTransitionWindow;
|
|
20
22
|
historyLimit: number;
|
|
21
23
|
temporal?: {
|
|
@@ -29,5 +31,5 @@ export interface StatusDiagnostics {
|
|
|
29
31
|
publicationError?: string;
|
|
30
32
|
}
|
|
31
33
|
export declare function formatScopeRevisionVector(revisions: ScopeRevisions): string;
|
|
32
|
-
export declare function compactStatus(snapshot: Snapshot,
|
|
34
|
+
export declare function compactStatus(snapshot: Snapshot, _revisions: ScopeRevisions, colorize: Colorize): string | undefined;
|
|
33
35
|
export declare function detailedStatus(snapshot: Snapshot, diagnostics: StatusDiagnostics): string;
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import { projectRecentTransitionsWithLimit } from "./history.js";
|
|
2
|
-
import { retainedMemoryScopes } from "./memory.js";
|
|
3
1
|
import { conciseDiagnostic } from "./protocol.js";
|
|
4
|
-
import { overlayStates } from "./state.js";
|
|
2
|
+
import { overlayStates, projectSemanticState } from "./state.js";
|
|
5
3
|
export const STATUS_KEY = "state-flow";
|
|
6
4
|
export function formatScopeRevisionVector(revisions) {
|
|
7
|
-
return `
|
|
5
|
+
return `g${revisions.global}c${revisions.cwd}s${revisions.session}`;
|
|
8
6
|
}
|
|
9
|
-
export function compactStatus(snapshot,
|
|
10
|
-
|
|
7
|
+
export function compactStatus(snapshot, _revisions, colorize) {
|
|
8
|
+
const { mode } = snapshot.config;
|
|
9
|
+
if (mode === "off")
|
|
11
10
|
return undefined;
|
|
12
|
-
return `${colorize("accent", "state-flow")} ${colorize("dim",
|
|
11
|
+
return `${colorize("accent", "state-flow")} ${colorize("dim", mode)}`;
|
|
13
12
|
}
|
|
14
13
|
function countArtifacts(states, scope) {
|
|
15
14
|
return Object.keys(states[scope].artifacts).length;
|
|
16
15
|
}
|
|
17
16
|
export function detailedStatus(snapshot, diagnostics) {
|
|
18
|
-
const projectedRecent = projectRecentTransitionsWithLimit(diagnostics.historyLimit, diagnostics.recent);
|
|
19
17
|
const available = diagnostics.temporal !== undefined && diagnostics.durableStateError === undefined;
|
|
20
|
-
const materialized = !available ? undefined : overlayStates(diagnostics.scopeStates.global, diagnostics.scopeStates.cwd, diagnostics.scopeStates.session);
|
|
21
|
-
|
|
18
|
+
const materialized = !available ? undefined : diagnostics.effectiveState ?? projectSemanticState(overlayStates(diagnostics.scopeStates.global, diagnostics.scopeStates.cwd, diagnostics.scopeStates.session));
|
|
19
|
+
// Only top-level plane boundaries gain whitespace; nested user JSON stays unchanged.
|
|
20
|
+
const stateJson = materialized === undefined ? undefined : JSON.stringify(materialized, null, 2).replace(/,\n(?= ")/g, ",\n\n");
|
|
22
21
|
const invalidated = available ? String(diagnostics.staleArtifacts.length) : "unavailable";
|
|
23
22
|
const invalidationLines = diagnostics.staleArtifacts.length === 0
|
|
24
|
-
? [
|
|
23
|
+
? []
|
|
25
24
|
: [
|
|
26
25
|
"Pending artifact invalidations:",
|
|
27
26
|
...diagnostics.staleArtifacts.map(({ scope, path, reason }) => `- [${scope}] ${path} — ${reason}`),
|
|
@@ -29,29 +28,21 @@ export function detailedStatus(snapshot, diagnostics) {
|
|
|
29
28
|
const temporal = available ? diagnostics.temporal : undefined;
|
|
30
29
|
const temporalLines = temporal === undefined
|
|
31
30
|
? [`Temporal materialization unavailable: ${conciseDiagnostic(diagnostics.durableStateError ?? "no selected branch runtime")}`,
|
|
32
|
-
`Hot history: unavailable; configured maximum depth ${diagnostics.historyLimit}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const artifacts = (scope) => available ? countArtifacts(diagnostics.scopeStates, scope) : "unknown";
|
|
39
|
-
const memoryScopes = available ? retainedMemoryScopes(diagnostics.scopeStates) : undefined;
|
|
31
|
+
`Hot history: unavailable; configured maximum depth ${diagnostics.historyLimit}`]
|
|
32
|
+
: [`Scope revisions: ${formatScopeRevisionVector(temporal.revisions)}`,
|
|
33
|
+
`Runtime metadata: step #${snapshot.meta.step}${snapshot.meta.bootstrap ? "; bootstrap" : ""}`,
|
|
34
|
+
`Hot history: offsets 0..${temporal.historyDepth}; maximum depth ${diagnostics.historyLimit}`];
|
|
35
|
+
const artifacts = (scope) => countArtifacts(diagnostics.scopeStates, scope);
|
|
36
|
+
const hasArtifacts = available && ["global", "cwd", "session"].some((scope) => artifacts(scope) > 0);
|
|
40
37
|
return [
|
|
41
|
-
`State Flow diagnostics — config.enabled=${snapshot.config.enabled}; branch mode=${snapshot.config.enabled ? "active" : "inactive"}`,
|
|
42
38
|
`Repository: ${diagnostics.repositoryRoot}`,
|
|
43
39
|
`Scope keys: CWD ${diagnostics.cwdScopeKey}; session ${diagnostics.sessionScopeKey}`,
|
|
44
|
-
"Session files: config.json owns behavior; runtime.json owns branch recovery; meta.json owns scope provenance",
|
|
45
|
-
`Runtime metadata: step #${snapshot.meta.step}; bootstrap ${snapshot.meta.bootstrap === true}`,
|
|
46
|
-
"Memory: owner state-flow; global retention enabled; global fallback active",
|
|
47
|
-
`Memory-bearing scopes: global ${memoryScopes?.global ?? "unknown"}; CWD ${memoryScopes?.cwd ?? "unknown"}; session ${memoryScopes?.session ?? "unknown"}`,
|
|
48
40
|
...temporalLines,
|
|
49
|
-
...(diagnostics.publicationError === undefined ? [] : [`Memory writes paused after
|
|
50
|
-
`Artifacts: global ${artifacts("global")}; CWD ${artifacts("cwd")}; session ${artifacts("session")}; pending invalidations ${invalidated}
|
|
51
|
-
available ? `Recent transitions: global ${diagnostics.recent.filter(({ transitions }) => transitions.some(({ scope }) => scope === "global")).length}; CWD ${diagnostics.recent.filter(({ transitions }) => transitions.some(({ scope }) => scope === "cwd")).length}; session ${diagnostics.recent.filter(({ transitions }) => transitions.some(({ scope }) => scope === "session")).length}; active ${projectedRecent.length}` : "Recent transitions: unavailable",
|
|
41
|
+
...(diagnostics.publicationError === undefined ? [] : [`Memory writes paused after mode change: ${conciseDiagnostic(diagnostics.publicationError)}`]),
|
|
42
|
+
...(hasArtifacts ? [`Artifacts: global ${artifacts("global")}; CWD ${artifacts("cwd")}; session ${artifacts("session")}; pending invalidations ${invalidated}`] : []),
|
|
52
43
|
...invalidationLines,
|
|
53
44
|
...(stateJson === undefined
|
|
54
45
|
? ["Effective memory: unavailable"]
|
|
55
|
-
: [
|
|
46
|
+
: ["Effective memory:", "", stateJson]),
|
|
56
47
|
].join("\n");
|
|
57
48
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { StateFlowMode } from "./snapshot.ts";
|
|
1
2
|
import type { ScopeRevisions } from "./temporal.ts";
|
|
2
3
|
export declare const STATE_FLOW_TELEGRAM_ID = "@llblab/pi-state-flow";
|
|
3
4
|
/** Resolve the package export or the compiled sibling-extension layout used in local development. */
|
|
4
5
|
export declare function stateFlowTelegramSectionSpecifiers(moduleUrl?: string): string[];
|
|
5
6
|
export interface StateFlowTelegramSnapshot {
|
|
6
|
-
|
|
7
|
+
/** The current session's selected mode. */
|
|
8
|
+
mode: StateFlowMode;
|
|
7
9
|
/** Legacy branch step retained for existing adapter ports; current runtime ports also supply owner revisions. */
|
|
8
10
|
step: number;
|
|
9
11
|
revisions?: ScopeRevisions;
|
|
@@ -12,11 +14,11 @@ export interface StateFlowTelegramSnapshot {
|
|
|
12
14
|
}
|
|
13
15
|
export type StateFlowTelegramScope = "global" | "cwd" | "session" | "effective";
|
|
14
16
|
export interface StateFlowTelegramState {
|
|
15
|
-
artifacts
|
|
16
|
-
contract
|
|
17
|
-
working
|
|
18
|
-
intents
|
|
19
|
-
response
|
|
17
|
+
artifacts?: Record<string, unknown>;
|
|
18
|
+
contract?: Record<string, unknown>;
|
|
19
|
+
working?: Record<string, unknown>;
|
|
20
|
+
intents?: Record<string, unknown>;
|
|
21
|
+
response?: string;
|
|
20
22
|
lazy?: unknown;
|
|
21
23
|
}
|
|
22
24
|
export type StateFlowTelegramRichText = string | StateFlowTelegramRichText[] | {
|
|
@@ -92,26 +94,26 @@ export interface StateFlowTelegramPort {
|
|
|
92
94
|
state(scope: StateFlowTelegramScope): StateFlowTelegramState;
|
|
93
95
|
/** Optional additive capability; absent legacy ports retain their branch-step presentation. */
|
|
94
96
|
revisions?(): ScopeRevisions;
|
|
97
|
+
/** Active may need a settled native boundary; inactive modes apply immediately. */
|
|
95
98
|
canStartNow(): boolean;
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
/** Select the current session's mode through the same lifecycle owners as the terminal commands. */
|
|
100
|
+
select(mode: StateFlowMode): StateFlowTelegramControlResult;
|
|
98
101
|
deferStart(): void;
|
|
99
102
|
cancelStart(): void;
|
|
100
103
|
}
|
|
101
|
-
export interface StateFlowTelegramInspectionPort extends Omit<StateFlowTelegramPort, "state" | "revisions" | "
|
|
104
|
+
export interface StateFlowTelegramInspectionPort extends Omit<StateFlowTelegramPort, "state" | "revisions" | "select"> {
|
|
102
105
|
inspect(scope: StateFlowTelegramScope): StateFlowTelegramInspection | Promise<StateFlowTelegramInspection>;
|
|
103
|
-
|
|
104
|
-
stop(): StateFlowTelegramControlResult | Promise<StateFlowTelegramControlResult>;
|
|
106
|
+
select(mode: StateFlowMode): StateFlowTelegramControlResult | Promise<StateFlowTelegramControlResult>;
|
|
105
107
|
}
|
|
106
108
|
export interface StateFlowTelegramAdapter {
|
|
107
109
|
ensure(): Promise<boolean>;
|
|
108
110
|
dispose(): void;
|
|
109
111
|
}
|
|
110
|
-
/** Main-menu section label
|
|
112
|
+
/** Main-menu section label shows only the current session mode. */
|
|
111
113
|
export declare function formatStateFlowSectionLabel(snapshot: StateFlowTelegramSnapshot): string;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
export declare function
|
|
114
|
+
export declare const STATE_FLOW_MODES: readonly ["off", "passive", "active"];
|
|
115
|
+
/** One radio-style mode row followed directly by read-only scope actions. */
|
|
116
|
+
export declare function buildStateFlowSectionView(snapshot: StateFlowTelegramSnapshot, callbackData: (action: string, payload?: string) => string): StateFlowTelegramView;
|
|
115
117
|
export declare function renderStateFlowRichState(scope: StateFlowTelegramScope, revisions: ScopeRevisions, state: StateFlowTelegramState): StateFlowTelegramRichMessage;
|
|
116
118
|
/** Default loader; injectable so tests and embedded hosts can control transport presence. */
|
|
117
119
|
export declare function loadStateFlowTelegramModules(): Promise<StateFlowTelegramModules>;
|