@fusengine/harness 0.1.85 → 0.1.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import { a as 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-D93HY8dq.mjs";
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,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-B4-MhOy_.mjs";
1
+ import { t as evaluate } from "../../evaluate-9bUzRquQ.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/cline/index.ts
4
4
  /**
@@ -1,8 +1,8 @@
1
- import { t as evaluate } from "../../evaluate-B4-MhOy_.mjs";
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-D93HY8dq.mjs";
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,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-B4-MhOy_.mjs";
1
+ import { t as evaluate } from "../../evaluate-9bUzRquQ.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/cursor/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-B4-MhOy_.mjs";
1
+ import { t as evaluate } from "../../evaluate-9bUzRquQ.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/gemini/index.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { n as readHermesInput, r as toHermesResponse, t as guard } from "../../hermes-1PUEoY8q.mjs";
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-ChbcU2uI.mjs";
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-B4-MhOy_.mjs";
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
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { o as resolveStdinMaxBytes } from "../limits-DG5pl-5s.mjs";
3
- import { r as loadDotenv, s as resolveTtlSec } from "../dotenv-DoqNlALG.mjs";
3
+ import { c as resolveTtlSec, r as loadDotenv } from "../dotenv-BLBkBTww.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-D_WchZ3R.mjs";
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-DptZbyMP.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-Boj3vnxD.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";
@@ -1,2 +1,2 @@
1
- import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-D_WchZ3R.mjs";
1
+ import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-B4kqWMA3.mjs";
2
2
  export { checkStaged, stagedContent, stagedFiles };
@@ -1,5 +1,5 @@
1
1
  import { a as resolveMaxLines, c as storeBudget, i as hookBudget, l as parseEnvInt, n as DEFAULT_STDIN_MAX_BYTES, o as resolveStdinMaxBytes, r as MAX_LINES_ENV_KEY, s as splitTarget, t as DEFAULT_MAX_LINES } from "../limits-DG5pl-5s.mjs";
2
- import { a as DEFAULT_TTL_SEC, c as ttlLabel, i as parseEnvFile, n as envCandidates, o as TTL_ENV_KEY, r as loadDotenv, s as resolveTtlSec, t as HOME_DIR } from "../dotenv-DoqNlALG.mjs";
2
+ import { c as resolveTtlSec, i as parseEnvFile, l as ttlLabel, n as envCandidates, o as DEFAULT_TTL_SEC, r as loadDotenv, s as TTL_ENV_KEY, t as HOME_DIR } from "../dotenv-BLBkBTww.mjs";
3
3
  import { n as STATE_ROOT, r as projectLayout, t as STATE_GITIGNORE } from "../layout-KWoE_Mqn.mjs";
4
4
  import "../config-la_KkjCS.mjs";
5
5
  export { DEFAULT_MAX_LINES, DEFAULT_STDIN_MAX_BYTES, DEFAULT_TTL_SEC, HOME_DIR, MAX_LINES_ENV_KEY, STATE_GITIGNORE, STATE_ROOT, TTL_ENV_KEY, envCandidates, hookBudget, loadDotenv, parseEnvFile, parseEnvInt, projectLayout, resolveMaxLines, resolveStdinMaxBytes, resolveTtlSec, splitTarget, storeBudget, ttlLabel };
@@ -106,4 +106,4 @@ function loadDotenv(id, env = process.env, home = homedir(), cwd = process.cwd()
106
106
  for (const path of envCandidates(id, home, cwd)) for (const [k, v] of Object.entries(parseEnvFile(path))) if (env[k] === void 0) env[k] = v;
107
107
  }
108
108
  //#endregion
109
- export { DEFAULT_TTL_SEC as a, ttlLabel as c, parseEnvFile as i, envCandidates as n, TTL_ENV_KEY as o, loadDotenv as r, resolveTtlSec as s, HOME_DIR as t };
109
+ export { harnessHome as a, resolveTtlSec as c, parseEnvFile as i, ttlLabel as l, envCandidates as n, DEFAULT_TTL_SEC as o, loadDotenv as r, TTL_ENV_KEY as s, HOME_DIR as t };
@@ -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) || /@tailwind|@apply/.test(content)) return { definitive: "tailwind" };
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));
@@ -1,23 +1,23 @@
1
1
  import { a as resolveMaxLines, l as parseEnvInt, s as splitTarget } from "./limits-DG5pl-5s.mjs";
2
- import { s as resolveTtlSec } from "./dotenv-DoqNlALG.mjs";
2
+ import { a as harnessHome, c as resolveTtlSec } from "./dotenv-BLBkBTww.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-B4-MhOy_.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-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-Bf-EsbDh.mjs";
11
- import { n as findMarketplacePlugins, r as readPluginMeta, t as resolveSkillPath } from "./skill-path-DhBGlQe3.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-DYPT8NY-.mjs";
11
+ import { n as findMarketplacePlugins, r as readPluginMeta, t as resolveSkillPath } from "./skill-path-DVML3zfp.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";
14
14
  import { d as loadIndex, i as cacheLookupMeta, n as webfetchCacheWrite, o as cacheLookupSubstringMeta, t as mcpCacheWrite, u as extractText } from "./mcp-store-BkBDmuxN.mjs";
15
15
  import { t as loadRefs } from "./loader-AGz4nK7d.mjs";
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";
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-5-ZPKb0u.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-D93HY8dq.mjs";
19
- import { i as toKimiResponse, n as kimiDenyResponse } from "./kimi-ChbcU2uI.mjs";
20
- import { r as toHermesResponse } from "./hermes-1PUEoY8q.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-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-resolve.ts
283
+ //#region src/policy/design/corpus-fs.ts
284
284
  /**
285
- * Corpus/plugins root resolution (fs) and the write guard over it. Resolution
286
- * is PER RUNTIME (Claude marketplaces, Codex versioned plugin cache — same
287
- * pattern as rules-root.ts); runtimes without a plugin structure (kimi today)
288
- * resolve to "" and the corpus gates stay dormant. There is NO cwd fallback
289
- * anywhere: an agent-controlled directory can never become its own taste
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
- /** Claude: `<home>/.claude/plugins/marketplaces/<mkt>/plugins/design-expert` ("" when absent). */
302
- function probeClaude$1(home) {
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}/`) && TOKENS_RE.test(basename(filePath))) return "tokens";
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
- /** Per-mode corpus-read threshold (component >= 1 file, page >= 2 files, full = index + 2 tokens). */
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 >= 2;
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) {
@@ -825,12 +893,35 @@ function claudeMdKey(prompt, ctx) {
825
893
  return `claude-md:${hashText(prompt)}:${hashText(ctx)}`;
826
894
  }
827
895
  /**
896
+ * Extract the APEX preamble portion of a `buildClaudeMdContext` result, i.e.
897
+ * everything BEFORE the `# <docName>\n` root-doc block it prepends on dev
898
+ * prompts. Returns "" when `ctx` has no preamble (plain prompt: `ctx` starts
899
+ * directly with the root-doc heading).
900
+ * @param ctx - The full `buildClaudeMdContext` return value.
901
+ * @param docName - Root doc file name (e.g. "AGENTS.md").
902
+ * @returns The preamble text, or "" when absent.
903
+ */
904
+ function extractApexPreamble(ctx, docName) {
905
+ const heading = `# ${docName}\n`;
906
+ if (ctx.startsWith(heading)) return "";
907
+ const sep = `\n\n${heading}`;
908
+ const idx = ctx.indexOf(sep);
909
+ return idx === -1 ? "" : ctx.slice(0, idx);
910
+ }
911
+ /**
828
912
  * UserPromptSubmit context injection: render the CLAUDE.md (+ optional APEX)
829
913
  * preamble as a Claude `additionalContext` response, or "" when nothing to emit.
830
914
  * Guarded by {@link oncePerWindow} via {@link claudeMdKey}: only a
831
915
  * near-simultaneous double-fire of the SAME turn (identical prompt AND identical
832
916
  * block, within {@link DEDUP_WINDOW_MS}) is suppressed. The invariant "CLAUDE.md
833
917
  * is emitted on EVERY message" is thus preserved.
918
+ *
919
+ * On kimi specifically, the root doc body is dropped from the emitted text:
920
+ * Kimi loads `<kimiHome>/AGENTS.md` natively at session start (`apex-target.ts`),
921
+ * so re-injecting its full body on every prompt is redundant terminal noise
922
+ * (kimi has no model-only hook channel — `runtime/inform.ts`). The APEX
923
+ * preamble, which is NOT part of `AGENTS.md`, is still emitted in full when the
924
+ * prompt is dev-shaped; a plain prompt leaves only the notice.
834
925
  * @param prompt - The raw user prompt.
835
926
  * @param cwd - Project root (for project-type detection).
836
927
  * @param id - Harness target id (defaults to "claude-code" — zero-regression default).
@@ -840,7 +931,12 @@ function promptSubmitContext(prompt, cwd, id = "claude-code") {
840
931
  const ctx = buildClaudeMdContext(prompt, cwd, id);
841
932
  if (!ctx) return "";
842
933
  if (!oncePerWindow(claudeMdKey(prompt, ctx), 3e3)) return "";
843
- return renderInform(id, "UserPromptSubmit", ctx, `${apexDocName(id)} injected`);
934
+ const notice = `${apexDocName(id)} injected`;
935
+ if (id === "kimi") {
936
+ const preamble = extractApexPreamble(ctx, apexDocName(id));
937
+ return preamble ? renderInform(id, "UserPromptSubmit", preamble, notice) : notice;
938
+ }
939
+ return renderInform(id, "UserPromptSubmit", ctx, notice);
844
940
  }
845
941
  /**
846
942
  * PreToolUse Task context injection: render the APEX sub-agent context as a
@@ -1024,6 +1120,45 @@ function sessionStartCore(cwd, home = homedir(), now = Date.now(), id = "claude-
1024
1120
  return ctx ? attachSystemMessage(contextResponse("SessionStart", ctx), `${apexDocName(id)} injected`) : "";
1025
1121
  }
1026
1122
  //#endregion
1123
+ //#region src/runtime/lifecycle/kimi-rules-native.ts
1124
+ /**
1125
+ * Guard for the kimi notice-only rules injection. Kimi Code CLI has no
1126
+ * model-only hook channel (`src/runtime/inform.ts`) — every `UserPromptSubmit`
1127
+ * stdout is BOTH appended to the model's context AND rendered raw in the
1128
+ * user's terminal. `injectRules` (`inject-rules.ts`) normally re-injects the
1129
+ * full ~18 Ko rules corpus on every prompt; when the installer has already
1130
+ * merged that same corpus into `<kimiHome>/AGENTS.md` — which Kimi loads
1131
+ * natively at session start via its documented `${agents_md}` mechanism,
1132
+ * independent of hooks — the re-injection is pure noise the user has to
1133
+ * scroll past. Confirmed present, fenced, in the local install:
1134
+ * `~/.kimi-code/AGENTS.md:87` / `:335`.
1135
+ *
1136
+ * Fail-safe semantics: fences absent, file absent, or any read error ⟹
1137
+ * `false` — the caller then falls back to the full corpus. A dump is
1138
+ * verbose but never wrong; a false `true` would silently drop the rules.
1139
+ */
1140
+ /** Opening fence the fusengine installer writes around the merged corpus. */
1141
+ const FENCE_START = "<!-- fusengine:kimi-rules:start -->";
1142
+ /** Closing fence the fusengine installer writes around the merged corpus. */
1143
+ const FENCE_END = "<!-- fusengine:kimi-rules:end -->";
1144
+ /**
1145
+ * Check whether the kimi rules corpus is already present, fenced, inside
1146
+ * `<kimiHome>/AGENTS.md`.
1147
+ * @param home - Kimi home dir override (defaults to `harnessHome("kimi")`,
1148
+ * which honors `KIMI_CODE_HOME`).
1149
+ * @returns `true` only when both fences are found in a readable file.
1150
+ */
1151
+ function rulesInAgentsMd(home) {
1152
+ try {
1153
+ const agentsMd = join(home ?? harnessHome("kimi"), "AGENTS.md");
1154
+ if (!existsSync(agentsMd)) return false;
1155
+ const content = readFileSync(agentsMd, "utf-8");
1156
+ return content.includes(FENCE_START) && content.includes(FENCE_END);
1157
+ } catch {
1158
+ return false;
1159
+ }
1160
+ }
1161
+ //#endregion
1027
1162
  //#region src/runtime/lifecycle/inject-rules.ts
1028
1163
  /** Read & concatenate all `*.md` files (sorted) under `rulesDir`. */
1029
1164
  function readRules(rulesDir) {
@@ -1047,6 +1182,13 @@ function readRules(rulesDir) {
1047
1182
  * with the *actual* `hookEventName` — the spec requires it to match the firing
1048
1183
  * event (a hardcoded "SessionStart" is non-conforming and may be dropped on
1049
1184
  * UserPromptSubmit/SubagentStart).
1185
+ *
1186
+ * On kimi's `UserPromptSubmit` specifically, when the corpus is already fenced
1187
+ * inside `<kimiHome>/AGENTS.md` (native load, {@link rulesInAgentsMd}), only the
1188
+ * notice is emitted — the re-injected corpus would otherwise dump into the
1189
+ * user's terminal on every single prompt for no model-context benefit.
1190
+ * `SessionStart`/`SubagentStart` always keep the full corpus (session bootstrap
1191
+ * / sub-agent contexts need it regardless of the native AGENTS.md load).
1050
1192
  * @param pluginRoot - `CLAUDE_PLUGIN_ROOT` of the claude-rules plugin.
1051
1193
  * @param event - The firing hook event name (e.g. "SessionStart").
1052
1194
  * @param id - Harness target id (defaults to "claude-code" — zero-regression default).
@@ -1054,7 +1196,9 @@ function readRules(rulesDir) {
1054
1196
  */
1055
1197
  function injectRules(pluginRoot, event, id = "claude-code") {
1056
1198
  const content = readRules(join(pluginRoot, "rules"));
1057
- return content ? renderInform(id, event, content, "rules 00-08 injected") : "";
1199
+ if (!content) return "";
1200
+ if (id === "kimi" && event === "UserPromptSubmit" && rulesInAgentsMd()) return "rules 00-08 injected";
1201
+ return renderInform(id, event, content, "rules 00-08 injected");
1058
1202
  }
1059
1203
  //#endregion
1060
1204
  //#region src/runtime/lifecycle/solid-detect.ts
@@ -7905,6 +8049,57 @@ function collectDesignEvidence(sessionId, cwd, baseDir = defaultStateDir(cwd)) {
7905
8049
  };
7906
8050
  }
7907
8051
  //#endregion
8052
+ //#region src/policy/design/screenshot-tools.ts
8053
+ /**
8054
+ * @module screenshot-tools
8055
+ * Screenshot-credit tool set (C1), split out of `runtime/design-helpers.ts` to
8056
+ * keep that file within the SOLID size budget (SRP).
8057
+ * @packageDocumentation
8058
+ */
8059
+ /**
8060
+ * Screenshot-credit tools: the single-shot capture PLUS the two fuse-browser
8061
+ * batch capture primitives (`browser_shots_batch`, `browser_site_shots`) — a
8062
+ * batch call that captures N urls/viewports must credit the quota too, or
8063
+ * capturing efficiently would make the quota infranchissable. LIMITATION
8064
+ * (deliberate, documented): this repo's cross-harness `NormalizedEvent` (see
8065
+ * `runtime/normalize.ts`) never surfaces `tool_response` for any tool — by
8066
+ * design, since its shape is undocumented for MCP tools and harness-specific
8067
+ * for built-ins — so no per-call item count reaches this gate. A batch call
8068
+ * therefore credits EXACTLY 1, same as a unit screenshot, never the N it may
8069
+ * have captured.
8070
+ */
8071
+ const SHOT_TOOLS = /* @__PURE__ */ new Set([
8072
+ "mcp__fuse-browser__browser_screenshot",
8073
+ "mcp__fuse-browser__browser_shots_batch",
8074
+ "mcp__fuse-browser__browser_site_shots"
8075
+ ]);
8076
+ //#endregion
8077
+ //#region src/policy/design/allowed-write.ts
8078
+ /**
8079
+ * @module allowed-write
8080
+ * The design-agent write allowlist, split out of `gates.ts` to keep that file
8081
+ * within the SOLID size budget (SRP).
8082
+ * @packageDocumentation
8083
+ */
8084
+ /** Extensions the design agent may always write: .html/.css/.md/.json. */
8085
+ const ALLOWED_WRITE = /\.(html|css|md|json)$/;
8086
+ /**
8087
+ * C4: `motion*.js` ONLY, matched on the BASENAME — every one of the 11
8088
+ * corpus references ships its animation as a separate `motion.js` /
8089
+ * `motion-nav.js` / `motion-scroll.js` file, so banning every `.js` forced
8090
+ * the agent to inline scripts the corpus explicitly teaches out-of-band.
8091
+ * Deliberately NOT `\.js$` in general (that would open arbitrary app code,
8092
+ * the exact thing this gate exists to block) — after the `motion` prefix,
8093
+ * either nothing (`motion.js`) or `.`/`-` then more (`motion-nav.js`) must
8094
+ * lead into `.js`; `app.js` and `motionless-app.js` — a bare `^motion`
8095
+ * prefix would wrongly pass this — do not match.
8096
+ */
8097
+ const MOTION_JS = /^motion([.-].*)?\.js$/;
8098
+ /** True when `filePath` is a write the design agent may make: .html/.css/.md/.json, or a `motion*.js` file. */
8099
+ function isAllowedWrite(filePath) {
8100
+ return ALLOWED_WRITE.test(filePath) || MOTION_JS.test(basename(filePath));
8101
+ }
8102
+ //#endregion
7908
8103
  //#region src/policy/design/design-system-rules.ts
7909
8104
  /**
7910
8105
  * Content rules for design-system.md — the four hard requirements the
@@ -7949,7 +8144,6 @@ function validateDesignSystem(content, corpusCitationOk = false) {
7949
8144
  }
7950
8145
  //#endregion
7951
8146
  //#region src/policy/design/gates.ts
7952
- const ALLOWED_WRITE = /\.(html|css|md|json)$/;
7953
8147
  const EXEMPT_DIRS = [
7954
8148
  "node_modules/",
7955
8149
  "dist/",
@@ -7957,7 +8151,7 @@ const EXEMPT_DIRS = [
7957
8151
  ".claude/"
7958
8152
  ];
7959
8153
  const NAV$2 = "mcp__fuse-browser__browser_navigate";
7960
- const SHOT$2 = "mcp__fuse-browser__browser_screenshot";
8154
+ const SHOT$1 = "mcp__fuse-browser__browser_screenshot";
7961
8155
  const GEMINI$2 = "mcp__gemini-design__create_frontend";
7962
8156
  const deny = (reason) => ({
7963
8157
  kind: "block",
@@ -7965,10 +8159,10 @@ const deny = (reason) => ({
7965
8159
  reason,
7966
8160
  actions: ["Follow the design pipeline phases (0→identity, 1→inspiration, 2→screenshots, 3→design-system, 4→generate) in order"]
7967
8161
  });
7968
- /** Block the design agent from writing anything but .html/.css/.md/.json. */
8162
+ /** Block the design agent from writing anything but .html/.css/.md/.json (+ motion*.js). */
7969
8163
  function htmlCssOnlyGate(filePath) {
7970
- if (EXEMPT_DIRS.some((d) => filePath.includes(d)) || ALLOWED_WRITE.test(filePath)) return null;
7971
- return deny("BLOCKED: design-expert can only write .html, .css, .md, and .json files. Framework files (.tsx, .astro, .vue, .swift, .php) must be written by the domain expert (astro-expert, react-expert, etc.) AFTER design validation.");
8164
+ if (EXEMPT_DIRS.some((d) => filePath.includes(d)) || isAllowedWrite(filePath)) return null;
8165
+ 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.");
7972
8166
  }
7973
8167
  /** Block edits to the harness-managed `.design-state-*` files (read-only to the agent). */
7974
8168
  function stateFileGate(filePath) {
@@ -8005,7 +8199,7 @@ function designPassNotice(i, cacheDir) {
8005
8199
  if (isWrite && fp && !EXEMPT_DIRS.some((d) => fp.includes(d)) && ALLOWED_WRITE.test(fp)) lines.push(`enforce-html-css-only: allowed: ${basename(fp)}`);
8006
8200
  if (i.tool === NAV$2) lines.push(`check-inspiration-read: pass (${i.url})`);
8007
8201
  if (i.tool === GEMINI$2 && geminiEnabled()) lines.push("validate-design-system: design-system.md ok");
8008
- if (isWrite || i.tool === NAV$2 || i.tool === SHOT$2 || i.tool === GEMINI$2) lines.push(`pipeline-gate: phase ${state.currentPhase} ok`);
8202
+ if (isWrite || i.tool === NAV$2 || i.tool === SHOT$1 || i.tool === GEMINI$2) lines.push(`pipeline-gate: phase ${state.currentPhase} ok`);
8009
8203
  }
8010
8204
  if (state && i.phase === "post" && isWrite) {
8011
8205
  if (basename(fp) === "design-system.md") lines.push("validate-design: design-system.md → phase 3");
@@ -8089,9 +8283,9 @@ const SKILLS = `${PLUGINS_DIR}/design-expert/skills`;
8089
8283
  /** Gate writing design-system.md: requires phase >= 2 and the per-mode screenshot quota. */
8090
8284
  function designSystemWriteGate(filePath, state, corpusRequired = false) {
8091
8285
  if (!filePath.endsWith("design-system.md")) return null;
8092
- 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 (note: browser_shots_batch/browser_site_shots do NOT advance the phase) 5) Then write design-system.md`);
8286
+ 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`);
8093
8287
  const needed = quotaFor(state.mode, corpusRequired);
8094
- 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 do NOT count) 3) Use browser_open + browser_navigate + browser_screenshot fullPage:true 4) Then write design-system.md`);
8288
+ 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`);
8095
8289
  return null;
