@buildaharness/aielia 0.3.8 → 0.3.10

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 (103) hide show
  1. package/README.md +6 -3
  2. package/dist/_memory-core-generated.d.ts +6 -0
  3. package/dist/action-approval-service.d.ts +2 -0
  4. package/dist/ask-draft.d.ts +22 -0
  5. package/dist/assistant-options.d.ts +35 -0
  6. package/dist/assistant-session.d.ts +1 -1
  7. package/dist/assistant.d.ts +11 -0
  8. package/dist/{bin-DETwedpj.js → bin-Cz3FY6Ew.js} +144 -254
  9. package/dist/bin-Cz3FY6Ew.js.map +1 -0
  10. package/dist/claude-cli-llm-client.d.ts +2 -0
  11. package/dist/claude-cli-prompt.d.ts +7 -0
  12. package/dist/cli-config.d.ts +2 -2
  13. package/dist/cli-session.d.ts +2 -1
  14. package/dist/cli.d.ts +2 -0
  15. package/dist/cli.js +1 -1
  16. package/dist/commands.d.ts +32 -0
  17. package/dist/config-keys.d.ts +43 -0
  18. package/dist/doctor-checks.d.ts +1 -2
  19. package/dist/fact-extraction.d.ts +4 -0
  20. package/dist/fact-repository.contract.d.ts +2 -0
  21. package/dist/fact-repository.d.ts +44 -0
  22. package/dist/file-tools-mcp-server.mjs +29 -0
  23. package/dist/goal-graph-store.d.ts +6 -0
  24. package/dist/harness-bridge.d.ts +5 -5
  25. package/dist/html-to-markdown.d.ts +11 -0
  26. package/dist/index.d.ts +98 -3
  27. package/dist/index.js +5003 -150
  28. package/dist/index.js.map +1 -1
  29. package/dist/layer-settings.d.ts +16 -3
  30. package/dist/llm-client-factory.d.ts +13 -0
  31. package/dist/memory-events.d.ts +177 -0
  32. package/dist/memory-service.d.ts +17 -0
  33. package/dist/model-pricing.d.ts +15 -9
  34. package/dist/node-display-names.d.ts +1 -1
  35. package/dist/project-command.d.ts +16 -0
  36. package/dist/{provider-setup-wX2IBw2X.js → provider-setup-DG8iYm_F.js} +14471 -13032
  37. package/dist/provider-setup-DG8iYm_F.js.map +1 -0
  38. package/dist/proxy-health.d.ts +8 -0
  39. package/dist/redact-url.d.ts +2 -0
  40. package/dist/reply-audit.d.ts +2 -0
  41. package/dist/response-service.d.ts +10 -0
  42. package/dist/run-explain.d.ts +58 -0
  43. package/dist/scripted-llm-client.d.ts +1 -1
  44. package/dist/{tui-app-CcxiwZyM.js → tui-app-oWbIUcBW.js} +3 -3
  45. package/dist/{tui-app-CcxiwZyM.js.map → tui-app-oWbIUcBW.js.map} +1 -1
  46. package/dist/turn-abort.d.ts +5 -0
  47. package/dist/turn-cost.d.ts +12 -0
  48. package/dist/turn-presentation.d.ts +86 -0
  49. package/dist/undo-action-command.d.ts +12 -0
  50. package/dist/undo-plan.d.ts +13 -0
  51. package/dist/version.d.ts +1 -1
  52. package/dist/web-fetch-core.d.ts +0 -14
  53. package/dist/writer/article-autosave.d.ts +12 -0
  54. package/dist/writer/article-change-summary.d.ts +28 -0
  55. package/dist/writer/article-claims.d.ts +49 -0
  56. package/dist/writer/article-comments.d.ts +20 -0
  57. package/dist/writer/article-consistency.d.ts +27 -0
  58. package/dist/writer/article-decorations.d.ts +23 -0
  59. package/dist/writer/article-dependencies.d.ts +44 -0
  60. package/dist/writer/article-draft.d.ts +23 -0
  61. package/dist/writer/article-edit-outline.d.ts +16 -0
  62. package/dist/writer/article-edit-suggest.d.ts +30 -0
  63. package/dist/writer/article-folder.d.ts +29 -0
  64. package/dist/writer/article-history.d.ts +73 -0
  65. package/dist/writer/article-ideas.d.ts +34 -0
  66. package/dist/writer/article-issues.d.ts +47 -0
  67. package/dist/writer/article-marks.d.ts +25 -0
  68. package/dist/writer/article-memory-store.d.ts +3 -0
  69. package/dist/writer/article-model.d.ts +1337 -0
  70. package/dist/writer/article-outline.d.ts +43 -0
  71. package/dist/writer/article-resolver.d.ts +55 -0
  72. package/dist/writer/article-revisions.d.ts +30 -0
  73. package/dist/writer/article-rules.d.ts +60 -0
  74. package/dist/writer/article-sections.d.ts +26 -0
  75. package/dist/writer/article-selection.d.ts +26 -0
  76. package/dist/writer/article-service.d.ts +542 -0
  77. package/dist/writer/article-source-links.d.ts +42 -0
  78. package/dist/writer/article-sources.d.ts +82 -0
  79. package/dist/writer/article-style-derive.d.ts +26 -0
  80. package/dist/writer/article-style.d.ts +31 -0
  81. package/dist/writer/article-suggestions.d.ts +33 -0
  82. package/dist/writer/article-support.d.ts +33 -0
  83. package/dist/writer/article-verify.d.ts +42 -0
  84. package/dist/writer/local-folder.d.ts +49 -0
  85. package/dist/writer/model-failure-hint.d.ts +7 -0
  86. package/dist/writer/repo-reader.d.ts +29 -0
  87. package/dist/writer/repo-search.d.ts +33 -0
  88. package/dist/writer/repo-verify-loop.d.ts +61 -0
  89. package/dist/writer/text-tool-calls.d.ts +11 -0
  90. package/dist/writer/work-progress.d.ts +51 -0
  91. package/dist/writer/write-activity.d.ts +61 -0
  92. package/dist/writer/write-models.d.ts +12 -0
  93. package/dist/writer/write-parameters.d.ts +31 -0
  94. package/dist/writer/write-permissions.d.ts +89 -0
  95. package/dist/writer/write-spend.d.ts +16 -0
  96. package/dist/writer/writer-chat-capture.d.ts +25 -0
  97. package/dist/writer/writer-chat-history.d.ts +17 -0
  98. package/dist/writer/writer-chat-state.d.ts +358 -0
  99. package/dist/writer/writer-chat-turn.d.ts +52 -0
  100. package/dist/writer/writer-intent.d.ts +20 -0
  101. package/package.json +3 -3
  102. package/dist/bin-DETwedpj.js.map +0 -1
  103. package/dist/provider-setup-wX2IBw2X.js.map +0 -1
