@wrongstack/core 0.309.0 → 0.310.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.
Files changed (129) hide show
  1. package/dist/chronicle/index.js +113 -41
  2. package/dist/chronicle/metrics-ingest.d.ts +7 -0
  3. package/dist/chronicle/metrics-schema.d.ts +4 -1
  4. package/dist/chronicle/project-server.js +94 -38
  5. package/dist/chronicle/query.d.ts +1 -0
  6. package/dist/chronicle/sqlite-journal-schema.d.ts +2 -1
  7. package/dist/chronicle/types.d.ts +2 -0
  8. package/dist/{agent-status-helpers.d.ts → coordination/agent-status-helpers.d.ts} +1 -1
  9. package/dist/{agent-status-tracker.d.ts → coordination/agent-status-tracker.d.ts} +2 -2
  10. package/dist/{middleware → coordination}/collab-pause.d.ts +1 -1
  11. package/dist/coordination/director-kanban-queue-helpers.d.ts +1 -1
  12. package/dist/coordination/director.d.ts +7 -0
  13. package/dist/coordination/explore-companion.d.ts +9 -6
  14. package/dist/coordination/fleet-status-tool.d.ts +1 -1
  15. package/dist/coordination/index.d.ts +5 -1
  16. package/dist/coordination/index.js +2392 -405
  17. package/dist/coordination/kanban-dispatch-port.d.ts +30 -0
  18. package/dist/coordination/kanban-ops-port.d.ts +21 -0
  19. package/dist/coordination/mailbox-hooks.d.ts +1 -1
  20. package/dist/coordination/mailbox-project-server.js +14 -9
  21. package/dist/coordination/mutation-engine.d.ts +5 -3
  22. package/dist/core/context.d.ts +35 -44
  23. package/dist/core/conversation-state.d.ts +16 -52
  24. package/dist/core/index.js +92 -25
  25. package/dist/core/provider-runner.d.ts +2 -2
  26. package/dist/core/run-env.d.ts +7 -28
  27. package/dist/core/streaming-response-builder.d.ts +2 -2
  28. package/dist/execution/index.js +138 -162
  29. package/dist/goal/index.js +100 -22
  30. package/dist/hq/auth-store.d.ts +9 -0
  31. package/dist/hq/cost-bridge.d.ts +1 -1
  32. package/dist/hq/index.js +69 -7
  33. package/dist/index.d.ts +12 -5
  34. package/dist/index.js +21185 -26807
  35. package/dist/infrastructure/index.js +232 -135
  36. package/dist/infrastructure/provider-cache-ledger.d.ts +1 -1
  37. package/dist/infrastructure/token-counter.d.ts +5 -1
  38. package/dist/kernel/events/file-events.d.ts +6 -0
  39. package/dist/kernel/events/provider-events.d.ts +10 -7
  40. package/dist/kernel/events/session-events.d.ts +4 -4
  41. package/dist/kernel/events/tool-events.d.ts +12 -2
  42. package/dist/observability/index.js +1 -1
  43. package/dist/plugin/index.js +218 -47
  44. package/dist/prompts/index.js +360 -3
  45. package/dist/security/auto-approve-policy.d.ts +2 -2
  46. package/dist/security/index.d.ts +1 -0
  47. package/dist/security/index.js +224 -68
  48. package/dist/security/kanban-boundary.d.ts +1 -1
  49. package/dist/security/kanban-governance-port.d.ts +28 -0
  50. package/dist/security/permission-helpers.d.ts +11 -0
  51. package/dist/security/permission-policy.d.ts +10 -1
  52. package/dist/security/yolo-risk.d.ts +17 -0
  53. package/dist/session-catalog/index.js +34 -5
  54. package/dist/session-catalog/project-server.js +34 -5
  55. package/dist/session-catalog/protocol.d.ts +1 -1
  56. package/dist/session-catalog/registry.d.ts +1 -1
  57. package/dist/session-catalog/store-schema.d.ts +1 -1
  58. package/dist/session-catalog/store.d.ts +1 -1
  59. package/dist/skills/index.js +39 -6
  60. package/dist/storage/annotations-store.d.ts +1 -1
  61. package/dist/storage/board-store-port.d.ts +45 -0
  62. package/dist/storage/completed-work-checkpoint.d.ts +1 -1
  63. package/dist/storage/config-loader/types.d.ts +1 -1
  64. package/dist/storage/event-bus-port.d.ts +27 -0
  65. package/dist/storage/file-session-writer.d.ts +47 -5
  66. package/dist/storage/goal-coordination.d.ts +1 -1
  67. package/dist/storage/goal-store.d.ts +1 -1
  68. package/dist/storage/index.d.ts +3 -4
  69. package/dist/storage/index.js +1107 -1462
  70. package/dist/storage/plan-store.d.ts +1 -1
  71. package/dist/storage/queue-store.d.ts +1 -1
  72. package/dist/storage/replay-log-store.d.ts +1 -1
  73. package/dist/storage/session-recovery.d.ts +10 -0
  74. package/dist/storage/session-resume-validation.d.ts +13 -1
  75. package/dist/storage/session-store/events.d.ts +1 -1
  76. package/dist/storage/session-store/load-session-data.d.ts +1 -1
  77. package/dist/storage/session-store/rename-session.d.ts +1 -1
  78. package/dist/storage/session-store/resume-session.d.ts +3 -1
  79. package/dist/storage/session-store/session-store-index.d.ts +2 -1
  80. package/dist/storage/session-store/types.d.ts +1 -1
  81. package/dist/storage/session-store.d.ts +70 -0
  82. package/dist/storage/session-summary-tracker.d.ts +8 -0
  83. package/dist/storage/session-write-buffer.d.ts +31 -2
  84. package/dist/storage/task-store.d.ts +1 -1
  85. package/dist/storage/todos-checkpoint.d.ts +1 -1
  86. package/dist/storage/tool-audit-log.d.ts +1 -1
  87. package/dist/tasking/index.js +100 -22
  88. package/dist/tasking/task-tracker.d.ts +24 -1
  89. package/dist/types/compactor.d.ts +2 -2
  90. package/dist/types/context.d.ts +212 -0
  91. package/dist/types/conversation-state.d.ts +109 -0
  92. package/dist/types/error-handler.d.ts +2 -2
  93. package/dist/types/file-event-record.d.ts +6 -0
  94. package/dist/types/index.d.ts +3 -3
  95. package/dist/types/index.js +17 -1
  96. package/dist/types/permission.d.ts +3 -3
  97. package/dist/types/plugin.d.ts +3 -3
  98. package/dist/types/provider-runner.d.ts +2 -2
  99. package/dist/types/provider.d.ts +10 -0
  100. package/dist/types/run-env.d.ts +32 -0
  101. package/dist/types/session.d.ts +3 -0
  102. package/dist/types/slash-command.d.ts +2 -2
  103. package/dist/types/token-counter.d.ts +30 -1
  104. package/dist/types/tool-executor.d.ts +2 -2
  105. package/dist/types/tool.d.ts +20 -5
  106. package/dist/utils/context-breakdown.d.ts +2 -2
  107. package/dist/utils/context-evidence.d.ts +12 -12
  108. package/dist/utils/crash-shield.d.ts +9 -0
  109. package/dist/utils/heap-watchdog.js +11 -3
  110. package/dist/utils/index.d.ts +2 -1
  111. package/dist/utils/index.js +126 -160
  112. package/dist/utils/regex-guard.d.ts +7 -30
  113. package/dist/utils/terminal-sanitize.d.ts +41 -0
  114. package/dist/utils/todos-format.d.ts +1 -1
  115. package/dist/utils/tool-subject.d.ts +1 -1
  116. package/dist/utils/tree-kill.d.ts +2 -0
  117. package/dist/utils/tree-kill.js +1 -0
  118. package/instructions/agents/chaos-monkey.md +5 -1
  119. package/instructions/coordination/subagent-baseline.md +10 -0
  120. package/instructions/system-lite.md +2 -0
  121. package/instructions/system-pro.md +40 -0
  122. package/instructions/system.md +15 -0
  123. package/package.json +7 -10
  124. package/dist/defaults/index.d.ts +0 -69
  125. package/dist/defaults/index.js +0 -37755
  126. /package/dist/{fleet-notifier.d.ts → coordination/fleet-notifier.d.ts} +0 -0
  127. /package/dist/{session-registry-atomic-file.d.ts → session-catalog/session-registry-atomic-file.d.ts} +0 -0
  128. /package/dist/{session-registry-types.d.ts → session-catalog/session-registry-types.d.ts} +0 -0
  129. /package/dist/{session-registry.d.ts → session-catalog/session-registry.d.ts} +0 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * AgentContext — the structural contract of the agent-run object.