8096
8290
  }
8097
8291
  /** Gate Gemini create_frontend: requires phase >= 3 and a validated design system. */
@@ -8238,7 +8432,6 @@ function designSystemContentGate(i) {
8238
8432
  * @packageDocumentation
8239
8433
  */
8240
8434
  const NAV$1 = "mcp__fuse-browser__browser_navigate";
8241
- const SHOT$1 = "mcp__fuse-browser__browser_screenshot";
8242
8435
  const SCROLL = "mcp__fuse-browser__browser_scroll";
8243
8436
  const GEMINI$1 = "mcp__gemini-design__create_frontend";
8244
8437
  /** Read design-system.md walking up to 6 parents from `cwd` ("" if absent/unreadable). */
@@ -8259,7 +8452,7 @@ function findDesignSystem(cwd) {
8259
8452
  }
8260
8453
  /** Apply a PostToolUse fuse-browser transition to the design state. */
8261
8454
  function recordPost(event, cacheDir, state, corpusRoot = "", corpusRequired = false, cwd = "") {
8262
- if (event.tool === SHOT$1) saveDesignState(cacheDir, recordScreenshot(state, corpusRequired));
8455
+ if (SHOT_TOOLS.has(event.tool)) saveDesignState(cacheDir, recordScreenshot(state, corpusRequired));
8263
8456
  else if (event.tool === NAV$1) saveDesignState(cacheDir, recordNavigate(state));
8264
8457
  else if (event.tool === SCROLL) saveDesignState(cacheDir, recordScroll(state));
8265
8458
  else if (event.tool === GEMINI$1) saveDesignState(cacheDir, {
@@ -1,6 +1,6 @@
1
- import { t as evaluate } from "./evaluate-B4-MhOy_.mjs";
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-D93HY8dq.mjs";
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
@@ -1,14 +1,14 @@
1
1
  import { a as resolveMaxLines, c as storeBudget, i as hookBudget, l as parseEnvInt, n as DEFAULT_STDIN_MAX_BYTES, o as resolveStdinMaxBytes, r as MAX_LINES_ENV_KEY, s as splitTarget, t as DEFAULT_MAX_LINES } from "./limits-DG5pl-5s.mjs";
2
- import { a as DEFAULT_TTL_SEC, c as ttlLabel, i as parseEnvFile, n as envCandidates, o as TTL_ENV_KEY, r as loadDotenv, s as resolveTtlSec, t as HOME_DIR } from "./dotenv-DoqNlALG.mjs";
2
+ import { c as resolveTtlSec, i as parseEnvFile, l as ttlLabel, n as envCandidates, o as DEFAULT_TTL_SEC, r as loadDotenv, s as TTL_ENV_KEY, t as HOME_DIR } from "./dotenv-BLBkBTww.mjs";
3
3
  import { n as STATE_ROOT, r as projectLayout, t as STATE_GITIGNORE } from "./layout-KWoE_Mqn.mjs";
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-B4-MhOy_.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-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-Bf-EsbDh.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-DYPT8NY-.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-B4-MhOy_.mjs";
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-D93HY8dq.mjs";
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,
@@ -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-B4-MhOy_.mjs";
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-Bf-EsbDh.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-DYPT8NY-.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-B4-MhOy_.mjs";
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
@@ -290,6 +290,13 @@ declare function claudeMdKey(prompt: string, ctx: string): string;
290
290
  * near-simultaneous double-fire of the SAME turn (identical prompt AND identical
291
291
  * block, within {@link DEDUP_WINDOW_MS}) is suppressed. The invariant "CLAUDE.md
292
292
  * is emitted on EVERY message" is thus preserved.
293
+ *
294
+ * On kimi specifically, the root doc body is dropped from the emitted text:
295
+ * Kimi loads `<kimiHome>/AGENTS.md` natively at session start (`apex-target.ts`),
296
+ * so re-injecting its full body on every prompt is redundant terminal noise
297
+ * (kimi has no model-only hook channel — `runtime/inform.ts`). The APEX
298
+ * preamble, which is NOT part of `AGENTS.md`, is still emitted in full when the
299
+ * prompt is dev-shaped; a plain prompt leaves only the notice.
293
300
  * @param prompt - The raw user prompt.
294
301
  * @param cwd - Project root (for project-type detection).
295
302
  * @param id - Harness target id (defaults to "claude-code" — zero-regression default).
@@ -373,6 +380,13 @@ declare function readRules(rulesDir: string): string;
373
380
  * with the *actual* `hookEventName` — the spec requires it to match the firing
374
381
  * event (a hardcoded "SessionStart" is non-conforming and may be dropped on
375
382
  * UserPromptSubmit/SubagentStart).
383
+ *
384
+ * On kimi's `UserPromptSubmit` specifically, when the corpus is already fenced
385
+ * inside `<kimiHome>/AGENTS.md` (native load, {@link rulesInAgentsMd}), only the
386
+ * notice is emitted — the re-injected corpus would otherwise dump into the
387
+ * user's terminal on every single prompt for no model-context benefit.
388
+ * `SessionStart`/`SubagentStart` always keep the full corpus (session bootstrap
389
+ * / sub-agent contexts need it regardless of the native AGENTS.md load).
376
390
  * @param pluginRoot - `CLAUDE_PLUGIN_ROOT` of the claude-rules plugin.
377
391
  * @param event - The firing hook event name (e.g. "SessionStart").
378
392
  * @param id - Harness target id (defaults to "claude-code" — zero-regression default).
@@ -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-DptZbyMP.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-Boj3vnxD.mjs";
4
4
  //#region src/runtime/storage.ts
5
5
  /**
6
6
  * The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
@@ -1,4 +1,4 @@
1
- import { t as HOME_DIR } from "./dotenv-DoqNlALG.mjs";
1
+ import { t as HOME_DIR } from "./dotenv-BLBkBTww.mjs";
2
2
  import { t as detectHarness } from "./harness-BMuLJ9lm.mjs";
3
3
  import { l as PLUGINS_DIR } from "./home-state-oUGFB4ds.mjs";
4
4
  import { join } from "node:path";
@@ -1,9 +1,9 @@
1
- import { c as ttlLabel } from "./dotenv-DoqNlALG.mjs";
1
+ import { l as ttlLabel } from "./dotenv-BLBkBTww.mjs";
2
2
  import { n as fuseHarnessHome } from "./home-state-oUGFB4ds.mjs";
3
3
  import { a as writeJsonFile, i as readJsonFile, t as atomicWrite } from "./json-io-DisYd2fb.mjs";
4
4
  import { i as resolveSessions } from "./doc-helpers-CWZegVdR.mjs";
5
5
  import { t as routeReferences } from "./router-PKVNBHge.mjs";
6
- import { t as resolveSkillPath } from "./skill-path-DhBGlQe3.mjs";
6
+ import { t as resolveSkillPath } from "./skill-path-DVML3zfp.mjs";
7
7
  import { dirname, join } from "node:path";
8
8
  import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
9
9
  import { createHmac, randomBytes } from "node:crypto";
@@ -1,2 +1,2 @@
1
- import { S as trivialCount, _ as recordBrainstormRequired, b as recordTarget, g as recordAgent, h as emptyTrack, i as withTrack, m as agentsFresh, n as saveTrack, r as trackJournalEnabled, t as loadTrack, v as recordDoc, x as recordTrivialEdit, y as recordRefRead } from "../store-Dw08Amqh.mjs";
1
+ import { S as trivialCount, _ as recordBrainstormRequired, b as recordTarget, g as recordAgent, h as emptyTrack, i as withTrack, m as agentsFresh, n as saveTrack, r as trackJournalEnabled, t as loadTrack, v as recordDoc, x as recordTrivialEdit, y as recordRefRead } from "../store-5-ZPKb0u.mjs";
2
2
  export { agentsFresh, emptyTrack, loadTrack, recordAgent, recordBrainstormRequired, recordDoc, recordRefRead, recordTarget, recordTrivialEdit, saveTrack, trackJournalEnabled, trivialCount, withTrack };
@@ -1,10 +1,10 @@
1
1
  import { a as resolveMaxLines, c as storeBudget, i as hookBudget } from "./limits-DG5pl-5s.mjs";
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-B4-MhOy_.mjs";
2
+ import { l as ttlLabel, t as HOME_DIR } from "./dotenv-BLBkBTww.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-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";
7
- import { n as findMarketplacePlugins, r as readPluginMeta, t as resolveSkillPath } from "./skill-path-DhBGlQe3.mjs";
7
+ import { n as findMarketplacePlugins, r as readPluginMeta, t as resolveSkillPath } from "./skill-path-DVML3zfp.mjs";
8
8
  import { dirname, extname, join, resolve } from "node:path";
9
9
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
10
10
  import { homedir } from "node:os";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/harness",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
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",