@wrongstack/core 0.280.1 → 0.281.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/dist/{agent-subagent-runner-PoqNKiR4.d.ts → agent-subagent-runner-DyOSK2Wy.d.ts} +39 -8
- package/dist/{compactor-U3agvUIG.d.ts → compactor-BxddyCFu.d.ts} +1 -1
- package/dist/{config-Cr3312zc.d.ts → config-CN-vdDEI.d.ts} +82 -2
- package/dist/coordination/index.d.ts +203 -20
- package/dist/coordination/index.js +981 -52
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -30
- package/dist/defaults/index.js +382 -30
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-Bs2fmldo.d.ts → events-C5hLU0AT.d.ts} +38 -2
- package/dist/execution/index.d.ts +16 -16
- package/dist/execution/index.js +161 -18
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/execution/prompt-enhancer.js +12 -3
- package/dist/execution/prompt-enhancer.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-Ct7IorLJ.d.ts → global-mailbox-CHM1QkCi.d.ts} +5 -2
- package/dist/{goal-store-C4F6DjC0.d.ts → goal-store-BLGZq16t.d.ts} +1 -1
- package/dist/hq/index.d.ts +6 -6
- package/dist/hq/index.js +35 -13
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-nP09-oP2.d.ts → index-BEFWNZYs.d.ts} +1 -2
- package/dist/{index-kidebiDh.d.ts → index-C1E-_71T.d.ts} +6 -6
- package/dist/index.d.ts +44 -48
- package/dist/index.js +14855 -13944
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +60 -8
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +11 -11
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-D910X5_r.d.ts → mcp-servers-EKRAcJDi.d.ts} +97 -4
- package/dist/models/index.d.ts +4 -5
- package/dist/models/index.js +22 -5
- package/dist/models/index.js.map +1 -1
- package/dist/{multi-agent-coordinator-CieyUoEL.d.ts → multi-agent-coordinator-IpHCuHUa.d.ts} +29 -1
- package/dist/{null-fleet-bus-DkdmZJ_W.d.ts → null-fleet-bus-ZBkKGR9j.d.ts} +105 -7
- package/dist/observability/index.d.ts +3 -3
- package/dist/{tool-executor-SiE1wlZo.d.ts → parallel-eternal-engine-Cc2CNgmv.d.ts} +6 -202
- package/dist/path-resolver-CMS5307d.d.ts +13 -0
- package/dist/{permission-Dx6dIqS2.d.ts → permission-B6YAtNFz.d.ts} +1 -1
- package/dist/{pipeline-BwAP21_4.d.ts → pipeline-E7_jqGyV.d.ts} +2 -2
- package/dist/{provider-model-resolve-CwQNZWt_.d.ts → provider-model-resolve-KgIdiEQ6.d.ts} +118 -5
- package/dist/{provider-runner-CYHFImzV.d.ts → provider-runner-DxWXNHL1.d.ts} +3 -3
- package/dist/{retry-policy-D4feSLk3.d.ts → retry-policy-V67lBOJz.d.ts} +2 -2
- package/dist/sdd/index.d.ts +9 -9
- package/dist/sdd/index.js +94 -10
- package/dist/sdd/index.js.map +1 -1
- package/dist/{permission-policy-C8vJcnX5.d.ts → secret-vault-D7jeyXUQ.d.ts} +119 -3
- package/dist/security/index.d.ts +5 -6
- package/dist/security/index.js +4 -1
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Dy-MzKp1.d.ts → selector-Bx2HgUkU.d.ts} +1 -1
- package/dist/{session-event-bridge-CqdiGnfU.d.ts → session-event-bridge-vA2fLV58.d.ts} +1 -1
- package/dist/{session-reader-Hk0WbNm9.d.ts → session-reader-B-Fi9L6I.d.ts} +1 -1
- package/dist/session-registry-Dvg7i_IA.d.ts +129 -0
- package/dist/storage/index.d.ts +71 -142
- package/dist/storage/index.js +161 -13
- package/dist/storage/index.js.map +1 -1
- package/dist/{todos-checkpoint-Bk2uP7Ex.d.ts → todos-checkpoint-B1QVkoa8.d.ts} +23 -5
- package/dist/{tool-BkOgs_KL.d.ts → tool-LVSLiE1s.d.ts} +18 -4
- package/dist/{strategy-compactor-CQwhbErd.d.ts → tool-executor-BWtYwuPI.d.ts} +210 -12
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +17 -41
- package/dist/types/index.js +182 -5085
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +6 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{worktree-manager-BjOFF6bt.d.ts → worktree-manager-C6CIilTT.d.ts} +1 -1
- package/dist/{wstack-paths-CMl_cYgq.d.ts → wstack-paths-C3K40Qst.d.ts} +2 -0
- package/instructions/agents/shadow-agent.md +23 -84
- package/instructions/coordination/director-preamble.md +12 -3
- package/instructions/coordination/subagent-baseline.md +39 -46
- package/instructions/leader-after-task.md +10 -28
- package/instructions/llm/llm-selector.md +1 -2
- package/instructions/modes/brief-system.md +7 -33
- package/instructions/modes/brief.md +5 -20
- package/instructions/modes/teach-system.md +12 -72
- package/instructions/modes/teach.md +12 -49
- package/instructions/sections/tool/commit-hygiene.md +5 -5
- package/instructions/sections/tool/context-management-full.md +6 -6
- package/instructions/sections/tool/delegation-compact.md +1 -1
- package/instructions/sections/tool/delegation-full.md +19 -23
- package/instructions/sections/tool/mailbox-full.md +11 -31
- package/instructions/sections/tool/mcp-full-control.md +5 -7
- package/instructions/sections/tool/mcp-full-use.md +7 -7
- package/instructions/system.md +22 -38
- package/package.json +1 -29
- package/dist/agent-bridge-DXC6QDJ4.d.ts +0 -35
- package/dist/logger-D3lV0cUZ.d.ts +0 -101
- package/dist/models-registry-CLkoOcHk.d.ts +0 -108
- package/dist/path-resolver-XfZ9eLxG.d.ts +0 -67
- package/dist/secret-vault-CImt2XrR.d.ts +0 -118
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as ContentBlock, S as SessionEvent, j as SessionMetadata, k as SessionStore } from './tool-
|
|
1
|
+
import { i as ContentBlock, S as SessionEvent, j as SessionMetadata, k as SessionStore } from './tool-LVSLiE1s.js';
|
|
2
2
|
|
|
3
3
|
type AttachmentKind = 'text' | 'image' | 'file';
|
|
4
4
|
interface AttachmentMeta {
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** Live status of a single agent within a session. */
|
|
2
|
+
type AgentLiveStatus = 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';
|
|
3
|
+
interface AgentEntry {
|
|
4
|
+
/** Unique agent id (ULID or UUID). */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Human-readable label (e.g. "leader", "bug-hunter #1"). */
|
|
7
|
+
name: string;
|
|
8
|
+
/** UTC ISO timestamp when this agent/run started, when known. */
|
|
9
|
+
startedAt?: string | undefined;
|
|
10
|
+
status: AgentLiveStatus;
|
|
11
|
+
/** Current tool name if running, undefined otherwise. */
|
|
12
|
+
currentTool?: string | undefined;
|
|
13
|
+
/** Iteration count so far. */
|
|
14
|
+
iterations: number;
|
|
15
|
+
/** Tool calls so far. */
|
|
16
|
+
toolCalls: number;
|
|
17
|
+
/** Cumulative cost in USD for this agent, when known. */
|
|
18
|
+
costUsd?: number | undefined;
|
|
19
|
+
/** Cumulative input tokens, when known. */
|
|
20
|
+
tokensIn?: number | undefined;
|
|
21
|
+
/** Cumulative output tokens, when known. */
|
|
22
|
+
tokensOut?: number | undefined;
|
|
23
|
+
/** Context window fill 0–100 (may exceed 100 when over limit), when known. */
|
|
24
|
+
ctxPct?: number | undefined;
|
|
25
|
+
/** Model id this agent is running on, when known. */
|
|
26
|
+
model?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Tail of the assistant text currently being streamed (capped, throttled).
|
|
29
|
+
* Lets a cross-process watcher see the response form in near-real-time
|
|
30
|
+
* instead of waiting for the completed turn to land in the session log.
|
|
31
|
+
*/
|
|
32
|
+
partialText?: string | undefined;
|
|
33
|
+
/** UTC ISO timestamp of last activity. */
|
|
34
|
+
lastActivityAt: string;
|
|
35
|
+
}
|
|
36
|
+
type SessionLiveStatus = 'active' | 'idle' | 'closing' | 'stale';
|
|
37
|
+
interface SessionRegistryEntry {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
projectSlug: string;
|
|
40
|
+
projectRoot: string;
|
|
41
|
+
projectName: string;
|
|
42
|
+
workingDir: string;
|
|
43
|
+
/**
|
|
44
|
+
* Which surface owns this session — `'tui'` / `'webui'` / `'cli'` (one-shot or
|
|
45
|
+
* REPL). Lets cross-process consumers (e.g. the WebUI Fleet HQ office map) label
|
|
46
|
+
* each live session by client kind. Optional for back-compat with older entries.
|
|
47
|
+
*/
|
|
48
|
+
clientType?: 'tui' | 'webui' | 'cli' | 'repl' | string | undefined;
|
|
49
|
+
/** Current git branch, if the project is a git repo. Detected at registration. */
|
|
50
|
+
gitBranch?: string | undefined;
|
|
51
|
+
status: SessionLiveStatus;
|
|
52
|
+
pid: number;
|
|
53
|
+
/** UTC ISO */
|
|
54
|
+
startedAt: string;
|
|
55
|
+
/** UTC ISO — updated on every heartbeat */
|
|
56
|
+
lastHeartbeatAt: string;
|
|
57
|
+
/** Count of tracked agents */
|
|
58
|
+
agentCount: number;
|
|
59
|
+
agents: AgentEntry[];
|
|
60
|
+
}
|
|
61
|
+
declare class SessionRegistry {
|
|
62
|
+
private readonly filePath;
|
|
63
|
+
private heartbeatTimer;
|
|
64
|
+
private currentSessionId;
|
|
65
|
+
/**
|
|
66
|
+
* Last full entry this process registered. Kept so the heartbeat can
|
|
67
|
+
* re-create our entry if it ever goes missing — e.g. our initial register()
|
|
68
|
+
* write was dropped (a wedged lock), the file was reset, or we were pruned.
|
|
69
|
+
*/
|
|
70
|
+
private lastEntry;
|
|
71
|
+
constructor(globalRoot: string);
|
|
72
|
+
/**
|
|
73
|
+
* Register the current session. Call once on session start.
|
|
74
|
+
* Starts the heartbeat timer.
|
|
75
|
+
*/
|
|
76
|
+
register(entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {
|
|
77
|
+
agents?: AgentEntry[] | undefined;
|
|
78
|
+
}): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Update agent status for the current session. Call on every
|
|
81
|
+
* significant status change (agent start, tool start, user wait, error).
|
|
82
|
+
*/
|
|
83
|
+
updateAgents(agents: AgentEntry[]): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Mark the session as closing. Called during shutdown.
|
|
86
|
+
* Stops the heartbeat timer.
|
|
87
|
+
*/
|
|
88
|
+
markClosing(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Remove the current session from the registry. Call on clean exit.
|
|
91
|
+
*/
|
|
92
|
+
unregister(): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* List all non-stale sessions. Prunes stale entries automatically.
|
|
95
|
+
*/
|
|
96
|
+
list(): Promise<SessionRegistryEntry[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Get a single session entry by ID. Returns undefined if not found or stale.
|
|
99
|
+
*/
|
|
100
|
+
get(sessionId: string): Promise<SessionRegistryEntry | undefined>;
|
|
101
|
+
/**
|
|
102
|
+
* List all sessions for a specific project (by slug).
|
|
103
|
+
*/
|
|
104
|
+
listByProject(projectSlug: string): Promise<SessionRegistryEntry[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Return the registry file path. Useful for WebUI to watch/read.
|
|
107
|
+
*/
|
|
108
|
+
get registryPath(): string;
|
|
109
|
+
private heartbeat;
|
|
110
|
+
private readAndPrune;
|
|
111
|
+
private atomicUpdate;
|
|
112
|
+
/**
|
|
113
|
+
* Break a contended lock if it is stale: the recorded owner pid is no longer
|
|
114
|
+
* alive, or the lock is older than {@link STALE_LOCK_MS}. Returns true when the
|
|
115
|
+
* lock was removed (caller should retry acquisition). Best-effort and
|
|
116
|
+
* race-tolerant — a fresh lock (age ~0, live owner) is never broken, so the
|
|
117
|
+
* common concurrent case self-heals on the next heartbeat.
|
|
118
|
+
*/
|
|
119
|
+
private breakStaleLock;
|
|
120
|
+
private writeAtomicLocked;
|
|
121
|
+
/** Legacy write without lock — used by heartbeat for performance. */
|
|
122
|
+
private writeAtomic;
|
|
123
|
+
private writeAtomicFile;
|
|
124
|
+
private pruneStaleTempFiles;
|
|
125
|
+
}
|
|
126
|
+
declare function getSessionRegistry(globalRoot?: string): SessionRegistry;
|
|
127
|
+
declare function hasSessionRegistry(): boolean;
|
|
128
|
+
|
|
129
|
+
export { type AgentEntry as A, type SessionLiveStatus as S, type AgentLiveStatus as a, SessionRegistry as b, type SessionRegistryEntry as c, getSessionRegistry as g, hasSessionRegistry as h };
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { M as MemoryBackend, j as FileMemoryBackendOptions } from '../todos-checkpoint-
|
|
2
|
-
export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, F as FileMemoryBackend, k as MemoryStoreOptions, l as MigrationContext, m as MigrationResult, P as PersistedQueueItem, n as PlanFile, o as PlanItem, p as PlanTemplate, Q as QueueStore, R as RecoveryLock, q as RecoveryLockOptions, S as SessionAnalyzer, r as SessionStoreOptions, T as TodosCheckpointFile, s as addPlanItem, t as attachPlanCheckpoint, u as attachTodosCheckpoint, v as clearPlan, w as deriveTodosFromPlanItem, x as emptyPlan, y as formatPlan, z as formatPlanTemplates, B as getPlanTemplate, E as listPlanTemplates, G as loadPlan, H as loadTodosCheckpoint, I as mutatePlan, J as parseEntries, K as removePlanItem, L as runConfigMigrations, N as savePlan, O as saveTodosCheckpoint, U as setPlanItemStatus } from '../todos-checkpoint-
|
|
3
|
-
import { M as MemoryScope, b as MemoryEntry, c as MemoryStore, E as EventBus } from '../events-
|
|
4
|
-
import { i as AgentExtension, k as AfterRunHook } from '../index-
|
|
5
|
-
import { P as Provider, c as Request,
|
|
6
|
-
import { P as ProviderConfig,
|
|
1
|
+
import { M as MemoryBackend, j as FileMemoryBackendOptions } from '../todos-checkpoint-B1QVkoa8.js';
|
|
2
|
+
export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, F as FileMemoryBackend, k as MemoryStoreOptions, l as MigrationContext, m as MigrationResult, P as PersistedQueueItem, n as PlanFile, o as PlanItem, p as PlanTemplate, Q as QueueStore, R as RecoveryLock, q as RecoveryLockOptions, S as SessionAnalyzer, r as SessionStoreOptions, T as TodosCheckpointFile, s as addPlanItem, t as attachPlanCheckpoint, u as attachTodosCheckpoint, v as clearPlan, w as deriveTodosFromPlanItem, x as emptyPlan, y as formatPlan, z as formatPlanTemplates, B as getPlanTemplate, E as listPlanTemplates, G as loadPlan, H as loadTodosCheckpoint, I as mutatePlan, J as parseEntries, K as removePlanItem, L as runConfigMigrations, N as savePlan, O as saveTodosCheckpoint, U as setPlanItemStatus } from '../todos-checkpoint-B1QVkoa8.js';
|
|
3
|
+
import { M as MemoryScope, b as MemoryEntry, c as MemoryStore, E as EventBus } from '../events-C5hLU0AT.js';
|
|
4
|
+
import { i as AgentExtension, k as AfterRunHook } from '../index-C1E-_71T.js';
|
|
5
|
+
import { P as Provider, c as Request, e as Response, S as SessionEvent, D as CompletedWorkEvidence } from '../tool-LVSLiE1s.js';
|
|
6
|
+
import { P as ProviderConfig, a2 as SyncCategory, j as SyncConfig } from '../config-CN-vdDEI.js';
|
|
7
7
|
import { S as SecretVault } from '../secret-vault-BAKpgFw_.js';
|
|
8
|
-
export { D as DefaultSessionReader, f as DefaultSessionReaderOptions, S as SessionReader } from '../session-reader-
|
|
8
|
+
export { D as DefaultSessionReader, f as DefaultSessionReaderOptions, S as SessionReader } from '../session-reader-B-Fi9L6I.js';
|
|
9
|
+
import { b as SessionRegistry, A as AgentEntry } from '../session-registry-Dvg7i_IA.js';
|
|
10
|
+
export { a as AgentLiveStatus, S as SessionLiveStatus, c as SessionRegistryEntry, g as getSessionRegistry, h as hasSessionRegistry } from '../session-registry-Dvg7i_IA.js';
|
|
9
11
|
import { S as SessionRewinder, C as CheckpointInfo, a as RewindResultExtended } from '../session-rewinder-C9HnMkhP.js';
|
|
10
12
|
import { T as TaskItem } from '../task-format-vGOIftmK.js';
|
|
11
13
|
export { a as DirectorStateCheckpoint, D as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from '../director-state-BfeCUbmk.js';
|
|
12
|
-
export { G as GoalFile, J as JournalEntry, M as MAX_JOURNAL_ENTRIES, a as MAX_PROGRESS_HISTORY, P as ProgressSnapshot, b as appendJournal, e as emptyGoal, f as formatGoal, g as goalFilePath, l as loadGoal, p as parseProgressFromText, r as recordProgress, s as saveGoal, c as setProgress, d as summarizeUsage } from '../goal-store-
|
|
14
|
+
export { G as GoalFile, J as JournalEntry, M as MAX_JOURNAL_ENTRIES, a as MAX_PROGRESS_HISTORY, P as ProgressSnapshot, b as appendJournal, e as emptyGoal, f as formatGoal, g as goalFilePath, l as loadGoal, p as parseProgressFromText, r as recordProgress, s as saveGoal, c as setProgress, d as summarizeUsage } from '../goal-store-BLGZq16t.js';
|
|
13
15
|
import { a as PromptEntry } from '../prompt-DLd35n4Q.js';
|
|
14
|
-
import { W as WstackPaths } from '../wstack-paths-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import '../permission-
|
|
16
|
+
import { W as WstackPaths } from '../wstack-paths-C3K40Qst.js';
|
|
17
|
+
import { S as SecretScrubber } from '../secret-scrubber-3MHDDAtm.js';
|
|
18
|
+
export { A as AuditLevel, C as CORE_RECONSTRUCT_EVENTS, a as STANDARD_AUDIT_EVENTS, S as SessionEventBridge, b as SessionEventBridgeOptions, c as SessionSamplingOptions, T as ToolProgressSamplingOptions, d as createSessionEventBridge, r as resolveAuditLevel, e as resolveSessionLoggingConfig } from '../session-event-bridge-vA2fLV58.js';
|
|
19
|
+
import '../permission-B6YAtNFz.js';
|
|
18
20
|
import '../logger-B63L5bTg.js';
|
|
19
|
-
import '../pipeline-
|
|
21
|
+
import '../pipeline-E7_jqGyV.js';
|
|
20
22
|
import '../mailbox-types-BGZWrYTJ.js';
|
|
21
23
|
import '../observability-D-HZN_mF.js';
|
|
22
24
|
import '../task-graph-u1q9Jkyk.js';
|
|
@@ -667,134 +669,6 @@ declare class ToolAuditLog {
|
|
|
667
669
|
private enqueue;
|
|
668
670
|
}
|
|
669
671
|
|
|
670
|
-
/** Live status of a single agent within a session. */
|
|
671
|
-
type AgentLiveStatus = 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';
|
|
672
|
-
interface AgentEntry {
|
|
673
|
-
/** Unique agent id (ULID or UUID). */
|
|
674
|
-
id: string;
|
|
675
|
-
/** Human-readable label (e.g. "leader", "bug-hunter #1"). */
|
|
676
|
-
name: string;
|
|
677
|
-
/** UTC ISO timestamp when this agent/run started, when known. */
|
|
678
|
-
startedAt?: string | undefined;
|
|
679
|
-
status: AgentLiveStatus;
|
|
680
|
-
/** Current tool name if running, undefined otherwise. */
|
|
681
|
-
currentTool?: string | undefined;
|
|
682
|
-
/** Iteration count so far. */
|
|
683
|
-
iterations: number;
|
|
684
|
-
/** Tool calls so far. */
|
|
685
|
-
toolCalls: number;
|
|
686
|
-
/** Cumulative cost in USD for this agent, when known. */
|
|
687
|
-
costUsd?: number | undefined;
|
|
688
|
-
/** Cumulative input tokens, when known. */
|
|
689
|
-
tokensIn?: number | undefined;
|
|
690
|
-
/** Cumulative output tokens, when known. */
|
|
691
|
-
tokensOut?: number | undefined;
|
|
692
|
-
/** Context window fill 0–100 (may exceed 100 when over limit), when known. */
|
|
693
|
-
ctxPct?: number | undefined;
|
|
694
|
-
/** Model id this agent is running on, when known. */
|
|
695
|
-
model?: string | undefined;
|
|
696
|
-
/**
|
|
697
|
-
* Tail of the assistant text currently being streamed (capped, throttled).
|
|
698
|
-
* Lets a cross-process watcher see the response form in near-real-time
|
|
699
|
-
* instead of waiting for the completed turn to land in the session log.
|
|
700
|
-
*/
|
|
701
|
-
partialText?: string | undefined;
|
|
702
|
-
/** UTC ISO timestamp of last activity. */
|
|
703
|
-
lastActivityAt: string;
|
|
704
|
-
}
|
|
705
|
-
type SessionLiveStatus = 'active' | 'idle' | 'closing' | 'stale';
|
|
706
|
-
interface SessionRegistryEntry {
|
|
707
|
-
sessionId: string;
|
|
708
|
-
projectSlug: string;
|
|
709
|
-
projectRoot: string;
|
|
710
|
-
projectName: string;
|
|
711
|
-
workingDir: string;
|
|
712
|
-
/**
|
|
713
|
-
* Which surface owns this session — `'tui'` / `'webui'` / `'cli'` (one-shot or
|
|
714
|
-
* REPL). Lets cross-process consumers (e.g. the WebUI Fleet HQ office map) label
|
|
715
|
-
* each live session by client kind. Optional for back-compat with older entries.
|
|
716
|
-
*/
|
|
717
|
-
clientType?: 'tui' | 'webui' | 'cli' | 'repl' | string | undefined;
|
|
718
|
-
/** Current git branch, if the project is a git repo. Detected at registration. */
|
|
719
|
-
gitBranch?: string | undefined;
|
|
720
|
-
status: SessionLiveStatus;
|
|
721
|
-
pid: number;
|
|
722
|
-
/** UTC ISO */
|
|
723
|
-
startedAt: string;
|
|
724
|
-
/** UTC ISO — updated on every heartbeat */
|
|
725
|
-
lastHeartbeatAt: string;
|
|
726
|
-
/** Count of tracked agents */
|
|
727
|
-
agentCount: number;
|
|
728
|
-
agents: AgentEntry[];
|
|
729
|
-
}
|
|
730
|
-
declare class SessionRegistry {
|
|
731
|
-
private readonly filePath;
|
|
732
|
-
private heartbeatTimer;
|
|
733
|
-
private currentSessionId;
|
|
734
|
-
/**
|
|
735
|
-
* Last full entry this process registered. Kept so the heartbeat can
|
|
736
|
-
* re-create our entry if it ever goes missing — e.g. our initial register()
|
|
737
|
-
* write was dropped (a wedged lock), the file was reset, or we were pruned.
|
|
738
|
-
*/
|
|
739
|
-
private lastEntry;
|
|
740
|
-
constructor(globalRoot: string);
|
|
741
|
-
/**
|
|
742
|
-
* Register the current session. Call once on session start.
|
|
743
|
-
* Starts the heartbeat timer.
|
|
744
|
-
*/
|
|
745
|
-
register(entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {
|
|
746
|
-
agents?: AgentEntry[] | undefined;
|
|
747
|
-
}): Promise<void>;
|
|
748
|
-
/**
|
|
749
|
-
* Update agent status for the current session. Call on every
|
|
750
|
-
* significant status change (agent start, tool start, user wait, error).
|
|
751
|
-
*/
|
|
752
|
-
updateAgents(agents: AgentEntry[]): Promise<void>;
|
|
753
|
-
/**
|
|
754
|
-
* Mark the session as closing. Called during shutdown.
|
|
755
|
-
* Stops the heartbeat timer.
|
|
756
|
-
*/
|
|
757
|
-
markClosing(): Promise<void>;
|
|
758
|
-
/**
|
|
759
|
-
* Remove the current session from the registry. Call on clean exit.
|
|
760
|
-
*/
|
|
761
|
-
unregister(): Promise<void>;
|
|
762
|
-
/**
|
|
763
|
-
* List all non-stale sessions. Prunes stale entries automatically.
|
|
764
|
-
*/
|
|
765
|
-
list(): Promise<SessionRegistryEntry[]>;
|
|
766
|
-
/**
|
|
767
|
-
* Get a single session entry by ID. Returns undefined if not found or stale.
|
|
768
|
-
*/
|
|
769
|
-
get(sessionId: string): Promise<SessionRegistryEntry | undefined>;
|
|
770
|
-
/**
|
|
771
|
-
* List all sessions for a specific project (by slug).
|
|
772
|
-
*/
|
|
773
|
-
listByProject(projectSlug: string): Promise<SessionRegistryEntry[]>;
|
|
774
|
-
/**
|
|
775
|
-
* Return the registry file path. Useful for WebUI to watch/read.
|
|
776
|
-
*/
|
|
777
|
-
get registryPath(): string;
|
|
778
|
-
private heartbeat;
|
|
779
|
-
private readAndPrune;
|
|
780
|
-
private atomicUpdate;
|
|
781
|
-
/**
|
|
782
|
-
* Break a contended lock if it is stale: the recorded owner pid is no longer
|
|
783
|
-
* alive, or the lock is older than {@link STALE_LOCK_MS}. Returns true when the
|
|
784
|
-
* lock was removed (caller should retry acquisition). Best-effort and
|
|
785
|
-
* race-tolerant — a fresh lock (age ~0, live owner) is never broken, so the
|
|
786
|
-
* common concurrent case self-heals on the next heartbeat.
|
|
787
|
-
*/
|
|
788
|
-
private breakStaleLock;
|
|
789
|
-
private writeAtomicLocked;
|
|
790
|
-
/** Legacy write without lock — used by heartbeat for performance. */
|
|
791
|
-
private writeAtomic;
|
|
792
|
-
private writeAtomicFile;
|
|
793
|
-
private pruneStaleTempFiles;
|
|
794
|
-
}
|
|
795
|
-
declare function getSessionRegistry(globalRoot?: string): SessionRegistry;
|
|
796
|
-
declare function hasSessionRegistry(): boolean;
|
|
797
|
-
|
|
798
672
|
/**
|
|
799
673
|
* AgentStatusTracker — subscribes to EventBus events and keeps the
|
|
800
674
|
* SessionRegistry updated with live agent status.
|
|
@@ -1019,6 +893,61 @@ declare class PromptUsageStore {
|
|
|
1019
893
|
}[]>;
|
|
1020
894
|
}
|
|
1021
895
|
|
|
896
|
+
declare const INPUT_HISTORY_DEFAULT_MAX = 100;
|
|
897
|
+
/**
|
|
898
|
+
* Per-project TUI prompt input history.
|
|
899
|
+
*
|
|
900
|
+
* Backed by a single JSON file at `~/.wrongstack/projects/<slug>/input-
|
|
901
|
+
* history.json`. Entries are newest-first, capped at `maxEntries`. Before
|
|
902
|
+
* any entry is written to disk it is passed through a `SecretScrubber` and
|
|
903
|
+
* dropped if it still contains a redacted marker — leaking a pasted API
|
|
904
|
+
* key into a history file would be a real incident, so the scrubber is
|
|
905
|
+
* mandatory, not optional.
|
|
906
|
+
*
|
|
907
|
+
* The store is intentionally small and synchronous-ish (load once at TUI
|
|
908
|
+
* boot, save debounced on change). It mirrors PromptUsageStore's shape so
|
|
909
|
+
* the two read as a family.
|
|
910
|
+
*/
|
|
911
|
+
declare class InputHistoryStore {
|
|
912
|
+
private readonly file;
|
|
913
|
+
private readonly scrubber;
|
|
914
|
+
private readonly maxEntries;
|
|
915
|
+
/**
|
|
916
|
+
* @param file Absolute path to the per-project input-history.json.
|
|
917
|
+
* @param scrubber SecretScrubber used to filter secrets before write.
|
|
918
|
+
* @param maxEntries Cap on the number of entries persisted. Default 100.
|
|
919
|
+
*/
|
|
920
|
+
constructor(file: string, scrubber: SecretScrubber, maxEntries?: number);
|
|
921
|
+
/**
|
|
922
|
+
* Load the persisted entries. Missing or corrupt file → empty list
|
|
923
|
+
* (never throws — history is best-effort).
|
|
924
|
+
*/
|
|
925
|
+
load(): Promise<string[]>;
|
|
926
|
+
/**
|
|
927
|
+
* Persist `entries` to disk after scrubbing each one. Entries that still
|
|
928
|
+
* contain a redaction marker AFTER scrubbing are dropped — a half-scrubbed
|
|
929
|
+
* prompt like "export API_KEY=***REDACTED***" is useless as history and
|
|
930
|
+
* keeping it risks confusing the agent. Dedup is the caller's job (the
|
|
931
|
+
* reducer already dedups); this method only scrubs, caps, and writes.
|
|
932
|
+
*/
|
|
933
|
+
save(entries: string[]): Promise<void>;
|
|
934
|
+
/** Truncate the file to an empty entry list (used by /clear). */
|
|
935
|
+
clear(): Promise<void>;
|
|
936
|
+
/**
|
|
937
|
+
* Run each entry through the scrubber and drop any that still contain a
|
|
938
|
+
* redaction marker. Internal so the test suite can pin the policy.
|
|
939
|
+
*/
|
|
940
|
+
private scrubAndFilter;
|
|
941
|
+
/**
|
|
942
|
+
* Heuristic: did the scrubber actually redact anything? DefaultSecretScrubber
|
|
943
|
+
* replaces matches with "***REDACTED***", so a residual marker means a secret
|
|
944
|
+
* was detected. Subclasses of SecretScrubber that use a different sentinel
|
|
945
|
+
* can be accommodated by widening this check in the future; for now the
|
|
946
|
+
* marker check covers the shipped scrubber.
|
|
947
|
+
*/
|
|
948
|
+
private looksRedacted;
|
|
949
|
+
}
|
|
950
|
+
|
|
1022
951
|
declare const ALL_SYNC_CATEGORIES: SyncCategory[];
|
|
1023
952
|
interface SyncResult {
|
|
1024
953
|
ok: boolean;
|
|
@@ -1061,4 +990,4 @@ declare class CloudSync {
|
|
|
1061
990
|
private walkDir;
|
|
1062
991
|
}
|
|
1063
992
|
|
|
1064
|
-
export { ALL_SYNC_CATEGORIES,
|
|
993
|
+
export { ALL_SYNC_CATEGORIES, AgentEntry, AgentStatusTracker, type AgentStatusTrackerOptions, type Annotation, AnnotationsStore, type AnnotationsStoreOptions, type AuditEntry, CloudSync, type CompletedWorkCheckpointFile, type ConsolidationOp, DefaultPromptStore, DefaultSessionRewinder, FileMemoryBackendOptions, FleetNotifier, type FleetNotifierOptions, GraphMemoryBackend, type GraphMemoryBackendOptions, INPUT_HISTORY_DEFAULT_MAX, InputHistoryStore, MemoryBackend, type MemoryConsolidatorOptions, PromptEntry, type PromptStore, type PromptUsage, PromptUsageStore, type ProviderConfigSnapshot, type RecoveryPlan, type ReplayEntry, ReplayLogStore, type ReplayLogStoreOptions, SessionMemoryConsolidator, SessionRecovery, SessionRegistry, type SessionRewinderOptions, type StaleSession, SyncCategory, SyncConfig, type SyncResult, type TaskFile, ToolAuditLog, type ToolAuditLogOptions, type VerifyResult, type WatchProviderConfigOptions, emptyTaskFile, generateSessionId, loadCompletedWorkCheckpoint, loadTasks, migratePromptEntry, mutateTasks, promptChecksum, sanitizeModel, saveCompletedWorkCheckpoint, saveTasks, watchProviderConfig };
|
package/dist/storage/index.js
CHANGED
|
@@ -372,6 +372,7 @@ function resolveWstackPaths(opts) {
|
|
|
372
372
|
projectHash: hash,
|
|
373
373
|
projectSlug: slug,
|
|
374
374
|
projectGoal: path2.join(projectDir, "goal.json"),
|
|
375
|
+
projectInputHistory: path2.join(projectDir, "input-history.json"),
|
|
375
376
|
projectSpecs: path2.join(projectDir, "specs"),
|
|
376
377
|
projectTaskGraphs: path2.join(projectDir, "task-graphs"),
|
|
377
378
|
projectSddSession: path2.join(projectDir, "sdd-session.json"),
|
|
@@ -1283,6 +1284,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
1283
1284
|
dir;
|
|
1284
1285
|
events;
|
|
1285
1286
|
secretScrubber;
|
|
1287
|
+
isSessionInUse;
|
|
1286
1288
|
/**
|
|
1287
1289
|
* In-memory cache for load() results, keyed by session ID. The cache is
|
|
1288
1290
|
* invalidated when the file's mtimeMs or size changes (indicating the
|
|
@@ -1302,6 +1304,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
1302
1304
|
this.dir = opts.dir;
|
|
1303
1305
|
this.events = opts.events;
|
|
1304
1306
|
this.secretScrubber = opts.secretScrubber;
|
|
1307
|
+
this.isSessionInUse = opts.isSessionInUse;
|
|
1305
1308
|
}
|
|
1306
1309
|
/**
|
|
1307
1310
|
* Clear the load() cache. Useful for testing or when the caller knows
|
|
@@ -2193,19 +2196,74 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2193
2196
|
});
|
|
2194
2197
|
await this.writeTombstone(id);
|
|
2195
2198
|
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Read the session id currently marked active in `active.json`, or `null`
|
|
2201
|
+
* when the lock is absent/unreadable. Shared by {@link delete} and
|
|
2202
|
+
* {@link prune} to avoid clobbering a session a live process is writing to.
|
|
2203
|
+
*/
|
|
2204
|
+
async readActiveSessionId() {
|
|
2205
|
+
try {
|
|
2206
|
+
const raw = await fsp2.readFile(path2.join(this.dir, "active.json"), "utf8");
|
|
2207
|
+
const active = JSON.parse(raw);
|
|
2208
|
+
return active.sessionId ?? null;
|
|
2209
|
+
} catch {
|
|
2210
|
+
return null;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2196
2213
|
async delete(id) {
|
|
2214
|
+
const activeId = await this.readActiveSessionId();
|
|
2215
|
+
if (activeId && id === activeId) {
|
|
2216
|
+
throw new Error(
|
|
2217
|
+
`Session ${id} is currently active in this project and cannot be deleted. Resume or start another session first.`
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2220
|
+
if (this.isSessionInUse) {
|
|
2221
|
+
const reason = await this.isSessionInUse(id);
|
|
2222
|
+
if (reason) {
|
|
2223
|
+
throw new Error(`Session ${id} is in use (${reason}) and cannot be deleted.`);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2197
2226
|
await this.deleteSession(id);
|
|
2198
2227
|
}
|
|
2228
|
+
async rename(id, name) {
|
|
2229
|
+
const trimmed = name.trim();
|
|
2230
|
+
const manifest = this.sessionPath(id, ".summary.json");
|
|
2231
|
+
const jsonlPath = this.sessionPath(id, ".jsonl");
|
|
2232
|
+
try {
|
|
2233
|
+
await fsp2.stat(jsonlPath);
|
|
2234
|
+
} catch (err) {
|
|
2235
|
+
const code = err?.code;
|
|
2236
|
+
if (code === "ENOENT") {
|
|
2237
|
+
throw new Error(`Session not found: ${id}`);
|
|
2238
|
+
}
|
|
2239
|
+
throw err;
|
|
2240
|
+
}
|
|
2241
|
+
const summary = await this.summaryFor(id);
|
|
2242
|
+
const { name: _drop, ...rest } = summary;
|
|
2243
|
+
const updated = trimmed ? { ...rest, name: trimmed } : rest;
|
|
2244
|
+
const t0 = Date.now();
|
|
2245
|
+
let outcome = "success";
|
|
2246
|
+
let errorMsg;
|
|
2247
|
+
try {
|
|
2248
|
+
await atomicWrite(manifest, JSON.stringify(updated), { mode: 384 });
|
|
2249
|
+
} catch (err) {
|
|
2250
|
+
outcome = "failure";
|
|
2251
|
+
errorMsg = toErrorMessage(err);
|
|
2252
|
+
this.emitError(id, manifest, "rename", errorMsg, false);
|
|
2253
|
+
throw err;
|
|
2254
|
+
} finally {
|
|
2255
|
+
this.emitWrite(id, manifest, "close", outcome, Date.now() - t0, void 0, errorMsg);
|
|
2256
|
+
}
|
|
2257
|
+
await this.appendToIndex(updated);
|
|
2258
|
+
this.invalidateShardManifestBySessionId(id);
|
|
2259
|
+
this._indexCache = null;
|
|
2260
|
+
this.clearLoadCache(id);
|
|
2261
|
+
return updated;
|
|
2262
|
+
}
|
|
2199
2263
|
async prune(maxAgeDays = 30) {
|
|
2200
2264
|
const cutoff = Date.now() - maxAgeDays * 864e5;
|
|
2201
2265
|
let deleted = 0;
|
|
2202
|
-
|
|
2203
|
-
try {
|
|
2204
|
-
const raw = await fsp2.readFile(path2.join(this.dir, "active.json"), "utf8");
|
|
2205
|
-
const active = JSON.parse(raw);
|
|
2206
|
-
activeSessionId = active.sessionId ?? null;
|
|
2207
|
-
} catch {
|
|
2208
|
-
}
|
|
2266
|
+
const activeSessionId = await this.readActiveSessionId();
|
|
2209
2267
|
const isPrunableJsonl = (name) => name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
|
|
2210
2268
|
const pruneFile = async (dir, name, prefix) => {
|
|
2211
2269
|
const jsonlPath = path2.join(dir, name);
|
|
@@ -3937,14 +3995,21 @@ function simpleHash(s) {
|
|
|
3937
3995
|
}
|
|
3938
3996
|
return Math.abs(h).toString(36);
|
|
3939
3997
|
}
|
|
3998
|
+
var textCache = /* @__PURE__ */ new Map();
|
|
3999
|
+
var rootCandidates;
|
|
3940
4000
|
function readBundledInstructionText(relativePath) {
|
|
4001
|
+
const cached = textCache.get(relativePath);
|
|
4002
|
+
if (cached !== void 0) return cached;
|
|
4003
|
+
let resolved = "";
|
|
3941
4004
|
for (const root of instructionRootCandidates()) {
|
|
3942
4005
|
try {
|
|
3943
|
-
|
|
4006
|
+
resolved = readFileSync(path2.join(root, relativePath), "utf8").trimEnd();
|
|
4007
|
+
break;
|
|
3944
4008
|
} catch {
|
|
3945
4009
|
}
|
|
3946
4010
|
}
|
|
3947
|
-
|
|
4011
|
+
textCache.set(relativePath, resolved);
|
|
4012
|
+
return resolved;
|
|
3948
4013
|
}
|
|
3949
4014
|
function renderInstructionTemplate(template, values) {
|
|
3950
4015
|
return template.replace(
|
|
@@ -3953,13 +4018,15 @@ function renderInstructionTemplate(template, values) {
|
|
|
3953
4018
|
);
|
|
3954
4019
|
}
|
|
3955
4020
|
function instructionRootCandidates() {
|
|
4021
|
+
if (rootCandidates !== void 0) return rootCandidates;
|
|
3956
4022
|
const here = path2.dirname(fileURLToPath(import.meta.url));
|
|
3957
4023
|
const candidates = [
|
|
3958
4024
|
path2.resolve(here, "../../instructions"),
|
|
3959
4025
|
path2.resolve(here, "../instructions"),
|
|
3960
4026
|
path2.resolve(here, "instructions")
|
|
3961
4027
|
];
|
|
3962
|
-
|
|
4028
|
+
rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
|
|
4029
|
+
return rootCandidates;
|
|
3963
4030
|
}
|
|
3964
4031
|
function isDirectory(candidate) {
|
|
3965
4032
|
try {
|
|
@@ -4594,7 +4661,11 @@ var KNOWN_DENIED_IN_PROJECT = [
|
|
|
4594
4661
|
{ key: "yolo", reason: "Disables all permission confirmation prompts." },
|
|
4595
4662
|
{ key: "extensions", reason: "Per-plugin config can carry command/credential fields." },
|
|
4596
4663
|
{ key: "hq", reason: "Carries HQ client token credential and endpoint URL." },
|
|
4597
|
-
{ key: "acp", reason: "Per-agent ACP command/args/env override \u2192 arbitrary command exec (RCE)." }
|
|
4664
|
+
{ key: "acp", reason: "Per-agent ACP command/args/env override \u2192 arbitrary command exec (RCE)." },
|
|
4665
|
+
{
|
|
4666
|
+
key: "fleet",
|
|
4667
|
+
reason: "Fleet supervision knobs: a repo-committed config could enable autonomous subagent spawning/steering/termination and mailbox traffic on the victim machine."
|
|
4668
|
+
}
|
|
4598
4669
|
];
|
|
4599
4670
|
var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
4600
4671
|
"version",
|
|
@@ -4636,7 +4707,8 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
4636
4707
|
"hq",
|
|
4637
4708
|
"sync",
|
|
4638
4709
|
"extensions",
|
|
4639
|
-
"acp"
|
|
4710
|
+
"acp",
|
|
4711
|
+
"fleet"
|
|
4640
4712
|
]);
|
|
4641
4713
|
function assertInProjectAllowListComplete() {
|
|
4642
4714
|
const missingFromBoth = [];
|
|
@@ -9236,6 +9308,82 @@ var PromptUsageStore = class {
|
|
|
9236
9308
|
).slice(0, limit);
|
|
9237
9309
|
}
|
|
9238
9310
|
};
|
|
9311
|
+
var INPUT_HISTORY_DEFAULT_MAX = 100;
|
|
9312
|
+
var InputHistoryStore = class {
|
|
9313
|
+
/**
|
|
9314
|
+
* @param file Absolute path to the per-project input-history.json.
|
|
9315
|
+
* @param scrubber SecretScrubber used to filter secrets before write.
|
|
9316
|
+
* @param maxEntries Cap on the number of entries persisted. Default 100.
|
|
9317
|
+
*/
|
|
9318
|
+
constructor(file, scrubber, maxEntries = INPUT_HISTORY_DEFAULT_MAX) {
|
|
9319
|
+
this.file = file;
|
|
9320
|
+
this.scrubber = scrubber;
|
|
9321
|
+
this.maxEntries = maxEntries;
|
|
9322
|
+
}
|
|
9323
|
+
file;
|
|
9324
|
+
scrubber;
|
|
9325
|
+
maxEntries;
|
|
9326
|
+
/**
|
|
9327
|
+
* Load the persisted entries. Missing or corrupt file → empty list
|
|
9328
|
+
* (never throws — history is best-effort).
|
|
9329
|
+
*/
|
|
9330
|
+
async load() {
|
|
9331
|
+
try {
|
|
9332
|
+
const raw = JSON.parse(await fsp2.readFile(this.file, "utf8"));
|
|
9333
|
+
if (raw && typeof raw === "object" && Array.isArray(raw.entries) && raw.entries.every((e) => typeof e === "string")) {
|
|
9334
|
+
return raw.entries.slice(0, this.maxEntries);
|
|
9335
|
+
}
|
|
9336
|
+
} catch {
|
|
9337
|
+
}
|
|
9338
|
+
return [];
|
|
9339
|
+
}
|
|
9340
|
+
/**
|
|
9341
|
+
* Persist `entries` to disk after scrubbing each one. Entries that still
|
|
9342
|
+
* contain a redaction marker AFTER scrubbing are dropped — a half-scrubbed
|
|
9343
|
+
* prompt like "export API_KEY=***REDACTED***" is useless as history and
|
|
9344
|
+
* keeping it risks confusing the agent. Dedup is the caller's job (the
|
|
9345
|
+
* reducer already dedups); this method only scrubs, caps, and writes.
|
|
9346
|
+
*/
|
|
9347
|
+
async save(entries) {
|
|
9348
|
+
const cleaned = this.scrubAndFilter(entries);
|
|
9349
|
+
await ensureDir(path2.dirname(this.file));
|
|
9350
|
+
const payload = {
|
|
9351
|
+
version: 1,
|
|
9352
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9353
|
+
entries: cleaned
|
|
9354
|
+
};
|
|
9355
|
+
await atomicWrite(this.file, JSON.stringify(payload, null, 2));
|
|
9356
|
+
}
|
|
9357
|
+
/** Truncate the file to an empty entry list (used by /clear). */
|
|
9358
|
+
async clear() {
|
|
9359
|
+
await ensureDir(path2.dirname(this.file));
|
|
9360
|
+
const payload = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: [] };
|
|
9361
|
+
await atomicWrite(this.file, JSON.stringify(payload, null, 2));
|
|
9362
|
+
}
|
|
9363
|
+
/**
|
|
9364
|
+
* Run each entry through the scrubber and drop any that still contain a
|
|
9365
|
+
* redaction marker. Internal so the test suite can pin the policy.
|
|
9366
|
+
*/
|
|
9367
|
+
scrubAndFilter(entries) {
|
|
9368
|
+
const out = [];
|
|
9369
|
+
for (const entry of entries) {
|
|
9370
|
+
const scrubbed = this.scrubber.scrub(entry);
|
|
9371
|
+
if (this.looksRedacted(scrubbed)) continue;
|
|
9372
|
+
out.push(scrubbed);
|
|
9373
|
+
}
|
|
9374
|
+
return out.slice(0, this.maxEntries);
|
|
9375
|
+
}
|
|
9376
|
+
/**
|
|
9377
|
+
* Heuristic: did the scrubber actually redact anything? DefaultSecretScrubber
|
|
9378
|
+
* replaces matches with "***REDACTED***", so a residual marker means a secret
|
|
9379
|
+
* was detected. Subclasses of SecretScrubber that use a different sentinel
|
|
9380
|
+
* can be accommodated by widening this check in the future; for now the
|
|
9381
|
+
* marker check covers the shipped scrubber.
|
|
9382
|
+
*/
|
|
9383
|
+
looksRedacted(text) {
|
|
9384
|
+
return text.includes("***REDACTED***");
|
|
9385
|
+
}
|
|
9386
|
+
};
|
|
9239
9387
|
var ALL_SYNC_CATEGORIES = ["settings", "skills", "prompts", "memory", "history"];
|
|
9240
9388
|
var CloudSync = class {
|
|
9241
9389
|
constructor(paths, getConfig, setConfig) {
|
|
@@ -9691,6 +9839,6 @@ function resolveSessionLoggingConfig(cfg) {
|
|
|
9691
9839
|
};
|
|
9692
9840
|
}
|
|
9693
9841
|
|
|
9694
|
-
export { ALL_SYNC_CATEGORIES, AgentStatusTracker, AnnotationsStore, CORE_RECONSTRUCT_EVENTS, CloudSync, ConfigMigrationError, DEFAULT_CONFIG_MIGRATIONS, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultMemoryStore, DefaultPromptStore, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DirectorStateCheckpoint, FileMemoryBackend, FleetNotifier, GraphMemoryBackend, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, PromptUsageStore, QueueStore, RecoveryLock, ReplayLogStore, STANDARD_AUDIT_EVENTS, SessionAnalyzer, SessionMemoryConsolidator, SessionRecovery, SessionRegistry, ToolAuditLog, addPlanItem, appendJournal, attachPlanCheckpoint, attachTodosCheckpoint, clearPlan, createSessionEventBridge, deriveTodosFromPlanItem, emptyGoal, emptyPlan, emptyTaskFile, formatGoal, formatPlan, formatPlanTemplates, generateSessionId, getPlanTemplate, getSessionRegistry, goalFilePath, hasSessionRegistry, listPlanTemplates, loadCompletedWorkCheckpoint, loadDirectorState, loadGoal, loadPlan, loadTasks, loadTodosCheckpoint, migratePromptEntry, mutatePlan, mutateTasks, parseEntries, parseProgressFromText, promptChecksum, recordProgress, removePlanItem, resolveAuditLevel, resolveSessionLoggingConfig, runConfigMigrations, sanitizeModel, saveCompletedWorkCheckpoint, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, setPlanItemStatus, setProgress, summarizeUsage, watchProviderConfig };
|
|
9842
|
+
export { ALL_SYNC_CATEGORIES, AgentStatusTracker, AnnotationsStore, CORE_RECONSTRUCT_EVENTS, CloudSync, ConfigMigrationError, DEFAULT_CONFIG_MIGRATIONS, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultMemoryStore, DefaultPromptStore, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DirectorStateCheckpoint, FileMemoryBackend, FleetNotifier, GraphMemoryBackend, INPUT_HISTORY_DEFAULT_MAX, InputHistoryStore, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, PromptUsageStore, QueueStore, RecoveryLock, ReplayLogStore, STANDARD_AUDIT_EVENTS, SessionAnalyzer, SessionMemoryConsolidator, SessionRecovery, SessionRegistry, ToolAuditLog, addPlanItem, appendJournal, attachPlanCheckpoint, attachTodosCheckpoint, clearPlan, createSessionEventBridge, deriveTodosFromPlanItem, emptyGoal, emptyPlan, emptyTaskFile, formatGoal, formatPlan, formatPlanTemplates, generateSessionId, getPlanTemplate, getSessionRegistry, goalFilePath, hasSessionRegistry, listPlanTemplates, loadCompletedWorkCheckpoint, loadDirectorState, loadGoal, loadPlan, loadTasks, loadTodosCheckpoint, migratePromptEntry, mutatePlan, mutateTasks, parseEntries, parseProgressFromText, promptChecksum, recordProgress, removePlanItem, resolveAuditLevel, resolveSessionLoggingConfig, runConfigMigrations, sanitizeModel, saveCompletedWorkCheckpoint, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, setPlanItemStatus, setProgress, summarizeUsage, watchProviderConfig };
|
|
9695
9843
|
//# sourceMappingURL=index.js.map
|
|
9696
9844
|
//# sourceMappingURL=index.js.map
|