@fusengine/harness 0.1.81 → 0.1.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/bin.mjs +1 -1
- package/dist/{handle-J5r2f_O_.mjs → handle-F35Gx-QS.mjs} +18 -74
- package/dist/runtime/index.mjs +1 -1
- package/dist/store-Dw08Amqh.mjs +845 -0
- package/dist/tracking/index.d.mts +13 -12
- package/dist/tracking/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/store-yr_QFsZY.mjs +0 -437
package/dist/cli/bin.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { t as detectHarness } from "../harness-BMuLJ9lm.mjs";
|
|
|
5
5
|
import { t as claudeHome } from "../home-state-oUGFB4ds.mjs";
|
|
6
6
|
import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-D_WchZ3R.mjs";
|
|
7
7
|
import { n as writeInitFile, t as initFor } from "../run-TAXNRSpD.mjs";
|
|
8
|
-
import { $ as runningVersion, Q as runDoctor, Z as notify, et as versionBanner, i as respond, t as handleHook, zt as todayUtc } from "../handle-
|
|
8
|
+
import { $ as runningVersion, Q as runDoctor, Z as notify, et as versionBanner, i as respond, t as handleHook, zt as todayUtc } from "../handle-F35Gx-QS.mjs";
|
|
9
9
|
import { delimiter, join } from "node:path";
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, readSync, readdirSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { homedir } from "node:os";
|
|
@@ -12,13 +12,13 @@ import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
|
12
12
|
import { a as nowStamp, l as throttleMs, n as readRoots, o as readState, s as setStateField, t as addRoot } from "./registry-IhHk2KlT.mjs";
|
|
13
13
|
import { d as loadIndex, i as cacheLookupMeta, n as webfetchCacheWrite, o as cacheLookupSubstringMeta, t as mcpCacheWrite, u as extractText } from "./mcp-store-BkBDmuxN.mjs";
|
|
14
14
|
import { t as loadRefs } from "./loader-AGz4nK7d.mjs";
|
|
15
|
-
import {
|
|
15
|
+
import { C as apexAuthorizationGate, S as trivialCount, _ as recordBrainstormRequired, a as journalLogPath, b as recordTarget, c as appendEvent, d as signTrack, f as verifyTrack, g as recordAgent, h as emptyTrack, i as withTrack, l as withTrackLockSync, m as agentsFresh, o as readTrackSync, p as writeLastNonce, r as trackJournalEnabled, s as diffTrackEvents, t as loadTrack, u as LOCK_FAILED, v as recordDoc, x as recordTrivialEdit, y as recordRefRead } from "./store-Dw08Amqh.mjs";
|
|
16
16
|
import { n as parseApplyPatch, t as isBypassPermissions } from "./permission-mode-BN3MNgbm.mjs";
|
|
17
17
|
import { _ as commandToString, d as collectFiles, f as pathExists, g as writeText, h as spawnCapture, i as denyResponse, l as systemMessage, m as sleep, n as blockResponse, p as readText$1, r as contextResponse, s as informResponse, t as attachSystemMessage } from "./claude-D93HY8dq.mjs";
|
|
18
18
|
import { i as toKimiResponse, n as kimiDenyResponse } from "./kimi-ChbcU2uI.mjs";
|
|
19
19
|
import { r as toHermesResponse } from "./hermes-1PUEoY8q.mjs";
|
|
20
20
|
import { basename, dirname, extname, join, relative, resolve, sep } from "node:path";
|
|
21
|
-
import { appendFileSync,
|
|
21
|
+
import { appendFileSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, rmdirSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
22
22
|
import { homedir } from "node:os";
|
|
23
23
|
import { mkdir, rmdir } from "node:fs/promises";
|
|
24
24
|
import { createHash } from "node:crypto";
|
|
@@ -1248,15 +1248,13 @@ function freshPassingReceipt(track, windowMs, now) {
|
|
|
1248
1248
|
return hits.length ? hits.reduce((a, b) => b.ts > a.ts ? b : a) : null;
|
|
1249
1249
|
}
|
|
1250
1250
|
/**
|
|
1251
|
-
* Sync variant reading the
|
|
1252
|
-
* (TaskCompleted / SubagentStop). Returns the newest passing receipt, or
|
|
1253
|
-
* on any read/verify failure (fail-closed: no proof ⇒
|
|
1251
|
+
* Sync variant reading the track directly (snapshot ⊕ journal) — for the sync
|
|
1252
|
+
* gates (TaskCompleted / SubagentStop). Returns the newest passing receipt, or
|
|
1253
|
+
* `null` on any read/verify failure (fail-closed: no proof ⇒ unverified).
|
|
1254
1254
|
*/
|
|
1255
1255
|
function freshReceiptFromFile(file, windowMs, now) {
|
|
1256
1256
|
try {
|
|
1257
|
-
|
|
1258
|
-
const track = verifyTrack(JSON.parse(readFileSync(file, "utf-8")));
|
|
1259
|
-
return track ? freshPassingReceipt(track, windowMs, now) : null;
|
|
1257
|
+
return freshPassingReceipt(readTrackSync(file, trackJournalEnabled()), windowMs, now);
|
|
1260
1258
|
} catch {
|
|
1261
1259
|
return null;
|
|
1262
1260
|
}
|
|
@@ -2115,62 +2113,6 @@ function harvestAgentEvidence(transcriptPath, track, now) {
|
|
|
2115
2113
|
return uses.reduce((acc, u) => applyToolUse(acc, u, now), track);
|
|
2116
2114
|
}
|
|
2117
2115
|
//#endregion
|
|
2118
|
-
//#region src/tracking/track-lock-sync.ts
|
|
2119
|
-
/**
|
|
2120
|
-
* Synchronous twin of {@link withTrackLock} for lifecycle paths that CANNOT
|
|
2121
|
-
* float async work (the SubagentStop dispatch runs synchronously in a
|
|
2122
|
-
* short-lived hook process — an async write could be dropped before exit,
|
|
2123
|
-
* see `evidence-harvest-io.ts`). Same semantics: `wx` lockfile, bounded total
|
|
2124
|
-
* retry, named skipped write on contention, stale reclamation. The wait uses
|
|
2125
|
-
* `Atomics.wait` (allowed on the main thread in both Node and Bun).
|
|
2126
|
-
*/
|
|
2127
|
-
/** Block the thread for `ms` (bounded by the caller's total budget). */
|
|
2128
|
-
function sleepSync(ms) {
|
|
2129
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
2130
|
-
}
|
|
2131
|
-
/** True when the lockfile is older than the TTL (orphaned by a dead process). */
|
|
2132
|
-
function isStale(lock) {
|
|
2133
|
-
try {
|
|
2134
|
-
return Date.now() - statSync(lock).mtimeMs > LOCK_TTL_MS;
|
|
2135
|
-
} catch {
|
|
2136
|
-
return false;
|
|
2137
|
-
}
|
|
2138
|
-
}
|
|
2139
|
-
/**
|
|
2140
|
-
* Run `fn` under the track lock of `dir`, synchronously.
|
|
2141
|
-
* @param dir - The track state directory (lockfile lives inside).
|
|
2142
|
-
* @param fn - The protected read-modify-write.
|
|
2143
|
-
* @returns `fn`'s result, or {@link LOCK_FAILED} when the lock stayed busy.
|
|
2144
|
-
*/
|
|
2145
|
-
function withTrackLockSync(dir, fn) {
|
|
2146
|
-
mkdirSync(dir, { recursive: true });
|
|
2147
|
-
const lock = join(dir, "track.lock");
|
|
2148
|
-
const deadline = Date.now() + 400;
|
|
2149
|
-
for (;;) try {
|
|
2150
|
-
closeSync(openSync(lock, "wx"));
|
|
2151
|
-
break;
|
|
2152
|
-
} catch {
|
|
2153
|
-
if (isStale(lock)) {
|
|
2154
|
-
try {
|
|
2155
|
-
unlinkSync(lock);
|
|
2156
|
-
} catch {}
|
|
2157
|
-
continue;
|
|
2158
|
-
}
|
|
2159
|
-
if (Date.now() >= deadline) {
|
|
2160
|
-
process.stderr.write(`harness: track lock busy, write skipped (${lock})\n`);
|
|
2161
|
-
return LOCK_FAILED;
|
|
2162
|
-
}
|
|
2163
|
-
sleepSync(8);
|
|
2164
|
-
}
|
|
2165
|
-
try {
|
|
2166
|
-
return fn();
|
|
2167
|
-
} finally {
|
|
2168
|
-
try {
|
|
2169
|
-
unlinkSync(lock);
|
|
2170
|
-
} catch {}
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
//#endregion
|
|
2174
2116
|
//#region src/freshness/evidence-harvest-io.ts
|
|
2175
2117
|
/**
|
|
2176
2118
|
* SubagentStop wiring for {@link harvestAgentEvidence}. The core SubagentStop
|
|
@@ -2204,6 +2146,14 @@ function harvestSubagentTrack(payload, cwd, now, baseDir = defaultStateDir(cwd))
|
|
|
2204
2146
|
const transcriptPath = typeof payload.agent_transcript_path === "string" ? payload.agent_transcript_path : void 0;
|
|
2205
2147
|
if (!transcriptPath) return;
|
|
2206
2148
|
const file = trackFile(typeof payload.session_id === "string" ? payload.session_id : "unknown", baseDir);
|
|
2149
|
+
if (trackJournalEnabled()) {
|
|
2150
|
+
const track = readTrackSync(file, true);
|
|
2151
|
+
const next = harvestAgentEvidence(transcriptPath, track, now);
|
|
2152
|
+
if (next === track) return;
|
|
2153
|
+
const log = journalLogPath(file);
|
|
2154
|
+
for (const ev of diffTrackEvents(track, next, now)) appendEvent(log, ev.field, ev.op, ev.value, ev.ts);
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2207
2157
|
if (withTrackLockSync(dirname(file), () => {
|
|
2208
2158
|
const track = loadTrackSync(file);
|
|
2209
2159
|
const next = harvestAgentEvidence(transcriptPath, track, now);
|
|
@@ -7752,15 +7702,9 @@ function uiDesignSkillGate(tool, filePath, content, ev) {
|
|
|
7752
7702
|
//#endregion
|
|
7753
7703
|
//#region src/policy/design/skill-evidence.ts
|
|
7754
7704
|
/**
|
|
7755
|
-
*
|
|
7756
|
-
*
|
|
7757
|
-
*
|
|
7758
|
-
* {@link uiDesignSkillGate}. Kept separate from the pure gate logic (SRP).
|
|
7759
|
-
* @packageDocumentation
|
|
7760
|
-
*/
|
|
7761
|
-
/**
|
|
7762
|
-
* Read the verified session track and derive {@link DesignEvidence}. Fail-closed
|
|
7763
|
-
* on a missing/corrupt/tampered track (no evidence → the gate blocks).
|
|
7705
|
+
* Read the verified session track (snapshot ⊕ journal) and derive
|
|
7706
|
+
* {@link DesignEvidence}. Fail-closed on a missing/corrupt/tampered track (no
|
|
7707
|
+
* evidence → the gate blocks).
|
|
7764
7708
|
* @param sessionId - the Claude session id.
|
|
7765
7709
|
* @param cwd - the project root (selects the per-project state dir).
|
|
7766
7710
|
* @param baseDir - override the track base dir (tests); defaults to the project state dir.
|
|
@@ -7768,7 +7712,7 @@ function uiDesignSkillGate(tool, filePath, content, ev) {
|
|
|
7768
7712
|
function collectDesignEvidence(sessionId, cwd, baseDir = defaultStateDir(cwd)) {
|
|
7769
7713
|
let track = null;
|
|
7770
7714
|
try {
|
|
7771
|
-
track =
|
|
7715
|
+
track = readTrackSync(trackFile(sessionId, baseDir), trackJournalEnabled());
|
|
7772
7716
|
} catch {
|
|
7773
7717
|
track = null;
|
|
7774
7718
|
}
|
package/dist/runtime/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as projectLayout } from "../layout-KWoE_Mqn.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-oUGFB4ds.mjs";
|
|
3
|
-
import { A as trackMcpResearch, At as defaultStateDir, B as generateProjectMap, C as seoPostToolUse, Ct as trimLogFile, D as securityAdvisoryForPatch, Dt as claudeMdKey, E as securityAdvisory, Et as projectContext, F as dispatchAipilot, Ft as loadSecurityState, G as countFiles, H as writeTree, I as dispatchLessons, It as saveSecurityState, J as lessonsArchiveFileFor, K as getFileDesc, L as cartoSessionStart, Lt as securityStateDir, M as trackEnrichment, Mt as trackFile, N as dispatchLifecycle, Nt as normalizeEvent, O as postTrackingSideEffects, Ot as promptSubmitContext, P as aipilotPostToolUse, Pt as isoUtc, R as generateEcosystemMap, Rt as securityStatePath, S as postEditContext, St as removeOldFiles, T as dispatchMemory, Tt as gitContext, U as loadEnriched, V as isProject, W as mergeLines, X as lessonsStateFileFor, Y as lessonsFileFor, _ as preCommitGate, _t as readRules, a as recordActivity, at as saveApexState, b as extractSymbols, bt as pruneEmptyDirs, c as MCP_TTL_MS, ct as trackAgentMemory, d as isMcpTool, dt as validateSolidGate, f as queryOf, ft as checkFileSize, g as gate, gt as injectRules, h as TRIVIAL_BUDGET, ht as solidDetectStart, i as respond, it as cleanupSession, j as trackSkillRead, jt as projectHash, k as trackWatchResearch, kt as taskContext, l as WEBFETCH_TTL_MS, lt as subagentCacheContext, m as REQUIRED_AGENTS, mt as detectSolidProfile, n as activityFor, nt as trackSessionChanges, o as mcpPostStore, ot as logToolFailure, p as DEFAULT_WINDOW_MS, pt as countLoc, q as listChildren, r as handlePre, rt as validateRulesLoaded, s as mcpPreIntercept, st as validateTeammateOutput, t as handleHook, tt as postEditTypescript, u as cacheQueryOf, ut as validateTailwind, v as detectDuplication, vt as runSessionStartCleanups, w as seoPostToolUseResponse, wt as devContext, x as lifecycleStdout, xt as purgeTtlTree, y as dryGate, yt as sessionStartCore, z as writePluginMap, zt as todayUtc } from "../handle-
|
|
3
|
+
import { A as trackMcpResearch, At as defaultStateDir, B as generateProjectMap, C as seoPostToolUse, Ct as trimLogFile, D as securityAdvisoryForPatch, Dt as claudeMdKey, E as securityAdvisory, Et as projectContext, F as dispatchAipilot, Ft as loadSecurityState, G as countFiles, H as writeTree, I as dispatchLessons, It as saveSecurityState, J as lessonsArchiveFileFor, K as getFileDesc, L as cartoSessionStart, Lt as securityStateDir, M as trackEnrichment, Mt as trackFile, N as dispatchLifecycle, Nt as normalizeEvent, O as postTrackingSideEffects, Ot as promptSubmitContext, P as aipilotPostToolUse, Pt as isoUtc, R as generateEcosystemMap, Rt as securityStatePath, S as postEditContext, St as removeOldFiles, T as dispatchMemory, Tt as gitContext, U as loadEnriched, V as isProject, W as mergeLines, X as lessonsStateFileFor, Y as lessonsFileFor, _ as preCommitGate, _t as readRules, a as recordActivity, at as saveApexState, b as extractSymbols, bt as pruneEmptyDirs, c as MCP_TTL_MS, ct as trackAgentMemory, d as isMcpTool, dt as validateSolidGate, f as queryOf, ft as checkFileSize, g as gate, gt as injectRules, h as TRIVIAL_BUDGET, ht as solidDetectStart, i as respond, it as cleanupSession, j as trackSkillRead, jt as projectHash, k as trackWatchResearch, kt as taskContext, l as WEBFETCH_TTL_MS, lt as subagentCacheContext, m as REQUIRED_AGENTS, mt as detectSolidProfile, n as activityFor, nt as trackSessionChanges, o as mcpPostStore, ot as logToolFailure, p as DEFAULT_WINDOW_MS, pt as countLoc, q as listChildren, r as handlePre, rt as validateRulesLoaded, s as mcpPreIntercept, st as validateTeammateOutput, t as handleHook, tt as postEditTypescript, u as cacheQueryOf, ut as validateTailwind, v as detectDuplication, vt as runSessionStartCleanups, w as seoPostToolUseResponse, wt as devContext, x as lifecycleStdout, xt as purgeTtlTree, y as dryGate, yt as sessionStartCore, z as writePluginMap, zt as todayUtc } from "../handle-F35Gx-QS.mjs";
|
|
4
4
|
//#region src/runtime/storage.ts
|
|
5
5
|
/**
|
|
6
6
|
* The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
|