@fusengine/harness 0.1.18 → 0.1.20

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.
@@ -1,2 +1,2 @@
1
- import { a as readClaudeInput, i as guard, n as denyResponse, o as toClaudeResponse, r as fileSizeGuard, t as contextResponse } from "../../claude-Bzx_v9y1.mjs";
1
+ import { a as readClaudeInput, i as guard, n as denyResponse, o as toClaudeResponse, r as fileSizeGuard, t as contextResponse } from "../../claude-c2Sskvb6.mjs";
2
2
  export { contextResponse, denyResponse, fileSizeGuard, guard, readClaudeInput, toClaudeResponse };
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-CpBKZ6G-.mjs";
1
+ import { t as evaluate } from "../../evaluate-CreJy519.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/cline/index.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { a as readClaudeInput, i as guard, n as denyResponse, t as contextResponse } from "../../claude-Bzx_v9y1.mjs";
1
+ import { a as readClaudeInput, i as guard, n as denyResponse, t as contextResponse } from "../../claude-c2Sskvb6.mjs";
2
2
  export { contextResponse, denyResponse, guard, readClaudeInput as readCodexInput };
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-CpBKZ6G-.mjs";
1
+ import { t as evaluate } from "../../evaluate-CreJy519.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/cursor/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-CpBKZ6G-.mjs";
1
+ import { t as evaluate } from "../../evaluate-CreJy519.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/gemini/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "./evaluate-CpBKZ6G-.mjs";
1
+ import { t as evaluate } from "./evaluate-CreJy519.mjs";
2
2
  import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/claude/index.ts
