@fusengine/harness 0.1.3 → 0.1.4
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/{index-BXBWKbL8.d.mts → index-BbJucvaG.d.mts} +6 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/policy/index.d.mts +2 -2
- package/dist/policy/index.mjs +2 -2
- package/dist/{policy-DMpyaPZ_.mjs → policy-C4zmyZR-.mjs} +14 -3
- package/dist/tracking/index.d.mts +30 -0
- package/dist/tracking/index.mjs +63 -0
- package/package.json +3 -2
|
@@ -96,6 +96,8 @@ interface ApexContext {
|
|
|
96
96
|
refs?: RefMeta[];
|
|
97
97
|
/** Absolute paths of SOLID refs already read this session. */
|
|
98
98
|
refsRead?: string[];
|
|
99
|
+
/** Whether the required prior agents (explore + research) ran within the freshness window. */
|
|
100
|
+
agentsFresh?: boolean;
|
|
99
101
|
}
|
|
100
102
|
/** A single APEX gate: returns a blocking {@link Prompt}, or null to pass. */
|
|
101
103
|
type ApexGate = (ctx: ApexContext) => Prompt | null;
|
|
@@ -103,7 +105,9 @@ type ApexGate = (ctx: ApexContext) => Prompt | null;
|
|
|
103
105
|
declare const docConsultedGate: ApexGate;
|
|
104
106
|
/** Gate: the routed SOLID references for this edit must have been read. */
|
|
105
107
|
declare const solidReadGate: ApexGate;
|
|
106
|
-
/**
|
|
108
|
+
/** Gate: the required prior agents (explore + research) must have run within the window. */
|
|
109
|
+
declare const freshnessGate: ApexGate;
|
|
110
|
+
/** Default APEX gate chain (freshness, then docs, then SOLID refs). */
|
|
107
111
|
declare const APEX_GATES: ReadonlyArray<ApexGate>;
|
|
108
112
|
/**
|
|
109
113
|
* Run the APEX gates (chain-of-responsibility): the first failing gate's prompt
|
|
@@ -111,4 +115,4 @@ declare const APEX_GATES: ReadonlyArray<ApexGate>;
|
|
|
111
115
|
*/
|
|
112
116
|
declare function evaluateApex(ctx: ApexContext, gates?: ReadonlyArray<ApexGate>): Prompt | null;
|
|
113
117
|
//#endregion
|
|
114
|
-
export { isApexCommand as S,
|
|
118
|
+
export { isApexCommand as C, detectProjectType as S, countLines as _, evaluateApex as a, DEV_KEYWORDS as b, PolicyContext as c, GIT_ASK as d, GIT_BLOCKED as f, FileSizeVerdict as g, matchPatterns as h, docConsultedGate as i, PolicyResult as l, SYSTEM_INSTALL as m, ApexContext as n, freshnessGate as o, PROJECT_INSTALL as p, ApexGate as r, solidReadGate as s, APEX_GATES as t, evaluate as u, evaluateFileSize as v, ProjectType as x, detectFramework as y };
|
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 {
|
|
8
|
+
import { C as isApexCommand, S as detectProjectType, _ as countLines, a as evaluateApex, b as DEV_KEYWORDS, c as PolicyContext, d as GIT_ASK, f as GIT_BLOCKED, g as FileSizeVerdict, h as matchPatterns, i as docConsultedGate, l as PolicyResult, m as SYSTEM_INSTALL, n as ApexContext, o as freshnessGate, p as PROJECT_INSTALL, r as ApexGate, s as solidReadGate, t as APEX_GATES, u as evaluate, v as evaluateFileSize, x as ProjectType, y as detectFramework } from "./index-BbJucvaG.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 setStateField, i as registryFile, l as stateFileFor, n as addRoot, o as nowStamp, r as readRoots, s as readState, t as ensureMemoryGitignore, u as throttleMs } from "./index-BEM-mQMC.mjs";
|
|
11
11
|
import { i as parseFrontmatter, n as scoreReferences, r as globToRe, t as routeReferences } from "./index-C2Lz-cwJ.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, ApexContext, ApexGate, ApexState, ApexTask, ApexTaskFile, AuthEntry, COLOR_THRESHOLDS, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DocSatisfactionStatus, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GRADIENT_BLOCKS, HarnessId, HarnessInfo, HarnessMode, HarnessVia, IndexSummary, MAX_LINES_ENV_KEY, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, Palette, PolicyContext, PolicyResult, ProgressBarOptions, ProjectType, Prompt, PromptKind, RefMeta, ReminderState, RouteResult, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, colors, compactJson, compactMarkdown, countLines, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, loadIndex, loadState, matchPatterns, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectRoot, projectRootOrNull, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, saveState, scoreReferences, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, ttlLabel };
|
|
14
|
+
export { APEX_GATES, ApexContext, ApexGate, ApexState, ApexTask, ApexTaskFile, AuthEntry, COLOR_THRESHOLDS, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DocSatisfactionStatus, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GRADIENT_BLOCKS, HarnessId, HarnessInfo, HarnessMode, HarnessVia, IndexSummary, MAX_LINES_ENV_KEY, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, Palette, PolicyContext, PolicyResult, ProgressBarOptions, ProjectType, Prompt, PromptKind, RefMeta, ReminderState, RouteResult, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, colors, compactJson, compactMarkdown, countLines, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, loadIndex, loadState, matchPatterns, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectRoot, projectRootOrNull, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, saveState, scoreReferences, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, ttlLabel };
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { i as ttlLabel, n as TTL_ENV_KEY, r as resolveTtlSec, t as DEFAULT_TTL_S
|
|
|
3
3
|
import { t as compactJson } from "./compact-json-DK2nX-MK.mjs";
|
|
4
4
|
import { n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./project-root-C4ks_q1G.mjs";
|
|
5
5
|
import { n as detectMode, r as modeFor, t as detectHarness } from "./harness-C8Nxxyn_.mjs";
|
|
6
|
-
import { a as
|
|
6
|
+
import { a as solidReadGate, c as isApexCommand, i as freshnessGate, n as docConsultedGate, o as DEV_KEYWORDS, r as evaluateApex, s as detectProjectType, t as APEX_GATES } from "./policy-C4zmyZR-.mjs";
|
|
7
7
|
import { a as SYSTEM_INSTALL, c as evaluateFileSize, i as PROJECT_INSTALL, l as detectFramework, n as GIT_ASK, o as matchPatterns, r as GIT_BLOCKED, s as countLines, t as evaluate } from "./evaluate-CsYyUucy.mjs";
|
|
8
8
|
import { i as resolveSessions, n as formatDocSatisfactionStatus, r as isDocConsulted, t as formatDocDeny } from "./doc-helpers-Dd_x1-tZ.mjs";
|
|
9
9
|
import { i as parseFrontmatter, n as scoreReferences, r as globToRe, t as routeReferences } from "./router-Dj3AfgBE.mjs";
|
|
@@ -13,4 +13,4 @@ import { a as jaccardSimilar, i as compactMarkdown, n as loadIndex, o as queryHa
|
|
|
13
13
|
import { t as incrementTrivialEditCounter } from "./freshness-BK9Xg6oG.mjs";
|
|
14
14
|
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-Bc4wdnCG.mjs";
|
|
15
15
|
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";
|
|
16
|
-
export { APEX_GATES, COLOR_THRESHOLDS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, GRADIENT_BLOCKS, MAX_LINES_ENV_KEY, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, SYSTEM_INSTALL, TIME_INTERVALS, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, colors, compactJson, compactMarkdown, countLines, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, loadIndex, loadState, matchPatterns, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectRoot, projectRootOrNull, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, saveState, scoreReferences, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, ttlLabel };
|
|
16
|
+
export { APEX_GATES, COLOR_THRESHOLDS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, GRADIENT_BLOCKS, MAX_LINES_ENV_KEY, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INSTALL, SYSTEM_INSTALL, TIME_INTERVALS, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, colors, compactJson, compactMarkdown, countLines, detectFramework, detectHarness, detectMode, detectProjectType, docConsultedGate, ensureMemoryGitignore, ensureStateDir, evaluate, evaluateApex, evaluateFileSize, extractText, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, isApexCommand, isCodeFile, isDocConsulted, jaccardSimilar, loadIndex, loadState, matchPatterns, modeFor, nowStamp, parseEnvInt, parseFrontmatter, progressiveColor, projectRoot, projectRootOrNull, queryHash, readRoots, readState, registryFile, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, saveState, scoreReferences, setStateField, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, ttlLabel };
|
package/dist/policy/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { APEX_GATES, ApexContext, ApexGate, DEV_KEYWORDS, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, PROJECT_INSTALL, PolicyContext, PolicyResult, ProjectType, SYSTEM_INSTALL, countLines, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, isApexCommand, matchPatterns, solidReadGate };
|
|
1
|
+
import { C as isApexCommand, S as detectProjectType, _ as countLines, a as evaluateApex, b as DEV_KEYWORDS, c as PolicyContext, d as GIT_ASK, f as GIT_BLOCKED, g as FileSizeVerdict, h as matchPatterns, i as docConsultedGate, l as PolicyResult, m as SYSTEM_INSTALL, n as ApexContext, o as freshnessGate, p as PROJECT_INSTALL, r as ApexGate, s as solidReadGate, t as APEX_GATES, u as evaluate, v as evaluateFileSize, x as ProjectType, y as detectFramework } from "../index-BbJucvaG.mjs";
|
|
2
|
+
export { APEX_GATES, ApexContext, ApexGate, DEV_KEYWORDS, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, PROJECT_INSTALL, PolicyContext, PolicyResult, ProjectType, SYSTEM_INSTALL, countLines, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, isApexCommand, matchPatterns, solidReadGate };
|
package/dist/policy/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as solidReadGate, c as isApexCommand, i as freshnessGate, n as docConsultedGate, o as DEV_KEYWORDS, r as evaluateApex, s as detectProjectType, t as APEX_GATES } from "../policy-C4zmyZR-.mjs";
|
|
2
2
|
import { a as SYSTEM_INSTALL, c as evaluateFileSize, i as PROJECT_INSTALL, l as detectFramework, n as GIT_ASK, o as matchPatterns, r as GIT_BLOCKED, s as countLines, t as evaluate } from "../evaluate-CsYyUucy.mjs";
|
|
3
|
-
export { APEX_GATES, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, PROJECT_INSTALL, SYSTEM_INSTALL, countLines, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, isApexCommand, matchPatterns, solidReadGate };
|
|
3
|
+
export { APEX_GATES, DEV_KEYWORDS, GIT_ASK, GIT_BLOCKED, PROJECT_INSTALL, SYSTEM_INSTALL, countLines, detectFramework, detectProjectType, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, freshnessGate, isApexCommand, matchPatterns, solidReadGate };
|
|
@@ -55,8 +55,19 @@ const solidReadGate = (ctx) => {
|
|
|
55
55
|
actions: missing
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
|
-
/**
|
|
59
|
-
const
|
|
58
|
+
/** Gate: the required prior agents (explore + research) must have run within the window. */
|
|
59
|
+
const freshnessGate = (ctx) => ctx.agentsFresh === false ? {
|
|
60
|
+
kind: "block",
|
|
61
|
+
title: "APEX: explore + research required",
|
|
62
|
+
reason: `Run explore-codebase and research-expert (within the freshness window) before editing ${ctx.framework}.`,
|
|
63
|
+
actions: ["Launch the explore-codebase agent", "Launch the research-expert agent"]
|
|
64
|
+
} : null;
|
|
65
|
+
/** Default APEX gate chain (freshness, then docs, then SOLID refs). */
|
|
66
|
+
const APEX_GATES = [
|
|
67
|
+
freshnessGate,
|
|
68
|
+
docConsultedGate,
|
|
69
|
+
solidReadGate
|
|
70
|
+
];
|
|
60
71
|
/**
|
|
61
72
|
* Run the APEX gates (chain-of-responsibility): the first failing gate's prompt
|
|
62
73
|
* wins; null means every gate passed (allow).
|
|
@@ -65,4 +76,4 @@ function evaluateApex(ctx, gates = APEX_GATES) {
|
|
|
65
76
|
return gates.reduce((hit, gate) => hit ?? gate(ctx), null);
|
|
66
77
|
}
|
|
67
78
|
//#endregion
|
|
68
|
-
export {
|
|
79
|
+
export { solidReadGate as a, isApexCommand as c, freshnessGate as i, docConsultedGate as n, DEV_KEYWORDS as o, evaluateApex as r, detectProjectType as s, APEX_GATES as t };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { t as AuthEntry } from "../doc-helpers-CG1nuf-c.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/tracking/session-state.d.ts
|
|
4
|
+
/** Recorded session activity that feeds the APEX gates. */
|
|
5
|
+
interface SessionTrack {
|
|
6
|
+
authorizations: Record<string, AuthEntry>;
|
|
7
|
+
refsRead: string[];
|
|
8
|
+
agents: {
|
|
9
|
+
name: string;
|
|
10
|
+
ts: number;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
/** A fresh, empty track. */
|
|
14
|
+
declare function emptyTrack(): SessionTrack;
|
|
15
|
+
/** Record a doc consultation (Context7/Exa) for a framework in this session. Immutable. */
|
|
16
|
+
declare function recordDoc(track: SessionTrack, framework: string, sessionId: string, source: string): SessionTrack;
|
|
17
|
+
/** Record that a SOLID reference file was read (deduped). Immutable. */
|
|
18
|
+
declare function recordRefRead(track: SessionTrack, path: string): SessionTrack;
|
|
19
|
+
/** Record an agent/tool call with a timestamp. Immutable. */
|
|
20
|
+
declare function recordAgent(track: SessionTrack, name: string, ts: number): SessionTrack;
|
|
21
|
+
/** True when ALL of `names` were called within `windowMs` before `now`. */
|
|
22
|
+
declare function agentsFresh(track: SessionTrack, names: string[], windowMs: number, now: number): boolean;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/tracking/store.d.ts
|
|
25
|
+
/** Load a session track from a file (an empty track if absent/corrupt). */
|
|
26
|
+
declare function loadTrack(file: string): Promise<SessionTrack>;
|
|
27
|
+
/** Persist a session track. */
|
|
28
|
+
declare function saveTrack(file: string, track: SessionTrack): Promise<void>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { SessionTrack, agentsFresh, emptyTrack, loadTrack, recordAgent, recordDoc, recordRefRead, saveTrack };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { n as readJsonFile, r as writeJsonFile } from "../json-io-RH82El2J.mjs";
|
|
2
|
+
//#region src/tracking/session-state.ts
|
|
3
|
+
/** A fresh, empty track. */
|
|
4
|
+
function emptyTrack() {
|
|
5
|
+
return {
|
|
6
|
+
authorizations: {},
|
|
7
|
+
refsRead: [],
|
|
8
|
+
agents: []
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Record a doc consultation (Context7/Exa) for a framework in this session. Immutable. */
|
|
12
|
+
function recordDoc(track, framework, sessionId, source) {
|
|
13
|
+
const prev = track.authorizations[framework] ?? {};
|
|
14
|
+
const sessions = new Set(prev.doc_sessions ?? []);
|
|
15
|
+
sessions.add(sessionId);
|
|
16
|
+
const sources = new Set(prev.sources ?? (prev.source ? [prev.source] : []));
|
|
17
|
+
sources.add(source);
|
|
18
|
+
return {
|
|
19
|
+
...track,
|
|
20
|
+
authorizations: {
|
|
21
|
+
...track.authorizations,
|
|
22
|
+
[framework]: {
|
|
23
|
+
...prev,
|
|
24
|
+
doc_sessions: [...sessions],
|
|
25
|
+
sources: [...sources]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Record that a SOLID reference file was read (deduped). Immutable. */
|
|
31
|
+
function recordRefRead(track, path) {
|
|
32
|
+
return track.refsRead.includes(path) ? track : {
|
|
33
|
+
...track,
|
|
34
|
+
refsRead: [...track.refsRead, path]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Record an agent/tool call with a timestamp. Immutable. */
|
|
38
|
+
function recordAgent(track, name, ts) {
|
|
39
|
+
return {
|
|
40
|
+
...track,
|
|
41
|
+
agents: [...track.agents, {
|
|
42
|
+
name,
|
|
43
|
+
ts
|
|
44
|
+
}]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** True when ALL of `names` were called within `windowMs` before `now`. */
|
|
48
|
+
function agentsFresh(track, names, windowMs, now) {
|
|
49
|
+
const cutoff = now - windowMs;
|
|
50
|
+
return names.every((n) => track.agents.some((a) => a.name === n && a.ts > cutoff));
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/tracking/store.ts
|
|
54
|
+
/** Load a session track from a file (an empty track if absent/corrupt). */
|
|
55
|
+
async function loadTrack(file) {
|
|
56
|
+
return await readJsonFile(file) ?? emptyTrack();
|
|
57
|
+
}
|
|
58
|
+
/** Persist a session track. */
|
|
59
|
+
async function saveTrack(file, track) {
|
|
60
|
+
await writeJsonFile(file, track);
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { agentsFresh, emptyTrack, loadTrack, recordAgent, recordDoc, recordRefRead, saveTrack };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusengine/harness",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
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",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"./statusline": { "bun": "./src/statusline/index.ts", "types": "./dist/statusline/index.d.mts", "import": "./dist/statusline/index.mjs" },
|
|
24
24
|
"./cli": { "bun": "./src/cli/index.ts", "types": "./dist/cli/index.d.mts", "import": "./dist/cli/index.mjs" },
|
|
25
25
|
"./init": { "bun": "./src/init/index.ts", "types": "./dist/init/index.d.mts", "import": "./dist/init/index.mjs" },
|
|
26
|
+
"./tracking": { "bun": "./src/tracking/index.ts", "types": "./dist/tracking/index.d.mts", "import": "./dist/tracking/index.mjs" },
|
|
26
27
|
"./adapters/claude": { "bun": "./src/adapters/claude/index.ts", "types": "./dist/adapters/claude/index.d.mts", "import": "./dist/adapters/claude/index.mjs" },
|
|
27
28
|
"./adapters/codex": { "bun": "./src/adapters/codex/index.ts", "types": "./dist/adapters/codex/index.d.mts", "import": "./dist/adapters/codex/index.mjs" },
|
|
28
29
|
"./adapters/cursor": { "bun": "./src/adapters/cursor/index.ts", "types": "./dist/adapters/cursor/index.d.mts", "import": "./dist/adapters/cursor/index.mjs" },
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"scripts": {
|
|
36
37
|
"test": "bun test",
|
|
37
38
|
"typecheck": "tsc --noEmit",
|
|
38
|
-
"build": "tsdown src/index.ts src/config/index.ts src/util/index.ts src/detect/index.ts src/policy/index.ts src/prompt/index.ts src/memory/index.ts src/cache/index.ts src/freshness/index.ts src/refs/index.ts src/state/index.ts src/statusline/index.ts src/cli/index.ts src/cli/bin.ts src/init/index.ts src/adapters/claude/index.ts src/adapters/codex/index.ts src/adapters/cursor/index.ts src/adapters/cline/index.ts src/adapters/gemini/index.ts --dts --format esm --clean --out-dir dist",
|
|
39
|
+
"build": "tsdown src/index.ts src/config/index.ts src/util/index.ts src/detect/index.ts src/policy/index.ts src/prompt/index.ts src/memory/index.ts src/cache/index.ts src/freshness/index.ts src/refs/index.ts src/state/index.ts src/statusline/index.ts src/cli/index.ts src/cli/bin.ts src/init/index.ts src/tracking/index.ts src/adapters/claude/index.ts src/adapters/codex/index.ts src/adapters/cursor/index.ts src/adapters/cline/index.ts src/adapters/gemini/index.ts --dts --format esm --clean --out-dir dist",
|
|
39
40
|
"prepublishOnly": "bun test && tsc --noEmit && bun run build"
|
|
40
41
|
},
|
|
41
42
|
"publishConfig": {
|