@@ -5,10 +5,11 @@
5
5
  * layer needed a second code path. An env value the operator set themselves always wins and renders as pinned,
6
6
  * the same precedence `explicitEnvOverride` already gives it.
7
7
  *
8
- * Floor layers (safety, approval, tool policy, verification, diagnostics) are listed but locked: there is no
9
- * flag for them and the adaptive policy's types make them un-decidable on purpose.
8
+ * Floor layers: control state, tool policy and verification each have a gate flag and may be switched off (they carry
9
+ * a `caution`). Approval staging is locked on purpose, and diagnostics and template hypotheses have no effect of their own
10
+ * (they only feed the control state), so they follow `control_state`.
10
11
  */
11
- export type LayerGroup = 'escalation' | 'opt_in' | 'floor';
12
+ export type LayerGroup = 'escalation' | 'behaviour' | 'opt_in' | 'floor';
12
13
  export interface LayerSetting {
13
14
  id: string;
14
15
  group: LayerGroup;
@@ -21,10 +22,22 @@ export interface LayerSetting {
21
22
  cost: string;
22
23
  /** What the audit found, in plain words — the record, not a promise. */
23
24
  evidence: string;
25
+ /** What switching it off gives up; set on floor layers a user may still switch off. */
26
+ caution?: string;
27
+ /** A layer with no gate of its own: it is on exactly when this layer is. */
28
+ followsLayer?: string;
29
+ /** Layers this one does nothing without. Switching it on while one of them is off is allowed but reported. */
30
+ requires?: readonly string[];
24
31
  }
25
32
  export declare const LAYER_SETTINGS: readonly LayerSetting[];
26
33
  export type LayerChoices = Readonly<Record<string, boolean>>;
27
34
  export declare function findLayer(id: string): LayerSetting | undefined;
35
+ /** The layers that have no switch of their own and are on exactly when `leader` is. */
36
+ export declare function followersOf(leader: LayerSetting): LayerSetting[];
37
+ /** The layers `layer` needs that are currently off. Empty when `layer` is off itself: nothing is lost then. */
38
+ export declare function unmetRequirements(layer: LayerSetting, choices: LayerChoices | undefined, pinned: ReadonlySet<string>, env: Env): LayerSetting[];
39
+ /** One line per switched-on layer that has no effect because a layer it needs is off. */
40
+ export declare function layerWarnings(choices: LayerChoices | undefined, pinned: ReadonlySet<string>, env: Env): string[];
28
41
  /** The layers a user may change: everything except the locked floor. */
29
42
  export declare function isToggleable(layer: LayerSetting): boolean;
30
43
  type Env = Record<string, string | undefined>;
@@ -0,0 +1,13 @@
1
+ import { ILLMClient } from '@buildaharness/runtime';
2
+ import { AssistantConfig } from './config.js';
3
+ export interface LlmClientFactoryOptions {
4
+ /** Passed to every HTTP client. The desktop app supplies Tauri's fetch, because its webview CSP blocks the global one. */
5
+ fetchImpl?: typeof fetch;
6
+ /**
7
+ * Builds the surface's own claude-cli client (the CLI's file/shell/web/action tools, desktop's Tauri bridge).
8
+ * Return undefined where `claude -p` cannot run (a plain browser tab) and the factory falls back to the proxy.
9
+ */
10
+ claudeCli: () => ILLMClient | undefined;
11
+ }
12
+ /** The one switch over the five backends. Only the claude-cli client and `fetch` differ per surface, and both come in through the options. */
13
+ export declare function createLlmClient(config: AssistantConfig, { fetchImpl, claudeCli }: LlmClientFactoryOptions): ILLMClient;
@@ -0,0 +1,177 @@
1
+ import { z } from 'zod';
2
+ import { UserFact } from './fact-extraction.js';
3
+ /**
4
+ * One record per memory transition: what changed, WHY (a closed, countable reason code) and which
5
+ * sources justified it. Pure (no I/O, no clock): `MemoryService` builds events from the changes it
6
+ * makes and hands them to an `EventSink`. The wire enums come from the shared contract
7
+ * (`spec/memory-core.json`), so the Python twin sees the same names.
8
+ *
9
+ * Privacy: an event holds ids and codes, never fact text, unless the caller asks for images
10
+ * (`withImages`, tied to the audit log flag). `factKey()` is a one-way id, so an event about a
11
+ * forgotten fact reveals nothing; `scrubForgotten()` also drops the quotes and images of every
12
+ * earlier event about it.
13
+ */
14
+ export declare const MEMORY_EVENTS_KEY: string;
15
+ export declare const MEMORY_EVENTS_KEEP: number;
16
+ export declare const MemoryEventKindSchema: z.ZodEnum<["promote", "decline", "correct", "contradict", "supersede", "retire", "forget", "expire", "restore", "recall"]>;
17
+ export declare const ReasonCodeSchema: z.ZodEnum<["user_stated", "user_corrected", "user_confirmed", "user_rejected", "inferred_high_conf", "inferred_pending_confirmation", "inferred_low_conf_session_only", "conflicts_with_fact", "superseded_by_newer", "explicit_forget", "retention_expired", "gate_blocked_secret", "gate_blocked_instruction", "duplicate"]>;
18
+ export declare const SourceRefSchema: z.ZodObject<{
19
+ type: z.ZodEnum<["user_message", "assistant_message", "tool_result", "prior_fact", "user_command"]>;
20
+ /** messageId | toolCallId | factKey | command name. */
21
+ ref: z.ZodString;
22
+ /** Short justification the reader sees; present only with images on, and removed when the fact is forgotten. */
23
+ quote: z.ZodOptional<z.ZodString>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
26
+ ref: string;
27
+ quote?: string | undefined;
28
+ }, {
29
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
30
+ ref: string;
31
+ quote?: string | undefined;
32
+ }>;
33
+ export declare const MemoryEventSchema: z.ZodObject<{
34
+ seq: z.ZodNumber;
35
+ at: z.ZodString;
36
+ session: z.ZodString;
37
+ turn: z.ZodString;
38
+ kind: z.ZodEnum<["promote", "decline", "correct", "contradict", "supersede", "retire", "forget", "expire", "restore", "recall"]>;
39
+ /** `factKey()` of the fact the event is about (the pre-image for a supersession). */
40
+ factId: z.ZodString;
41
+ /** `factKey()` of the replacement, for a supersession. */
42
+ afterFactId: z.ZodOptional<z.ZodString>;
43
+ attributeKey: z.ZodOptional<z.ZodString>;
44
+ store: z.ZodOptional<z.ZodEnum<["durable", "pending", "rejected", "session"]>>;
45
+ before: z.ZodOptional<z.ZodObject<{
46
+ text: z.ZodString;
47
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
48
+ text: z.ZodString;
49
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
50
+ text: z.ZodString;
51
+ }, z.ZodTypeAny, "passthrough">>>;
52
+ after: z.ZodOptional<z.ZodObject<{
53
+ text: z.ZodString;
54
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
55
+ text: z.ZodString;
56
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
57
+ text: z.ZodString;
58
+ }, z.ZodTypeAny, "passthrough">>>;
59
+ reason: z.ZodEnum<["user_stated", "user_corrected", "user_confirmed", "user_rejected", "inferred_high_conf", "inferred_pending_confirmation", "inferred_low_conf_session_only", "conflicts_with_fact", "superseded_by_newer", "explicit_forget", "retention_expired", "gate_blocked_secret", "gate_blocked_instruction", "duplicate"]>;
60
+ sources: z.ZodArray<z.ZodObject<{
61
+ type: z.ZodEnum<["user_message", "assistant_message", "tool_result", "prior_fact", "user_command"]>;
62
+ /** messageId | toolCallId | factKey | command name. */
63
+ ref: z.ZodString;
64
+ /** Short justification the reader sees; present only with images on, and removed when the fact is forgotten. */
65
+ quote: z.ZodOptional<z.ZodString>;
66
+ }, "strip", z.ZodTypeAny, {
67
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
68
+ ref: string;
69
+ quote?: string | undefined;
70
+ }, {
71
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
72
+ ref: string;
73
+ quote?: string | undefined;
74
+ }>, "many">;
75
+ decidedBy: z.ZodEnum<["user", "classifier", "reviewer", "consolidation", "rule"]>;
76
+ confidence: z.ZodOptional<z.ZodEnum<["high", "medium", "low"]>>;
77
+ group: z.ZodOptional<z.ZodString>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ at: string;
80
+ kind: "retire" | "restore" | "promote" | "decline" | "correct" | "contradict" | "supersede" | "forget" | "expire" | "recall";
81
+ reason: "user_stated" | "user_corrected" | "user_confirmed" | "user_rejected" | "inferred_high_conf" | "inferred_pending_confirmation" | "inferred_low_conf_session_only" | "conflicts_with_fact" | "superseded_by_newer" | "explicit_forget" | "retention_expired" | "gate_blocked_secret" | "gate_blocked_instruction" | "duplicate";
82
+ session: string;
83
+ seq: number;
84
+ factId: string;
85
+ turn: string;
86
+ sources: {
87
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
88
+ ref: string;
89
+ quote?: string | undefined;
90
+ }[];
91
+ decidedBy: "reviewer" | "rule" | "user" | "consolidation" | "classifier";
92
+ confidence?: "high" | "medium" | "low" | undefined;
93
+ before?: z.objectOutputType<{
94
+ text: z.ZodString;
95
+ }, z.ZodTypeAny, "passthrough"> | undefined;
96
+ after?: z.objectOutputType<{
97
+ text: z.ZodString;
98
+ }, z.ZodTypeAny, "passthrough"> | undefined;
99
+ store?: "rejected" | "durable" | "pending" | "session" | undefined;
100
+ group?: string | undefined;
101
+ afterFactId?: string | undefined;
102
+ attributeKey?: string | undefined;
103
+ }, {
104
+ at: string;
105
+ kind: "retire" | "restore" | "promote" | "decline" | "correct" | "contradict" | "supersede" | "forget" | "expire" | "recall";
106
+ reason: "user_stated" | "user_corrected" | "user_confirmed" | "user_rejected" | "inferred_high_conf" | "inferred_pending_confirmation" | "inferred_low_conf_session_only" | "conflicts_with_fact" | "superseded_by_newer" | "explicit_forget" | "retention_expired" | "gate_blocked_secret" | "gate_blocked_instruction" | "duplicate";
107
+ session: string;
108
+ seq: number;
109
+ factId: string;
110
+ turn: string;
111
+ sources: {
112
+ type: "user_message" | "assistant_message" | "tool_result" | "prior_fact" | "user_command";
113
+ ref: string;
114
+ quote?: string | undefined;
115
+ }[];
116
+ decidedBy: "reviewer" | "rule" | "user" | "consolidation" | "classifier";
117
+ confidence?: "high" | "medium" | "low" | undefined;
118
+ before?: z.objectInputType<{
119
+ text: z.ZodString;
120
+ }, z.ZodTypeAny, "passthrough"> | undefined;
121
+ after?: z.objectInputType<{
122
+ text: z.ZodString;
123
+ }, z.ZodTypeAny, "passthrough"> | undefined;
124
+ store?: "rejected" | "durable" | "pending" | "session" | undefined;
125
+ group?: string | undefined;
126
+ afterFactId?: string | undefined;
127
+ attributeKey?: string | undefined;
128
+ }>;
129
+ export type MemoryEventKind = z.infer<typeof MemoryEventKindSchema>;
130
+ export type ReasonCode = z.infer<typeof ReasonCodeSchema>;
131
+ export type SourceRef = z.infer<typeof SourceRefSchema>;
132
+ export type MemoryEvent = z.infer<typeof MemoryEventSchema>;
133
+ export type MemoryEventDraft = Omit<MemoryEvent, 'seq' | 'at'>;
134
+ export interface EventSink {
135
+ emit(events: MemoryEvent[]): void | Promise<void>;
136
+ }
137
+ export declare class InMemoryEventSink implements EventSink {
138
+ readonly events: MemoryEvent[];
139
+ emit(events: MemoryEvent[]): void;
140
+ }
141
+ /** Stable, non-reversible id for a fact (FNV-1a over `text|extractedAt`): lets events point at a fact without carrying its words. */
142
+ export declare function factKey(fact: Pick<UserFact, 'text' | 'extractedAt'>): string;
143
+ export declare function keyOfFactId(id: string): string;
144
+ /** The slice of an audit entry an event is derived from (structural, so this module never imports the service). */
145
+ export interface AuditLike {
146
+ op: 'add' | 'replace' | 'retire' | 'remove' | 'confirm' | 'reject' | 'undo' | 'archive' | 'restore';
147
+ factId: string;
148
+ before?: UserFact;
149
+ after?: UserFact;
150
+ store: 'durable' | 'pending' | 'rejected';
151
+ writer: string;
152
+ turn: string;
153
+ group?: string;
154
+ }
155
+ /** Project one audit change onto its event: kind, reason, decider and sources, from the op, the writer and the fact's own provenance bits (never its wording). */
156
+ export declare function eventFromAudit(a: AuditLike, withImages: boolean): MemoryEventDraft;
157
+ /** Drops quotes and images from every earlier event about a forgotten fact, so the log cannot be used to read it back. */
158
+ export declare function scrubForgotten(log: MemoryEvent[], forgottenKeys: Set<string>): MemoryEvent[];
159
+ /** Keeps the newest `keep` events. */
160
+ export declare function trimEvents(log: MemoryEvent[], keep?: number): MemoryEvent[];
161
+ /**
162
+ * Replays an event stream from empty and returns the ids of the durable facts, in order. This is
163
+ * the correctness check for the log: it must equal `factKey()` over the stored durable list.
164
+ * `unsupported` counts events it cannot replay (an undo reinserts at a recorded position).
165
+ */
166
+ export declare function foldDurable(events: MemoryEvent[]): {
167
+ ids: string[];
168
+ unsupported: number;
169
+ };
170
+ export interface EventFilter {
171
+ /** A fact id as printed by `formatMemoryEvents` (`f_xxxxxxxx`), or an attribute key. */
172
+ fact?: string;
173
+ kind?: MemoryEventKind;
174
+ }
175
+ export declare function filterEvents(events: MemoryEvent[], f?: EventFilter): MemoryEvent[];
176
+ /** `/memory history events [fact]`: one line per event, with the reason and its sources. Shared by the CLI and chat-ui. */
177
+ export declare function formatMemoryEvents(events: MemoryEvent[]): string;
@@ -4,6 +4,7 @@ import { UserFact } from './fact-extraction.js';
4
4
  import { Corroboration } from './contradiction-checker.js';
5
5
  import { DigestStore, SessionDigest } from './episodic-digest.js';
6
6
  import { StatedFact, FactCategory } from './turn-intent-classifier.js';
7
+ import { EventSink, EventFilter, MemoryEvent } from './memory-events.js';
7
8
  import { MemoryWriteMode, CrossTurnWriter } from './memory-governance.js';
8
9
  import { ConsolidationProposal } from './memory-consolidation.js';
9
10
  import { VerifiedReviewOp } from './memory-reviewer.js';
@@ -47,6 +48,8 @@ export interface AuditEntry {
47
48
  undoes?: number;
48
49
  /** M6: the user erased this fact from history (`/memory archive forget`); before/after were removed and the entry can no longer be undone. */
49
50
  erased?: boolean;
51
+ /** Export only: the images of a forgotten fact are left out of `/memory export`; the stored log still has them so `/memory undo` works. */
52
+ withheld?: boolean;
50
53
  /** M5: entries applied together (one consolidation proposal) share a group; undoing one undoes the group. */
51
54
  group?: string;
52
55
  /** M5: position the pre-image held in the durable list, so undo restores order exactly. */
@@ -203,6 +206,8 @@ export declare function memoryBudgetedRenderEnabled(env?: Record<string, string
203
206
  export declare function memoryWriteGateEnabled(env?: Record<string, string | undefined>): boolean;
204
207
  /** `AUDIT_MEMORY_AUDIT_LOG`: append-only `memory:audit`. Default OFF until the pilot; `=0` restores the unlogged path. */
205
208
  export declare function memoryAuditLogEnabled(env?: Record<string, string | undefined>): boolean;
209
+ /** `AUDIT_MEMORY_EVENTS`: metadata-only transition events (kind, reason code, source refs, ids; no fact text unless the audit log is on). Default ON; `=0`/`off` restores no events. */
210
+ export declare function memoryEventsEnabled(env?: Record<string, string | undefined>): boolean;
206
211
  /** Outcome of `admitCandidate()` for one candidate. `session` = kept session-scoped only, never durable or pending. */
207
212
  export interface AdmitDecision {
208
213
  action: 'admit' | 'session' | 'flag' | 'drop';
@@ -278,6 +283,8 @@ export declare class MemoryService {
278
283
  private readonly writeMode;
279
284
  /** Time source for every timestamp this service writes (extractedAt of stated facts, audit `at`, retiredAt, usage flush). Injectable so the cross-runtime conformance fixtures are byte-reproducible; default is wall-clock, i.e. no behaviour change. */
280
285
  private readonly clock;
286
+ /** Every fact list goes through this seam (see fact-repository.ts); the key-value implementation keeps today's keys. */
287
+ private readonly repo;
281
288
  constructor(memory: MemoryAdapter, reminderStore: ReminderStore, experienceStore: ExperienceStore, llmClient: ILLMClient, model: () => string | undefined,
282
289
  /** Resolves to `config.activeProject` if the user set one via `/project <name>`, else the workspace root — read through a getter (same convention as `model` above) so a mid-session `/project`/`/config set activeProject` change takes effect on the very next turn. See UserFact.project's doc comment for how this is used. */
283
290
  currentProject?: () => string,
@@ -356,6 +363,16 @@ export declare class MemoryService {
356
363
  private flushChain;
357
364
  private serialized;
358
365
  private appendAudit;
366
+ /** Extra destinations for events (the eval collector); each receives every event, whether or not the stored log is on. */
367
+ private eventSinks;
368
+ private eventSeqLocal;
369
+ addEventSink(sink: EventSink): void;
370
+ /** Stamps seq/at, appends to the stored event log (when `AUDIT_MEMORY_EVENTS` is on) and fans out to the extra sinks. A sink that throws never blocks the memory write. */
371
+ private emitEvents;
372
+ /** `/memory history events [fact]`: the newest transition events, optionally for one fact id or attribute key. */
373
+ getEvents(limit?: number, filter?: EventFilter): Promise<MemoryEvent[]>;
374
+ /** A decision that wrote nothing (a promotion declined, a duplicate, a contradiction found) still leaves an event. */
375
+ private decisionEvent;
359
376
  private appendAuditNow;
360
377
  /** `/memory history` — newest last; the last `limit` entries. */
361
378
  getAuditLog(limit?: number): Promise<AuditEntry[]>;
@@ -1,19 +1,25 @@
1
1
  /**
2
- * Static, approximate per-model pricing — a fallback used only by the proxy backend's /cost
3
- * display. The proxy (packages/proxy/src/forward.ts) is a thin pass-through to Anthropic/
4
- * OpenAI and never computes or returns a dollar cost itself, only the raw token counts each
5
- * provider's response already includes. This table is NOT billing-accurate: it doesn't account
6
- * for prompt-caching discounts, batch pricing, or any rate change since it was last updated —
7
- * update the numbers below if Anthropic's published pricing changes. The Claude CLI backend
8
- * needs no such table; its costUsd comes from Claude's own real accounting (see
9
- * claude-cli-prompt.ts's parseClaudeCliOutput).
2
+ * Static, approximate per-model pricing — a fallback for every backend whose response carries
3
+ * token counts but no dollar figure. Anthropic and OpenAI responses report tokens only; OpenRouter
4
+ * (usage.cost) and the Claude CLI (total_cost_usd) report a real cost, which callers prefer over
5
+ * this table. This table is NOT billing-accurate: it ignores batch pricing, long-context tiers and
6
+ * any rate change since it was last updated — update the numbers below when published pricing changes.
10
7
  */
11
8
  export interface ModelPriceUsd {
12
9
  inputPerMTok: number;
13
10
  outputPerMTok: number;
11
+ /** Rate for input tokens served from the provider's prompt cache; absent = same as inputPerMTok. */
12
+ cachedInputPerMTok?: number;
13
+ /** Rate for input tokens written to the prompt cache; absent = same as inputPerMTok. */
14
+ cacheWritePerMTok?: number;
14
15
  }
15
- /** Returns undefined (rather than a misleading number) when the model is unset or not a recognized Claude tier — callers must not silently treat "no estimate" as "free". */
16
+ /**
17
+ * Returns undefined (rather than a misleading number) when the model is unset or not a recognized one — callers must not silently treat "no estimate" as "free".
18
+ * `cachedInputTokens` follows OpenAI's convention (a subset of inputTokens, billed at the cached rate); it is ignored for models with no cached rate.
19
+ */
16
20
  export declare function estimateCostUsd(model: string | undefined, usage: {
17
21
  inputTokens: number;
18
22
  outputTokens: number;
23
+ cachedInputTokens?: number;
24
+ cacheWriteTokens?: number;
19
25
  }): number | undefined;
@@ -20,7 +20,7 @@ export interface WhyChainItem {
20
20
  * Collapses a turn's raw layerActivity (one event per layer per main-loop iteration — see
21
21
  * harness-runtime.ts's onLayerActivity doc comment) down to just the layers that fired, in the
22
22
  * order they fired, merging consecutive re-fires of the same layer (back-to-back loop
23
- * iterations) into a single link. Shared by the CLI's `/why` and chat-ui's "Why?" panel so both
23
+ * iterations) into a single link. Used by run-explain.ts, which both the CLI's `/why` and chat-ui's `/why` print, so both
24
24
  * surfaces summarize a turn identically instead of drifting apart.
25
25
  */
26
26
  export declare function buildWhyChain(layerActivity: LayerActivityEvent[]): WhyChainItem[];
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `/project [name]` for every surface: no argument shows the active project, `clear` reverts to the workspace
3
+ * default, anything else switches to that name. Pure: the surface persists the config change and shows the message.
4
+ */
5
+ export type ProjectCommand = {
6
+ kind: 'show';
7
+ message: string;
8
+ } | {
9
+ kind: 'set';
10
+ project: string;
11
+ message: string;
12
+ } | {
13
+ kind: 'clear';
14
+ message: string;
15
+ };
16
+ export declare function parseProjectCommand(args: readonly string[], currentProject: string | undefined): ProjectCommand;