4
4
  /**
package/dist/cli/bin.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { r as resolveTtlSec } from "../ttl-BG55s6HZ.mjs";
3
3
  import { t as detectHarness } from "../harness-C8Nxxyn_.mjs";
4
- import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-_Cy9-Tgv.mjs";
4
+ import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-0LTLAbmo.mjs";
5
5
  import { n as writeInitFile, t as initFor } from "../run-D91N4ul1.mjs";
6
- import { t as handleHook } from "../handle-SPlcCQYl.mjs";
6
+ import { t as handleHook } from "../handle-DztC8AKY.mjs";
7
7
  //#region src/cli/bin.ts
8
8
  /**
9
9
  * harness — CLI for @fusengine/harness.
@@ -1,2 +1,2 @@
1
- import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-_Cy9-Tgv.mjs";
1
+ import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-0LTLAbmo.mjs";
2
2
  export { checkStaged, stagedContent, stagedFiles };
@@ -271,10 +271,35 @@ const GUARDS = [
271
271
  interfaceSeparationGuard,
272
272
  installGuard
273
273
  ];
274
- /** Run the guard chain; the first firing guard's Prompt wins, else null. */
274
+ /** Block prompt returned when a guard or gate throws (fail-closed). */
275
+ const FAIL_CLOSED = {
276
+ kind: "block",
277
+ title: "Policy error",
278
+ reason: "A policy check errored — blocked for safety (fail-closed).",
279
+ actions: ["Fix the failing guard/gate, then retry"]
280
+ };
281
+ const USER_GUARDS = [];
282
+ /** Register a user guard — runs AFTER the privileged core chain (two-tier). */
283
+ function registerGuard(guard) {
284
+ USER_GUARDS.push(guard);
285
+ }
286
+ /** Remove all registered user guards (mainly for tests). */
287
+ function clearUserGuards() {
288
+ USER_GUARDS.length = 0;
289
+ }
290
+ /**
291
+ * Run the guard chain — privileged core guards first, then user guards — and
292
+ * return the first firing Prompt, else null. Fail-closed: a guard that throws
293
+ * blocks (never silently passes).
294
+ */
275
295
  function runGuards(ctx) {
276
- for (const guard of GUARDS) {
277
- const hit = guard(ctx);
296
+ for (const guard of [...GUARDS, ...USER_GUARDS]) {
297
+ let hit;
298
+ try {
299
+ hit = guard(ctx);
300
+ } catch {
301
+ return FAIL_CLOSED;
302
+ }
278
303
  if (hit) return hit;
279
304
  }
280
305
  return null;
@@ -342,4 +367,4 @@ function evaluate(ctx) {
342
367
  };
343
368
  }
344
369
  //#endregion
345
- export { PROJECT_INSTALL as C, evaluateFileSize as D, countLines as E, detectFramework as O, GIT_BLOCKED as S, matchPatterns as T, protectedPathGuard as _, GO_DECL_RE as a, securityGuard as b, PY_MODEL_RE as c, interfaceSeparationGuard as d, ASK_WRITERS as f, PROTECTED_FRAGMENTS as g, bashWriteGuard as h, installGuard as i, SWIFT_PROTO_RE as l, CODE_REDIRECT as m, GUARDS as n, JAVA_DECL_RE as o, CODE_MUTATORS as p, runGuards as r, PHP_DECL_RE as s, evaluate as t, TS_DECL_RE as u, ASK_PATTERNS as v, SYSTEM_INSTALL as w, GIT_ASK as x, CRITICAL_PATTERNS as y };
370
+ export { evaluateFileSize as A, securityGuard as C, SYSTEM_INSTALL as D, PROJECT_INSTALL as E, matchPatterns as O, CRITICAL_PATTERNS as S, GIT_BLOCKED as T, CODE_REDIRECT as _, registerGuard as a, protectedPathGuard as b, GO_DECL_RE as c, PY_MODEL_RE as d, SWIFT_PROTO_RE as f, CODE_MUTATORS as g, ASK_WRITERS as h, clearUserGuards as i, detectFramework as j, countLines as k, JAVA_DECL_RE as l, interfaceSeparationGuard as m, FAIL_CLOSED as n, runGuards as o, TS_DECL_RE as p, GUARDS as r, installGuard as s, evaluate as t, PHP_DECL_RE as u, bashWriteGuard as v, GIT_ASK as w, ASK_PATTERNS as x, PROTECTED_FRAGMENTS as y };
@@ -1,5 +1,5 @@
1
1
  import { r as projectLayout } from "./layout-C0jaaCQC.mjs";
2
- import { O as detectFramework, t as evaluate } from "./evaluate-CpBKZ6G-.mjs";
2
+ import { j as detectFramework, n as FAIL_CLOSED, t as evaluate } from "./evaluate-CreJy519.mjs";
3
3
  import { c as evaluateApex, i as detectCreationIntent, r as capVerbosity } from "./verbosity-D82yP4WD.mjs";
4
4
  import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
5
5
  import { a as extractText, r as cacheStore, t as cacheLookup } from "./store-DeIsfMg5.mjs";
@@ -78,14 +78,19 @@ function existingLineCount(path) {
78
78
  * track. Returns the first blocking prompt, or null to allow.
79
79
  */
80
80
  async function gate(input) {
81
- const quick = evaluate({
82
- tool: input.tool,
83
- filePath: input.filePath,
84
- content: input.content,
85
- command: input.command,
86
- agentType: input.agentType,
87
- existingLines: existingLineCount(input.filePath)
88
- });
81
+ let quick;
82
+ try {
83
+ quick = evaluate({
84
+ tool: input.tool,
85
+ filePath: input.filePath,
86
+ content: input.content,
87
+ command: input.command,
88
+ agentType: input.agentType,
89
+ existingLines: existingLineCount(input.filePath)
90
+ });
91
+ } catch {
92
+ return FAIL_CLOSED;
93
+ }
89
94
  if (quick.decision !== "allow" && quick.prompt) return quick.prompt;
90
95
  if (!input.filePath) return null;
91
96
  const window = input.windowMs ?? 12e4;
@@ -95,7 +100,7 @@ async function gate(input) {
95
100
  await saveTrack(input.trackFile, recordTrivialEdit(track, input.now, window, input.now));
96
101
  return null;
97
102
  }
98
- return evaluateApex({
103
+ const ctx = {
99
104
  sessionId: input.sessionId,
100
105
  framework: input.framework,
101
106
  filePath: input.filePath,
@@ -106,7 +111,12 @@ async function gate(input) {
106
111
  agentsFresh: agentsFresh(track, [...REQUIRED_AGENTS], window, input.now),
107
112
  brainstormRequired: track.brainstormRequired,
108
113
  brainstormFresh: agentsFresh(track, ["brainstorming"], window, input.now)
109
- });
114
+ };
115
+ try {
116
+ return evaluateApex(ctx);
117
+ } catch {
118
+ return FAIL_CLOSED;
119
+ }
110
120
  }
111
121
  //#endregion
112
122
  //#region src/runtime/mcp.ts
@@ -142,6 +152,11 @@ function mutateWith(id, input) {
142
152
  if (id === "gemini-cli") return JSON.stringify({ hookSpecificOutput: { tool_input: input } });
143
153
  return "";
144
154
  }
155
+ /** The doc provider a served cache-hit satisfies (`exa`/`context7`), else undefined. */
156
+ function docSourceOf(tool) {
157
+ if (/exa/i.test(tool)) return "exa";
158
+ if (/context7/i.test(tool)) return "context7";
159
+ }
145
160
  /**
146
161
  * Pre-event MCP interception: serve a fresh cache hit (deny + cached content),
147
162
  * else cap exa verbosity (allow + mutated input), else null to allow normally.
@@ -152,12 +167,15 @@ function mcpPreIntercept(id, tool, input, dir, ttlMs, now) {
152
167
  const cached = cacheLookup(dir, tool, queryOf(input), ttlMs, now);
153
168
  if (cached) {
154
169
  const served = denyWith(id, cached);
155
- if (served) return served;
170
+ if (served) return {
171
+ stdout: served,
172
+ docSource: docSourceOf(tool)
173
+ };
156
174
  }
157
175
  const capped = capVerbosity(tool, input);
158
176
  if (capped) {
159
177
  const mutated = mutateWith(id, capped);
160
- if (mutated) return mutated;
178
+ if (mutated) return { stdout: mutated };
161
179
  }
162
180
  return null;
163
181
  }
@@ -291,10 +309,18 @@ async function handleHook(id, payload, opts) {
291
309
  };
292
310
  }
293
311
  const intercept = mcpPreIntercept(id, event.tool, event.input, mcpDir, MCP_TTL_MS, opts.now);
294
- if (intercept !== null) return {
295
- stdout: intercept,
296
- exit: 0
297
- };
312
+ if (intercept !== null) {
313
+ if (intercept.docSource) await recordActivity(file, {
314
+ kind: "doc",
315
+ framework,
316
+ sessionId: event.sessionId,
317
+ source: intercept.docSource
318
+ });
319
+ return {
320
+ stdout: intercept.stdout,
321
+ exit: 0
322
+ };
323
+ }
298
324
  const prompt = await gate({
299
325
  sessionId: event.sessionId,
300
326
  framework,
@@ -191,7 +191,17 @@ declare function installGuard(ctx: GuardContext): Prompt | null;
191
191
  //#region src/policy/guards/index.d.ts
192
192
  /** Ordered guard chain: critical/security + protected first, then writes/installs. */
193
193
  declare const GUARDS: ReadonlyArray<Guard>;
194
- /** Run the guard chain; the first firing guard's Prompt wins, else null. */
194
+ /** Block prompt returned when a guard or gate throws (fail-closed). */
195
+ declare const FAIL_CLOSED: Prompt;
196
+ /** Register a user guard — runs AFTER the privileged core chain (two-tier). */
197
+ declare function registerGuard(guard: Guard): void;
198
+ /** Remove all registered user guards (mainly for tests). */
199
+ declare function clearUserGuards(): void;
200
+ /**
201
+ * Run the guard chain — privileged core guards first, then user guards — and
202
+ * return the first firing Prompt, else null. Fail-closed: a guard that throws
203
+ * blocks (never silently passes).
204
+ */
195
205
  declare function runGuards(ctx: GuardContext): Prompt | null;
196
206
  //#endregion
197
207
  //#region src/policy/creation-intent.d.ts
@@ -214,4 +224,4 @@ declare const MAX_TOKENS = 2e3;
214
224
  */
215
225
  declare function capVerbosity(tool: string, input: Record<string, unknown>): Record<string, unknown> | null;
216
226
  //#endregion
217
- export { docConsultedGate as A, SYSTEM_INSTALL as B, securityGuard as C, ApexContext as D, APEX_GATES as E, PolicyResult as F, detectFramework as G, FileSizeVerdict as H, evaluate as I, detectProjectType as J, DEV_KEYWORDS as K, GIT_ASK as L, freshnessGate as M, solidReadGate as N, ApexGate as O, PolicyContext as P, GIT_BLOCKED as R, CRITICAL_PATTERNS as S, GuardContext as T, countLines as U, matchPatterns as V, evaluateFileSize as W, isApexCommand as Y, CODE_REDIRECT as _, GUARDS as a, protectedPathGuard as b, GO_DECL_RE as c, PY_MODEL_RE as d, SWIFT_PROTO_RE as f, CODE_MUTATORS as g, ASK_WRITERS as h, detectCreationIntent as i, evaluateApex as j, brainstormGate as k, JAVA_DECL_RE as l, interfaceSeparationGuard as m, MAX_TOKENS as n, runGuards as o, TS_DECL_RE as p, ProjectType as q, capVerbosity as r, installGuard as s, MAX_EXA_RESULTS as t, PHP_DECL_RE as u, bashWriteGuard as v, Guard as w, ASK_PATTERNS as x, PROTECTED_FRAGMENTS as y, PROJECT_INSTALL as z };
227
+ export { ApexContext as A, GIT_ASK as B, protectedPathGuard as C, Guard as D, securityGuard as E, freshnessGate as F, FileSizeVerdict as G, PROJECT_INSTALL as H, solidReadGate as I, detectFramework as J, countLines as K, PolicyContext as L, brainstormGate as M, docConsultedGate as N, GuardContext as O, evaluateApex as P, isApexCommand as Q, PolicyResult as R, PROTECTED_FRAGMENTS as S, CRITICAL_PATTERNS as T, SYSTEM_INSTALL as U, GIT_BLOCKED as V, matchPatterns as W, ProjectType as X, DEV_KEYWORDS as Y, detectProjectType as Z, interfaceSeparationGuard as _, FAIL_CLOSED as a, CODE_REDIRECT as b, registerGuard as c, GO_DECL_RE as d, JAVA_DECL_RE as f, TS_DECL_RE as g, SWIFT_PROTO_RE as h, detectCreationIntent as i, ApexGate as j, APEX_GATES as k, runGuards as l, PY_MODEL_RE as m, MAX_TOKENS as n, GUARDS as o, PHP_DECL_RE as p, evaluateFileSize as q, capVerbosity as r, clearUserGuards as s, MAX_EXA_RESULTS as t, installGuard as u, ASK_WRITERS as v, ASK_PATTERNS as w, bashWriteGuard as x, CODE_MUTATORS as y, evaluate as z };
package/dist/index.d.mts CHANGED
@@ -5,10 +5,10 @@ import { a as detectHarness, i as HarnessVia, n as HarnessInfo, o as detectMode,
5
5
  import { a as isDocConsulted, i as formatDocSatisfactionStatus, n as DocSatisfactionStatus, o as resolveSessions, r as formatDocDeny, t as AuthEntry } from "./doc-helpers-CG1nuf-c.mjs";
6
6
  import { t as incrementTrivialEditCounter } from "./index-BOBXQ91y.mjs";
7
7
  import { i as compactJson, n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./index-C1vLIMwN.mjs";
8
- import { A as docConsultedGate, B as SYSTEM_INSTALL, C as securityGuard, D as ApexContext, E as APEX_GATES, F as PolicyResult, G as detectFramework, H as FileSizeVerdict, I as evaluate, J as detectProjectType, K as DEV_KEYWORDS, L as GIT_ASK, M as freshnessGate, N as solidReadGate, O as ApexGate, P as PolicyContext, R as GIT_BLOCKED, S as CRITICAL_PATTERNS, T as GuardContext, U as countLines, V as matchPatterns, W as evaluateFileSize, Y as isApexCommand, _ as CODE_REDIRECT, a as GUARDS, b as protectedPathGuard, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as CODE_MUTATORS, h as ASK_WRITERS, i as detectCreationIntent, j as evaluateApex, k as brainstormGate, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as MAX_TOKENS, o as runGuards, p as TS_DECL_RE, q as ProjectType, r as capVerbosity, s as installGuard, t as MAX_EXA_RESULTS, u as PHP_DECL_RE, v as bashWriteGuard, w as Guard, x as ASK_PATTERNS, y as PROTECTED_FRAGMENTS, z as PROJECT_INSTALL } from "./index-oco-cH5T.mjs";
8
+ import { A as ApexContext, B as GIT_ASK, C as protectedPathGuard, D as Guard, E as securityGuard, F as freshnessGate, G as FileSizeVerdict, H as PROJECT_INSTALL, I as solidReadGate, J as detectFramework, K as countLines, L as PolicyContext, M as brainstormGate, N as docConsultedGate, O as GuardContext, P as evaluateApex, Q as isApexCommand, R as PolicyResult, S as PROTECTED_FRAGMENTS, T as CRITICAL_PATTERNS, U as SYSTEM_INSTALL, V as GIT_BLOCKED, W as matchPatterns, X as ProjectType, Y as DEV_KEYWORDS, Z as detectProjectType, _ as interfaceSeparationGuard, a as FAIL_CLOSED, b as CODE_REDIRECT, c as registerGuard, d as GO_DECL_RE, f as JAVA_DECL_RE, g as TS_DECL_RE, h as SWIFT_PROTO_RE, i as detectCreationIntent, j as ApexGate, k as APEX_GATES, l as runGuards, m as PY_MODEL_RE, n as MAX_TOKENS, o as GUARDS, p as PHP_DECL_RE, q as evaluateFileSize, r as capVerbosity, s as clearUserGuards, t as MAX_EXA_RESULTS, u as installGuard, v as ASK_WRITERS, w as ASK_PATTERNS, x as bashWriteGuard, y as CODE_MUTATORS, z as evaluate } from "./index-DNAzITvw.mjs";
9
9
  import { n as RouteResult, r as ScoredRef, t as RefMeta } from "./types-CY5qT2X1.mjs";
10
10
  import { a as ReminderState, c as readState, d as throttleMs, i as registryFile, l as setStateField, n as addRoot, o as lessonsFileFor, r as readRoots, s as nowStamp, t as ensureMemoryGitignore, u as stateFileFor } from "./index-DLYhervv.mjs";
11
11
  import { a as globToRe, i as scoreReferences, n as toRefMeta, o as parseFrontmatter, r as routeReferences, t as loadRefs } from "./index-hL_r6tlc.mjs";
12
12
  import { a as taskStart, c as ensureStateDir, d as stateFilePath, f as acquireLock, i as taskCreate, l as loadState, n as ApexTaskFile, o as ApexState, r as taskComplete, s as apexStateDir, t as ApexTask, u as saveState } from "./index-CPoF_hLP.mjs";
13
13
  import { _ as TIME_INTERVALS, a as formatCost, c as formatTokens, d as colors, f as progressiveColor, g as PROGRESS_CHARS, h as PROGRESS_BAR_DEFAULTS, i as formatBasename, l as ColorFn, m as GRADIENT_BLOCKS, n as generateGradientBar, o as formatPath, p as COLOR_THRESHOLDS, r as generateProgressBar, s as formatTimeLeft, t as ProgressBarOptions, u as Palette } from "./index-BWK8slRi.mjs";
14
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexState, ApexTask, ApexTaskFile, AuthEntry, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DocSatisfactionStatus, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, Guard, GuardContext, HarnessId, HarnessInfo, HarnessMode, HarnessVia, IndexSummary, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, Palette, PolicyContext, PolicyResult, ProgressBarOptions, ProjectLayout, ProjectType, Prompt, PromptKind, RefMeta, ReminderState, RouteResult, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, cacheLookup, cachePath, cacheStore, capVerbosity, colors, compactJson, compactMarkdown, countLines, detectCreationIntent, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, lessonsFileFor, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel };
14
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexState, ApexTask, ApexTaskFile, AuthEntry, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DocSatisfactionStatus, FAIL_CLOSED, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, Guard, GuardContext, HarnessId, HarnessInfo, HarnessMode, HarnessVia, IndexSummary, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, Palette, PolicyContext, PolicyResult, ProgressBarOptions, ProjectLayout, ProjectType, Prompt, PromptKind, RefMeta, ReminderState, RouteResult, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, cacheLookup, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countLines, detectCreationIntent, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, lessonsFileFor, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel };
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import { t as compactJson } from "./compact-json-DK2nX-MK.mjs";
5
5
  import { n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./project-root-ff0_poWU.mjs";
6
6
  import { n as detectMode, r as modeFor, t as detectHarness } from "./harness-C8Nxxyn_.mjs";
7
7
  import { n as detectProjectType, r as isApexCommand, t as DEV_KEYWORDS } from "./policy-EuVJ_5hS.mjs";
8
- import { C as PROJECT_INSTALL, D as evaluateFileSize, E as countLines, O as detectFramework, S as GIT_BLOCKED, T as matchPatterns, _ as protectedPathGuard, a as GO_DECL_RE, b as securityGuard, c as PY_MODEL_RE, d as interfaceSeparationGuard, f as ASK_WRITERS, g as PROTECTED_FRAGMENTS, h as bashWriteGuard, i as installGuard, l as SWIFT_PROTO_RE, m as CODE_REDIRECT, n as GUARDS, o as JAVA_DECL_RE, p as CODE_MUTATORS, r as runGuards, s as PHP_DECL_RE, t as evaluate, u as TS_DECL_RE, v as ASK_PATTERNS, w as SYSTEM_INSTALL, x as GIT_ASK, y as CRITICAL_PATTERNS } from "./evaluate-CpBKZ6G-.mjs";
8
+ import { A as evaluateFileSize, C as securityGuard, D as SYSTEM_INSTALL, E as PROJECT_INSTALL, O as matchPatterns, S as CRITICAL_PATTERNS, T as GIT_BLOCKED, _ as CODE_REDIRECT, a as registerGuard, b as protectedPathGuard, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as CODE_MUTATORS, h as ASK_WRITERS, i as clearUserGuards, j as detectFramework, k as countLines, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as bashWriteGuard, w as GIT_ASK, x as ASK_PATTERNS, y as PROTECTED_FRAGMENTS } from "./evaluate-CreJy519.mjs";
9
9
  import { i as resolveSessions, n as formatDocSatisfactionStatus, r as isDocConsulted, t as formatDocDeny } from "./doc-helpers-Dd_x1-tZ.mjs";
10
10
  import { i as parseFrontmatter, n as scoreReferences, r as globToRe, t as routeReferences } from "./router-Dj3AfgBE.mjs";
11
11
  import { a as APEX_GATES, c as evaluateApex, i as detectCreationIntent, l as freshnessGate, n as MAX_TOKENS, o as brainstormGate, r as capVerbosity, s as docConsultedGate, t as MAX_EXA_RESULTS, u as solidReadGate } from "./verbosity-D82yP4WD.mjs";
@@ -17,4 +17,4 @@ import { t as incrementTrivialEditCounter } from "./freshness-CezohJHo.mjs";
17
17
  import { n as toRefMeta, t as loadRefs } from "./loader-BephwI8n.mjs";
18
18
  import { a as ensureStateDir, c as stateFilePath, i as apexStateDir, l as acquireLock, n as taskCreate, o as loadState, r as taskStart, s as saveState, t as taskComplete } from "./state-Cs0Y0MG_.mjs";
19
19
  import { a as formatPath, c as colors, d as GRADIENT_BLOCKS, f as PROGRESS_BAR_DEFAULTS, i as formatCost, l as progressiveColor, m as TIME_INTERVALS, n as generateProgressBar, o as formatTimeLeft, p as PROGRESS_CHARS, r as formatBasename, s as formatTokens, t as generateGradientBar, u as COLOR_THRESHOLDS } from "./statusline-D87eUNXl.mjs";
20
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, cacheLookup, cachePath, cacheStore, capVerbosity, colors, compactJson, compactMarkdown, countLines, detectCreationIntent, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, lessonsFileFor, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel };
20
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, FAIL_CLOSED, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, cacheLookup, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countLines, detectCreationIntent, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, lessonsFileFor, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel };
@@ -1,2 +1,2 @@
1
- import { A as docConsultedGate, B as SYSTEM_INSTALL, C as securityGuard, D as ApexContext, E as APEX_GATES, F as PolicyResult, G as detectFramework, H as FileSizeVerdict, I as evaluate, J as detectProjectType, K as DEV_KEYWORDS, L as GIT_ASK, M as freshnessGate, N as solidReadGate, O as ApexGate, P as PolicyContext, R as GIT_BLOCKED, S as CRITICAL_PATTERNS, T as GuardContext, U as countLines, V as matchPatterns, W as evaluateFileSize, Y as isApexCommand, _ as CODE_REDIRECT, a as GUARDS, b as protectedPathGuard, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as CODE_MUTATORS, h as ASK_WRITERS, i as detectCreationIntent, j as evaluateApex, k as brainstormGate, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as MAX_TOKENS, o as runGuards, p as TS_DECL_RE, q as ProjectType, r as capVerbosity, s as installGuard, t as MAX_EXA_RESULTS, u as PHP_DECL_RE, v as bashWriteGuard, w as Guard, x as ASK_PATTERNS, y as PROTECTED_FRAGMENTS, z as PROJECT_INSTALL } from "../index-oco-cH5T.mjs";
2
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, Guard, GuardContext, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_TOKENS, PHP_DECL_RE, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, PolicyContext, PolicyResult, ProjectType, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, bashWriteGuard, brainstormGate, capVerbosity, countLines, detectCreationIntent, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, matchPatterns, protectedPathGuard, runGuards, securityGuard, solidReadGate };
1
+ import { A as ApexContext, B as GIT_ASK, C as protectedPathGuard, D as Guard, E as securityGuard, F as freshnessGate, G as FileSizeVerdict, H as PROJECT_INSTALL, I as solidReadGate, J as detectFramework, K as countLines, L as PolicyContext, M as brainstormGate, N as docConsultedGate, O as GuardContext, P as evaluateApex, Q as isApexCommand, R as PolicyResult, S as PROTECTED_FRAGMENTS, T as CRITICAL_PATTERNS, U as SYSTEM_INSTALL, V as GIT_BLOCKED, W as matchPatterns, X as ProjectType, Y as DEV_KEYWORDS, Z as detectProjectType, _ as interfaceSeparationGuard, a as FAIL_CLOSED, b as CODE_REDIRECT, c as registerGuard, d as GO_DECL_RE, f as JAVA_DECL_RE, g as TS_DECL_RE, h as SWIFT_PROTO_RE, i as detectCreationIntent, j as ApexGate, k as APEX_GATES, l as runGuards, m as PY_MODEL_RE, n as MAX_TOKENS, o as GUARDS, p as PHP_DECL_RE, q as evaluateFileSize, r as capVerbosity, s as clearUserGuards, t as MAX_EXA_RESULTS, u as installGuard, v as ASK_WRITERS, w as ASK_PATTERNS, x as bashWriteGuard, y as CODE_MUTATORS, z as evaluate } from "../index-DNAzITvw.mjs";
2
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, FAIL_CLOSED, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, Guard, GuardContext, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_TOKENS, PHP_DECL_RE, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, PolicyContext, PolicyResult, ProjectType, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, bashWriteGuard, brainstormGate, capVerbosity, clearUserGuards, countLines, detectCreationIntent, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, matchPatterns, protectedPathGuard, registerGuard, runGuards, securityGuard, solidReadGate };
@@ -1,4 +1,4 @@
1
1
  import { n as detectProjectType, r as isApexCommand, t as DEV_KEYWORDS } from "../policy-EuVJ_5hS.mjs";
