@llblab/pi-kit 0.24.0 → 0.25.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/CHANGELOG.md +10 -0
- package/README.md +6 -5
- package/node_modules/@llblab/pi-claude-usage/AGENTS.md +20 -0
- package/node_modules/@llblab/pi-claude-usage/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +13 -0
- package/node_modules/@llblab/pi-claude-usage/LICENSE +22 -0
- package/node_modules/@llblab/pi-claude-usage/README.md +110 -0
- package/node_modules/@llblab/pi-claude-usage/banner.jpg +0 -0
- package/node_modules/@llblab/pi-claude-usage/index.ts +1159 -0
- package/node_modules/@llblab/pi-claude-usage/package.json +60 -0
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +42 -56
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +16 -3
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +19 -0
- package/node_modules/@llblab/pi-state-flow/README.md +15 -12
- 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/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 +275 -199
- 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 +4 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/session.js +2 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +17 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +49 -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 +3 -3
- 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 +36 -32
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +12 -4
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +5 -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 +32 -29
- package/node_modules/@llblab/pi-state-flow/index.ts +3 -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 +274 -197
- 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 +6 -3
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +55 -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 +3 -3
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +2 -2
- package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +5 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +2 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +55 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +21 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +144 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +9 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +19 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +13 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +29 -6
- package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +16 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +5 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +6 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +7 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +13 -5
- package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +2 -2
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -1
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +79 -1
- package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +197 -0
- package/node_modules/@llblab/pi-telegram/lib/bus.ts +33 -0
- package/node_modules/@llblab/pi-telegram/lib/commands.ts +38 -6
- package/node_modules/@llblab/pi-telegram/lib/extension.ts +15 -0
- package/node_modules/@llblab/pi-telegram/lib/locks.ts +6 -1
- package/node_modules/@llblab/pi-telegram/lib/polling.ts +10 -2
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +19 -5
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/package.json +7 -3
|
@@ -5,15 +5,15 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
|
5
5
|
import { getDurableRepositoryRoot } from "./durable.js";
|
|
6
6
|
import { DEFAULT_HISTORY_LIMIT, MAX_HISTORY_LIMIT } from "./history.js";
|
|
7
7
|
import { isObject } from "./json.js";
|
|
8
|
+
import { isStateFlowMode } from "./snapshot.js";
|
|
8
9
|
/** Read the repository-global config once at extension load/reload. Missing config uses defaults; invalid config never falls back. */
|
|
9
10
|
export function loadStateFlowConfig(agentDir = getAgentDir(), repositoryRoot = getDurableRepositoryRoot(agentDir)) {
|
|
10
11
|
const directory = repositoryRoot;
|
|
11
12
|
const path = join(directory, "config.json");
|
|
12
13
|
const defaults = {
|
|
13
14
|
directory,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
passiveTools: true,
|
|
15
|
+
mode: "off",
|
|
16
|
+
inactiveMode: "off",
|
|
17
17
|
logging: false,
|
|
18
18
|
showSuccessfulPatches: true,
|
|
19
19
|
historyLimit: DEFAULT_HISTORY_LIMIT,
|
|
@@ -27,10 +27,13 @@ export function loadStateFlowConfig(agentDir = getAgentDir(), repositoryRoot = g
|
|
|
27
27
|
catch (error) {
|
|
28
28
|
throw new Error(`Cannot read State Flow configuration: ${path}`, { cause: error });
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
// autoStart/passiveBootstrap/passiveTools are read-only compatibility inputs; explicit mode is authoritative.
|
|
31
|
+
const allowed = new Set(["mode", "autoStart", "passiveBootstrap", "passiveTools", "logging", "showSuccessfulPatches", "historyLimit"]);
|
|
31
32
|
if (!isObject(value) || Object.keys(value).some((key) => !allowed.has(key))) {
|
|
32
33
|
throw new Error(`State Flow configuration contains unknown settings: ${path}`);
|
|
33
34
|
}
|
|
35
|
+
if (Object.hasOwn(value, "mode") && !isStateFlowMode(value.mode))
|
|
36
|
+
throw new Error(`State Flow mode must be "active", "passive" or "off": ${path}`);
|
|
34
37
|
if (Object.hasOwn(value, "autoStart") && typeof value.autoStart !== "boolean")
|
|
35
38
|
throw new Error(`State Flow autoStart must be a boolean: ${path}`);
|
|
36
39
|
if (Object.hasOwn(value, "passiveBootstrap") && typeof value.passiveBootstrap !== "boolean")
|
|
@@ -43,13 +46,19 @@ export function loadStateFlowConfig(agentDir = getAgentDir(), repositoryRoot = g
|
|
|
43
46
|
throw new Error(`State Flow showSuccessfulPatches must be a boolean: ${path}`);
|
|
44
47
|
if (Object.hasOwn(value, "historyLimit") && (!Number.isSafeInteger(value.historyLimit) || value.historyLimit < 0 || value.historyLimit > MAX_HISTORY_LIMIT))
|
|
45
48
|
throw new Error(`State Flow historyLimit must be an integer from 0 to ${MAX_HISTORY_LIMIT}: ${path}`);
|
|
49
|
+
const legacyInactive = value.passiveBootstrap !== false || value.passiveTools !== false ? "passive" : "off";
|
|
50
|
+
const hasLegacyMode = Object.hasOwn(value, "autoStart") || Object.hasOwn(value, "passiveBootstrap") || Object.hasOwn(value, "passiveTools");
|
|
51
|
+
const mode = isStateFlowMode(value.mode) ? value.mode : value.autoStart === true ? "active" : hasLegacyMode ? legacyInactive : "off";
|
|
46
52
|
return {
|
|
47
53
|
directory,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
passiveTools: value.passiveTools !== false,
|
|
54
|
+
mode,
|
|
55
|
+
inactiveMode: isStateFlowMode(value.mode) ? inactiveModeFor(value.mode) : hasLegacyMode ? legacyInactive : "off",
|
|
51
56
|
logging: value.logging === true,
|
|
52
57
|
showSuccessfulPatches: value.showSuccessfulPatches !== false,
|
|
53
58
|
historyLimit: typeof value.historyLimit === "number" ? value.historyLimit : DEFAULT_HISTORY_LIMIT,
|
|
54
59
|
};
|
|
55
60
|
}
|
|
61
|
+
/** Explicit modes never carry a separate passive policy: only Off stays off when inactive. */
|
|
62
|
+
export function inactiveModeFor(mode) {
|
|
63
|
+
return mode === "off" ? "off" : "passive";
|
|
64
|
+
}
|
|
@@ -4,12 +4,12 @@ import type { RecentTransitionWindow } from "./history.ts";
|
|
|
4
4
|
import { type JsonValue } from "./json.ts";
|
|
5
5
|
import type { Snapshot } from "./snapshot.ts";
|
|
6
6
|
import type { RehydrationPhase } from "./rehydration.ts";
|
|
7
|
-
import { type AtomicScopePatches, type
|
|
7
|
+
import { type AtomicScopePatches, type SemanticState } from "./state.ts";
|
|
8
8
|
/** Refresh only our section; Pi owns system frames, tools and forced-prompt precedence. */
|
|
9
9
|
export declare function projectSystemProtocol(messages: AgentMessage[], protocol: string | undefined): AgentMessage[];
|
|
10
10
|
type LazyValueKind = "array" | "boolean" | "null" | "number" | "object" | "string";
|
|
11
11
|
/** Fixed-budget navigation only: never place lazy bodies or partial key catalogs in baseline context. */
|
|
12
|
-
export declare function lazyNavigationHint(state:
|
|
12
|
+
export declare function lazyNavigationHint(state: SemanticState): {
|
|
13
13
|
available: boolean;
|
|
14
14
|
path: string;
|
|
15
15
|
keys?: Record<string, LazyValueKind>;
|
|
@@ -22,7 +22,7 @@ export type ModelStateUpdate = {
|
|
|
22
22
|
deleted: true;
|
|
23
23
|
});
|
|
24
24
|
/** Exact projected replacements, not authored merge patches; paths are unambiguous key/index segments. */
|
|
25
|
-
export declare function acceptedStateUpdates(before:
|
|
25
|
+
export declare function acceptedStateUpdates(before: SemanticState, after: SemanticState, patches: AtomicScopePatches): {
|
|
26
26
|
effective: ModelStateUpdate[];
|
|
27
27
|
lazy_navigation?: {
|
|
28
28
|
available: boolean;
|
|
@@ -31,14 +31,14 @@ export declare function acceptedStateUpdates(before: MaterializedState, after: M
|
|
|
31
31
|
} | undefined;
|
|
32
32
|
};
|
|
33
33
|
export interface ContextView {
|
|
34
|
-
state:
|
|
34
|
+
state: SemanticState;
|
|
35
35
|
lazy_navigation?: ReturnType<typeof lazyNavigationHint>;
|
|
36
36
|
artifact_invalidations: readonly ArtifactInvalidationNotice[];
|
|
37
37
|
knowledge_rehydration: {
|
|
38
38
|
phase: RehydrationPhase;
|
|
39
39
|
} | null;
|
|
40
40
|
}
|
|
41
|
-
export declare function contextView(state:
|
|
41
|
+
export declare function contextView(state: SemanticState, hints: ArtifactModelHints, invalidations: readonly ArtifactInvalidationNotice[], phase?: RehydrationPhase): ContextView;
|
|
42
42
|
/** Volatile model projection only. Native messages own trajectory; this cache owns no persistence or lifecycle. */
|
|
43
43
|
export declare class ContextProjection {
|
|
44
44
|
private identity;
|
|
@@ -48,7 +48,7 @@ export declare class ContextProjection {
|
|
|
48
48
|
private notices;
|
|
49
49
|
reset(): void;
|
|
50
50
|
/** Called only after successful publication and ancillary acceptance, immediately before returning the native result. */
|
|
51
|
-
acceptPatch(before:
|
|
51
|
+
acceptPatch(before: SemanticState, after: SemanticState, patches: AtomicScopePatches, hints: ArtifactModelHints): {
|
|
52
52
|
effective: ModelStateUpdate[];
|
|
53
53
|
lazy_navigation?: {
|
|
54
54
|
available: boolean;
|
|
@@ -65,13 +65,13 @@ export interface PassiveContinuation {
|
|
|
65
65
|
activeRunStartedAt?: number;
|
|
66
66
|
preserveContext?: true;
|
|
67
67
|
handoff: AgentMessage;
|
|
68
|
-
state:
|
|
68
|
+
state: SemanticState;
|
|
69
69
|
}
|
|
70
70
|
export declare function syntheticUser(text: string): AgentMessage;
|
|
71
|
-
export declare function createPassiveContinuation(state:
|
|
71
|
+
export declare function createPassiveContinuation(state: SemanticState, startedAt?: number, activeRunStartedAt?: number, preserveContext?: boolean): PassiveContinuation;
|
|
72
72
|
/** Keep the interrupted run through later results; an idle stop retains only later conversation. */
|
|
73
73
|
export declare function passiveContinuationMessages(messages: AgentMessage[], continuation: PassiveContinuation): AgentMessage[];
|
|
74
|
-
export declare function runtimeContextMessage(snapshot: Snapshot, state:
|
|
74
|
+
export declare function runtimeContextMessage(snapshot: Snapshot, state: SemanticState, recentTransitions?: RecentTransitionWindow, artifactInvalidations?: readonly ArtifactInvalidationNotice[], rehydrationPhase?: RehydrationPhase, artifactHints?: ArtifactModelHints): AgentMessage;
|
|
75
75
|
/** Render a view already projected by this domain without cloning the full semantic overlay twice. */
|
|
76
76
|
export declare function runtimeContextHead(snapshot: Snapshot, view: ContextView, recentTransitions?: RecentTransitionWindow): AgentMessage;
|
|
77
77
|
/** Captured identity survives text decoration; an uncertain boundary retains available context. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { projectArtifactForModel } from "./artifact.js";
|
|
3
3
|
import { applyPatch, isObject, presentationJson, sameJson } from "./json.js";
|
|
4
|
-
import { projectStateForModel } from "./state.js";
|
|
4
|
+
import { projectSemanticPatch, projectStateForModel } from "./state.js";
|
|
5
5
|
/** Refresh only our section; Pi owns system frames, tools and forced-prompt precedence. */
|
|
6
6
|
export function projectSystemProtocol(messages, protocol) {
|
|
7
7
|
let lastSystem = -1;
|
|
@@ -74,8 +74,8 @@ function projectedStateUpdates(previous, current, patches, beforeNavigation, nav
|
|
|
74
74
|
const diff = (left, right, path) => {
|
|
75
75
|
if (left === undefined && right === undefined || left !== undefined && right !== undefined && sameJson(left, right))
|
|
76
76
|
return;
|
|
77
|
-
if (isObject(
|
|
78
|
-
for (const key of new Set([...Object.keys(left), ...Object.keys(right)]))
|
|
77
|
+
if (isObject(right) && (isObject(left) || left === undefined && path.length === 1 && Object.keys(right).length > 0)) {
|
|
78
|
+
for (const key of new Set([...Object.keys(left ?? {}), ...Object.keys(right)]))
|
|
79
79
|
diff(child(left, key), child(right, key), [...path, key]);
|
|
80
80
|
}
|
|
81
81
|
else if (Array.isArray(left) && Array.isArray(right) && left.length === right.length) {
|
|
@@ -336,8 +336,9 @@ function projectRecentForModel(recent) {
|
|
|
336
336
|
const projected = structuredClone(recent);
|
|
337
337
|
for (const record of projected)
|
|
338
338
|
for (const transition of record.transitions) {
|
|
339
|
+
transition.patch = projectSemanticPatch(transition.patch);
|
|
339
340
|
delete transition.patch.lazy;
|
|
340
|
-
if (transition.patch.artifacts
|
|
341
|
+
if (!isObject(transition.patch.artifacts))
|
|
341
342
|
continue;
|
|
342
343
|
for (const [path, entry] of Object.entries(transition.patch.artifacts)) {
|
|
343
344
|
Object.defineProperty(transition.patch.artifacts, path, {
|
|
@@ -149,8 +149,8 @@ export async function inspectStateFlowContinuationProvenance(header, repositoryR
|
|
|
149
149
|
const runtime = parseSessionRuntime(files.get(paths.config), files.get(paths.runtime), selected.cwd, selected.id);
|
|
150
150
|
if (!runtime)
|
|
151
151
|
throw new Error("incomplete canonical session runtime");
|
|
152
|
-
if (
|
|
153
|
-
return { stateFlow: { enabled: false, restorable: true }, reason: "State Flow
|
|
152
|
+
if (runtime.config.mode !== "active")
|
|
153
|
+
return { stateFlow: { enabled: false, restorable: true }, reason: "State Flow is not active on selected runtime" };
|
|
154
154
|
const streams = ["global", "cwd", "session"].map((scope) => {
|
|
155
155
|
const owned = temporalScopePaths(selected.cwd, selected.id, scope, root, sessionKey);
|
|
156
156
|
return parseScopeStream(files.get(owned.checkpoint), files.get(owned.patches), scope, scope === "cwd" ? selected.cwd : undefined, files.get(owned.meta));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ArtifactProvenanceRegistry } from "./artifact.ts";
|
|
2
2
|
import { type ScopeStream, type TemporalState } from "./temporal.ts";
|
|
3
|
-
import type
|
|
3
|
+
import { type StateScope } from "./state.ts";
|
|
4
4
|
/** Canonical semantic sources plus runtime-owned temporal metadata. */
|
|
5
5
|
export interface ScopeStreamSources {
|
|
6
6
|
checkpoint: string;
|
|
@@ -6,6 +6,7 @@ import { parseArtifactProvenanceRegistry, serializeArtifactProvenanceRegistry, }
|
|
|
6
6
|
import { MAX_HISTORY_LIMIT } from "./history.js";
|
|
7
7
|
import { canonicalJson, isJsonValue, isObject } from "./json.js";
|
|
8
8
|
import { validateScopeStream, validateTemporalState } from "./temporal.js";
|
|
9
|
+
import { selectSemanticFields } from "./state.js";
|
|
9
10
|
const SESSION_KEY_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
10
11
|
const STATE_FILE = "state.json";
|
|
11
12
|
const CHECKPOINT_FILE = "checkpoint.json";
|
|
@@ -33,8 +34,8 @@ export function serializeScopeStream(stream, scope, cwdIdentity) {
|
|
|
33
34
|
if (scope !== "cwd" && cwdIdentity !== undefined)
|
|
34
35
|
throw new Error("Only State Flow CWD scope serialization accepts a CWD identity");
|
|
35
36
|
return {
|
|
36
|
-
checkpoint: `${canonicalJson(stream.checkpoint.state)}\n`,
|
|
37
|
-
patches: stream.patches.map((record) => `${canonicalJson(record.patch)}\n`).join(""),
|
|
37
|
+
checkpoint: `${canonicalJson(selectSemanticFields(stream.checkpoint.state))}\n`,
|
|
38
|
+
patches: stream.patches.map((record) => `${canonicalJson(selectSemanticFields(record.patch))}\n`).join(""),
|
|
38
39
|
temporal: {
|
|
39
40
|
revision: stream.revision,
|
|
40
41
|
checkpoint: structuredClone(stream.checkpoint.through),
|
|
@@ -96,8 +97,10 @@ export function classifyScopeStream(checkpointSource, patchesSource, scope, expe
|
|
|
96
97
|
// 0.17.4 and earlier did not persist scope revisions. Credit only their still-retained
|
|
97
98
|
// semantic tail; discarded ancestry cannot be reconstructed without inventing history.
|
|
98
99
|
revision: temporal.revision === undefined ? patches.length : temporal.revision,
|
|
99
|
-
checkpoint: { through: temporal.checkpoint, state: checkpoint },
|
|
100
|
-
patches: patches.map((patch, index) => ({
|
|
100
|
+
checkpoint: { through: temporal.checkpoint, state: isObject(checkpoint) ? selectSemanticFields(checkpoint) : checkpoint },
|
|
101
|
+
patches: patches.map((patch, index) => ({
|
|
102
|
+
transition: boundaries[index], patch: isObject(patch) ? selectSemanticFields(patch) : patch,
|
|
103
|
+
})),
|
|
101
104
|
};
|
|
102
105
|
validateScopeStream(stream, scope, MAX_HISTORY_LIMIT);
|
|
103
106
|
return { kind: "present", stream };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type Snapshot } from "./snapshot.ts";
|
|
1
|
+
import { type InactiveMode, type Snapshot } from "./snapshot.ts";
|
|
2
2
|
export declare function startEpisode(bootstrap: boolean): Snapshot;
|
|
3
3
|
/** Re-enable a branch checkpoint without discarding its runtime config or provenance. */
|
|
4
4
|
export declare function resumeEpisode(snapshot: Snapshot, bootstrap: boolean): Snapshot;
|
|
5
|
-
/**
|
|
6
|
-
export declare function
|
|
5
|
+
/** Select an inactive mode for only this branch; durable defaults and session history remain intact. */
|
|
6
|
+
export declare function deactivateEpisode(snapshot: Snapshot, mode: InactiveMode): Snapshot;
|
|
7
7
|
/** Apply one user-run boundary while preserving checkpoint-owned runtime state. */
|
|
8
8
|
export declare function prepareRun(snapshot: Snapshot, prompt: string): boolean;
|
|
9
9
|
/** Retain the full prompt only while its run remains recoverable and unfinished. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { emptySnapshot } from "./snapshot.js";
|
|
2
2
|
export function startEpisode(bootstrap) {
|
|
3
|
-
const snapshot = emptySnapshot(
|
|
3
|
+
const snapshot = emptySnapshot("active");
|
|
4
4
|
if (bootstrap)
|
|
5
5
|
snapshot.meta.bootstrap = true;
|
|
6
6
|
return snapshot;
|
|
@@ -8,15 +8,15 @@ export function startEpisode(bootstrap) {
|
|
|
8
8
|
/** Re-enable a branch checkpoint without discarding its runtime config or provenance. */
|
|
9
9
|
export function resumeEpisode(snapshot, bootstrap) {
|
|
10
10
|
const next = structuredClone(snapshot);
|
|
11
|
-
next.config.
|
|
11
|
+
next.config.mode = "active";
|
|
12
12
|
if (bootstrap)
|
|
13
13
|
next.meta.bootstrap = true;
|
|
14
14
|
return next;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
export function
|
|
16
|
+
/** Select an inactive mode for only this branch; durable defaults and session history remain intact. */
|
|
17
|
+
export function deactivateEpisode(snapshot, mode) {
|
|
18
18
|
const next = structuredClone(snapshot);
|
|
19
|
-
next.config.
|
|
19
|
+
next.config.mode = mode;
|
|
20
20
|
return next;
|
|
21
21
|
}
|
|
22
22
|
/** Apply one user-run boundary while preserving checkpoint-owned runtime state. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { formatPatchStateArguments } from "./protocol.ts";
|
|
3
|
+
import { type StateFlowMode } from "./snapshot.ts";
|
|
3
4
|
import { type ModelState, type StateScope } from "./state.ts";
|
|
4
5
|
import { type StateFlowTelegramLoader } from "./telegram.ts";
|
|
5
6
|
export interface StateFlowExtensionOptions {
|
|
@@ -11,11 +12,8 @@ export interface StateFlowExtensionOptions {
|
|
|
11
12
|
telegram?: {
|
|
12
13
|
load?: StateFlowTelegramLoader;
|
|
13
14
|
};
|
|
14
|
-
/** Test/SDK
|
|
15
|
-
|
|
16
|
-
bootstrap?: boolean;
|
|
17
|
-
tools?: boolean;
|
|
18
|
-
};
|
|
15
|
+
/** Test/SDK override of the default mode for new sessions; repository config remains the Pi default. */
|
|
16
|
+
mode?: StateFlowMode;
|
|
19
17
|
}
|
|
20
18
|
export { formatPatchStateArguments };
|
|
21
19
|
export declare const PATCH_STATE_TOOL_NAME = "patch_state";
|