@fusengine/harness 0.1.84 → 0.1.86
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/adapters/claude/index.mjs +1 -1
- package/dist/adapters/cline/index.mjs +1 -1
- package/dist/adapters/codex/index.mjs +2 -2
- package/dist/adapters/cursor/index.mjs +1 -1
- package/dist/adapters/gemini/index.mjs +1 -1
- package/dist/adapters/hermes/index.mjs +1 -1
- package/dist/adapters/kimi/index.mjs +1 -1
- package/dist/{claude-D93HY8dq.mjs → claude-CEWX-8m9.mjs} +1 -1
- package/dist/cli/bin.mjs +2 -2
- package/dist/cli/index.mjs +1 -1
- package/dist/{evaluate-B4-MhOy_.mjs → evaluate-9bUzRquQ.mjs} +12 -1
- package/dist/{handle-DsP67KZ4.mjs → handle-Dzf4JbrL.mjs} +158 -33
- package/dist/{hermes-1PUEoY8q.mjs → hermes-H6qePmBC.mjs} +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{kimi-ChbcU2uI.mjs → kimi-CqLkpg1A.mjs} +2 -2
- package/dist/policy/index.mjs +2 -2
- package/dist/{run-D_WchZ3R.mjs → run-B4kqWMA3.mjs} +1 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/{validate-Bf-EsbDh.mjs → validate-C-TB06Mw.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as fileSizeGuard, c as readClaudeInput, i as denyResponse, l as systemMessage, n as blockResponse, o as guard, r as contextResponse, s as informResponse, t as attachSystemMessage, u as toClaudeResponse } from "../../claude-
|
|
1
|
+
import { a as fileSizeGuard, c as readClaudeInput, i as denyResponse, l as systemMessage, n as blockResponse, o as guard, r as contextResponse, s as informResponse, t as attachSystemMessage, u as toClaudeResponse } from "../../claude-CEWX-8m9.mjs";
|
|
2
2
|
export { attachSystemMessage, blockResponse, contextResponse, denyResponse, fileSizeGuard, guard, informResponse, readClaudeInput, systemMessage, toClaudeResponse };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as evaluate } from "../../evaluate-
|
|
1
|
+
import { t as evaluate } from "../../evaluate-9bUzRquQ.mjs";
|
|
2
2
|
import { f as countLines } from "../../home-state-oUGFB4ds.mjs";
|
|
3
3
|
import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
|
|
4
4
|
import { n as parseApplyPatch, t as isBypassPermissions } from "../../permission-mode-BN3MNgbm.mjs";
|
|
5
|
-
import { _ as commandToString, c as readClaudeInput, i as denyResponse, r as contextResponse, s as informResponse } from "../../claude-
|
|
5
|
+
import { _ as commandToString, c as readClaudeInput, i as denyResponse, r as contextResponse, s as informResponse } from "../../claude-CEWX-8m9.mjs";
|
|
6
6
|
//#region src/adapters/codex/index.ts
|
|
7
7
|
/**
|
|
8
8
|
* OpenAI Codex CLI adapter (hook-mode). Codex's `PreToolUse` hook (since 2026)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as readHermesInput, r as toHermesResponse, t as guard } from "../../hermes-
|
|
1
|
+
import { n as readHermesInput, r as toHermesResponse, t as guard } from "../../hermes-H6qePmBC.mjs";
|
|
2
2
|
export { guard, readHermesInput, toHermesResponse };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as toKimiResponse, n as kimiDenyResponse, r as readKimiInput, t as guard } from "../../kimi-
|
|
1
|
+
import { i as toKimiResponse, n as kimiDenyResponse, r as readKimiInput, t as guard } from "../../kimi-CqLkpg1A.mjs";
|
|
2
2
|
export { guard, kimiDenyResponse, readKimiInput, toKimiResponse };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as evaluate } from "./evaluate-
|
|
1
|
+
import { t as evaluate } from "./evaluate-9bUzRquQ.mjs";
|
|
2
2
|
import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
package/dist/cli/bin.mjs
CHANGED
|
@@ -3,9 +3,9 @@ import { o as resolveStdinMaxBytes } from "../limits-DG5pl-5s.mjs";
|
|
|
3
3
|
import { r as loadDotenv, s as resolveTtlSec } from "../dotenv-DoqNlALG.mjs";
|
|
4
4
|
import { t as detectHarness } from "../harness-BMuLJ9lm.mjs";
|
|
5
5
|
import { t as claudeHome } from "../home-state-oUGFB4ds.mjs";
|
|
6
|
-
import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-
|
|
6
|
+
import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-B4kqWMA3.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-Dzf4JbrL.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";
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-
|
|
1
|
+
import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-B4kqWMA3.mjs";
|
|
2
2
|
export { checkStaged, stagedContent, stagedFiles };
|
|
@@ -261,6 +261,17 @@ const NEXT_CONTENT = /use client|use server|NextRequest|NextResponse|from ['"]ne
|
|
|
261
261
|
const NEXT_ROUTE = /(page|layout|loading|error|route|middleware)\.(ts|tsx|js|jsx)$/;
|
|
262
262
|
/** TanStack Start markers (file routes, server fns, start/router imports). */
|
|
263
263
|
const TANSTACK_CONTENT = /createFileRoute|createServerFn|from ['"]@tanstack\/react-(start|router)/;
|
|
264
|
+
/**
|
|
265
|
+
* C7: Tailwind CSS-file signals, verified against official docs (v3 + v4) —
|
|
266
|
+
* `@tailwind` (v3 layer directive, removed in v4), `@apply` (both versions),
|
|
267
|
+
* `@config` (v3 native / v4 compat, JS config path), `@source` (v4 content
|
|
268
|
+
* globbing), `@theme` (v4 design-token block), `theme(` (the function, both
|
|
269
|
+
* versions' syntax). Deliberately NOT a bare utility-class-in-selector scan
|
|
270
|
+
* (e.g. `.flex{}`) — an ordinary hand-written class named `.flex` is exactly
|
|
271
|
+
* the false-positive shape this fix removes; only genuine Tailwind-specific
|
|
272
|
+
* at-rules/functions count.
|
|
273
|
+
*/
|
|
274
|
+
const TAILWIND_CSS_CONTENT = /@tailwind\b|@apply\b|@config\b|@source\b|@theme\b|\btheme\(/;
|
|
264
275
|
/** Derive the raw signal an extension + content carry (no filesystem access). */
|
|
265
276
|
function fileSignal(filePath, content) {
|
|
266
277
|
if (/\.swift$/.test(filePath)) return { definitive: "swift" };
|
|
@@ -269,7 +280,7 @@ function fileSignal(filePath, content) {
|
|
|
269
280
|
if (/\.go$/.test(filePath)) return { definitive: "go" };
|
|
270
281
|
if (/\.rb$/.test(filePath)) return { definitive: "ruby" };
|
|
271
282
|
if (/\.rs$/.test(filePath)) return { definitive: "rust" };
|
|
272
|
-
if (/\.css$/.test(filePath)
|
|
283
|
+
if (/\.css$/.test(filePath) && TAILWIND_CSS_CONTENT.test(content)) return { definitive: "tailwind" };
|
|
273
284
|
const masked = maskCommentsAndStrings(content, "c");
|
|
274
285
|
const isTs = TANSTACK_CONTENT.test(masked);
|
|
275
286
|
const isNext = !isTs && (NEXT_ROUTE.test(filePath) || NEXT_CONTENT.test(masked));
|
|
@@ -3,11 +3,11 @@ import { s as resolveTtlSec } from "./dotenv-DoqNlALG.mjs";
|
|
|
3
3
|
import { r as projectLayout } from "./layout-KWoE_Mqn.mjs";
|
|
4
4
|
import { i as walkUpFor, n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./project-root-3kk7gCOp.mjs";
|
|
5
5
|
import { t as detectHarness } from "./harness-BMuLJ9lm.mjs";
|
|
6
|
-
import { D as isVendorPath, G as isFileSizeScoped, K as resolveSolidRefFramework, W as computeEditResultLines, b as interfaceDeclLevel, et as detectFramework, g as conventionsMode, lt as requiredArchSkill, n as FAIL_CLOSED, ot as detectModularArchitecture, rt as maskCommentsAndStrings, st as detectProjectType$1, t as evaluate } from "./evaluate-
|
|
6
|
+
import { D as isVendorPath, G as isFileSizeScoped, K as resolveSolidRefFramework, W as computeEditResultLines, b as interfaceDeclLevel, et as detectFramework, g as conventionsMode, lt as requiredArchSkill, n as FAIL_CLOSED, ot as detectModularArchitecture, rt as maskCommentsAndStrings, st as detectProjectType$1, t as evaluate } from "./evaluate-9bUzRquQ.mjs";
|
|
7
7
|
import { a as sanitizeSessionId, c as sessionsDir, d as countFrameworkCodeLines, f as countLines, i as loadSessionState, l as PLUGINS_DIR, n as fuseHarnessHome, o as saveSessionState, p as evaluateFileSize, r as fusengineCache, t as claudeHome } from "./home-state-oUGFB4ds.mjs";
|
|
8
8
|
import { a as writeJsonFile, i as readJsonFile, r as hashText, t as atomicWrite } from "./json-io-DisYd2fb.mjs";
|
|
9
9
|
import { r as isDocConsulted } from "./doc-helpers-CWZegVdR.mjs";
|
|
10
|
-
import { D as frameworkSolidGate, F as isExcludedSwiftPath, G as evaluateApex, H as PRE_AUTH_GATES, P as isExcludedJsPath, R as capVerbosity, S as parseField, T as usesTailwindUtilities, V as POST_AUTH_GATES, W as docConsultedGate, b as scanPlugin, c as EXCLUDE_DIRS$1, d as buildApexTaskInjection, g as buildClaudeMdContext, l as PROJECT_INDICATORS, n as missingSeoElements, o as parseEnrichment, p as apexAgentSteps, r as descFromText, s as parseEntry, t as isHtmlLike, v as apexDocName, w as skillTriggerGate, y as harnessHomeSegment, z as detectCreationIntent } from "./validate-
|
|
10
|
+
import { D as frameworkSolidGate, F as isExcludedSwiftPath, G as evaluateApex, H as PRE_AUTH_GATES, P as isExcludedJsPath, R as capVerbosity, S as parseField, T as usesTailwindUtilities, V as POST_AUTH_GATES, W as docConsultedGate, b as scanPlugin, c as EXCLUDE_DIRS$1, d as buildApexTaskInjection, g as buildClaudeMdContext, l as PROJECT_INDICATORS, n as missingSeoElements, o as parseEnrichment, p as apexAgentSteps, r as descFromText, s as parseEntry, t as isHtmlLike, v as apexDocName, w as skillTriggerGate, y as harnessHomeSegment, z as detectCreationIntent } from "./validate-C-TB06Mw.mjs";
|
|
11
11
|
import { n as findMarketplacePlugins, r as readPluginMeta, t as resolveSkillPath } from "./skill-path-DhBGlQe3.mjs";
|
|
12
12
|
import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
13
13
|
import { a as nowStamp, l as throttleMs, n as readRoots, o as readState, s as setStateField, t as addRoot } from "./registry-IhHk2KlT.mjs";
|
|
@@ -15,9 +15,9 @@ import { d as loadIndex, i as cacheLookupMeta, n as webfetchCacheWrite, o as cac
|
|
|
15
15
|
import { t as loadRefs } from "./loader-AGz4nK7d.mjs";
|
|
16
16
|
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";
|
|
17
17
|
import { n as parseApplyPatch, t as isBypassPermissions } from "./permission-mode-BN3MNgbm.mjs";
|
|
18
|
-
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-
|
|
19
|
-
import { i as toKimiResponse, n as kimiDenyResponse } from "./kimi-
|
|
20
|
-
import { r as toHermesResponse } from "./hermes-
|
|
18
|
+
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-CEWX-8m9.mjs";
|
|
19
|
+
import { i as toKimiResponse, n as kimiDenyResponse } from "./kimi-CqLkpg1A.mjs";
|
|
20
|
+
import { r as toHermesResponse } from "./hermes-H6qePmBC.mjs";
|
|
21
21
|
import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
22
22
|
import { appendFileSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, rmdirSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
23
23
|
import { homedir } from "node:os";
|
|
@@ -280,17 +280,17 @@ function maxSemver(versions) {
|
|
|
280
280
|
return versions.length === 0 ? null : versions.reduce((a, b) => compareSemver(a, b) >= 0 ? a : b);
|
|
281
281
|
}
|
|
282
282
|
//#endregion
|
|
283
|
-
//#region src/policy/design/corpus-
|
|
283
|
+
//#region src/policy/design/corpus-fs.ts
|
|
284
284
|
/**
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* reference (self-attested proof — the failure this gate exists to prevent).
|
|
285
|
+
* @module corpus-fs
|
|
286
|
+
* Shared fs primitives for corpus/plugins root resolution, split out of
|
|
287
|
+
* `corpus-resolve.ts` so `corpus-resolve-cache.ts` can reuse them without a
|
|
288
|
+
* circular import (both modules feed `corpus-resolve.ts`'s `probeClaude`).
|
|
289
|
+
* @packageDocumentation
|
|
291
290
|
*/
|
|
291
|
+
/** The refs-design/ path suffix common to every design-corpus-bearing plugin tree. */
|
|
292
292
|
const CORPUS_SUFFIX = join("skills", "design-web", "references", "refs-design");
|
|
293
|
-
/** Immediate child dir names of `dir`, or [] when unreadable. */
|
|
293
|
+
/** Immediate child dir names of `dir`, alphabetically sorted, or [] when unreadable. */
|
|
294
294
|
function children$2(dir) {
|
|
295
295
|
try {
|
|
296
296
|
return readdirSync(dir).sort();
|
|
@@ -298,8 +298,60 @@ function children$2(dir) {
|
|
|
298
298
|
return [];
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/policy/design/corpus-resolve-cache.ts
|
|
303
|
+
/**
|
|
304
|
+
* @module corpus-resolve-cache
|
|
305
|
+
* Claude Code's per-plugin VERSIONED CACHE tree, split out of
|
|
306
|
+
* `corpus-resolve.ts` to keep that file within the SOLID size budget (SRP).
|
|
307
|
+
*
|
|
308
|
+
* Claude Code caches every installed marketplace plugin at
|
|
309
|
+
* `~/.claude/plugins/cache/<mkt>/<plugin>/<version>/` — a tree SEPARATE from
|
|
310
|
+
* `~/.claude/plugins/marketplaces/<mkt>/plugins/<plugin>/` (the marketplace's
|
|
311
|
+
* own checkout), one version dir per `plugin.json` version bump, orphaned
|
|
312
|
+
* versions pruned ~14 days after being superseded (docs: "Plugin caching and
|
|
313
|
+
* file resolution"). The design corpus can ship under EITHER tree, and under
|
|
314
|
+
* a DIFFERENT plugin id in each: a machine observed 2026-07-29 has the corpus
|
|
315
|
+
* at `cache/fusengine-plugins/fuse-design/2.2.3/...` while the marketplace
|
|
316
|
+
* checkout is `marketplaces/fusengine-plugins/plugins/design-expert/...`.
|
|
317
|
+
* Identification here is therefore STRUCTURAL, never by plugin name: a
|
|
318
|
+
* candidate `<mkt>/<plugin>/<version>/` dir qualifies iff it itself contains
|
|
319
|
+
* `CORPUS_SUFFIX` — matching a hardcoded name would silently miss a
|
|
320
|
+
* renamed/relocated corpus (the exact defect this module fixes).
|
|
321
|
+
* @packageDocumentation
|
|
322
|
+
*/
|
|
323
|
+
/** Real (non-prerelease) semver dirs, same filter `probeCodex` uses. */
|
|
324
|
+
const SEMVER_RE = /^\d+\.\d+(\.\d+)?$/;
|
|
325
|
+
/**
|
|
326
|
+
* Claude: `<home>/.claude/plugins/cache/<mkt>/<plugin>/<highest STABLE semver
|
|
327
|
+
* containing refs-design>` ("" when no plugin under any marketplace cache
|
|
328
|
+
* ships the corpus). Marketplaces and plugin ids are both walked — neither is
|
|
329
|
+
* assumed — so a corpus shipped under any plugin name is found.
|
|
330
|
+
*/
|
|
331
|
+
function probeClaudeCache(home) {
|
|
332
|
+
const cacheRoot = join(home, ".claude", "plugins", "cache");
|
|
333
|
+
for (const mkt of children$2(cacheRoot)) {
|
|
334
|
+
const mktDir = join(cacheRoot, mkt);
|
|
335
|
+
for (const plugin of children$2(mktDir)) {
|
|
336
|
+
const pluginDir = join(mktDir, plugin);
|
|
337
|
+
const latest = maxSemver(children$2(pluginDir).filter((v) => SEMVER_RE.test(v) && existsSync(join(pluginDir, v, CORPUS_SUFFIX))));
|
|
338
|
+
if (latest) return join(pluginDir, latest);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return "";
|
|
342
|
+
}
|
|
343
|
+
//#endregion
|
|
344
|
+
//#region src/policy/design/corpus-resolve.ts
|
|
345
|
+
/**
|
|
346
|
+
* Corpus/plugins root resolution (fs) and the write guard over it. Resolution
|
|
347
|
+
* is PER RUNTIME (Claude marketplaces, Codex versioned plugin cache — same
|
|
348
|
+
* pattern as rules-root.ts); runtimes without a plugin structure (kimi today)
|
|
349
|
+
* resolve to "" and the corpus gates stay dormant. There is NO cwd fallback
|
|
350
|
+
* anywhere: an agent-controlled directory can never become its own taste
|
|
351
|
+
* reference (self-attested proof — the failure this gate exists to prevent).
|
|
352
|
+
*/
|
|
353
|
+
/** Claude marketplace checkout: `<home>/.claude/plugins/marketplaces/<mkt>/plugins/design-expert` ("" when absent). */
|
|
354
|
+
function probeClaudeMarketplace(home) {
|
|
303
355
|
const markets = join(home, ".claude", "plugins", "marketplaces");
|
|
304
356
|
for (const m of children$2(markets)) {
|
|
305
357
|
const de = join(markets, m, "plugins", "design-expert");
|
|
@@ -307,6 +359,14 @@ function probeClaude$1(home) {
|
|
|
307
359
|
}
|
|
308
360
|
return "";
|
|
309
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Claude: the marketplace checkout WINS when present (a single unambiguous
|
|
364
|
+
* live git checkout); the versioned plugin CACHE tree is the fallback, since
|
|
365
|
+
* Claude Code keeps orphaned prior-version cache dirs ~14 days after a bump.
|
|
366
|
+
*/
|
|
367
|
+
function probeClaude$1(home) {
|
|
368
|
+
return probeClaudeMarketplace(home) || probeClaudeCache(home);
|
|
369
|
+
}
|
|
310
370
|
/** Codex: `<CODEX_HOME|~/.codex>/plugins/cache/<mkt>/design-expert/<highest STABLE semver>` ("" when absent). */
|
|
311
371
|
function probeCodex$1(env, home) {
|
|
312
372
|
const cache = join(env.CODEX_HOME ?? join(home, ".codex"), "plugins", "cache");
|
|
@@ -373,14 +433,22 @@ const CORPUS_LINE_RE = /^[-*]\s*Corpus:\s*(.+)$/gim;
|
|
|
373
433
|
function classifyCorpusRead(filePath, corpusRoot) {
|
|
374
434
|
if (!corpusRoot) return null;
|
|
375
435
|
if (filePath === join(corpusRoot, "README.md")) return "index";
|
|
376
|
-
if (filePath.startsWith(`${corpusRoot}/`)
|
|
436
|
+
if (!filePath.startsWith(`${corpusRoot}/`)) return null;
|
|
437
|
+
if (TOKENS_RE.test(basename(filePath))) return "tokens";
|
|
438
|
+
if (basename(filePath) === "design-system.md") return "sheet";
|
|
377
439
|
return null;
|
|
378
440
|
}
|
|
379
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Per-mode corpus-read threshold (component >= 1 file, page >= 2 files,
|
|
443
|
+
* full = index + 3 tokens — C5: raised from 2, since 2 references still let
|
|
444
|
+
* an agent pattern-match by tonal affinity without ever opening the one
|
|
445
|
+
* reference that actually answered the brief). `"sheet"` reads (C6,
|
|
446
|
+
* `design-system.md`) never count toward this — only `TOKENS_RE` matches do.
|
|
447
|
+
*/
|
|
380
448
|
function corpusReady(reads, mode) {
|
|
381
449
|
if (mode === "component") return reads.length >= 1;
|
|
382
450
|
if (mode === "page") return reads.length >= 2;
|
|
383
|
-
return reads.includes("README.md") && reads.filter((r) => TOKENS_RE.test(basename(r))).length >=
|
|
451
|
+
return reads.includes("README.md") && reads.filter((r) => TOKENS_RE.test(basename(r))).length >= 3;
|
|
384
452
|
}
|
|
385
453
|
/** True when the content carries a `- Corpus: ref/section` citation line (form only). */
|
|
386
454
|
function hasCorpusCitation(content) {
|
|
@@ -7905,6 +7973,57 @@ function collectDesignEvidence(sessionId, cwd, baseDir = defaultStateDir(cwd)) {
|
|
|
7905
7973
|
};
|
|
7906
7974
|
}
|
|
7907
7975
|
//#endregion
|
|
7976
|
+
//#region src/policy/design/screenshot-tools.ts
|
|
7977
|
+
/**
|
|
7978
|
+
* @module screenshot-tools
|
|
7979
|
+
* Screenshot-credit tool set (C1), split out of `runtime/design-helpers.ts` to
|
|
7980
|
+
* keep that file within the SOLID size budget (SRP).
|
|
7981
|
+
* @packageDocumentation
|
|
7982
|
+
*/
|
|
7983
|
+
/**
|
|
7984
|
+
* Screenshot-credit tools: the single-shot capture PLUS the two fuse-browser
|
|
7985
|
+
* batch capture primitives (`browser_shots_batch`, `browser_site_shots`) — a
|
|
7986
|
+
* batch call that captures N urls/viewports must credit the quota too, or
|
|
7987
|
+
* capturing efficiently would make the quota infranchissable. LIMITATION
|
|
7988
|
+
* (deliberate, documented): this repo's cross-harness `NormalizedEvent` (see
|
|
7989
|
+
* `runtime/normalize.ts`) never surfaces `tool_response` for any tool — by
|
|
7990
|
+
* design, since its shape is undocumented for MCP tools and harness-specific
|
|
7991
|
+
* for built-ins — so no per-call item count reaches this gate. A batch call
|
|
7992
|
+
* therefore credits EXACTLY 1, same as a unit screenshot, never the N it may
|
|
7993
|
+
* have captured.
|
|
7994
|
+
*/
|
|
7995
|
+
const SHOT_TOOLS = /* @__PURE__ */ new Set([
|
|
7996
|
+
"mcp__fuse-browser__browser_screenshot",
|
|
7997
|
+
"mcp__fuse-browser__browser_shots_batch",
|
|
7998
|
+
"mcp__fuse-browser__browser_site_shots"
|
|
7999
|
+
]);
|
|
8000
|
+
//#endregion
|
|
8001
|
+
//#region src/policy/design/allowed-write.ts
|
|
8002
|
+
/**
|
|
8003
|
+
* @module allowed-write
|
|
8004
|
+
* The design-agent write allowlist, split out of `gates.ts` to keep that file
|
|
8005
|
+
* within the SOLID size budget (SRP).
|
|
8006
|
+
* @packageDocumentation
|
|
8007
|
+
*/
|
|
8008
|
+
/** Extensions the design agent may always write: .html/.css/.md/.json. */
|
|
8009
|
+
const ALLOWED_WRITE = /\.(html|css|md|json)$/;
|
|
8010
|
+
/**
|
|
8011
|
+
* C4: `motion*.js` ONLY, matched on the BASENAME — every one of the 11
|
|
8012
|
+
* corpus references ships its animation as a separate `motion.js` /
|
|
8013
|
+
* `motion-nav.js` / `motion-scroll.js` file, so banning every `.js` forced
|
|
8014
|
+
* the agent to inline scripts the corpus explicitly teaches out-of-band.
|
|
8015
|
+
* Deliberately NOT `\.js$` in general (that would open arbitrary app code,
|
|
8016
|
+
* the exact thing this gate exists to block) — after the `motion` prefix,
|
|
8017
|
+
* either nothing (`motion.js`) or `.`/`-` then more (`motion-nav.js`) must
|
|
8018
|
+
* lead into `.js`; `app.js` and `motionless-app.js` — a bare `^motion`
|
|
8019
|
+
* prefix would wrongly pass this — do not match.
|
|
8020
|
+
*/
|
|
8021
|
+
const MOTION_JS = /^motion([.-].*)?\.js$/;
|
|
8022
|
+
/** True when `filePath` is a write the design agent may make: .html/.css/.md/.json, or a `motion*.js` file. */
|
|
8023
|
+
function isAllowedWrite(filePath) {
|
|
8024
|
+
return ALLOWED_WRITE.test(filePath) || MOTION_JS.test(basename(filePath));
|
|
8025
|
+
}
|
|
8026
|
+
//#endregion
|
|
7908
8027
|
//#region src/policy/design/design-system-rules.ts
|
|
7909
8028
|
/**
|
|
7910
8029
|
* Content rules for design-system.md — the four hard requirements the
|
|
@@ -7917,14 +8036,22 @@ const OKLCH_RE = /oklch\(\s*[\d.]+%?\s+0\.0*[1-9]/;
|
|
|
7917
8036
|
* system may SAY "Inter" ("## Interaction states", "we never use Inter"), it
|
|
7918
8037
|
* may not USE it as a font. Covered forms: CSS declarations (`font:`,
|
|
7919
8038
|
* `font-family:` in any case, multiline values), JS config (`fontFamily:`),
|
|
7920
|
-
* custom properties (`--*font*`/`--*ff*`/`--*type
|
|
7921
|
-
*
|
|
7922
|
-
*
|
|
7923
|
-
*
|
|
8039
|
+
* custom properties named in English (`--*font*`/`--*ff*`/`--*type*`, value
|
|
8040
|
+
* unquoted or quoted), ANY custom property whose value quotes a forbidden
|
|
8041
|
+
* name (`--police-texte: "Inter", …` — a non-English property name has no
|
|
8042
|
+
* keyword to key off, so the quote itself is the usage signal: a quoted
|
|
8043
|
+
* token in a `--*` value is a font-family entry, not prose), `@import`
|
|
8044
|
+
* URLs, and Markdown table cells (`| Body | Inter |`). Explicitly OUT of
|
|
8045
|
+
* scope (chosen, not overlooked): unquoted prose in bullet lines —
|
|
8046
|
+
* distinguishing "usage" from "mention" there is prose parsing, not a
|
|
8047
|
+
* regex's job. Accepted trade-off of the quote signal: `--comment: "we
|
|
8048
|
+
* never use Inter"` is flagged too — a quoted mention reads identically to
|
|
8049
|
+
* a quoted usage once the property name carries no keyword to disambiguate.
|
|
7924
8050
|
*/
|
|
7925
8051
|
const FONT_DECL_RE = /(?:font(?:-family)?|fontFamily|--[\w-]*(?:font|ff|type)[\w-]*)\s*:[^;\n]*(?:\n\s*)?[^;\n]*\b(?:Inter|Roboto|Arial|Open Sans)\b/i;
|
|
7926
8052
|
const FONT_IMPORT_RE = /family=[^&"')]*\b(?:Inter|Roboto|Arial|Open Sans)\b/i;
|
|
7927
8053
|
const FONT_TABLE_RE = /\|\s*\*{0,2}(?:Inter|Roboto|Arial|Open Sans)\*{0,2}\s*\|/;
|
|
8054
|
+
const FONT_QUOTED_PROP_RE = /--[\w-]+\s*:[^;\n]*["'][^;\n]*(?:\n\s*)?[^;\n]*\b(?:Inter|Roboto|Arial|Open Sans)\b/i;
|
|
7928
8055
|
/**
|
|
7929
8056
|
* Return the requirements missing from a design-system.md (empty = valid).
|
|
7930
8057
|
* The corpus citation satisfies the source requirement ONLY when the corpus
|
|
@@ -7936,12 +8063,11 @@ function validateDesignSystem(content, corpusCitationOk = false) {
|
|
|
7936
8063
|
if (!content.includes("## Design Reference")) missing.push("## Design Reference section");
|
|
7937
8064
|
if (!/https?:\/\//.test(content) && !(corpusCitationOk && hasCorpusCitation(content))) missing.push("reference URL (https://…) or Corpus citation");
|
|
7938
8065
|
if (!OKLCH_RE.test(content)) missing.push("oklch() color with chroma > 0");
|
|
7939
|
-
if (FONT_DECL_RE.test(content) || FONT_IMPORT_RE.test(content) || FONT_TABLE_RE.test(content)) missing.push("forbidden font (Inter/Roboto/Arial/Open Sans)");
|
|
8066
|
+
if (FONT_DECL_RE.test(content) || FONT_IMPORT_RE.test(content) || FONT_TABLE_RE.test(content) || FONT_QUOTED_PROP_RE.test(content)) missing.push("forbidden font (Inter/Roboto/Arial/Open Sans)");
|
|
7940
8067
|
return missing;
|
|
7941
8068
|
}
|
|
7942
8069
|
//#endregion
|
|
7943
8070
|
//#region src/policy/design/gates.ts
|
|
7944
|
-
const ALLOWED_WRITE = /\.(html|css|md|json)$/;
|
|
7945
8071
|
const EXEMPT_DIRS = [
|
|
7946
8072
|
"node_modules/",
|
|
7947
8073
|
"dist/",
|
|
@@ -7949,7 +8075,7 @@ const EXEMPT_DIRS = [
|
|
|
7949
8075
|
".claude/"
|
|
7950
8076
|
];
|
|
7951
8077
|
const NAV$2 = "mcp__fuse-browser__browser_navigate";
|
|
7952
|
-
const SHOT$
|
|
8078
|
+
const SHOT$1 = "mcp__fuse-browser__browser_screenshot";
|
|
7953
8079
|
const GEMINI$2 = "mcp__gemini-design__create_frontend";
|
|
7954
8080
|
const deny = (reason) => ({
|
|
7955
8081
|
kind: "block",
|
|
@@ -7957,10 +8083,10 @@ const deny = (reason) => ({
|
|
|
7957
8083
|
reason,
|
|
7958
8084
|
actions: ["Follow the design pipeline phases (0→identity, 1→inspiration, 2→screenshots, 3→design-system, 4→generate) in order"]
|
|
7959
8085
|
});
|
|
7960
|
-
/** Block the design agent from writing anything but .html/.css/.md/.json. */
|
|
8086
|
+
/** Block the design agent from writing anything but .html/.css/.md/.json (+ motion*.js). */
|
|
7961
8087
|
function htmlCssOnlyGate(filePath) {
|
|
7962
|
-
if (EXEMPT_DIRS.some((d) => filePath.includes(d)) ||
|
|
7963
|
-
return deny("BLOCKED: design-expert can only write .html, .css, .md, and
|
|
8088
|
+
if (EXEMPT_DIRS.some((d) => filePath.includes(d)) || isAllowedWrite(filePath)) return null;
|
|
8089
|
+
return deny("BLOCKED: design-expert can only write .html, .css, .json, .md, and motion*.js files. Framework files (.tsx, .astro, .vue, .swift, .php) must be written by the domain expert (astro-expert, react-expert, etc.) AFTER design validation.");
|
|
7964
8090
|
}
|
|
7965
8091
|
/** Block edits to the harness-managed `.design-state-*` files (read-only to the agent). */
|
|
7966
8092
|
function stateFileGate(filePath) {
|
|
@@ -7997,7 +8123,7 @@ function designPassNotice(i, cacheDir) {
|
|
|
7997
8123
|
if (isWrite && fp && !EXEMPT_DIRS.some((d) => fp.includes(d)) && ALLOWED_WRITE.test(fp)) lines.push(`enforce-html-css-only: allowed: ${basename(fp)}`);
|
|
7998
8124
|
if (i.tool === NAV$2) lines.push(`check-inspiration-read: pass (${i.url})`);
|
|
7999
8125
|
if (i.tool === GEMINI$2 && geminiEnabled()) lines.push("validate-design-system: design-system.md ok");
|
|
8000
|
-
if (isWrite || i.tool === NAV$2 || i.tool === SHOT$
|
|
8126
|
+
if (isWrite || i.tool === NAV$2 || i.tool === SHOT$1 || i.tool === GEMINI$2) lines.push(`pipeline-gate: phase ${state.currentPhase} ok`);
|
|
8001
8127
|
}
|
|
8002
8128
|
if (state && i.phase === "post" && isWrite) {
|
|
8003
8129
|
if (basename(fp) === "design-system.md") lines.push("validate-design: design-system.md → phase 3");
|
|
@@ -8081,9 +8207,9 @@ const SKILLS = `${PLUGINS_DIR}/design-expert/skills`;
|
|
|
8081
8207
|
/** Gate writing design-system.md: requires phase >= 2 and the per-mode screenshot quota. */
|
|
8082
8208
|
function designSystemWriteGate(filePath, state, corpusRequired = false) {
|
|
8083
8209
|
if (!filePath.endsWith("design-system.md")) return null;
|
|
8084
|
-
if (state.currentPhase < 2) return deny(`BLOCKED: Cannot write design-system.md at phase ${state.currentPhase}. RECOVERY: 1) Read identity templates from skills/design-system/ 2) Read design-inspiration.md 3) Read the refs-design corpus (README.md + relevant tokens-*.md) with the Read tool 4) Screenshot real sector sites with mcp__fuse-browser__browser_screenshot on a LIVE session (
|
|
8210
|
+
if (state.currentPhase < 2) return deny(`BLOCKED: Cannot write design-system.md at phase ${state.currentPhase}. RECOVERY: 1) Read identity templates from skills/design-system/ 2) Read design-inspiration.md 3) Read the refs-design corpus (README.md + relevant tokens-*.md) with the Read tool 4) Screenshot real sector sites with mcp__fuse-browser__browser_screenshot on a LIVE session (browser_shots_batch/browser_site_shots also count, 1 credit per call) 5) Then write design-system.md`);
|
|
8085
8211
|
const needed = quotaFor(state.mode, corpusRequired);
|
|
8086
|
-
if (state.screenshotsCount < needed) return deny(`BLOCKED: ${state.screenshotsCount}/${needed} screenshots for mode '${state.mode}'. RECOVERY: 1) Read the refs-design corpus (README.md + tokens-*.md) if not done 2) Take ${needed - state.screenshotsCount} more screenshots of REAL sector sites with mcp__fuse-browser__browser_screenshot (browser_shots_batch/browser_site_shots
|
|
8212
|
+
if (state.screenshotsCount < needed) return deny(`BLOCKED: ${state.screenshotsCount}/${needed} screenshots for mode '${state.mode}'. RECOVERY: 1) Read the refs-design corpus (README.md + tokens-*.md) if not done 2) Take ${needed - state.screenshotsCount} more screenshots of REAL sector sites with mcp__fuse-browser__browser_screenshot (browser_shots_batch/browser_site_shots also count, 1 credit per call) 3) Use browser_open + browser_navigate + browser_screenshot fullPage:true 4) Then write design-system.md`);
|
|
8087
8213
|
return null;
|
|
8088
8214
|
}
|
|
8089
8215
|
/** Gate Gemini create_frontend: requires phase >= 3 and a validated design system. */
|
|
@@ -8230,7 +8356,6 @@ function designSystemContentGate(i) {
|
|
|
8230
8356
|
* @packageDocumentation
|
|
8231
8357
|
*/
|
|
8232
8358
|
const NAV$1 = "mcp__fuse-browser__browser_navigate";
|
|
8233
|
-
const SHOT$1 = "mcp__fuse-browser__browser_screenshot";
|
|
8234
8359
|
const SCROLL = "mcp__fuse-browser__browser_scroll";
|
|
8235
8360
|
const GEMINI$1 = "mcp__gemini-design__create_frontend";
|
|
8236
8361
|
/** Read design-system.md walking up to 6 parents from `cwd` ("" if absent/unreadable). */
|
|
@@ -8251,7 +8376,7 @@ function findDesignSystem(cwd) {
|
|
|
8251
8376
|
}
|
|
8252
8377
|
/** Apply a PostToolUse fuse-browser transition to the design state. */
|
|
8253
8378
|
function recordPost(event, cacheDir, state, corpusRoot = "", corpusRequired = false, cwd = "") {
|
|
8254
|
-
if (event.tool
|
|
8379
|
+
if (SHOT_TOOLS.has(event.tool)) saveDesignState(cacheDir, recordScreenshot(state, corpusRequired));
|
|
8255
8380
|
else if (event.tool === NAV$1) saveDesignState(cacheDir, recordNavigate(state));
|
|
8256
8381
|
else if (event.tool === SCROLL) saveDesignState(cacheDir, recordScroll(state));
|
|
8257
8382
|
else if (event.tool === GEMINI$1) saveDesignState(cacheDir, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as evaluate } from "./evaluate-
|
|
1
|
+
import { t as evaluate } from "./evaluate-9bUzRquQ.mjs";
|
|
2
2
|
import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
3
|
-
import { _ as commandToString, c as readClaudeInput } from "./claude-
|
|
3
|
+
import { _ as commandToString, c as readClaudeInput } from "./claude-CEWX-8m9.mjs";
|
|
4
4
|
//#region src/adapters/hermes/index.ts
|
|
5
5
|
/**
|
|
6
6
|
* Hermes Agent adapter (hook-mode). Nous Research's hermes-agent (2026) pipes a
|
package/dist/index.mjs
CHANGED
|
@@ -4,11 +4,11 @@ import { n as STATE_ROOT, r as projectLayout, t as STATE_GITIGNORE } from "./lay
|
|
|
4
4
|
import { t as compactJson } from "./compact-json-DK2nX-MK.mjs";
|
|
5
5
|
import { i as walkUpFor, n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./project-root-3kk7gCOp.mjs";
|
|
6
6
|
import { n as detectMode, r as modeFor, t as detectHarness } from "./harness-BMuLJ9lm.mjs";
|
|
7
|
-
import { $ as matchPatterns, B as protectedPathGuard, C as isInterfacesPath, D as isVendorPath, E as isTypesPath, F as FILE_REDIRECT, H as CRITICAL_PATTERNS, I as SAFE_PREFIXES, J as GIT_BLOCKED, L as SESSION_STATE_FRAGMENT, M as ASK_WRITERS, N as CODE_MUTATORS, O as langOfPath, P as CODE_REDIRECT, Q as isRalphMode, R as PROTECTED_FRAGMENTS, S as isHooksPath, T as isStoresPath, U as securityGuard, V as ASK_PATTERNS, X as RALPH_SAFE, Y as PROJECT_INSTALL, Z as SYSTEM_INSTALL, a as registerGuard, at as DEV_KEYWORDS, b as interfaceDeclLevel, c as GO_DECL_RE, ct as isApexCommand, d as PY_MODEL_RE, et as detectFramework, f as RUST_DECL_RE, h as interfaceSeparationGuard, i as clearUserGuards, it as maskCommentsOnly, j as bashWriteGuard, k as lexProfileOf, l as JAVA_DECL_RE, lt as requiredArchSkill, m as TS_DECL_RE, n as FAIL_CLOSED, o as runGuards, ot as detectModularArchitecture, p as SWIFT_PROTO_RE, q as GIT_ASK, r as GUARDS, rt as maskCommentsAndStrings, s as installGuard, st as detectProjectType, t as evaluate, u as PHP_DECL_RE, v as declaresExportedTypeAlias, w as isQueryPath, x as isComponentsPath, y as declaresInterface, z as PROTECTED_GIT_RE } from "./evaluate-
|
|
7
|
+
import { $ as matchPatterns, B as protectedPathGuard, C as isInterfacesPath, D as isVendorPath, E as isTypesPath, F as FILE_REDIRECT, H as CRITICAL_PATTERNS, I as SAFE_PREFIXES, J as GIT_BLOCKED, L as SESSION_STATE_FRAGMENT, M as ASK_WRITERS, N as CODE_MUTATORS, O as langOfPath, P as CODE_REDIRECT, Q as isRalphMode, R as PROTECTED_FRAGMENTS, S as isHooksPath, T as isStoresPath, U as securityGuard, V as ASK_PATTERNS, X as RALPH_SAFE, Y as PROJECT_INSTALL, Z as SYSTEM_INSTALL, a as registerGuard, at as DEV_KEYWORDS, b as interfaceDeclLevel, c as GO_DECL_RE, ct as isApexCommand, d as PY_MODEL_RE, et as detectFramework, f as RUST_DECL_RE, h as interfaceSeparationGuard, i as clearUserGuards, it as maskCommentsOnly, j as bashWriteGuard, k as lexProfileOf, l as JAVA_DECL_RE, lt as requiredArchSkill, m as TS_DECL_RE, n as FAIL_CLOSED, o as runGuards, ot as detectModularArchitecture, p as SWIFT_PROTO_RE, q as GIT_ASK, r as GUARDS, rt as maskCommentsAndStrings, s as installGuard, st as detectProjectType, t as evaluate, u as PHP_DECL_RE, v as declaresExportedTypeAlias, w as isQueryPath, x as isComponentsPath, y as declaresInterface, z as PROTECTED_GIT_RE } from "./evaluate-9bUzRquQ.mjs";
|
|
8
8
|
import { d as countFrameworkCodeLines, f as countLines, l as PLUGINS_DIR, p as evaluateFileSize, u as SOLID_REF } from "./home-state-oUGFB4ds.mjs";
|
|
9
9
|
import { i as resolveSessions, n as formatDocSatisfactionStatus, r as isDocConsulted, t as formatDocDeny } from "./doc-helpers-CWZegVdR.mjs";
|
|
10
10
|
import { i as parseFrontmatter, n as scoreReferences, r as globToRe, t as routeReferences } from "./router-PKVNBHge.mjs";
|
|
11
|
-
import { A as importsTanstackQuery, B as APEX_GATES, C as detectRequiredSkills, D as frameworkSolidGate, E as SKILL_TRIGGERS, G as evaluateApex, H as PRE_AUTH_GATES, I as MAX_EXA_RESULTS, K as freshnessGate, L as MAX_TOKENS, M as countStores, N as declaresStore, O as declaresCustomHook, R as capVerbosity, S as parseField, T as usesTailwindUtilities, U as brainstormGate, V as POST_AUTH_GATES, W as docConsultedGate, _ as detectClaudeMdProjectType, a as firstHeading, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as buildClaudeMdContext, h as buildApexInstruction, i as firstComment, j as queryCapActive, k as declaresQueryHook, l as PROJECT_INDICATORS, m as DEV_VERBS, n as missingSeoElements, o as parseEnrichment, q as solidReadGate, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, w as skillTriggerGate, x as parseBodyDesc, z as detectCreationIntent } from "./validate-
|
|
11
|
+
import { A as importsTanstackQuery, B as APEX_GATES, C as detectRequiredSkills, D as frameworkSolidGate, E as SKILL_TRIGGERS, G as evaluateApex, H as PRE_AUTH_GATES, I as MAX_EXA_RESULTS, K as freshnessGate, L as MAX_TOKENS, M as countStores, N as declaresStore, O as declaresCustomHook, R as capVerbosity, S as parseField, T as usesTailwindUtilities, U as brainstormGate, V as POST_AUTH_GATES, W as docConsultedGate, _ as detectClaudeMdProjectType, a as firstHeading, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as buildClaudeMdContext, h as buildApexInstruction, i as firstComment, j as queryCapActive, k as declaresQueryHook, l as PROJECT_INDICATORS, m as DEV_VERBS, n as missingSeoElements, o as parseEnrichment, q as solidReadGate, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, w as skillTriggerGate, x as parseBodyDesc, z as detectCreationIntent } from "./validate-C-TB06Mw.mjs";
|
|
12
12
|
import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
13
13
|
import { a as nowStamp, c as stateFileFor, i as lessonsFileFor, l as throttleMs, n as readRoots, o as readState, r as registryFile, s as setStateField, t as addRoot, u as ensureMemoryGitignore } from "./registry-IhHk2KlT.mjs";
|
|
14
14
|
import { a as cacheLookupSubstring, c as cacheStore, d as loadIndex, f as summarizeIndex, h as queryHash, i as cacheLookupMeta, l as mcpCacheKey, m as jaccardSimilar, n as webfetchCacheWrite, o as cacheLookupSubstringMeta, p as compactMarkdown, r as cacheLookup, s as cachePath, t as mcpCacheWrite, u as extractText } from "./mcp-store-BkBDmuxN.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as evaluate } from "./evaluate-
|
|
1
|
+
import { t as evaluate } from "./evaluate-9bUzRquQ.mjs";
|
|
2
2
|
import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
|
|
3
|
-
import { _ as commandToString, c as readClaudeInput } from "./claude-
|
|
3
|
+
import { _ as commandToString, c as readClaudeInput } from "./claude-CEWX-8m9.mjs";
|
|
4
4
|
//#region src/adapters/kimi/index.ts
|
|
5
5
|
/**
|
|
6
6
|
* Kimi Code CLI adapter (hook-mode). Moonshot AI's Kimi Code CLI (v0.27.0,
|
package/dist/policy/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as matchPatterns, B as protectedPathGuard, C as isInterfacesPath, D as isVendorPath, E as isTypesPath, F as FILE_REDIRECT, H as CRITICAL_PATTERNS, I as SAFE_PREFIXES, J as GIT_BLOCKED, L as SESSION_STATE_FRAGMENT, M as ASK_WRITERS, N as CODE_MUTATORS, O as langOfPath, P as CODE_REDIRECT, Q as isRalphMode, R as PROTECTED_FRAGMENTS, S as isHooksPath, T as isStoresPath, U as securityGuard, V as ASK_PATTERNS, X as RALPH_SAFE, Y as PROJECT_INSTALL, Z as SYSTEM_INSTALL, a as registerGuard, at as DEV_KEYWORDS, b as interfaceDeclLevel, c as GO_DECL_RE, ct as isApexCommand, d as PY_MODEL_RE, et as detectFramework, f as RUST_DECL_RE, h as interfaceSeparationGuard, i as clearUserGuards, it as maskCommentsOnly, j as bashWriteGuard, k as lexProfileOf, l as JAVA_DECL_RE, lt as requiredArchSkill, m as TS_DECL_RE, n as FAIL_CLOSED, o as runGuards, ot as detectModularArchitecture, p as SWIFT_PROTO_RE, q as GIT_ASK, r as GUARDS, rt as maskCommentsAndStrings, s as installGuard, st as detectProjectType, t as evaluate, u as PHP_DECL_RE, v as declaresExportedTypeAlias, w as isQueryPath, x as isComponentsPath, y as declaresInterface, z as PROTECTED_GIT_RE } from "../evaluate-
|
|
1
|
+
import { $ as matchPatterns, B as protectedPathGuard, C as isInterfacesPath, D as isVendorPath, E as isTypesPath, F as FILE_REDIRECT, H as CRITICAL_PATTERNS, I as SAFE_PREFIXES, J as GIT_BLOCKED, L as SESSION_STATE_FRAGMENT, M as ASK_WRITERS, N as CODE_MUTATORS, O as langOfPath, P as CODE_REDIRECT, Q as isRalphMode, R as PROTECTED_FRAGMENTS, S as isHooksPath, T as isStoresPath, U as securityGuard, V as ASK_PATTERNS, X as RALPH_SAFE, Y as PROJECT_INSTALL, Z as SYSTEM_INSTALL, a as registerGuard, at as DEV_KEYWORDS, b as interfaceDeclLevel, c as GO_DECL_RE, ct as isApexCommand, d as PY_MODEL_RE, et as detectFramework, f as RUST_DECL_RE, h as interfaceSeparationGuard, i as clearUserGuards, it as maskCommentsOnly, j as bashWriteGuard, k as lexProfileOf, l as JAVA_DECL_RE, lt as requiredArchSkill, m as TS_DECL_RE, n as FAIL_CLOSED, o as runGuards, ot as detectModularArchitecture, p as SWIFT_PROTO_RE, q as GIT_ASK, r as GUARDS, rt as maskCommentsAndStrings, s as installGuard, st as detectProjectType, t as evaluate, u as PHP_DECL_RE, v as declaresExportedTypeAlias, w as isQueryPath, x as isComponentsPath, y as declaresInterface, z as PROTECTED_GIT_RE } from "../evaluate-9bUzRquQ.mjs";
|
|
2
2
|
import { d as countFrameworkCodeLines, f as countLines, l as PLUGINS_DIR, p as evaluateFileSize, u as SOLID_REF } from "../home-state-oUGFB4ds.mjs";
|
|
3
|
-
import { A as importsTanstackQuery, B as APEX_GATES, C as detectRequiredSkills, D as frameworkSolidGate, E as SKILL_TRIGGERS, G as evaluateApex, H as PRE_AUTH_GATES, I as MAX_EXA_RESULTS, K as freshnessGate, L as MAX_TOKENS, M as countStores, N as declaresStore, O as declaresCustomHook, R as capVerbosity, S as parseField, T as usesTailwindUtilities, U as brainstormGate, V as POST_AUTH_GATES, W as docConsultedGate, _ as detectClaudeMdProjectType, a as firstHeading, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as buildClaudeMdContext, h as buildApexInstruction, i as firstComment, j as queryCapActive, k as declaresQueryHook, l as PROJECT_INDICATORS, m as DEV_VERBS, n as missingSeoElements, o as parseEnrichment, q as solidReadGate, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, w as skillTriggerGate, x as parseBodyDesc, z as detectCreationIntent } from "../validate-
|
|
3
|
+
import { A as importsTanstackQuery, B as APEX_GATES, C as detectRequiredSkills, D as frameworkSolidGate, E as SKILL_TRIGGERS, G as evaluateApex, H as PRE_AUTH_GATES, I as MAX_EXA_RESULTS, K as freshnessGate, L as MAX_TOKENS, M as countStores, N as declaresStore, O as declaresCustomHook, R as capVerbosity, S as parseField, T as usesTailwindUtilities, U as brainstormGate, V as POST_AUTH_GATES, W as docConsultedGate, _ as detectClaudeMdProjectType, a as firstHeading, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as buildClaudeMdContext, h as buildApexInstruction, i as firstComment, j as queryCapActive, k as declaresQueryHook, l as PROJECT_INDICATORS, m as DEV_VERBS, n as missingSeoElements, o as parseEnrichment, q as solidReadGate, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, w as skillTriggerGate, x as parseBodyDesc, z as detectCreationIntent } from "../validate-C-TB06Mw.mjs";
|
|
4
4
|
import "../policy-la_KkjCS.mjs";
|
|
5
5
|
export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, DEV_VERBS, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_TOKENS, PHP_DECL_RE, PLUGINS_DIR, POST_AUTH_GATES, PRE_AUTH_GATES, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, RALPH_SAFE, RUST_DECL_RE, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, capVerbosity, clearUserGuards, countFrameworkCodeLines, countLines, countStores, declaresCustomHook, declaresExportedTypeAlias, declaresInterface, declaresQueryHook, declaresStore, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, firstComment, firstHeading, frameworkSolidGate, freshnessGate, importsTanstackQuery, installGuard, interfaceDeclLevel, interfaceSeparationGuard, isApexCommand, isComponentsPath, isHooksPath, isHtmlLike, isInterfacesPath, isQueryPath, isRalphMode, isStoresPath, isTypesPath, isVendorPath, langOfPath, lexProfileOf, loadApexTaskState, maskCommentsAndStrings, maskCommentsOnly, matchPatterns, missingSeoElements, parseBodyDesc, parseEnrichment, parseEntry, parseField, protectedPathGuard, queryCapActive, registerGuard, requiredArchSkill, runGuards, securityGuard, skillTriggerGate, solidReadGate, usesTailwindUtilities };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as isCodeFile } from "./project-root-3kk7gCOp.mjs";
|
|
2
|
-
import { t as evaluate } from "./evaluate-
|
|
2
|
+
import { t as evaluate } from "./evaluate-9bUzRquQ.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
|
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-Dzf4JbrL.mjs";
|
|
4
4
|
//#region src/runtime/storage.ts
|
|
5
5
|
/**
|
|
6
6
|
* The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as resolveMaxLines, c as storeBudget, i as hookBudget } from "./limits-DG5pl-5s.mjs";
|
|
2
2
|
import { c as ttlLabel, t as HOME_DIR } from "./dotenv-DoqNlALG.mjs";
|
|
3
|
-
import { A as moduleAwarePath, S as isHooksPath, T as isStoresPath, _ as rolloutVerdict, at as DEV_KEYWORDS, it as maskCommentsOnly, nt as projectCaps, rt as maskCommentsAndStrings, tt as nearestManifestDir, x as isComponentsPath, y as declaresInterface } from "./evaluate-
|
|
3
|
+
import { A as moduleAwarePath, S as isHooksPath, T as isStoresPath, _ as rolloutVerdict, at as DEV_KEYWORDS, it as maskCommentsOnly, nt as projectCaps, rt as maskCommentsAndStrings, tt as nearestManifestDir, x as isComponentsPath, y as declaresInterface } from "./evaluate-9bUzRquQ.mjs";
|
|
4
4
|
import { d as countFrameworkCodeLines, l as PLUGINS_DIR, u as SOLID_REF } from "./home-state-oUGFB4ds.mjs";
|
|
5
5
|
import { r as isDocConsulted, t as formatDocDeny } from "./doc-helpers-CWZegVdR.mjs";
|
|
6
6
|
import { t as routeReferences } from "./router-PKVNBHge.mjs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusengine/harness",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.86",
|
|
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",
|