2
- import { C as PROJECT_INSTALL, D as evaluateFileSize, E as countLines, O as detectFramework, S as GIT_BLOCKED, T as matchPatterns, _ as protectedPathGuard, a as GO_DECL_RE, b as securityGuard, c as PY_MODEL_RE, d as interfaceSeparationGuard, f as ASK_WRITERS, g as PROTECTED_FRAGMENTS, h as bashWriteGuard, i as installGuard, l as SWIFT_PROTO_RE, m as CODE_REDIRECT, n as GUARDS, o as JAVA_DECL_RE, p as CODE_MUTATORS, r as runGuards, s as PHP_DECL_RE, t as evaluate, u as TS_DECL_RE, v as ASK_PATTERNS, w as SYSTEM_INSTALL, x as GIT_ASK, y as CRITICAL_PATTERNS } from "../evaluate-CpBKZ6G-.mjs";
2
+ import { A as evaluateFileSize, C as securityGuard, D as SYSTEM_INSTALL, E as PROJECT_INSTALL, O as matchPatterns, S as CRITICAL_PATTERNS, T as GIT_BLOCKED, _ as CODE_REDIRECT, a as registerGuard, b as protectedPathGuard, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as CODE_MUTATORS, h as ASK_WRITERS, i as clearUserGuards, j as detectFramework, k as countLines, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as bashWriteGuard, w as GIT_ASK, x as ASK_PATTERNS, y as PROTECTED_FRAGMENTS } from "../evaluate-CreJy519.mjs";
3
3
  import { a as APEX_GATES, c as evaluateApex, i as detectCreationIntent, l as freshnessGate, n as MAX_TOKENS, o as brainstormGate, r as capVerbosity, s as docConsultedGate, t as MAX_EXA_RESULTS, u as solidReadGate } from "../verbosity-D82yP4WD.mjs";
