@fusengine/harness 0.1.49 → 0.1.51

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,6 +1,6 @@
1
1
  import { t as Prompt } from "../types-DVbIl9md.mjs";
2
2
  import { t as RefMeta } from "../types-CY5qT2X1.mjs";
3
- import { t as AgentQuality } from "../session-state-DMpotbRz.mjs";
3
+ import { t as AgentQuality } from "../session-state-CY4iohn_.mjs";
4
4
 
5
5
  //#region src/runtime/paths.d.ts
6
6
  /**
@@ -108,18 +108,17 @@ interface GateInput {
108
108
  /** Prior agents the freshness gate requires before a code edit. */
109
109
  declare const REQUIRED_AGENTS: ReadonlyArray<string>;
110
110
  /**
111
- * Default freshness window for {@link REQUIRED_AGENTS}, in ms. Matches the
112
- * plugin's `FUSE_ENFORCE_TTL_SEC` default (120s). Only a fallback for direct
113
- * programmatic callers that omit `windowMs` (e.g. tests) — the real CLI path
114
- * always supplies `windowMs` from `resolveTtlSec()` (`src/config/ttl.ts`).
111
+ * Default freshness window (ms). Matches the plugin's `FUSE_ENFORCE_TTL_SEC`
112
+ * default (120s); only a fallback for callers that omit `windowMs` (e.g. tests) —
113
+ * the real CLI path always supplies it from `resolveTtlSec()` (`src/config/ttl.ts`).
115
114
  */
116
115
  declare const DEFAULT_WINDOW_MS = 12e4;
117
116
  /** Trivial edits allowed within the window before the full APEX gates apply. */
118
117
  declare const TRIVIAL_BUDGET = 4;
119
118
  /**
120
- * Full gate: the stateless guards (file-size, git, security...) first, then a
121
- * trivial-edit fast path, then the stateful APEX gates fed from the session
122
- * track. Returns the first blocking prompt, or null to allow.
119
+ * Full gate: {@link runGates} yields the first blocking prompt (or null); the
120
+ * anti-loop tail ({@link withDenyLoop}) rewrites an identical retried deny's
121
+ * message (decision unchanged). Sidecar dir = the track's dir (tests off `$HOME`).
123
122
  */
124
123
  declare function gate(input: GateInput): Promise<Prompt | null>;
125
124
  //#endregion