3
+ *
4
+ * Dependency-leaf module (Roadmap 10A): imports ONLY from sibling `types/*`
5
+ * modules. The concrete `Context` class (core/context.ts) implements this
6
+ * interface; tsc enforces structural compatibility on every build, so the
7
+ * interface cannot drift from the class silently.
8
+ *
9
+ * Why this exists: the CYCLE-12 type SCC was caused by `types/*.ts` and
10
+ * `utils/*` modules importing the `Context` CLASS type back from
11
+ * `core/context.ts`. Consumers below declare `AgentContext` instead — the
12
+ * back-edge disappears while the class stays the single implementation.
13
+ *
14
+ * Scope (2026-08-23): only `types/compactor.ts` and `conversation-state.ts`
15
+ * consume `AgentContext` today. Six back-edges on the `Context` class type
16
+ * remain (`types/tool.ts`, `types/error-handler.ts`, `types/provider-runner.ts`,
17
+ * `types/permission.ts`, `types/slash-command.ts`, `types/plugin.ts`) — they
18
+ * require the full class surface (state, file-tracking, catalogTools) which
19
+ * needs `ConversationState` resolved in this leaf first. Do not claim
20
+ * acyclicity until those flip.
21
+ *
22
+ * Statics (`Context.MAX_MESSAGES`, `Context.MAX_MESSAGE_TOKENS`) are read
23
+ * through the `messageLimits` accessor so runtime subclass overrides keep
24
+ * working (the reason the old `ctx.constructor` cast existed) without any
25
+ * consumer importing the class type.
26
+ */
27
+ import type { ContextEvidenceState } from './context-evidence.js';
28
+ import type { ConversationStateApi } from './conversation-state.js';
29
+ import type { TextBlock } from './blocks.js';
30
+ import type { FileEventRecord } from './file-event-record.js';
31
+ import type { Message } from './messages.js';
32
+ import type { Usage } from './provider.js';
33
+ import type { RunEnv } from './run-env.js';
34
+ import type { SessionEvent, SessionWriter } from './session.js';
35
+ import type { SideEffect } from './side-effect.js';
36
+ import type { Tool } from './tool.js';
37
+ /** A single todo row projected to the model and the UI. */
38
+ export interface TodoItem {
39
+ id: string;
40
+ content: string;
41
+ status: 'pending' | 'in_progress' | 'completed';
42
+ activeForm?: string | undefined;
43
+ /** When promoted from a plan item, stores the plan item's id. */
44
+ promotedFromPlan?: string | undefined;
45
+ /** When promoted from a task, stores the task's id. */
46
+ promotedFromTask?: string | undefined;
47
+ /** Durable Kanban owner when the todo row is a UI projection of a real card. */
48
+ kanbanBoardId?: string | undefined;
49
+ /** Durable Kanban card represented by this todo row. */
50
+ kanbanTaskId?: string | undefined;
51
+ /** Titles of the unfinished work this row waits on (board-derived). */
52
+ blockedBy?: string[] | undefined;
53
+ }
54
+ /** Conversation retention limits, honoring runtime subclass overrides. */
55
+ export interface ContextMessageLimits {
56
+ readonly maxMessages: number;
57
+ readonly maxMessageTokens: number;
58
+ }
59
+ /**
60
+ * Provider-bound memory evidence kept outside conversation history.
61
+ * Owners replace their own slot instead of appending (see class JSDoc).
62
+ */
63
+ export interface ProviderMemoryEvidence {
64
+ /** Stable owner key, for example `sage.tool-memory`. */
65
+ source: string;
66
+ /** Provider-bound evidence text; never appended to chat/tool history. */
67
+ text: string;
68
+ }
69
+ /**
70
+ * The conversation-facing surface of the run object — the COMPLETE instance
71
+ * surface of the `Context` class (Roadmap 10A close-out). Mirrored 1:1 from
72
+ * the class declaration; `class Context implements RunEnv, AgentContext`
73
+ * makes tsc enforce compatibility on every core build.
74
+ */
75
+ export interface AgentContext extends RunEnv {
76
+ messages: Message[];
77
+ meta: Record<string, unknown>;
78
+ todos: TodoItem[];
79
+ toolAdjacencyDirty: boolean;
80
+ systemPrompt: TextBlock[];
81
+ tools: Tool[];
82
+ contextEvidence: ContextEvidenceState;
83
+ /** Observable mutation wrapper; the concrete class satisfies this structurally. */
84
+ readonly state: ConversationStateApi;
85
+ registerAbortHook(fn: () => void | Promise<void>): () => void;
86
+ /** Retention limits honoring runtime subclass overrides of the statics. */
87
+ readonly messageLimits: ContextMessageLimits;
88
+ /**
89
+ * File-tracking surface (see the Context class for full semantics).
90
+ * `readFiles` is the permission write-bypass source of truth — it must
91
+ * NEVER contain files only touched by edit/write.
92
+ */
93
+ readFiles: Set<string>;
94
+ /** Files written by edit/write this session (observability only). */
95
+ writtenFiles: Set<string>;
96
+ /** Last-known mtime per tracked path; permission + edit-staleness checks. */
97
+ fileMtimes: Map<string, number>;
98
+ /** sha-256 (hex) at last recorded read/write; authoritative staleness arbiter. */
99
+ fileHashes: Map<string, string>;
100
+ /**
101
+ * Record a file observation. `source: 'write'` routes to writtenFiles;
102
+ * 'user' (default) routes to readFiles. `contentHash`, when available,
103
+ * becomes the authoritative staleness arbiter for later edits.
104
+ */
105
+ recordRead(absPath: string, mtimeMs: number, source?: 'user' | 'write', contentHash?: string): void;
106
+ /** Tool instances visible to tool_search/catalog surfaces. */
107
+ catalogTools: Tool[];
108
+ /** Structured side-effect records for the current run (bounded, MAX_SIDE_EFFECTS). */
109
+ sideEffects: SideEffect[];
110
+ /** Tracked file events for the current session (bounded, MAX_FILE_EVENTS). */
111
+ fileEvents: FileEventRecord[];
112
+ /** When false (default), file tools reject paths outside projectRoot. */
113
+ allowOutsideProjectRoot: boolean;
114
+ /** Current kanban task ID; tools use this via recordFileEvent() for task scope. */
115
+ currentKanbanTaskId: string | undefined;
116
+ /** Current kanban board ID, paired with currentKanbanTaskId. */
117
+ currentKanbanBoardId: string | undefined;
118
+ /** Session-level trace ID for correlating storage events with agent iterations. */
119
+ traceId: string | undefined;
120
+ /** Logical provider request whose response produced the current tool calls. */
121
+ activeLogicalRequestId: string | undefined;
122
+ /** Content-addressed prompt composition for activeLogicalRequestId. */
123
+ activePromptManifestId: string | undefined;
124
+ /**
125
+ * Session id pinned to the currently-executing run; event sites must
126
+ * prefer this over session.id (see Context class for session-swap
127
+ * rationale).
128
+ */
129
+ activeRunSessionId: string | undefined;
130
+ /** Writer pinned alongside activeRunSessionId for run-scoped appends. */
131
+ activeRunSessionWriter: SessionWriter | undefined;
132
+ /**
133
+ * Session id that events of the in-flight run must be stamped with:
134
+ * run-pinned id when active, otherwise the live session id.
135
+ */
136
+ eventSessionId(): string;
137
+ /** WorkingDir-change callbacks; public for structural typing. */
138
+ readonly _onWorkingDirChanged: Array<(newDir: string, oldDir: string) => void>;
139
+ /** Barrier serializing externally requested provider/model changes. */
140
+ _modelTransition: Promise<void>;
141
+ runModelTransition<T>(transition: () => T | Promise<T>): Promise<T>;
142
+ waitForModelTransition(): Promise<void>;
143
+ /** True when conversation gained new tool_use/tool_result blocks (adjacency repair). */
144
+ pendingPostToolContext: string | undefined;
145
+ /** Provider-bound memory evidence outside conversation/tool history. */
146
+ memoryEvidence: ProviderMemoryEvidence[];
147
+ setMemoryEvidence(source: string, text: string | undefined, maxChars?: number): void;
148
+ clearMemoryEvidence(source?: string): void;
149
+ /** Pre-computed total-request token estimate from the last pre-flight. */
150
+ lastRequestTokens: number | undefined;
151
+ /** Provider-authoritative prompt-token count from the most recent response. */
152
+ lastRealInputTokens: number | undefined;
153
+ /** Lazy observable wrapper backing `state`. */
154
+ _state: ConversationStateApi | null;
155
+ readonly _conversationJournalQueue: Array<{
156
+ event: SessionEvent;
157
+ bytes: number;
158
+ writer: SessionWriter;
159
+ }>;
160
+ _conversationJournalBytes: number;
161
+ _conversationJournalDrain: Promise<void> | null;
162
+ /** Wait until every exact conversation event queued so far is in the writer buffer. */
163
+ flushConversationJournal(): Promise<void>;
164
+ conversationJournalBytes(event: SessionEvent): number;
165
+ _journalDropCount: number;
166
+ _journalDropWarnAt: number;
167
+ /** Throttled notice that a conversation event never reached the journal. */
168
+ warnConversationJournalDrop(eventType: SessionEvent['type']): void;
169
+ enqueueConversationJournal(event: SessionEvent, writer: SessionWriter): void;
170
+ startConversationJournalDrain(): void;
171
+ /** Run-scoped abort hooks (drained by drainAbortHooks). */
172
+ readonly abortHooks: Set<() => void | Promise<void>>;
173
+ registerAgentHook(fn: () => void | Promise<void>): () => void;
174
+ drainAbortHooks(): Promise<void>;
175
+ /** Session-lifetime teardown hooks (drained by drainAgentHooks). */
176
+ readonly agentHooks: Set<() => void | Promise<void>>;
177
+ drainAgentHooks(): Promise<void>;
178
+ /** Enforce MAX_TRACKED_FILES cap on all four tracking structures. */
179
+ trimTrackedFiles(): void;
180
+ /** Clear accumulated file-read metadata after compaction/boundaries. */
181
+ clearFileTracking(): void;
182
+ /** Record a structured side effect for the audit trail (no undo). */
183
+ recordSideEffect(sideEffect: SideEffect): void;
184
+ /** Set the current kanban task context for file operations. */
185
+ setCurrentKanbanTask(taskId: string | undefined, boardId?: string | undefined): void;
186
+ /** Record a comprehensive file event (audit trail + JSONL persistence). */
187
+ recordFileEvent(input: {
188
+ operation: 'create' | 'read' | 'update' | 'delete' | 'rename';
189
+ filePath: string;
190
+ absPath: string;
191
+ toolName: string;
192
+ toolUseId: string;
193
+ durationMs?: number | undefined;
194
+ fileSize?: number | undefined;
195
+ lines?: number | undefined;
196
+ bytes?: number | undefined;
197
+ }): void;
198
+ /** True if the model/user explicitly saw this file's content. */
199
+ hasRead(absPath: string): boolean;
200
+ /** True if edit/write wrote this file in the current session. */
201
+ hasWritten(absPath: string): boolean;
202
+ lastReadMtime(absPath: string): number | undefined;
203
+ /** sha-256 (hex) of the content at the last recorded read/write, if any. */
204
+ lastReadHash(absPath: string): string | undefined;
205
+ /** Change the working directory (validated within projectRoot); fires callbacks. */
206
+ setWorkingDir(dir: string): string;
207
+ /** Register a workingDir-change callback; returns unsubscribe. */
208
+ onWorkingDirChanged(cb: (newDir: string, oldDir: string) => void): () => void;
209
+ /** Current usage snapshot from tokenCounter. */
210
+ usage(): Usage;
211
+ }
212
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Conversation-state type leaf (Roadmap 10A).
3
+ *
4
+ * Dependency-leaf module: imports ONLY from sibling `types/*` modules. The
5
+ * concrete `ConversationState` class stays in `core/conversation-state.ts`
6
+ * (it has a runtime dep on `utils/token-estimate.js`); this leaf carries its
7
+ * TYPE surface so `AgentContext` (types/context.ts) can declare
8
+ * `state: ConversationStateApi` without importing the class module — the
9
+ * remaining CYCLE-12 back-edge (`types/tool.ts` et al. → `core/context.ts`)
10
+ * needs exactly this to flip.
11
+ *
12
+ * The class satisfies `ConversationStateApi` structurally; tsc enforces the
13
+ * compatibility on every build of core (the class re-exports these types for
14
+ * existing import paths).
15
+ */
16
+ import type { ContentBlock } from './blocks.js';
17
+ import type { TodoItem } from './context.js';
18
+ import type { Message } from './messages.js';
19
+ export type StateChange = {
20
+ kind: 'message_appended';
21
+ message: Message;
22
+ } | {
23
+ kind: 'messages_replaced';
24
+ messages: readonly Message[];
25
+ }
26
+ /** The oldest `count` messages were evicted; see the `messages_dropped` SessionEvent. */
27
+ | {
28
+ kind: 'messages_dropped';
29
+ count: number;
30
+ } | {
31
+ kind: 'message_updated';
32
+ index: number;
33
+ message: Message;
34
+ } | {
35
+ kind: 'todos_replaced';
36
+ todos: readonly TodoItem[];
37
+ /**
38
+ * Final all-completed snapshot when the tactical list auto-clears.
39
+ * Observational mirrors use this to move cards to Done instead of
40
+ * interpreting the empty active list as "the work vanished".
41
+ */
42
+ completedSnapshot?: readonly TodoItem[] | undefined;
43
+ } | {
44
+ kind: 'meta_set';
45
+ key: string;
46
+ value: unknown;
47
+ } | {
48
+ kind: 'meta_deleted';
49
+ key: string;
50
+ } | {
51
+ kind: 'meta_cleared';
52
+ };
53
+ export interface ReadonlyConversationState {
54
+ readonly messages: readonly Message[];
55
+ readonly todos: readonly TodoItem[];
56
+ readonly meta: Readonly<Record<string, unknown>>;
57
+ }
58
+ /**
59
+ * Structural API of the ConversationState wrapper — the COMPLETE instance
60
+ * surface of the concrete class in `core/conversation-state.ts` (Roadmap
61
+ * 10A). The class satisfies this interface structurally (it holds no
62
+ * private instance members), which makes `AgentContext.state` assignable
63
+ * both to the API and from the class — the property that lets the
64
+ * CYCLE-12 back-edges flip without importing the class module.
65
+ */
66
+ export interface ConversationStateApi {
67
+ readonly messages: readonly Message[];
68
+ readonly todos: readonly TodoItem[];
69
+ readonly meta: Readonly<Record<string, unknown>>;
70
+ /** Monotonic mutation counter for consumers that need to detect rewrites. */
71
+ readonly revision: number;
72
+ /** Cheap O(1)-freeze immutable snapshot (see class JSDoc for semantics). */
73
+ snapshot(): ReadonlyConversationState;
74
+ appendMessage(message: Message): void;
75
+ /**
76
+ * Append a content block to the trailing user message's content array.
77
+ * Returns false when there is no trailing user message to fold into.
78
+ */
79
+ appendBlockToLastUserMessage(block: ContentBlock): boolean;
80
+ replaceMessages(messages: Message[]): void;
81
+ replaceTodos(todos: TodoItem[]): void;
82
+ setMeta(key: string, value: unknown): void;
83
+ deleteMeta(key: string): void;
84
+ clearMeta(): void;
85
+ /**
86
+ * Subscribe to mutations that go through this wrapper. Direct mutations of
87
+ * the compatibility arrays are intentionally not observed. Returns an
88
+ * unsubscribe function.
89
+ */
90
+ onChange(listener: (change: StateChange, state: ConversationStateApi) => void): () => void;
91
+ /** Owning context the wrapper reads/mutates. */
92
+ readonly ctx: import('./context.js').AgentContext;
93
+ /**
94
+ * Registered change subscribers. The concrete class and this leaf both
95
+ * type the handler parameter identically (`state: ConversationStateApi`),
96
+ * so the class's Set is assignable in both directions without the class
97
+ * importing anything from this leaf — and without variance escapes.
98
+ */
99
+ listeners: Set<(change: StateChange, state: ConversationStateApi) => void>;
100
+ /** Backing mutation counter behind the `revision` getter. */
101
+ _revision: number;
102
+ /** Retention-cap overflow computation (see class JSDoc). */
103
+ overflowCount(arr: readonly Message[]): number;
104
+ /** Protocol-safe front-eviction boundary (see class JSDoc). */
105
+ protocolSafeDropCount(arr: readonly Message[], drop: number): number;
106
+ /** Notify subscribers of a mutation and bump the revision. */
107
+ emit(change: StateChange): void;
108
+ }
109
+ //# sourceMappingURL=conversation-state.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { Context } from '../core/context.js';
1
+ import type { AgentContext } from './context.js';
2
2
  import type { Response } from './provider.js';