4
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_TOKENS, PHP_DECL_RE, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, bashWriteGuard, brainstormGate, capVerbosity, countLines, detectCreationIntent, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, matchPatterns, protectedPathGuard, runGuards, securityGuard, solidReadGate };
4
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, FAIL_CLOSED, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_TOKENS, PHP_DECL_RE, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PY_MODEL_RE, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, bashWriteGuard, brainstormGate, capVerbosity, clearUserGuards, countLines, detectCreationIntent, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, matchPatterns, protectedPathGuard, registerGuard, runGuards, securityGuard, solidReadGate };
@@ -1,5 +1,5 @@
1
1
  import { t as isCodeFile } from "./project-root-ff0_poWU.mjs";
2
- import { t as evaluate } from "./evaluate-CpBKZ6G-.mjs";
2
+ import { t as evaluate } from "./evaluate-CreJy519.mjs";
3
3
  import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
4
4
  import { execSync } from "node:child_process";
5
5
  //#region src/cli/run.ts
@@ -117,12 +117,17 @@ declare const MCP_TTL_MS = 1728e5;
117
117
  declare function isMcpTool(tool: string): boolean;
118
118
  /** The query/url that keys the cache. */
119
119
  declare function queryOf(input: Record<string, unknown>): string;
120
+ /** A pre-event MCP interception: the native response + any doc source it satisfied. */
121
+ interface McpIntercept {
122
+ stdout: string;
123
+ docSource?: string;
124
+ }
120
125
  /**
121
126
  * Pre-event MCP interception: serve a fresh cache hit (deny + cached content),
122
127
  * else cap exa verbosity (allow + mutated input), else null to allow normally.
123
128
  * Harnesses without input-mutation/cache support fall through to null.
124
129
  */