@@ -240,8 +239,24 @@ declare function mcpPostStore(tool: string, input: Record<string, unknown>, resp
240
239
  //#endregion
241
240
  //#region src/runtime/inject-context.d.ts
242
241
  /**
242
+ * Build the {@link oncePerWindow} key for the CLAUDE.md preamble gate. The
243
+ * prompt hash keeps two distinct legitimate turns from colliding — even non-dev
244
+ * prompts, whose block is prompt-independent (just CLAUDE.md) and would
245
+ * otherwise hash-collide within the window — while the content hash still lets a
246
+ * same-turn double-fire of an identical block be suppressed. Single source of
247
+ * truth so the owner invariant test guards the real production key.
248
+ * @param prompt - The raw user prompt.
249
+ * @param ctx - The rendered CLAUDE.md (+ optional APEX) block.
250
+ * @returns The namespaced dedup key.
251
+ */
252
+ declare function claudeMdKey(prompt: string, ctx: string): string;
253
+ /**
243
254
  * UserPromptSubmit context injection: render the CLAUDE.md (+ optional APEX)
244
255
  * preamble as a Claude `additionalContext` response, or "" when nothing to emit.
256
+ * Guarded by {@link oncePerWindow} via {@link claudeMdKey}: only a
257
+ * near-simultaneous double-fire of the SAME turn (identical prompt AND identical
258
+ * block, within {@link DEDUP_WINDOW_MS}) is suppressed. The invariant "CLAUDE.md
259
+ * is emitted on EVERY message" is thus preserved.
245
260
  * @param prompt - The raw user prompt.
246
261
  * @param cwd - Project root (for project-type detection).
247
262
  * @returns The native hook stdout (possibly empty).
@@ -811,4 +826,4 @@ interface PreContext {
811
826
  */
812
827
  declare function handlePre(ctx: PreContext): Promise<HandleOutcome>;
813
828
  //#endregion
814
- export { Activity, DEFAULT_WINDOW_MS, DuplicationVerdict, type GateInput, HandleOptions, HandleOutcome, LifecycleInput, MCP_TTL_MS, McpIntercept, NormalizedEvent, PluginScope, PreContext, REQUIRED_AGENTS, SolidProfile, TRIVIAL_BUDGET, ToolEvent, WEBFETCH_TTL_MS, activityFor, aipilotPostToolUse, cacheQueryOf, cartoSessionStart, checkFileSize, claudeHome, cleanupSession, countFiles, countLoc, defaultStateDir, detectDuplication, detectSolidProfile, devContext, dispatchAipilot, dispatchLessons, dispatchLifecycle, dispatchMemory, dryGate, extractSymbols, fuseHarnessHome, fusengineCache, gate, generateEcosystemMap, generateProjectMap, getFileDesc, gitContext, handleHook, handlePre, harnessStateDir, injectRules, isMcpTool, isProject, isoUtc, lessonsFileFor, lessonsStateFileFor, lifecycleStdout, listChildren, loadEnriched, loadSecurityState, loadSessionState, logToolFailure, mcpPostStore, mcpPreIntercept, mergeLines, normalizeEvent, postEditContext, postEditTypescript, postTrackingSideEffects, preCommitGate, projectContext, projectHash, promptSubmitContext, pruneEmptyDirs, purgeTtlTree, queryOf, readRules, recordActivity, removeOldFiles, respond, runSessionStartCleanups, sanitizeSessionId, saveApexState, saveSecurityState, saveSessionState, securityAdvisory, securityStateDir, securityStatePath, seoPostToolUse, seoPostToolUseResponse, sessionStartCore, sessionStatePath, sessionsDir, solidDetectStart, subagentCacheContext, taskContext, todayUtc, trackAgentMemory, trackEnrichment, trackFile, trackMcpResearch, trackSessionChanges, trackSkillRead, trackWatchResearch, trimLogFile, validateRulesLoaded, validateSolidGate, validateTailwind, validateTeammateOutput, writePluginMap, writeTree };
829
+ export { Activity, DEFAULT_WINDOW_MS, DuplicationVerdict, type GateInput, HandleOptions, HandleOutcome, LifecycleInput, MCP_TTL_MS, McpIntercept, NormalizedEvent, PluginScope, PreContext, REQUIRED_AGENTS, SolidProfile, TRIVIAL_BUDGET, ToolEvent, WEBFETCH_TTL_MS, activityFor, aipilotPostToolUse, cacheQueryOf, cartoSessionStart, checkFileSize, claudeHome, claudeMdKey, cleanupSession, countFiles, countLoc, defaultStateDir, detectDuplication, detectSolidProfile, devContext, dispatchAipilot, dispatchLessons, dispatchLifecycle, dispatchMemory, dryGate, extractSymbols, fuseHarnessHome, fusengineCache, gate, generateEcosystemMap, generateProjectMap, getFileDesc, gitContext, handleHook, handlePre, harnessStateDir, injectRules, isMcpTool, isProject, isoUtc, lessonsFileFor, lessonsStateFileFor, lifecycleStdout, listChildren, loadEnriched, loadSecurityState, loadSessionState, logToolFailure, mcpPostStore, mcpPreIntercept, mergeLines, normalizeEvent, postEditContext, postEditTypescript, postTrackingSideEffects, preCommitGate, projectContext, projectHash, promptSubmitContext, pruneEmptyDirs, purgeTtlTree, queryOf, readRules, recordActivity, removeOldFiles, respond, runSessionStartCleanups, sanitizeSessionId, saveApexState, saveSecurityState, saveSessionState, securityAdvisory, securityStateDir, securityStatePath, seoPostToolUse, seoPostToolUseResponse, sessionStartCore, sessionStatePath, sessionsDir, solidDetectStart, subagentCacheContext, taskContext, todayUtc, trackAgentMemory, trackEnrichment, trackFile, trackMcpResearch, trackSessionChanges, trackSkillRead, trackWatchResearch, trimLogFile, validateRulesLoaded, validateSolidGate, validateTailwind, validateTeammateOutput, writePluginMap, writeTree };
@@ -1,6 +1,6 @@
1
1
  import { r as projectLayout } from "../layout-C0jaaCQC.mjs";
2
2
  import { a as sanitizeSessionId, c as sessionsDir, i as loadSessionState, n as fuseHarnessHome, o as saveSessionState, r as fusengineCache, s as sessionStatePath, t as claudeHome } from "../home-state-D0RLWP8J.mjs";
3
- import { $ as saveApexState, A as trackSkillRead, At as securityStateDir, B as writePluginMap, C as seoPostToolUse, Ct as defaultStateDir, D as postTrackingSideEffects, Dt as isoUtc, E as securityAdvisory, Et as normalizeEvent, F as dispatchLessons, G as mergeLines, H as isProject, I as lessonsFileFor, J as listChildren, K as countFiles, L as lessonsStateFileFor, M as dispatchLifecycle, Mt as todayUtc, N as aipilotPostToolUse, O as trackWatchResearch, Ot as loadSecurityState, P as dispatchAipilot, Q as cleanupSession, R as cartoSessionStart, S as postEditContext, St as taskContext, T as dispatchMemory, Tt as trackFile, U as writeTree, V as generateProjectMap, W as loadEnriched, X as trackSessionChanges, Y as postEditTypescript, Z as validateRulesLoaded, _ as preCommitGate, _t as trimLogFile, a as recordActivity, at as validateSolidGate, b as extractSymbols, bt as projectContext, c as MCP_TTL_MS, ct as detectSolidProfile, d as isMcpTool, dt as readRules, et as logToolFailure, f as queryOf, ft as runSessionStartCleanups, g as gate, gt as removeOldFiles, h as TRIVIAL_BUDGET, ht as purgeTtlTree, i as respond, it as validateTailwind, j as trackEnrichment, jt as securityStatePath, k as trackMcpResearch, kt as saveSecurityState, l as WEBFETCH_TTL_MS, lt as solidDetectStart, m as REQUIRED_AGENTS, mt as pruneEmptyDirs, n as activityFor, nt as trackAgentMemory, o as mcpPostStore, ot as checkFileSize, p as DEFAULT_WINDOW_MS, pt as sessionStartCore, q as getFileDesc, r as handlePre, rt as subagentCacheContext, s as mcpPreIntercept, st as countLoc, t as handleHook, tt as validateTeammateOutput, u as cacheQueryOf, ut as injectRules, v as detectDuplication, vt as devContext, w as seoPostToolUseResponse, wt as projectHash, x as lifecycleStdout, xt as promptSubmitContext, y as dryGate, yt as gitContext, z as generateEcosystemMap } from "../handle-D1hHqHvh.mjs";
3
+ import { $ as saveApexState, A as trackSkillRead, At as saveSecurityState, B as writePluginMap, C as seoPostToolUse, Ct as taskContext, D as postTrackingSideEffects, Dt as normalizeEvent, E as securityAdvisory, Et as trackFile, F as dispatchLessons, G as mergeLines, H as isProject, I as lessonsFileFor, J as listChildren, K as countFiles, L as lessonsStateFileFor, M as dispatchLifecycle, Mt as securityStatePath, N as aipilotPostToolUse, Nt as todayUtc, O as trackWatchResearch, Ot as isoUtc, P as dispatchAipilot, Q as cleanupSession, R as cartoSessionStart, S as postEditContext, St as promptSubmitContext, T as dispatchMemory, Tt as projectHash, U as writeTree, V as generateProjectMap, W as loadEnriched, X as trackSessionChanges, Y as postEditTypescript, Z as validateRulesLoaded, _ as preCommitGate, _t as trimLogFile, a as recordActivity, at as validateSolidGate, b as extractSymbols, bt as projectContext, c as MCP_TTL_MS, ct as detectSolidProfile, d as isMcpTool, dt as readRules, et as logToolFailure, f as queryOf, ft as runSessionStartCleanups, g as gate, gt as removeOldFiles, h as TRIVIAL_BUDGET, ht as purgeTtlTree, i as respond, it as validateTailwind, j as trackEnrichment, jt as securityStateDir, k as trackMcpResearch, kt as loadSecurityState, l as WEBFETCH_TTL_MS, lt as solidDetectStart, m as REQUIRED_AGENTS, mt as pruneEmptyDirs, n as activityFor, nt as trackAgentMemory, o as mcpPostStore, ot as checkFileSize, p as DEFAULT_WINDOW_MS, pt as sessionStartCore, q as getFileDesc, r as handlePre, rt as subagentCacheContext, s as mcpPreIntercept, st as countLoc, t as handleHook, tt as validateTeammateOutput, u as cacheQueryOf, ut as injectRules, v as detectDuplication, vt as devContext, w as seoPostToolUseResponse, wt as defaultStateDir, x as lifecycleStdout, xt as claudeMdKey, y as dryGate, yt as gitContext, z as generateEcosystemMap } from "../handle-QfgfNSh6.mjs";
4
4
  //#region src/runtime/storage.ts
5
5
  /**
6
6
  * The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
@@ -10,4 +10,4 @@ function harnessStateDir(root) {
10
10
  return projectLayout(root).stateDir;
11
11
  }
12
12
  //#endregion
13
- export { DEFAULT_WINDOW_MS, MCP_TTL_MS, REQUIRED_AGENTS, TRIVIAL_BUDGET, WEBFETCH_TTL_MS, activityFor, aipilotPostToolUse, cacheQueryOf, cartoSessionStart, checkFileSize, claudeHome, cleanupSession, countFiles, countLoc, defaultStateDir, detectDuplication, detectSolidProfile, devContext, dispatchAipilot, dispatchLessons, dispatchLifecycle, dispatchMemory, dryGate, extractSymbols, fuseHarnessHome, fusengineCache, gate, generateEcosystemMap, generateProjectMap, getFileDesc, gitContext, handleHook, handlePre, harnessStateDir, injectRules, isMcpTool, isProject, isoUtc, lessonsFileFor, lessonsStateFileFor, lifecycleStdout, listChildren, loadEnriched, loadSecurityState, loadSessionState, logToolFailure, mcpPostStore, mcpPreIntercept, mergeLines, normalizeEvent, postEditContext, postEditTypescript, postTrackingSideEffects, preCommitGate, projectContext, projectHash, promptSubmitContext, pruneEmptyDirs, purgeTtlTree, queryOf, readRules, recordActivity, removeOldFiles, respond, runSessionStartCleanups, sanitizeSessionId, saveApexState, saveSecurityState, saveSessionState, securityAdvisory, securityStateDir, securityStatePath, seoPostToolUse, seoPostToolUseResponse, sessionStartCore, sessionStatePath, sessionsDir, solidDetectStart, subagentCacheContext, taskContext, todayUtc, trackAgentMemory, trackEnrichment, trackFile, trackMcpResearch, trackSessionChanges, trackSkillRead, trackWatchResearch, trimLogFile, validateRulesLoaded, validateSolidGate, validateTailwind, validateTeammateOutput, writePluginMap, writeTree };
13
+ export { DEFAULT_WINDOW_MS, MCP_TTL_MS, REQUIRED_AGENTS, TRIVIAL_BUDGET, WEBFETCH_TTL_MS, activityFor, aipilotPostToolUse, cacheQueryOf, cartoSessionStart, checkFileSize, claudeHome, claudeMdKey, cleanupSession, countFiles, countLoc, defaultStateDir, detectDuplication, detectSolidProfile, devContext, dispatchAipilot, dispatchLessons, dispatchLifecycle, dispatchMemory, dryGate, extractSymbols, fuseHarnessHome, fusengineCache, gate, generateEcosystemMap, generateProjectMap, getFileDesc, gitContext, handleHook, handlePre, harnessStateDir, injectRules, isMcpTool, isProject, isoUtc, lessonsFileFor, lessonsStateFileFor, lifecycleStdout, listChildren, loadEnriched, loadSecurityState, loadSessionState, logToolFailure, mcpPostStore, mcpPreIntercept, mergeLines, normalizeEvent, postEditContext, postEditTypescript, postTrackingSideEffects, preCommitGate, projectContext, projectHash, promptSubmitContext, pruneEmptyDirs, purgeTtlTree, queryOf, readRules, recordActivity, removeOldFiles, respond, runSessionStartCleanups, sanitizeSessionId, saveApexState, saveSecurityState, saveSessionState, securityAdvisory, securityStateDir, securityStatePath, seoPostToolUse, seoPostToolUseResponse, sessionStartCore, sessionStatePath, sessionsDir, solidDetectStart, subagentCacheContext, taskContext, todayUtc, trackAgentMemory, trackEnrichment, trackFile, trackMcpResearch, trackSessionChanges, trackSkillRead, trackWatchResearch, trimLogFile, validateRulesLoaded, validateSolidGate, validateTailwind, validateTeammateOutput, writePluginMap, writeTree };
@@ -9,6 +9,21 @@ interface SessionTarget {
9
9
  set_at: string;
10
10
  }
11
11
  //#endregion
12
+ //#region src/tracking/receipts.d.ts
13
+ /**
14
+ * A verification receipt captured at PostToolUse from a Bash verification
15
+ * command. Feeds the TaskCompleted receipt gate: a "done" over modified code
16
+ * files is refused unless a fresh, passing receipt (`exitCode === 0`, `fail === 0`)
17
+ * exists. `pass`/`fail` are parsed only for test runs; `tsc` carries the code alone.
18
+ */
19
+ interface Receipt {
20
+ kind: "tsc" | "test";
21
+ exitCode: number;
22
+ pass?: number;
23
+ fail?: number;
24
+ ts: number;
25
+ }
26
+ //#endregion
12
27
  //#region src/tracking/session-state.d.ts
13
28
  /** Quality of a recorded agent call (the freshness gate ignores insufficient ones). */
14
29
  type AgentQuality = "sufficient" | "insufficient";
@@ -34,6 +49,8 @@ interface SessionTrack {
34
49
  }[];
35
50
  trivialEdits: number[];
36
51
  brainstormRequired?: boolean;
52
+ /** Verification receipts (tsc/test) at PostToolUse; absent/empty reads as unverified in the TaskCompleted gate (backward compat, fail-closed). See {@link Receipt}. */
53
+ receipts?: Receipt[];
37
54
  }