3
3
  export type RecoveryDecision = {
4
4
  /**
@@ -30,7 +30,7 @@ export interface ErrorHandler {
30
30
  * retry the current turn, continue with a substitute response, or fail
31
31
  * deliberately. Callers should not infer control flow from truthiness.
32
32
  */
33
- recover(err: unknown, ctx: Context): Promise<RecoveryDecision | null>;
33
+ recover(err: unknown, ctx: AgentContext): Promise<RecoveryDecision | null>;
34
34
  classify(err: unknown): {
35
35
  kind: 'rate_limit' | 'overloaded' | 'server' | 'client' | 'network' | 'abort' | 'context_overflow' | 'content_filter' | 'unknown';
36
36
  retryable: boolean;
@@ -39,6 +39,12 @@ export interface FileEventRecord {
39
39
  provider: string;
40
40
  /** LLM model id (e.g. "claude-sonnet-4-20250514") */
41
41
  model: string;
42
+ /** Logical provider request that produced the mutating tool call. */
43
+ logicalRequestId?: string | undefined;
44
+ /** Content-addressed provider-visible prompt identity. */
45
+ promptManifestId?: string | undefined;
46
+ /** Strength of the prompt-to-file attribution edge. */
47
+ provenanceConfidence: 'explicit' | 'correlated' | 'inferred' | 'unknown';
42
48
  /** Tool that performed the operation (e.g. "read", "write", "edit") */
43
49
  toolName: string;
44
50
  /** Tool-use block correlation ID for pairing start/end */
@@ -7,7 +7,7 @@ export type { AdaptiveConcurrencyConfig, AgentLearningConfig, AutonomyConfig, Br
7
7
  export { DEFAULT_TUI_THINKING_WORD, FLEET_CHAT_VERBOSITY_VALUES, MAX_TUI_THINKING_WORD_LENGTH, normalizeTokenSavingTier, normalizeTuiThinkingWord, resolveFleetChatVerbosity, resolveTokenSavingTier, THEME_PRESET_IDS, } from './config.js';
8
8
  export type { CompletedWorkEvidence, CompletedWorkSource, ContextEvidenceState, ContextFileEvidence, ContextIntentEvidence, ContextRepeatedReadEvidence, ToolEvidenceStatus, ToolOutputMetadata, } from './context-evidence.js';
9
9
  export type { ContextSnapshot, ContextWindowAggressiveOn, ContextWindowConfigLike, ContextWindowMode, ContextWindowModeId, ContextWindowModeSelectionId, ContextWindowPolicy, ContextWindowThresholds, DeprecatedContextWindowModeId, } from './context-window.js';
10
- export { CONTEXT_WINDOW_MODES, CONTEXT_WINDOW_MODE_PINNED_META_KEY, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, LARGE_WINDOW_DEEP_MODE_THRESHOLD, formatContextWindowModeList, getContextWindowMode, isContextWindowModeId, isContextWindowModeSelectionId, isDeprecatedContextWindowModeId, listContextWindowModes, normalizeContextWindowModeId, resolveContextWindowPolicy, } from './context-window.js';
10
+ export { CONTEXT_WINDOW_MODE_PINNED_META_KEY, CONTEXT_WINDOW_MODES, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, formatContextWindowModeList, getContextWindowMode, isContextWindowModeId, isContextWindowModeSelectionId, isDeprecatedContextWindowModeId, LARGE_WINDOW_DEEP_MODE_THRESHOLD, listContextWindowModes, normalizeContextWindowModeId, resolveContextWindowPolicy, } from './context-window.js';
11
11
  export type { CouncilDistinctness, CouncilLLMCaller, CouncilModelTarget, CouncilOption, CouncilPersona, CouncilProfileConfig, CouncilQuestion, CouncilResolutionMethod, CouncilResult, CouncilSeatConfig, CouncilUsage, CouncilVoteResult, CouncilVoteStatus, ResolvedCouncilProfile, ResolvedCouncilSeat, } from './council.js';
12
12
  export { DEFAULT_AUTONOMY_CONFIG, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONTEXT_CONFIG, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_TOOLS_CONFIG, } from './default-config.js';
13
13
  export type { DesignKitEntry, DesignKitLoader, DesignKitManifest, DesignKitTokens, DesignStack, DesignStudioState, DesignTokenSet, TokenValueKind, } from './design-kit.js';
@@ -34,7 +34,7 @@ export { BUILTIN_PROMPT_CATEGORIES, isBuiltinCategory, PROMPT_CATEGORY_LABELS }
34
34
  export type { InstalledPromptEntry, ManifestValidation, PromptManifestData, PromptRegistryManifest, PromptRegistryRef, RegistryDiff, } from './prompt-registry.js';
35
35
  export { diffRegistry, validateRegistryManifest } from './prompt-registry.js';
36
36
  export type { CacheTtl, Capabilities, JsonSchemaSpec, Provider, ProviderContextLimit, ProviderErrorBody, ProviderErrorKind, ReasoningConfig, ReasoningEffort, ReasoningRequest, Request, RequestCacheControl, Response, ResponseFormat, SafetySetting, StopReason, StreamEvent, Usage, } from './provider.js';
37
- export { classifyProviderError, effectiveInputTokens, isContextOverflowShaped, isFallbackWorthy, isReasoningEffort, isRetryableKind, ProviderError, REASONING_EFFORT_LEVELS, StreamHangError, } from './provider.js';
37
+ export { classifyProviderError, effectiveInputTokens, freshInputTokens, isContextOverflowShaped, isFallbackWorthy, isReasoningEffort, isRetryableKind, ProviderError, promptCacheHitRatio, REASONING_EFFORT_LEVELS, StreamHangError, } from './provider.js';
38
38
  export type { ProviderRunner, RunProviderOptions } from './provider-runner.js';
39
39
  export type { Renderer } from './renderer.js';
40
40
  export type { SecretScrubber } from './secret-scrubber.js';
@@ -53,7 +53,7 @@ export type { BuildContext, ModelCapabilities, SystemPromptBuilder, SystemPrompt
53
53
  export { flattenSystemPromptRegions } from './system-prompt.js';
54
54
  export type { SystemPromptContributor } from './system-prompt-contributor.js';
55
55
  export type { CriticalPathResult, SerializableTaskGraph, SerializableTaskGraphNodes, SerializedTaskGraph, TaskAssignment, TaskDependency, TaskEdge, TaskFilter, TaskGraph, TaskNode, TaskPriority, TaskProgress, TaskSort, TaskStatus, TaskType, } from './task-graph.js';
56
- export type { CacheStats, TokenCounter } from './token-counter.js';
56
+ export type { CacheStats, ProviderCacheStats, TokenCounter } from './token-counter.js';
57
57
  export type { JSONSchema, Permission, RiskTier, Tool, ToolCallContext, ToolErrorInfo, ToolFinalEvent, ToolIconId, ToolProgressEvent, ToolStreamEvent, } from './tool.js';
58
58
  export { ToolErrorCategory } from './tool.js';
59
59
  export type { ConfirmAwaiter, GovernedToolExecutionResult, GovernedToolExecutor, ToolBatchResult, ToolConfirmPendingResult, ToolExecution, ToolExecutionOutput, ToolExecutorInit, ToolExecutorLike, ToolExecutorOptions, ToolExecutorStrategy, } from './tool-executor.js';
@@ -929,6 +929,15 @@ function isReasoningEffort(value) {
929
929
  function effectiveInputTokens(usage) {
930
930
  return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
931
931
  }
932
+ function freshInputTokens(usage) {
933
+ return Math.max(0, effectiveInputTokens(usage) - (usage.cacheRead ?? 0));
934
+ }
935
+ function promptCacheHitRatio(usage) {
936
+ const total = effectiveInputTokens(usage);
937
+ if (!Number.isFinite(total) || total <= 0) return 0;
938
+ const cached = Number.isFinite(usage.cacheRead) ? Math.max(0, usage.cacheRead ?? 0) : 0;
939
+ return Math.min(1, cached / total);
940
+ }
932
941
  var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
933
942
  var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
934
943
  var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
@@ -1064,7 +1073,12 @@ function isContextOverflowShaped(err) {
1064
1073
  const providerErr = err;
1065
1074
  if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
1066
1075
  if (providerErr.status < 400) return false;
1067
- const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw].filter(Boolean).join("\n");
1076
+ const text = [
1077
+ providerErr.message,
1078
+ providerErr.body?.message,
1079
+ providerErr.body?.type,
1080
+ providerErr.body?.raw
1081
+ ].filter(Boolean).join("\n");
1068
1082
  return CONTEXT_OVERFLOW_RE.test(text);
1069
1083
  }
1070
1084
  function describeStatus(status, type) {
@@ -1375,6 +1389,7 @@ export {
1375
1389
  effectiveInputTokens,
1376
1390
  flattenSystemPromptRegions,
1377
1391
  formatContextWindowModeList,
1392
+ freshInputTokens,
1378
1393
  getContextWindowMode,
1379
1394
  isAgentError,
1380
1395
  isBuiltinCategory,
@@ -1406,6 +1421,7 @@ export {
1406
1421
  normalizeTokenSavingTier,
1407
1422
  normalizeTuiThinkingWord,
1408
1423
  projectSessionMarkers,
1424
+ promptCacheHitRatio,
1409
1425
  resolveContextWindowPolicy,
1410
1426
  resolveFleetChatVerbosity,
1411
1427
  resolveTokenSavingTier,
@@ -1,4 +1,4 @@
1
- import type { Context } from '../core/context.js';
1
+ import type { AgentContext } from './context.js';
2
2
  import type { Permission, Tool } from './tool.js';
3
3
  export interface TrustPolicy {
4
4
  [toolNameOrPattern: string]: {
@@ -110,13 +110,13 @@ export interface DirectoryPolicy {
110
110
  rules: DirectoryRule[];
111
111
  }
112
112
  export interface PermissionPolicy {
113
- evaluate(tool: Tool, input: unknown, ctx: Context): Promise<PermissionDecision>;
113
+ evaluate(tool: Tool, input: unknown, ctx: AgentContext): Promise<PermissionDecision>;
114
114
  /**
115
115
  * Side-effect-free permission evaluation trace. Returns the same
116
116
  * logical result as `evaluate()` without prompting the user,
117
117
  * writing to trust files, or mutating session state.
118
118
  */
119
- explain?(tool: Tool, input: unknown, ctx: Context): Promise<PermissionTrace>;
119
+ explain?(tool: Tool, input: unknown, ctx: AgentContext): Promise<PermissionTrace>;
120
120
  trust(rule: {
121
121
  tool: string;
122
122
  pattern: string;
@@ -2,7 +2,7 @@ import type { Mailbox } from '../coordination/mailbox-types.js';
2
2
  import type { Notifier } from '../notifications/notifier.js';
3
3
  export type { Notifier };
4
4
  import type { ToolCallPipelinePayload } from '../core/agent.js';
5
- import type { Context } from '../core/context.js';
5
+ import type { AgentContext } from './context.js';
6
6
  import type { ExtensionRegistry } from '../extension/registry.js';
7
7
  import type { Container } from '../kernel/container.js';
8
8
  import type { EventBus, EventName, Listener } from '../kernel/events.js';
@@ -174,10 +174,10 @@ export interface PluginPipelines {
174
174
  userInput: ReadonlyPipeline<{
175
175
  content: import('./blocks.js').ContentBlock[];
176
176
  text: string;
177
- ctx: Context;
177
+ ctx: AgentContext;
178
178
  }>;
179
179
  assistantOutput: ReadonlyPipeline<TextBlock>;
180
- contextWindow: ReadonlyPipeline<Context>;
180
+ contextWindow: ReadonlyPipeline<AgentContext>;
181
181
  [k: string]: ReadonlyPipeline<any>;
182
182
  }
183
183
  export interface PluginAPI {
@@ -1,9 +1,9 @@
1
1
  import type { EventBus } from '../kernel/events.js';
2
+ import type { AgentContext } from './context.js';
2
3
  import type { Logger } from './logger.js';
3
4
  import type { Tracer } from './observability.js';
4
5
  import type { Provider, Request, Response } from './provider.js';
5
6
  import type { RetryPolicy } from './retry-policy.js';
6
- import type { Context } from '../core/context.js';
7
7
  /**
8
8
  * Options passed to a ProviderRunner when calling the provider.
9
9
  * Shape intentionally mirrors runProviderWithRetry's parameters
@@ -13,7 +13,7 @@ export interface RunProviderOptions {
13
13
  provider: Provider;
14
14
  request: Request;
15
15
  signal: AbortSignal;
16
- ctx: Context;
16
+ ctx: AgentContext;
17
17
  events: EventBus;
18
18
  retry: RetryPolicy;
19
19
  logger: Logger;
@@ -101,6 +101,16 @@ export interface Usage {
101
101
  * full prompt the model saw, not only the bill-at-full-rate slice.
102
102
  */
103
103
  export declare function effectiveInputTokens(usage: Usage): number;
104
+ /** Prompt tokens that were not served by a cache read. */
105
+ export declare function freshInputTokens(usage: Usage): number;
106
+ /**
107
+ * Cache-read share of the complete prompt context, normalized to [0, 1].
108
+ *
109
+ * Keeping the clamp at the shared telemetry boundary protects every UI from
110
+ * malformed/hybrid gateway counters while provider adapters preserve the
111
+ * real total context in the disjoint Usage buckets.
112
+ */
113
+ export declare function promptCacheHitRatio(usage: Usage): number;
104
114
  export interface ReasoningRequest {
105
115
  enabled?: boolean | undefined;
106
116
  effort?: ReasoningEffort | undefined;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * RunEnv — the read-only environment view of the agent run.
3
+ *
4
+ * Dependency-leaf module (Roadmap 10A): imports ONLY from sibling `types/*`
5
+ * modules, never from `core/`. The concrete `Context` class satisfies this
6
+ * interface structurally; `extractRunEnv()` (in `core/run-env.ts`) builds a
7
+ * frozen view for subsystems that want to declare "env-only" access.
8
+ *
9
+ * Consumers that only need these fields should type their parameters as
10
+ * `RunEnv` — not `Context` — so the type module graph stays acyclic.
11
+ */
12
+ import type { Provider } from './provider.js';
13
+ import type { SessionWriter } from './session.js';
14
+ import type { TextBlock } from './blocks.js';
15
+ import type { TokenCounter } from './token-counter.js';
16
+ import type { Tool } from './tool.js';
17
+ export interface RunEnv {
18
+ readonly provider: Provider;
19
+ readonly session: SessionWriter;
20
+ readonly signal: AbortSignal;
21
+ readonly tokenCounter: TokenCounter;
22
+ readonly cwd: string;
23
+ readonly projectRoot: string;
24
+ /** Mutable working directory — starts as `cwd`. */
25
+ readonly workingDir: string;
26
+ readonly model: string;
27
+ readonly systemPrompt: readonly TextBlock[];
28
+ readonly tools: readonly Tool[];
29
+ readonly agentId: string;
30
+ readonly agentName: string;
31
+ }
32
+ //# sourceMappingURL=run-env.d.ts.map
@@ -416,6 +416,9 @@ export type SessionEvent = {
416
416
  agentName: string;
417
417
  provider: string;
418
418
  model: string;
419
+ logicalRequestId?: string | undefined;
420
+ promptManifestId?: string | undefined;
421
+ provenanceConfidence?: 'explicit' | 'correlated' | 'inferred' | 'unknown' | undefined;
419
422
  toolName: string;
420
423
  toolUseId: string;
421
424
  scope: 'project' | 'session' | 'task';
@@ -1,4 +1,4 @@
1
- import type { Context } from '../core/context.js';
1
+ import type { AgentContext } from './context.js';
2
2
  /**
3
3
  * A slash command registered with the CLI or available to plugins.
4
4
  * Plugins receive a view of the registry via PluginAPI.slashCommands.
@@ -49,7 +49,7 @@ export interface SlashCommand {
49
49
  * the model's response starts streaming. `{ metadata }` carries
50
50
  * structured data for the REPL/TUI to act on (e.g. SDD session state).
51
51
  */
52
- run(args: string, ctx?: Context | undefined): Promise<{
52
+ run(args: string, ctx?: AgentContext | undefined): Promise<{
53
53
  exit?: boolean | undefined;
54
54
  message?: string | undefined;
55
55
  runText?: string | undefined;
@@ -1,10 +1,37 @@
1
1
  import type { Usage } from './provider.js';
2
+ export interface ProviderCacheStats {
3
+ provider: string;
4
+ input: number;
5
+ cacheRead: number;
6
+ cacheWrite: number;
7
+ /** cacheRead / complete prompt context for this provider. Clamped to [0, 1]. */
8
+ hitRatio: number;
9
+ /**
10
+ * Tokens written into the cache by this provider, split by TTL when the
11
+ * upstream exposes the breakdown. Anthropic-family providers (incl.
12
+ * MiniMax on the Anthropic surface) emit `cache_creation` with a 5-min
13
+ * and a 1-hour sub-bucket; OpenAI-family gateways emit a single
14
+ * aggregate and leave these undefined.
15
+ */
16
+ cacheWrite5m?: number | undefined;
17
+ cacheWrite1h?: number | undefined;
18
+ }
2
19
  export interface CacheStats {
3
20
  /** Tokens served from cache (cheaper). */
4
21
  readTokens: number;
5
22
  /** Tokens written into the cache (more expensive than input on first hit). */
6
23
  writeTokens: number;
7
- /** Hit ratio: cacheRead / (cacheRead + input). 0 when nothing cached. */
24
+ /**
25
+ * 5-minute cache-write tokens for providers that expose the TTL split
26
+ * (Anthropic family). Undefined when the provider only emits an aggregate.
27
+ */
28
+ cacheWrite5m?: number | undefined;
29
+ /**
30
+ * 1-hour cache-write tokens for providers that expose the TTL split
31
+ * (Anthropic family). Undefined when the provider only emits an aggregate.
32
+ */
33
+ cacheWrite1h?: number | undefined;
34
+ /** Hit ratio: cacheRead / total prompt context. Clamped to [0, 1]. */
8
35
  hitRatio: number;
9
36
  /**
10
37
  * USD saved by cache reads: cacheRead tokens billed at the cache-read rate
@@ -13,6 +40,8 @@ export interface CacheStats {
13
40
  * this is the gross read discount, the figure users recognize as "saved".
14
41
  */
15
42
  savedUsd: number;
43
+ /** Session totals split by routed provider, most cache-read tokens first. */
44
+ providers?: ProviderCacheStats[] | undefined;
16
45
  }
17
46
  export interface TokenCounter {
18
47
  account(usage: Usage, model?: string, providerId?: string): void | undefined;
@@ -1,5 +1,5 @@
1
- import type { ToolResultBlock, ToolUseBlock } from '../types/blocks.js';
2
- import type { Tool } from '../types/tool.js';
1
+ import type { ToolResultBlock, ToolUseBlock } from './blocks.js';
2
+ import type { Tool } from './tool.js';
3
3
  /** Context.meta key installed by ToolExecutor for governed calls made by meta-tools. */
4
4
  export declare const GOVERNED_TOOL_EXECUTOR_META_KEY = "toolExecutor.executeGoverned";
5
5
  /** Result returned to meta-tools after a nested call traverses the normal executor. */