125
- declare function mcpPreIntercept(id: string, tool: string, input: Record<string, unknown>, dir: string, ttlMs: number, now: number): string | null;
130
+ declare function mcpPreIntercept(id: string, tool: string, input: Record<string, unknown>, dir: string, ttlMs: number, now: number): McpIntercept | null;
126
131
  /** Post-event: store the MCP/WebFetch response (extracted to markdown) in the cache. */
127
132
  declare function mcpPostStore(tool: string, input: Record<string, unknown>, response: unknown, dir: string): void;
128
133
  //#endregion
@@ -149,4 +154,4 @@ interface HandleOutcome {
149
154
  */
150
155
  declare function handleHook(id: string, payload: Record<string, unknown>, opts: HandleOptions): Promise<HandleOutcome>;
151
156
  //#endregion
152
- export { Activity, DEFAULT_WINDOW_MS, GateInput, HandleOptions, HandleOutcome, MCP_TTL_MS, NormalizedEvent, REQUIRED_AGENTS, TRIVIAL_BUDGET, ToolEvent, activityFor, gate, handleHook, harnessStateDir, isMcpTool, mcpPostStore, mcpPreIntercept, normalizeEvent, queryOf, recordActivity, respond, trackFile };
157
+ export { Activity, DEFAULT_WINDOW_MS, GateInput, HandleOptions, HandleOutcome, MCP_TTL_MS, McpIntercept, NormalizedEvent, REQUIRED_AGENTS, TRIVIAL_BUDGET, ToolEvent, activityFor, gate, handleHook, harnessStateDir, isMcpTool, mcpPostStore, mcpPreIntercept, normalizeEvent, queryOf, recordActivity, respond, trackFile };
@@ -1,5 +1,5 @@
1
1
  import { r as projectLayout } from "../layout-C0jaaCQC.mjs";
2
- import { a as normalizeEvent, c as mcpPostStore, d as DEFAULT_WINDOW_MS, f as REQUIRED_AGENTS, h as activityFor, i as trackFile, l as mcpPreIntercept, m as gate, n as respond, o as MCP_TTL_MS, p as TRIVIAL_BUDGET, r as recordActivity, s as isMcpTool, t as handleHook, u as queryOf } from "../handle-SPlcCQYl.mjs";
2
+ import { a as normalizeEvent, c as mcpPostStore, d as DEFAULT_WINDOW_MS, f as REQUIRED_AGENTS, h as activityFor, i as trackFile, l as mcpPreIntercept, m as gate, n as respond, o as MCP_TTL_MS, p as TRIVIAL_BUDGET, r as recordActivity, s as isMcpTool, t as handleHook, u as queryOf } from "../handle-DztC8AKY.mjs";
3
3
  //#region src/runtime/storage.ts
4
4
  /**
5
5
  * The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/harness",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Harness-agnostic toolkit for AI coding agents: runtime harness detection (Claude Code, Codex, Cursor, Cline, Gemini, Aider...), pure policy core (env config, project/framework detection, SOLID/file-size limits, APEX freshness, guard patterns, portable prompts), cache, project memory, ref routing, state/locks, statusline, per-harness adapters (Claude/Cursor/Cline/Gemini) and a cli-mode harness-check binary. Bun-native, with a built dist for Node + bundlers.",
5
5
  "type": "module",
6
6
  "module": "src/index.ts",