38
55
  /** A fresh, empty track. */
39
56
  declare function emptyTrack(): SessionTrack;
@@ -346,4 +346,4 @@ async function saveTrack(file, track) {
346
346
  writeLastNonce(envelope.nonce);
347
347
  }
348
348
  //#endregion
349
- export { emptyTrack as a, recordDoc as c, recordTrivialEdit as d, trivialCount as f, agentsFresh as i, recordRefRead as l, saveTrack as n, recordAgent as o, apexAuthorizationGate as p, verifyTrack as r, recordBrainstormRequired as s, loadTrack as t, recordTarget as u };
349
+ export { writeLastNonce as a, recordAgent as c, recordRefRead as d, recordTarget as f, apexAuthorizationGate as h, verifyTrack as i, recordBrainstormRequired as l, trivialCount as m, saveTrack as n, agentsFresh as o, recordTrivialEdit as p, signTrack as r, emptyTrack as s, loadTrack as t, recordDoc as u };
@@ -1,4 +1,4 @@
1
- import { a as recordAgent, c as recordRefRead, d as trivialCount, i as emptyTrack, l as recordTarget, n as SessionTrack, o as recordBrainstormRequired, r as agentsFresh, s as recordDoc, t as AgentQuality, u as recordTrivialEdit } from "../session-state-DMpotbRz.mjs";
1
+ import { a as recordAgent, c as recordRefRead, d as trivialCount, i as emptyTrack, l as recordTarget, n as SessionTrack, o as recordBrainstormRequired, r as agentsFresh, s as recordDoc, t as AgentQuality, u as recordTrivialEdit } from "../session-state-CY4iohn_.mjs";
2
2
 
3
3
  //#region src/tracking/store.d.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { a as emptyTrack, c as recordDoc, d as recordTrivialEdit, f as trivialCount, i as agentsFresh, l as recordRefRead, n as saveTrack, o as recordAgent, s as recordBrainstormRequired, t as loadTrack, u as recordTarget } from "../store-QSSTO3lY.mjs";
1
+ import { c as recordAgent, d as recordRefRead, f as recordTarget, l as recordBrainstormRequired, m as trivialCount, n as saveTrack, o as agentsFresh, p as recordTrivialEdit, s as emptyTrack, t as loadTrack, u as recordDoc } from "../store-CQ4roWrU.mjs";
2
2
  export { agentsFresh, emptyTrack, loadTrack, recordAgent, recordBrainstormRequired, recordDoc, recordRefRead, recordTarget, recordTrivialEdit, saveTrack, trivialCount };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/harness",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
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",