@fusengine/harness 0.1.46 → 0.1.48

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/README.md CHANGED
@@ -116,6 +116,8 @@ Ten portable guards + the APEX gate chain, all evaluated before a tool runs:
116
116
  | APEX freshness | `explore-codebase` + `research-expert` not run within the window |
117
117
  | APEX doc-consulted | no doc source (Context7 / Exa / fuse-browser / WebSearch / WebFetch) consulted this session |
118
118
  | APEX solid-read | required SOLID refs (auto-discovered, or `FUSE_HARNESS_REFS`) not read |
119
+ | framework sub-skill | framework / shadcn / Tailwind code whose required skill (`skills/<name>/`) wasn't read this session |
120
+ | Gemini MCP (opt-in) | hand-written Tailwind UI without a `mcp__gemini-design__*` call — only when `FUSE_ENFORCE_GEMINI_MCP` is set |
119
121
  | brainstorm | creating a new file without brainstorming (when flagged) |
120
122
  | MCP verbosity / cache | caps exa `numResults`; serves a fresh cached MCP/WebFetch result |
121
123
 
@@ -131,6 +133,8 @@ through per window without the full APEX gates.
131
133
  | `FUSE_HARNESS_MARKETPLACES` | Comma-list of marketplace names whose `solid-*` skill refs are auto-discovered when `FUSE_HARNESS_REFS` is unset (default `fusengine-plugins`; an absent marketplace contributes nothing). Standalone `.claude`/`.codex`/`.cursor`/`.agents` skills are always scanned. |
132
134
  | `FUSE_ENFORCE_TTL_SEC` | APEX freshness window in seconds. |
133
135
  | `FUSE_LESSONS_THROTTLE_MIN` | Lessons-injection throttle (memory module). |
136
+ | `FUSE_ENFORCE_GEMINI_MCP` | **Opt-in (default off).** `1`/`true` blocks hand-written Tailwind UI (`.tsx/.jsx/.vue/.svelte`, ≥3 utility classes) until a `mcp__gemini-design__*` call is made this session. Read fresh per call. |
137
+ | `RALPH_MODE` | **Opt-in (default off).** `1`/`true` enables autonomous "Ralph" mode: exempts the safe git commands (`add`/`commit`/`checkout -b`/`status`/`diff`/`log`) from the confirmation ASK and auto-approves project installs. Destructive git (force-push, `reset --hard`) and system installs still gate. |
134
138
 
135
139
  ## Library usage
136
140
 
@@ -1,2 +1,2 @@
1
- import { a as guard, c as toClaudeResponse, i as fileSizeGuard, n as contextResponse, o as readClaudeInput, r as denyResponse, s as systemMessage, t as blockResponse } from "../../claude-DLh0fHWM.mjs";
1
+ import { a as guard, c as toClaudeResponse, i as fileSizeGuard, n as contextResponse, o as readClaudeInput, r as denyResponse, s as systemMessage, t as blockResponse } from "../../claude-U1KTaRG4.mjs";
2
2
  export { blockResponse, contextResponse, denyResponse, fileSizeGuard, guard, readClaudeInput, systemMessage, toClaudeResponse };
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-d7Pp8XJH.mjs";
1
+ import { t as evaluate } from "../../evaluate-qYC5xClb.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/cline/index.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { a as guard, n as contextResponse, o as readClaudeInput, r as denyResponse } from "../../claude-DLh0fHWM.mjs";
1
+ import { a as guard, n as contextResponse, o as readClaudeInput, r as denyResponse } from "../../claude-U1KTaRG4.mjs";
2
2
  export { contextResponse, denyResponse, guard, readClaudeInput as readCodexInput };
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "../../evaluate-d7Pp8XJH.mjs";
1
+ import { t as evaluate } from "../../evaluate-qYC5xClb.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-d7Pp8XJH.mjs";
1
+ import { t as evaluate } from "../../evaluate-qYC5xClb.mjs";
2
2
  import { t as formatPrompt } from "../../types-ernB1Dy3.mjs";
3
3
  //#region src/adapters/gemini/index.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as evaluate } from "./evaluate-d7Pp8XJH.mjs";
1
+ import { t as evaluate } from "./evaluate-qYC5xClb.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
@@ -2,9 +2,9 @@
2
2
  import { r as loadDotenv, s as resolveTtlSec } from "../dotenv-B9nM4cuQ.mjs";
3
3
  import { t as detectHarness } from "../harness-C8Nxxyn_.mjs";
4
4
  import { t as claudeHome } from "../home-state-mKZxP4oZ.mjs";
5
- import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-DLXtA5DH.mjs";
5
+ import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-CaqeQFYp.mjs";
6
6
  import { n as writeInitFile, t as initFor } from "../run-Do2JltgU.mjs";
7
- import { Mt as todayUtc, t as handleHook } from "../handle-vK4kMxfE.mjs";
7
+ import { Mt as todayUtc, t as handleHook } from "../handle-CCV0ycdr.mjs";
8
8
  import { delimiter, dirname, join } from "node:path";
9
9
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
10
10
  import { homedir } from "node:os";
@@ -1,2 +1,2 @@
1
- import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-DLXtA5DH.mjs";
1
+ import { n as stagedContent, r as stagedFiles, t as checkStaged } from "../run-CaqeQFYp.mjs";
2
2
  export { checkStaged, stagedContent, stagedFiles };
@@ -147,6 +147,27 @@ const PROJECT_INSTALL = [
147
147
  function matchPatterns(cmd, patterns) {
148
148
  return patterns.some((re) => re.test(cmd));
149
149
  }
150
+ /** Git commands exempt from confirmation when Ralph mode is on (parity git-guard.py RALPH_SAFE). */
151
+ const RALPH_SAFE = [
152
+ "git add",
153
+ "git commit",
154
+ "git checkout -b",
155
+ "git branch --show-current",
156
+ "git status",
157
+ "git diff",
158
+ "git log"
159
+ ];
160
+ /**
161
+ * OPT-IN autonomous "Ralph" mode: OFF unless `RALPH_MODE` is `1`/`true`, read
162
+ * fresh on each call. Only the env var activates it — the Python source also
163
+ * auto-enabled on a `.claude/ralph/prd.json` file or a `feature/*` branch, but
164
+ * those silent activations are dropped here: a mode that removes git/install
165
+ * confirmations must never turn on implicitly (owner: default OFF, env opt-in).
166
+ */
167
+ function isRalphMode() {
168
+ const v = process.env.RALPH_MODE;
169
+ return v === "1" || v === "true";
170
+ }
150
171
  //#endregion
151
172
  //#region src/policy/file-size-scope.ts
152
173
  /**
@@ -302,23 +323,32 @@ function stripHeredoc(cmd) {
302
323
  }
303
324
  return out;
304
325
  }
305
- /** Guards against dangerous Bash commands (critical → block, sensitive → ask). */
326
+ /**
327
+ * Guards against dangerous Bash commands. Parity `security_rules.validate_command`
328
+ * + `security-guard.py`: ACCUMULATE every matched violation, then deny when any
329
+ * critical matched else ask, joining all violation labels in the reason. The
330
+ * generic `rm` ask is exempt when the command targets a trash location (parity
331
+ * `not re.search('trash', cmd)`).
332
+ */
306
333
  function securityGuard(ctx) {
307
334
  if (ctx.tool !== "Bash" || !ctx.command) return null;
308
335
  const cmd = stripHeredoc(ctx.command);
309
- for (const { re, label } of CRITICAL_PATTERNS) if (re.test(cmd)) return {
336
+ const hasTrash = /trash/i.test(cmd);
337
+ const critical = CRITICAL_PATTERNS.filter(({ re }) => re.test(cmd)).map((p) => p.label);
338
+ const ask = ASK_PATTERNS.filter(({ re, label }) => re.test(cmd) && !(hasTrash && label.startsWith("DELETE: 'rm'"))).map((p) => p.label);
339
+ if (critical.length === 0 && ask.length === 0) return null;
340
+ if (critical.length > 0) return {
310
341
  kind: "block",
311
342
  title: "Dangerous command",
312
- reason: `${label}.`,
343
+ reason: `${[...critical, ...ask].join(", ")}.`,
313
344
  actions: ["Remove the destructive command", "Scope the operation to a specific safe path"]
314
345
  };
315
- for (const { re, label } of ASK_PATTERNS) if (re.test(cmd)) return {
346
+ return {
316
347
  kind: "ask",
317
348
  title: "Dangerous command",
318
- reason: `${label}.`,
349
+ reason: `${ask.join(", ")}.`,
319
350
  actions: ["Confirm this command is intended", "Run with least privilege"]
320
351
  };
321
- return null;
322
352
  }
323
353
  //#endregion
324
354
  //#region src/policy/guards/protected-path.ts
@@ -611,7 +641,7 @@ function bashWriteGuard(ctx) {
611
641
  /** TS/JS component files: top-level `interface`/`type Foo`. */
612
642
  const TS_DECL_RE = /^\s*(export\s+)?(interface|type)\s+[A-Z]/m;
613
643
  /** Python view models: class subclassing a schema/protocol base. */
614
- const PY_MODEL_RE = /^\s*class\s+\w+\((BaseModel|TypedDict|Protocol)\)/m;
644
+ const PY_MODEL_RE = /^\s*class\s+\w+\s*\([^)]*\b(?:BaseModel|TypedDict|Protocol)\b/m;
615
645
  /**
616
646
  * PHP controllers: top-level `interface`, `abstract class`, or a concrete
617
647
  * `class …Interface/DTO/Request`. Union of the TS-only `abstract class` rule
@@ -662,16 +692,23 @@ function interfaceSeparationGuard(ctx) {
662
692
  }
663
693
  //#endregion
664
694
  //#region src/policy/guards/install.ts
665
- /** Asks for confirmation before a dependency or system package install. */
695
+ /**
696
+ * Asks for confirmation before a dependency or system package install. In Ralph
697
+ * mode (opt-in `RALPH_MODE`) a PROJECT install is auto-approved for autonomous
698
+ * runs (parity install-guard.py:52), but a SYSTEM install always asks.
699
+ */
666
700
  function installGuard(ctx) {
667
701
  if (ctx.tool !== "Bash" || !ctx.command) return null;
668
- if (matchPatterns(ctx.command, PROJECT_INSTALL) || matchPatterns(ctx.command, SYSTEM_INSTALL)) return {
702
+ const isSystem = matchPatterns(ctx.command, SYSTEM_INSTALL);
703
+ const isProject = matchPatterns(ctx.command, PROJECT_INSTALL);
704
+ if (!isSystem && !isProject) return null;
705
+ if (!isSystem && isProject && isRalphMode()) return null;
706
+ return {
669
707
  kind: "ask",
670
708
  title: "Dependency install",
671
709
  reason: `This command installs packages: ${ctx.command.trim()}`,
672
710
  actions: ["Confirm this install is intended"]
673
711
  };
674
- return null;
675
712
  }
676
713
  //#endregion
677
714
  //#region src/policy/guards/index.ts
@@ -730,7 +767,9 @@ function evaluate(ctx) {
730
767
  message: guard.reason,
731
768
  prompt: guard
732
769
  };
733
- if (ctx.command && matchPatterns(ctx.command, GIT_BLOCKED)) {
770
+ const cmd = ctx.command;
771
+ const ralphSafe = !!cmd && isRalphMode() && RALPH_SAFE.some((s) => cmd.startsWith(s));
772
+ if (!ralphSafe && ctx.command && matchPatterns(ctx.command, GIT_BLOCKED)) {
734
773
  const reason = `Destructive git command: ${ctx.command}`;
735
774
  return {
736
775
  decision: "deny",
@@ -743,7 +782,7 @@ function evaluate(ctx) {
743
782
  }
744
783
  };
745
784
  }
746
- if (ctx.command && matchPatterns(ctx.command, GIT_ASK)) return {
785
+ if (!ralphSafe && ctx.command && matchPatterns(ctx.command, GIT_ASK)) return {
747
786
  decision: "deny",
748
787
  message: `Git operation requires confirmation: ${ctx.command}`,
749
788
  prompt: {
@@ -781,4 +820,4 @@ function evaluate(ctx) {
781
820
  };
782
821
  }
783
822
  //#endregion
784
- export { PROJECT_INSTALL as A, PROTECTED_GIT_RE as C, securityGuard as D, CRITICAL_PATTERNS as E, countFrameworkCodeLines as F, countLines as I, evaluateFileSize as L, matchPatterns as M, PLUGINS_DIR as N, GIT_ASK as O, SOLID_REF as P, PROTECTED_FRAGMENTS as S, ASK_PATTERNS as T, CODE_MUTATORS as _, registerGuard as a, SAFE_PREFIXES as b, GO_DECL_RE as c, PY_MODEL_RE as d, SWIFT_PROTO_RE as f, ASK_WRITERS as g, bashWriteGuard as h, clearUserGuards as i, SYSTEM_INSTALL as j, GIT_BLOCKED as k, JAVA_DECL_RE as l, interfaceSeparationGuard as m, FAIL_CLOSED as n, runGuards as o, TS_DECL_RE as p, GUARDS as r, installGuard as s, evaluate as t, PHP_DECL_RE as u, CODE_REDIRECT as v, protectedPathGuard as w, SESSION_STATE_FRAGMENT as x, FILE_REDIRECT as y };
823
+ export { PROJECT_INSTALL as A, PROTECTED_GIT_RE as C, securityGuard as D, CRITICAL_PATTERNS as E, PLUGINS_DIR as F, SOLID_REF as I, countFrameworkCodeLines as L, SYSTEM_INSTALL as M, isRalphMode as N, GIT_ASK as O, matchPatterns as P, countLines as R, PROTECTED_FRAGMENTS as S, ASK_PATTERNS as T, CODE_MUTATORS as _, registerGuard as a, SAFE_PREFIXES as b, GO_DECL_RE as c, PY_MODEL_RE as d, SWIFT_PROTO_RE as f, ASK_WRITERS as g, bashWriteGuard as h, clearUserGuards as i, RALPH_SAFE as j, GIT_BLOCKED as k, JAVA_DECL_RE as l, interfaceSeparationGuard as m, FAIL_CLOSED as n, runGuards as o, TS_DECL_RE as p, GUARDS as r, installGuard as s, evaluate as t, PHP_DECL_RE as u, CODE_REDIRECT as v, protectedPathGuard as w, SESSION_STATE_FRAGMENT as x, FILE_REDIRECT as y, evaluateFileSize as z };
@@ -1,8 +1,8 @@
1
1
  import { a as parseEnvInt, i as splitTarget, r as resolveMaxLines } from "./limits-CHn8AIL1.mjs";
2
2
  import { r as projectLayout } from "./layout-C0jaaCQC.mjs";
3
3
  import { i as walkUpFor, n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./project-root-3kk7gCOp.mjs";
4
- import { A as detectCreationIntent, B as detectProjectType$1, C as findMarketplacePlugins, E as frameworkSolidGate, H as requiredArchSkill, L as detectFramework, N as docConsultedGate, P as evaluateApex, _ as scanPlugin, c as EXCLUDE_DIRS$1, d as buildApexTaskInjection, h as buildClaudeMdContext, k as capVerbosity, l as PROJECT_INDICATORS, n as missingSeoElements, o as parseEnrichment, r as descFromText, s as parseEntry, t as isHtmlLike, w as readPluginMeta, x as skillTriggerGate, y as parseField, z as detectModularArchitecture } from "./validate-CjFtMZz0.mjs";
5
- import { F as countFrameworkCodeLines, I as countLines, N as PLUGINS_DIR, n as FAIL_CLOSED, t as evaluate } from "./evaluate-d7Pp8XJH.mjs";
4
+ import { B as detectFramework, C as resolveSkillPath, D as frameworkSolidGate, G as requiredArchSkill, H as detectModularArchitecture, I as docConsultedGate, L as evaluateApex, M as capVerbosity, N as detectCreationIntent, O as isExcludedJsPath, S as usesTailwindUtilities, T as readPluginMeta, U as detectProjectType$1, _ as scanPlugin, c as EXCLUDE_DIRS$1, d as buildApexTaskInjection, h as buildClaudeMdContext, k as isExcludedSwiftPath, l as PROJECT_INDICATORS, n as missingSeoElements, o as parseEnrichment, r as descFromText, s as parseEntry, t as isHtmlLike, w as findMarketplacePlugins, x as skillTriggerGate, y as parseField } from "./validate-ebDjIyOa.mjs";
5
+ import { F as PLUGINS_DIR, L as countFrameworkCodeLines, R as countLines, n as FAIL_CLOSED, t as evaluate } from "./evaluate-qYC5xClb.mjs";
6
6
  import { a as writeJsonFile, i as readJsonFile, r as hashText, t as atomicWrite } from "./json-io-DisYd2fb.mjs";
7
7
  import { a as sanitizeSessionId, c as sessionsDir, i as loadSessionState, n as fuseHarnessHome, o as saveSessionState, r as fusengineCache, t as claudeHome } from "./home-state-mKZxP4oZ.mjs";
8
8
  import { r as isDocConsulted } from "./doc-helpers-CWZegVdR.mjs";
@@ -10,8 +10,8 @@ import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
10
10
  import { a as nowStamp, l as throttleMs, n as readRoots, o as readState, s as setStateField, t as addRoot } from "./registry-CymilZiZ.mjs";
11
11
  import { d as loadIndex, i as cacheLookupMeta, n as webfetchCacheWrite, o as cacheLookupSubstringMeta, t as mcpCacheWrite, u as extractText } from "./mcp-store-BkBDmuxN.mjs";
12
12
  import { t as loadRefs } from "./loader-AGz4nK7d.mjs";
13
- import { c as recordDoc, d as trivialCount, i as agentsFresh, l as recordRefRead, n as saveTrack, o as recordAgent, r as verifyTrack, s as recordBrainstormRequired, t as loadTrack, u as recordTrivialEdit } from "./store-CNjFenWe.mjs";
14
- import { d as readText, f as sleep, l as collectFiles, m as writeText, n as contextResponse, p as spawnCapture, r as denyResponse, s as systemMessage, t as blockResponse, u as pathExists } from "./claude-DLh0fHWM.mjs";
13
+ import { c as recordDoc, d as trivialCount, i as agentsFresh, l as recordRefRead, n as saveTrack, o as recordAgent, r as verifyTrack, s as recordBrainstormRequired, t as loadTrack, u as recordTrivialEdit } from "./store-ARx-GQSQ.mjs";
14
+ import { d as readText, f as sleep, l as collectFiles, m as writeText, n as contextResponse, p as spawnCapture, r as denyResponse, s as systemMessage, t as blockResponse, u as pathExists } from "./claude-U1KTaRG4.mjs";
15
15
  import { basename, dirname, extname, join, relative, resolve, sep } from "node:path";
16
16
  import { appendFileSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
17
17
  import { homedir } from "node:os";
@@ -3537,7 +3537,7 @@ const EXEMPT_PATTERNS = [
3537
3537
  /\.claude-plugin\//,
3538
3538
  /CHANGELOG\.md$/,
3539
3539
  /marketplace\.json$/,
3540
- /\/\.claude\/(apex|memory|logs)\//,
3540
+ /\/\.claude\/(apex|memory|logs|fusengine-cache)\//,
3541
3541
  /\/\.fuse-harness\//
3542
3542
  ];
3543
3543
  /**
@@ -3849,11 +3849,12 @@ function nextModular(filePath, content, cwd) {
3849
3849
  }
3850
3850
  /** Laravel FuseCore architecture: `app/` domain ban + module.json + cross-module `use` rules. */
3851
3851
  function fusecore(filePath, content, cwd) {
3852
- for (const b of PHP_BLOCKED_IN_APP) if (filePath.includes(b)) return block$1(`BLOCKED: FuseCore domain code in '${b}' must move to FuseCore/{Module}/App/.`);
3852
+ for (const b of PHP_BLOCKED_IN_APP) if (filePath.includes(b)) return block$1(`BLOCKED: FuseCore project. Code in '${b.replace(/^\/|\/$/g, "")}' FORBIDDEN. Move to '${b.replaceAll("/app/", "/FuseCore/{Module}/App/").replace(/^\/|\/$/g, "")}'.`);
3853
3853
  const mod = filePath.match(/\/FuseCore\/([A-Za-z]+)\//);
3854
3854
  if (!mod) return null;
3855
3855
  const name = mod[1] ?? "";
3856
- if (!existsSync(join(cwd, "FuseCore", name, "module.json"))) return block$1(`BLOCKED: FuseCore module '${name}' is missing module.json — create it first.`);
3856
+ const mj = join(cwd, "FuseCore", name, "module.json");
3857
+ if (!existsSync(mj)) return block$1(`BLOCKED: Module '${name}' missing module.json. Create ${mj} first.`);
3857
3858
  for (const m of content.matchAll(/use\s+FuseCore\\(\w+)\\/g)) {
3858
3859
  const imported = m[1] ?? "";
3859
3860
  if (name === "Core") {
@@ -3873,6 +3874,19 @@ function modularGate(tool, filePath, content, cwd) {
3873
3874
  }
3874
3875
  //#endregion
3875
3876
  //#region src/runtime/framework-skill-gate.ts
3877
+ /** PHP paths the Laravel skill check skips — broader than the SOLID vendor-only exclude (parity check-laravel-skill.py `/(vendor|storage|bootstrap/cache)/`). */
3878
+ const PHP_SKILL_EXCLUDE_RE = /\/(vendor|storage|bootstrap\/cache)\//;
3879
+ /**
3880
+ * Whether the sub-skill gate should skip this path — parity with the early return
3881
+ * in check-*-skill.py (build/vendor artifacts never require a sub-skill).
3882
+ * @param framework - the detected framework ("laravel" | "swift" | JS otherwise).
3883
+ * @param filePath - the file being written.
3884
+ */
3885
+ function skillGateExcluded(framework, filePath) {
3886
+ if (framework === "laravel") return PHP_SKILL_EXCLUDE_RE.test(filePath);
3887
+ if (framework === "swift") return isExcludedSwiftPath(filePath);
3888
+ return isExcludedJsPath(filePath);
3889
+ }
3876
3890
  /**
3877
3891
  * Effective line count for the SOLID size check. On an Edit, `content` is only
3878
3892
  * the `new_string` snippet, so for Next.js — mirroring the base file-size guard
@@ -3912,6 +3926,7 @@ function frameworkSkillGate(input, refsRead, existingCodeLines) {
3912
3926
  const content = input.content ?? "";
3913
3927
  const solid = frameworkSolidGate(input.filePath, content, effectiveLines(input.tool, input.framework, content, existingCodeLines));
3914
3928
  if (solid) return solid;
3929
+ if (skillGateExcluded(input.framework, input.filePath)) return null;
3915
3930
  const forced = input.cwd ? requiredArchSkill(input.cwd) : null;
3916
3931
  return skillTriggerGate(input.framework, content, refsRead, forced, input.cwd, input.filePath);
3917
3932
  }
@@ -3979,6 +3994,122 @@ function shadcnSkillGate(tool, filePath, content, ev) {
3979
3994
  });
3980
3995
  }
3981
3996
  //#endregion
3997
+ //#region src/policy/tailwind-skill-gate.ts
3998
+ /** Vendored/build paths exempt (parity check-tailwind-skill.py `/(node_modules|dist|build)/`). */
3999
+ const TW_EXCLUDE_RE = /(^|\/)(node_modules|dist|build)\//;
4000
+ /** A read reference proving a base Tailwind skill was consulted (Phase 1). */
4001
+ const TW_BASE_SKILL_RE = /skills\/(tailwindcss-v4|tailwindcss-utilities)\//;
4002
+ /**
4003
+ * True when this Write/Edit is a `.tsx`/`.jsx` file carrying Tailwind utility
4004
+ * classes, outside vendored dirs — the trigger condition of Phase 1.
4005
+ * @param tool - the tool name.
4006
+ * @param filePath - the file being written.
4007
+ * @param content - the written content.
4008
+ */
4009
+ function isTailwindWrite(tool, filePath, content) {
4010
+ if (tool !== "Write" && tool !== "Edit") return false;
4011
+ if (TW_EXCLUDE_RE.test(filePath)) return false;
4012
+ return usesTailwindUtilities(filePath, content);
4013
+ }
4014
+ /** True when `tailwindcss-v4` or `tailwindcss-utilities` was read this session (Phase 1 base skill). */
4015
+ function tailwindBaseSkillRead(refsRead) {
4016
+ return refsRead.some((p) => TW_BASE_SKILL_RE.test(p));
4017
+ }
4018
+ /**
4019
+ * Gate a Tailwind-scoped write: block until a base Tailwind skill is read
4020
+ * (parity check-tailwind-skill.py Phase 1). Returns `null` when out of scope
4021
+ * or already satisfied.
4022
+ * @param tool - the tool name.
4023
+ * @param filePath - the file being written.
4024
+ * @param content - the written content.
4025
+ * @param refsRead - in-session read reference paths.
4026
+ */
4027
+ function tailwindSkillGate(tool, filePath, content, refsRead) {
4028
+ if (!isTailwindWrite(tool, filePath, content)) return null;
4029
+ if (tailwindBaseSkillRead(refsRead)) return null;
4030
+ return {
4031
+ kind: "block",
4032
+ title: "Tailwind CSS skill",
4033
+ reason: "BLOCKED: Tailwind skill not consulted. Read tailwindcss-v4/SKILL.md or tailwindcss-utilities/SKILL.md, or use mcp__context7__query-docs (topic: tailwindcss), then retry.",
4034
+ actions: [`Read ${resolveSkillPath("tailwindcss-v4")} or ${resolveSkillPath("tailwindcss-utilities")}`]
4035
+ };
4036
+ }
4037
+ //#endregion
4038
+ //#region src/policy/gemini-mcp-gate.ts
4039
+ /** UI file extensions the gate polices (parity enforce-gemini-mcp.py UI_EXT). */
4040
+ const UI_EXT_RE = /\.(tsx|jsx|vue|svelte)$/;
4041
+ /** Paths exempt from the gate (parity EXEMPT_DIRS). */
4042
+ const GEMINI_EXEMPT_RE = /(node_modules|dist|build|\.next|\.claude)\//;
4043
+ /** A live `mcp__gemini-design__*` call recorded this session proves consultation. */
4044
+ const GEMINI_MCP_SOURCE_RE = /gemini-mcp/i;
4045
+ /** Tailwind utility patterns (parity TAILWIND_PATTERNS). */
4046
+ const TW_PATTERNS = [
4047
+ /\bflex\b/,
4048
+ /\bgrid\b/,
4049
+ /\bp-\d/,
4050
+ /\bpx-\d/,
4051
+ /\bpy-\d/,
4052
+ /\bm-\d/,
4053
+ /\bmx-\d/,
4054
+ /\bmy-\d/,
4055
+ /\bmt-\d/,
4056
+ /\bmb-\d/,
4057
+ /\bbg-\w+/,
4058
+ /\btext-\w+/,
4059
+ /\brounded/,
4060
+ /\bshadow/,
4061
+ /\bborder\b/,
4062
+ /\bgap-\d/,
4063
+ /\bw-\w+/,
4064
+ /\bh-\w+/,
4065
+ /\bjustify-\w+/,
4066
+ /\bitems-\w+/,
4067
+ /\bspace-\w+-\d/
4068
+ ];
4069
+ /** Min distinct Tailwind patterns before the gate fires (parity MIN_TAILWIND_CLASSES). */
4070
+ const MIN_TW = 3;
4071
+ /** Min newlines an Edit's new_string must have to be gated (parity MIN_LINES_FOR_EDIT). */
4072
+ const MIN_LINES_EDIT = 2;
4073
+ /** OPT-IN: off unless `FUSE_ENFORCE_GEMINI_MCP` is `1`/`true`. Read fresh each call (dynamic). */
4074
+ function geminiMcpEnforced() {
4075
+ const v = process.env.FUSE_ENFORCE_GEMINI_MCP;
4076
+ return v === "1" || v === "true";
4077
+ }
4078
+ /** Count distinct Tailwind utility patterns present in `content` (parity count_tailwind_classes). */
4079
+ function countTailwindClasses(content) {
4080
+ return TW_PATTERNS.reduce((n, re) => re.test(content) ? n + 1 : n, 0);
4081
+ }
4082
+ /** True when a `mcp__gemini-design__*` call was recorded this session (parity gemini_was_called). */
4083
+ function geminiMcpConsulted(authorizations, sessionId) {
4084
+ if (!authorizations) return false;
4085
+ return Object.values(authorizations).some((a) => a.doc_sessions?.includes(sessionId) && (a.sources ?? (a.source ? [a.source] : [])).some((s) => GEMINI_MCP_SOURCE_RE.test(s)));
4086
+ }
4087
+ /**
4088
+ * Gate a UI write when `FUSE_ENFORCE_GEMINI_MCP` is on: block hand-written
4089
+ * Tailwind (>= 3 classes) in a `.tsx/.jsx/.vue/.svelte` file unless a Gemini
4090
+ * Design MCP call was made this session. Returns `null` when disabled (default),
4091
+ * out of scope, or already satisfied.
4092
+ * @param tool - the tool name.
4093
+ * @param filePath - the file being written.
4094
+ * @param content - the written content (new_string on Edit).
4095
+ * @param ev - session evidence (authorizations + sessionId).
4096
+ */
4097
+ function geminiMcpGate(tool, filePath, content, ev) {
4098
+ if (!geminiMcpEnforced()) return null;
4099
+ if (tool !== "Write" && tool !== "Edit") return null;
4100
+ if (!filePath || !UI_EXT_RE.test(filePath) || GEMINI_EXEMPT_RE.test(filePath)) return null;
4101
+ if (!content) return null;
4102
+ if (tool === "Edit" && (content.match(/\n/g)?.length ?? 0) < MIN_LINES_EDIT) return null;
4103
+ if (countTailwindClasses(content) < MIN_TW) return null;
4104
+ if (geminiMcpConsulted(ev.authorizations, ev.sessionId)) return null;
4105
+ return {
4106
+ kind: "block",
4107
+ title: "Gemini Design MCP",
4108
+ reason: "BLOCKED: UI code with Tailwind detected but Gemini Design MCP not used. Use mcp__gemini-design__create_frontend, modify_frontend, or snippet_frontend BEFORE writing UI code manually.",
4109
+ actions: ["Call mcp__gemini-design__create_frontend / modify_frontend / snippet_frontend, then retry"]
4110
+ };
4111
+ }
4112
+ //#endregion
3982
4113
  //#region src/freshness/explore-tools.ts
3983
4114
  /** Native exploration tools (parity `apex_constants.EXPLORE_TOOLS`). */
3984
4115
  const EXPLORE_TOOLS = /* @__PURE__ */ new Set(["Glob", "Grep"]);
@@ -4005,9 +4136,17 @@ const EXPLORE_BASH_CMDS = /* @__PURE__ */ new Set([
4005
4136
  "head",
4006
4137
  "tail"
4007
4138
  ]);
4008
- /** Cached MCP result reads count as research (parity `CACHE_READ_RE` + doc-helpers). */
4139
+ /** Legacy Python cache names still credited (parity `CACHE_READ_RE` + doc-helpers). */
4009
4140
  const CACHE_READ_RE = /\/context\/mcp\/(exa-search|exa-code-context|context7)-/;
4010
4141
  /**
4142
+ * Real TS cache stores: `<root>/.harness/cache/<fnv16>.md` (core MCP store,
4143
+ * `projectLayout().cacheDir`) and `~/.fuse-harness/cache/**` (ai-pilot doc
4144
+ * caches, `cache-base.cacheBaseDir`). Segment-matched — not resolved against
4145
+ * `homedir()` — so tilde-prefixed and absolute paths both hit; the `.md`
4146
+ * suffix keeps session-state JSON reads from counting as research.
4147
+ */
4148
+ const TS_CACHE_READ_RE = /\.(?:fuse-)?harness[\\/]cache[\\/].*\.md$/;
4149
+ /**
4011
4150
  * First non-assignment shell token's basename, or "" — mirrors Python
4012
4151
  * `_bash_executable` (skips leading `VAR=value` env prefixes, e.g. `FOO=1 grep`).
4013
4152
  * @param cmd - Raw Bash `command` string.
@@ -4039,7 +4178,7 @@ function classifyExplore(tool, input) {
4039
4178
  };
4040
4179
  if (tool === "Read") {
4041
4180
  const path = String(input?.file_path ?? input?.path ?? "");
4042
- if (path && CACHE_READ_RE.test(path)) return {
4181
+ if (path && (CACHE_READ_RE.test(path) || TS_CACHE_READ_RE.test(path))) return {
4043
4182
  phase: "research-expert",
4044
4183
  cacheHit: true
4045
4184
  };
@@ -4157,10 +4296,12 @@ async function apexScopedGate(input, track, window) {
4157
4296
  authorizations: track.authorizations,
4158
4297
  refs: input.refs,
4159
4298
  refsRead: track.refsRead,
4299
+ refsReadAt: track.refsReadAt,
4300
+ now: input.now,
4160
4301
  agentsFresh: freshnessFor([...REQUIRED_AGENTS]),
4161
4302
  missingAgents: REQUIRED_AGENTS.filter((name) => !freshnessFor([name])),
4162
4303
  windowMs: window,
4163
- brainstormRequired: input.tool === "Edit" ? false : track.brainstormRequired,
4304
+ brainstormRequired: input.tool === "Edit" || input.agentId ? false : track.brainstormRequired,
4164
4305
  brainstormFresh: freshnessFor(["brainstorming"], Number.MAX_SAFE_INTEGER)
4165
4306
  };
4166
4307
  try {
@@ -4221,6 +4362,15 @@ async function gate(input) {
4221
4362
  });
4222
4363
  if (shadcnBlock) return shadcnBlock;
4223
4364
  }
4365
+ if (isTailwindWrite(input.tool, filePath, input.content ?? "")) {
4366
+ const twBlock = tailwindSkillGate(input.tool, filePath, input.content ?? "", track.refsRead);
4367
+ if (twBlock) return twBlock;
4368
+ }
4369
+ const geminiBlock = geminiMcpGate(input.tool, filePath, input.content ?? "", {
4370
+ authorizations: track.authorizations,
4371
+ sessionId: input.sessionId
4372
+ });
4373
+ if (geminiBlock) return geminiBlock;
4224
4374
  if (isApexScoped(input.filePath)) {
4225
4375
  const apex = await apexScopedGate(input, track, window);
4226
4376
  if (apex) return apex;
@@ -4343,7 +4493,7 @@ function mcpPostStore(tool, input, response, dir, now = Date.now()) {
4343
4493
  /** Apply an activity to a session's track and persist it (PostToolUse path). */
4344
4494
  async function recordActivity(file, activity) {
4345
4495
  const track = await loadTrack(file);
4346
- await saveTrack(file, activity.kind === "agent" ? recordAgent(track, activity.name, activity.ts, activity.quality) : activity.kind === "doc" ? recordDoc(track, activity.framework, activity.sessionId, activity.source) : recordRefRead(track, activity.path));
4496
+ await saveTrack(file, activity.kind === "agent" ? recordAgent(track, activity.name, activity.ts, activity.quality) : activity.kind === "doc" ? recordDoc(track, activity.framework, activity.sessionId, activity.source) : recordRefRead(track, activity.path, activity.ts));
4347
4497
  }
4348
4498
  //#endregion
4349
4499
  //#region src/runtime/respond.ts
@@ -4646,25 +4796,6 @@ function htmlCssOnlyGate(filePath) {
4646
4796
  function stateFileGate(filePath) {
4647
4797
  return filePath.includes(".design-state-") ? deny("BLOCKED: .design-state files are READ-ONLY for you. Hooks update them automatically as you progress. Do NOT try to modify them — it will not unblock you. Follow the pipeline: Phase 0→1→2→3→4→5→6 in order.") : null;
4648
4798
  }
4649
- /**
4650
- * Ports browser_helpers.is_exempt: design-system.md is NOT exempt (it must meet
4651
- * the quota); other `.md` files and vendored dirs ARE exempt from the check.
4652
- */
4653
- function screenshotExempt(filePath) {
4654
- if (filePath.endsWith("design-system.md")) return false;
4655
- return filePath.endsWith(".md") || EXEMPT_DIRS.some((d) => filePath.includes(d));
4656
- }
4657
- /**
4658
- * Block ANY non-exempt write (html/css/design-system.md) until the per-mode
4659
- * screenshot quota is met. Ports check-browser-browsing.py's "Browse N sites
4660
- * BEFORE writing" deny for the active design agent.
4661
- */
4662
- function preScreenshotWriteGate(filePath, state) {
4663
- if (screenshotExempt(filePath)) return null;
4664
- const needed = MIN_SCREENSHOTS[state.mode];
4665
- if (state.screenshotsCount < needed) return deny(`BLOCKED: ${state.screenshotsCount}/${needed} fuse-browser screenshots for mode '${state.mode}'. Browse ${needed - state.screenshotsCount} more site(s) BEFORE writing. Read design-inspiration.md, then browser_open + browser_navigate + browser_screenshot.`);
4666
- return null;
4667
- }
4668
4799
  /** Return the requirements missing from a design-system.md (empty = valid). */
4669
4800
  function validateDesignSystem(content) {
4670
4801
  const missing = [];
@@ -4759,7 +4890,7 @@ function designGate(payload, event, cacheDir, cwd) {
4759
4890
  }
4760
4891
  if (event.tool === "Write" || event.tool === "Edit") {
4761
4892
  const fp = event.filePath ?? "";
4762
- const base = stateFileGate(fp) ?? htmlCssOnlyGate(fp) ?? preScreenshotWriteGate(fp, state) ?? designSystemWriteGate(fp, state);
4893
+ const base = stateFileGate(fp) ?? htmlCssOnlyGate(fp) ?? designSystemWriteGate(fp, state);
4763
4894
  if (base) return base;
4764
4895
  if (geminiEnabled() && state.geminiCalls === 0 && /\.(html|css)$/.test(fp)) return {
4765
4896
  kind: "block",
@@ -4775,7 +4906,14 @@ function designGate(payload, event, cacheDir, cwd) {
4775
4906
  if (!geminiEnabled()) return null;
4776
4907
  const block = geminiCreateGate(state);
4777
4908
  if (block) return block;
4778
- const missing = validateDesignSystem(findDesignSystem(cwd));
4909
+ const ds = findDesignSystem(cwd);
4910
+ if (ds === "") return {
4911
+ kind: "block",
4912
+ title: "Design pipeline",
4913
+ reason: "BLOCKED: design-system.md not found. RECOVERY: 1) Read the identity templates 2) Read design-inspiration.md 3) Browse 4 reference sites 4) Write design-system.md, then retry create_frontend.",
4914
+ actions: ["Create design-system.md via the pipeline, then retry create_frontend"]
4915
+ };
4916
+ const missing = validateDesignSystem(ds);
4779
4917
  if (missing.length) return {
4780
4918
  kind: "block",
4781
4919
  title: "Design pipeline",
@@ -4819,13 +4957,10 @@ async function handlePre(ctx) {
4819
4957
  stdout: securityAdvisory(event.tool, event.filePath ?? "", opts.now),
4820
4958
  exit: 0
4821
4959
  };
4822
- if (opts.scope === "solid" && event.filePath) {
4823
- const solidDeny = validateSolidGate(event.tool, event.filePath, event.content ?? "");
4824
- if (solidDeny) return {
4825
- stdout: solidDeny,
4826
- exit: 0
4827
- };
4828
- }
4960
+ if (opts.scope === "solid") return {
4961
+ stdout: validateSolidGate(event.tool, event.filePath ?? "", event.content ?? ""),
4962
+ exit: 0
4963
+ };
4829
4964
  if (event.tool === "Task") {
4830
4965
  const taskCtx = taskContext(opts.cwd);
4831
4966
  if (taskCtx) return {
@@ -4844,6 +4979,7 @@ async function handlePre(ctx) {
4844
4979
  refs: opts.refsDir ? await loadRefs(opts.refsDir) : void 0,
4845
4980
  isReplaceAll: event.input.replace_all === true,
4846
4981
  agentType: event.agentType,
4982
+ agentId: typeof payload.agent_id === "string" ? payload.agent_id : void 0,
4847
4983
  windowMs: opts.windowMs,
4848
4984
  now: opts.now,
4849
4985
  trackFile: file,
@@ -4900,6 +5036,7 @@ function docSourceOf(tool) {
4900
5036
  if (tool === "WebSearch") return "websearch";
4901
5037
  if (tool === "WebFetch") return "webfetch";
4902
5038
  if (/^mcp__shadcn__/i.test(tool)) return "shadcn-mcp";
5039
+ if (/^mcp__gemini-design__/i.test(tool)) return "gemini-mcp";
4903
5040
  }
4904
5041
  /**
4905
5042
  * Map a live tool-use to the activity to record, or null when nothing is
@@ -4932,7 +5069,8 @@ function activityFor(event) {
4932
5069
  const path = String(event.input?.file_path ?? event.input?.path ?? "");
4933
5070
  if (path.endsWith(".md")) out.push({
4934
5071
  kind: "ref",
4935
- path
5072
+ path,
5073
+ ts: event.now
4936
5074
  });
4937
5075
  }
4938
5076
  return out;
@@ -113,6 +113,16 @@ declare const SYSTEM_INSTALL: ReadonlyArray<RegExp>;
113
113
  declare const PROJECT_INSTALL: ReadonlyArray<RegExp>;
114
114
  /** True when `cmd` matches any pattern in `patterns`. */
115
115
  declare function matchPatterns(cmd: string, patterns: ReadonlyArray<RegExp>): boolean;
116
+ /** Git commands exempt from confirmation when Ralph mode is on (parity git-guard.py RALPH_SAFE). */
117
+ declare const RALPH_SAFE: ReadonlyArray<string>;
118
+ /**
119
+ * OPT-IN autonomous "Ralph" mode: OFF unless `RALPH_MODE` is `1`/`true`, read
120
+ * fresh on each call. Only the env var activates it — the Python source also
121
+ * auto-enabled on a `.claude/ralph/prd.json` file or a `feature/*` branch, but
122
+ * those silent activations are dropped here: a mode that removes git/install
123
+ * confirmations must never turn on implicitly (owner: default OFF, env opt-in).
124
+ */
125
+ declare function isRalphMode(): boolean;
116
126
  //#endregion
117
127
  //#region src/policy/interfaces/types.d.ts
118
128
  /** Harness-agnostic input to {@link evaluate}. */
@@ -146,7 +156,7 @@ interface PolicyResult {
146
156
  declare function evaluate(ctx: PolicyContext): PolicyResult;
147
157
  //#endregion
148
158
  //#region src/policy/apex-gates.d.ts
149
- /** Gate: the routed SOLID references for this edit must have been read. */
159
+ /** Gate: the routed SOLID references for this edit must have been read within the TTL. */
150
160
  declare const solidReadGate: ApexGate;
151
161
  /** Gate: the required prior agents (explore + research) must have run within the window. */
152
162
  declare const freshnessGate: ApexGate;
@@ -168,11 +178,22 @@ interface ApexContext {
168
178
  refs?: RefMeta[];
169
179
  /** Absolute paths of SOLID refs already read this session. */
170
180
  refsRead?: string[];
181
+ /**
182
+ * Epoch-ms read timestamp per `refsRead` path (parity track-solid-reads.py
183
+ * `solid_reads[].timestamp`). PARITY: the TTL applies ONLY to solidReadGate —
184
+ * Python TTL-izes SOLID reads exclusively (require-solid-read.py); the
185
+ * skill-trigger/design/shadcn gates stay session-scoped (no TTL). A path in
186
+ * `refsRead` with no stamp here (tracks recorded before this field existed)
187
+ * counts as read — backward compat.
188
+ */
189
+ refsReadAt?: Record<string, number>;
190
+ /** Current epoch ms for the SOLID-read TTL check; absent → reads never expire. */
191
+ now?: number;
171
192
  /** Whether the required prior agents (explore + research) ran within the freshness window. */
172
193
  agentsFresh?: boolean;
173
194
  /** Names of REQUIRED_AGENTS that have NOT run fresh (subset), for a precise freshnessGate message. Absent → generic wording. */
174
195
  missingAgents?: string[];
175
- /** Freshness window in ms, used only to label the block message with its TTL (e.g. "2min"). */
196
+ /** Freshness window in ms: labels the block messages' TTL (e.g. "2min") and bounds the SOLID-read TTL in solidReadGate. */
176
197
  windowMs?: number;
177
198
  /** Whether brainstorming is required for this edit (creation intent on a new file). */
178
199
  brainstormRequired?: boolean;
@@ -214,7 +235,13 @@ interface LabeledPattern {
214
235
  declare const CRITICAL_PATTERNS: LabeledPattern[];
215
236
  /** Patterns that warrant explicit confirmation before running — parity `security_rules.py`'s ask-level violation names. */
216
237
  declare const ASK_PATTERNS: LabeledPattern[];
217
- /** Guards against dangerous Bash commands (critical → block, sensitive → ask). */
238
+ /**
239
+ * Guards against dangerous Bash commands. Parity `security_rules.validate_command`
240
+ * + `security-guard.py`: ACCUMULATE every matched violation, then deny when any
241
+ * critical matched else ask, joining all violation labels in the reason. The
242
+ * generic `rm` ask is exempt when the command targets a trash location (parity
243
+ * `not re.search('trash', cmd)`).
244
+ */
218
245
  declare function securityGuard(ctx: GuardContext): Prompt | null;
219
246
  //#endregion
220
247
  //#region src/policy/guards/protected-path.d.ts
@@ -323,7 +350,11 @@ declare const JAVA_DECL_RE: RegExp;
323
350
  declare function interfaceSeparationGuard(ctx: GuardContext): Prompt | null;
324
351
  //#endregion
325
352
  //#region src/policy/guards/install.d.ts
326
- /** Asks for confirmation before a dependency or system package install. */
353
+ /**
354
+ * Asks for confirmation before a dependency or system package install. In Ralph
355
+ * mode (opt-in `RALPH_MODE`) a PROJECT install is auto-approved for autonomous
356
+ * runs (parity install-guard.py:52), but a SYSTEM install always asks.
357
+ */
327
358
  declare function installGuard(ctx: GuardContext): Prompt | null;
328
359
  //#endregion
329
360
  //#region src/policy/guards/index.d.ts
@@ -571,4 +602,4 @@ declare function isHtmlLike(path: string): boolean;
571
602
  */
572
603
  declare function missingSeoElements(html: string): string[];
573
604
  //#endregion
574
- export { ASK_PATTERNS as $, FAIL_CLOSED as A, ProjectType as At, SWIFT_PROTO_RE as B, usesTailwindUtilities as C, SOLID_REF as Ct, MAX_TOKENS as D, detectFramework as Dt, MAX_EXA_RESULTS as E, evaluateFileSize as Et, installGuard as F, CODE_MUTATORS as G, interfaceSeparationGuard as H, GO_DECL_RE as I, SAFE_PREFIXES as J, CODE_REDIRECT as K, JAVA_DECL_RE as L, clearUserGuards as M, detectProjectType as Mt, registerGuard as N, isApexCommand as Nt, capVerbosity as O, DEV_KEYWORDS as Ot, runGuards as P, requiredArchSkill as Pt, protectedPathGuard as Q, PHP_DECL_RE as R, skillTriggerGate as S, PLUGINS_DIR as St, frameworkSolidGate as T, countLines as Tt, bashWriteGuard as U, TS_DECL_RE as V, ASK_WRITERS as W, PROTECTED_FRAGMENTS as X, SESSION_STATE_FRAGMENT as Y, PROTECTED_GIT_RE as Z, DEV_VERBS as _, GIT_BLOCKED as _t, firstHeading as a, APEX_GATES as at, detectClaudeMdProjectType as b, matchPatterns as bt, parseEntry as c, brainstormGate as ct, EXCLUDE_DIRS as d, freshnessGate as dt, CRITICAL_PATTERNS as et, PROJECT_INDICATORS as f, solidReadGate as ft, loadApexTaskState as g, GIT_ASK as gt, buildApexTaskInjection as h, PolicyResult as ht, firstComment as i, GuardContext as it, GUARDS as j, detectModularArchitecture as jt, detectCreationIntent as k, ModularArchitecture as kt, parseBodyDesc as l, docConsultedGate as lt, buildApexTaskContext as m, PolicyContext as mt, missingSeoElements as n, securityGuard as nt, TreeEntry as o, ApexContext as ot, ApexTaskState as p, evaluate as pt, FILE_REDIRECT as q, descFromText as r, Guard as rt, parseEnrichment as s, ApexGate as st, isHtmlLike as t, LabeledPattern as tt, parseField as u, evaluateApex as ut, buildApexInstruction as v, PROJECT_INSTALL as vt, SKILL_TRIGGERS as w, countFrameworkCodeLines as wt, detectRequiredSkills as x, FileSizeVerdict as xt, buildClaudeMdContext as y, SYSTEM_INSTALL as yt, PY_MODEL_RE as z };
605
+ export { ASK_PATTERNS as $, FAIL_CLOSED as A, DEV_KEYWORDS as At, SWIFT_PROTO_RE as B, usesTailwindUtilities as C, FileSizeVerdict as Ct, MAX_TOKENS as D, countLines as Dt, MAX_EXA_RESULTS as E, countFrameworkCodeLines as Et, installGuard as F, isApexCommand as Ft, CODE_MUTATORS as G, interfaceSeparationGuard as H, GO_DECL_RE as I, requiredArchSkill as It, SAFE_PREFIXES as J, CODE_REDIRECT as K, JAVA_DECL_RE as L, clearUserGuards as M, ProjectType as Mt, registerGuard as N, detectModularArchitecture as Nt, capVerbosity as O, evaluateFileSize as Ot, runGuards as P, detectProjectType as Pt, protectedPathGuard as Q, PHP_DECL_RE as R, skillTriggerGate as S, matchPatterns as St, frameworkSolidGate as T, SOLID_REF as Tt, bashWriteGuard as U, TS_DECL_RE as V, ASK_WRITERS as W, PROTECTED_FRAGMENTS as X, SESSION_STATE_FRAGMENT as Y, PROTECTED_GIT_RE as Z, DEV_VERBS as _, GIT_BLOCKED as _t, firstHeading as a, APEX_GATES as at, detectClaudeMdProjectType as b, SYSTEM_INSTALL as bt, parseEntry as c, brainstormGate as ct, EXCLUDE_DIRS as d, freshnessGate as dt, CRITICAL_PATTERNS as et, PROJECT_INDICATORS as f, solidReadGate as ft, loadApexTaskState as g, GIT_ASK as gt, buildApexTaskInjection as h, PolicyResult as ht, firstComment as i, GuardContext as it, GUARDS as j, ModularArchitecture as jt, detectCreationIntent as k, detectFramework as kt, parseBodyDesc as l, docConsultedGate as lt, buildApexTaskContext as m, PolicyContext as mt, missingSeoElements as n, securityGuard as nt, TreeEntry as o, ApexContext as ot, ApexTaskState as p, evaluate as pt, FILE_REDIRECT as q, descFromText as r, Guard as rt, parseEnrichment as s, ApexGate as st, isHtmlLike as t, LabeledPattern as tt, parseField as u, evaluateApex as ut, buildApexInstruction as v, PROJECT_INSTALL as vt, SKILL_TRIGGERS as w, PLUGINS_DIR as wt, detectRequiredSkills as x, isRalphMode as xt, buildClaudeMdContext as y, RALPH_SAFE as yt, PY_MODEL_RE as z };
package/dist/index.d.mts CHANGED
@@ -5,10 +5,9 @@ import { a as HarnessInfo, i as HarnessId, n as detectMode, o as HarnessMode, r
5
5
  import { a as isDocConsulted, i as formatDocSatisfactionStatus, n as DocSatisfactionStatus, o as resolveSessions, r as formatDocDeny, t as AuthEntry } from "./doc-helpers-BNfYWvYv.mjs";
6
6
  import { t as incrementTrivialEditCounter } from "./index-BOBXQ91y.mjs";
7
7
  import { a as compactJson, i as walkUpFor, n as projectRoot, r as projectRootOrNull, t as isCodeFile } from "./index-BEMumjOw.mjs";
8
- import { $ as ASK_PATTERNS, A as FAIL_CLOSED, At as ProjectType, B as SWIFT_PROTO_RE, C as usesTailwindUtilities, Ct as SOLID_REF, D as MAX_TOKENS, Dt as detectFramework, E as MAX_EXA_RESULTS, Et as evaluateFileSize, F as installGuard, G as CODE_MUTATORS, H as interfaceSeparationGuard, I as GO_DECL_RE, J as SAFE_PREFIXES, K as CODE_REDIRECT, L as JAVA_DECL_RE, M as clearUserGuards, Mt as detectProjectType, N as registerGuard, Nt as isApexCommand, O as capVerbosity, Ot as DEV_KEYWORDS, P as runGuards, Pt as requiredArchSkill, Q as protectedPathGuard, R as PHP_DECL_RE, S as skillTriggerGate, St as PLUGINS_DIR, T as frameworkSolidGate, Tt as countLines, U as bashWriteGuard, V as TS_DECL_RE, W as ASK_WRITERS, X as PROTECTED_FRAGMENTS, Y as SESSION_STATE_FRAGMENT, Z as PROTECTED_GIT_RE, _ as DEV_VERBS, _t as GIT_BLOCKED, a as firstHeading, at as APEX_GATES, b as detectClaudeMdProjectType, bt as matchPatterns, c as parseEntry, ct as brainstormGate, d as EXCLUDE_DIRS, dt as freshnessGate, et as CRITICAL_PATTERNS, f as PROJECT_INDICATORS, ft as solidReadGate, g as loadApexTaskState, gt as GIT_ASK, h as buildApexTaskInjection, ht as PolicyResult, i as firstComment, it as GuardContext, j as GUARDS, jt as detectModularArchitecture, k as detectCreationIntent, kt as ModularArchitecture, l as parseBodyDesc, lt as docConsultedGate, m as buildApexTaskContext, mt as PolicyContext, n as missingSeoElements, nt as securityGuard, o as TreeEntry, ot as ApexContext, p as ApexTaskState, pt as evaluate, q as FILE_REDIRECT, r as descFromText, rt as Guard, s as parseEnrichment, st as ApexGate, t as isHtmlLike, tt as LabeledPattern, u as parseField, ut as evaluateApex, v as buildApexInstruction, vt as PROJECT_INSTALL, w as SKILL_TRIGGERS, wt as countFrameworkCodeLines, x as detectRequiredSkills, xt as FileSizeVerdict, y as buildClaudeMdContext, yt as SYSTEM_INSTALL, z as PY_MODEL_RE } from "./index-CVhw7eA0.mjs";
8
+ import { $ as ASK_PATTERNS, A as FAIL_CLOSED, At as DEV_KEYWORDS, B as SWIFT_PROTO_RE, C as usesTailwindUtilities, Ct as FileSizeVerdict, D as MAX_TOKENS, Dt as countLines, E as MAX_EXA_RESULTS, Et as countFrameworkCodeLines, F as installGuard, Ft as isApexCommand, G as CODE_MUTATORS, H as interfaceSeparationGuard, I as GO_DECL_RE, It as requiredArchSkill, J as SAFE_PREFIXES, K as CODE_REDIRECT, L as JAVA_DECL_RE, M as clearUserGuards, Mt as ProjectType, N as registerGuard, Nt as detectModularArchitecture, O as capVerbosity, Ot as evaluateFileSize, P as runGuards, Pt as detectProjectType, Q as protectedPathGuard, R as PHP_DECL_RE, S as skillTriggerGate, St as matchPatterns, T as frameworkSolidGate, Tt as SOLID_REF, U as bashWriteGuard, V as TS_DECL_RE, W as ASK_WRITERS, X as PROTECTED_FRAGMENTS, Y as SESSION_STATE_FRAGMENT, Z as PROTECTED_GIT_RE, _ as DEV_VERBS, _t as GIT_BLOCKED, a as firstHeading, at as APEX_GATES, b as detectClaudeMdProjectType, bt as SYSTEM_INSTALL, c as parseEntry, ct as brainstormGate, d as EXCLUDE_DIRS, dt as freshnessGate, et as CRITICAL_PATTERNS, f as PROJECT_INDICATORS, ft as solidReadGate, g as loadApexTaskState, gt as GIT_ASK, h as buildApexTaskInjection, ht as PolicyResult, i as firstComment, it as GuardContext, j as GUARDS, jt as ModularArchitecture, k as detectCreationIntent, kt as detectFramework, l as parseBodyDesc, lt as docConsultedGate, m as buildApexTaskContext, mt as PolicyContext, n as missingSeoElements, nt as securityGuard, o as TreeEntry, ot as ApexContext, p as ApexTaskState, pt as evaluate, q as FILE_REDIRECT, r as descFromText, rt as Guard, s as parseEnrichment, st as ApexGate, t as isHtmlLike, tt as LabeledPattern, u as parseField, ut as evaluateApex, v as buildApexInstruction, vt as PROJECT_INSTALL, w as SKILL_TRIGGERS, wt as PLUGINS_DIR, x as detectRequiredSkills, xt as isRalphMode, y as buildClaudeMdContext, yt as RALPH_SAFE, z as PY_MODEL_RE } from "./index-BqfOFKm7.mjs";
9
9
  import { n as RouteResult, r as ScoredRef, t as RefMeta } from "./types-CY5qT2X1.mjs";
10
10
  import { a as ReminderState, c as readState, d as throttleMs, i as registryFile, l as setStateField, n as addRoot, o as lessonsFileFor, r as readRoots, s as nowStamp, t as ensureMemoryGitignore, u as stateFileFor } from "./index-DLYhervv.mjs";
11
11
  import { a as globToRe, i as scoreReferences, n as toRefMeta, o as parseFrontmatter, r as routeReferences, t as loadRefs } from "./index-mmRF3KNp.mjs";
12
- import { a as taskStart, c as ensureStateDir, d as stateFilePath, f as acquireLock, i as taskCreate, l as loadState, n as ApexTaskFile, o as ApexState, r as taskComplete, s as apexStateDir, t as ApexTask, u as saveState } from "./index-BA-SqNR7.mjs";
13
12
  import { _ as TIME_INTERVALS, a as formatCost, c as formatTokens, d as colors, f as progressiveColor, g as PROGRESS_CHARS, h as PROGRESS_BAR_DEFAULTS, i as formatBasename, l as ColorFn, m as GRADIENT_BLOCKS, n as generateGradientBar, o as formatPath, p as COLOR_THRESHOLDS, r as generateProgressBar, s as formatTimeLeft, t as ProgressBarOptions, u as Palette } from "./index-BWK8slRi.mjs";
14
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexState, ApexTask, ApexTaskFile, ApexTaskState, AuthEntry, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, CacheHit, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DEV_VERBS, DocSatisfactionStatus, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, Guard, GuardContext, HOME_DIR, type HarnessId, type HarnessInfo, type HarnessMode, type HarnessVia, IndexSummary, JAVA_DECL_RE, LabeledPattern, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, ModularArchitecture, PHP_DECL_RE, PLUGINS_DIR, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, Palette, type PolicyContext, type PolicyResult, ProgressBarOptions, ProjectLayout, ProjectType, Prompt, PromptKind, RefMeta, ReminderState, RouteResult, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, TreeEntry, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, cacheLookup, cacheLookupMeta, cacheLookupSubstring, cacheLookupSubstringMeta, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectHarness, detectMode, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, ensureMemoryGitignore, ensureStateDir, envCandidates, evaluate, evaluateApex, evaluateFileSize, extractText, firstComment, firstHeading, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, frameworkSolidGate, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, isHtmlLike, jaccardSimilar, lessonsFileFor, loadApexTaskState, loadDotenv, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, mcpCacheWrite, missingSeoElements, modeFor, nowStamp, parseBodyDesc, parseEnrichment, parseEntry, parseEnvFile, parseEnvInt, parseField, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, requiredArchSkill, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, skillTriggerGate, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel, usesTailwindUtilities, walkUpFor, webfetchCacheWrite };
13
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexTaskState, AuthEntry, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, CacheHit, ColorFn, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DEV_VERBS, DocSatisfactionStatus, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, Guard, GuardContext, HOME_DIR, type HarnessId, type HarnessInfo, type HarnessMode, type HarnessVia, IndexSummary, JAVA_DECL_RE, LabeledPattern, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, ModularArchitecture, PHP_DECL_RE, PLUGINS_DIR, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, Palette, type PolicyContext, type PolicyResult, ProgressBarOptions, ProjectLayout, ProjectType, Prompt, PromptKind, RALPH_SAFE, RefMeta, ReminderState, RouteResult, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, ScoredRef, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, TreeEntry, addRoot, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, cacheLookup, cacheLookupMeta, cacheLookupSubstring, cacheLookupSubstringMeta, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectHarness, detectMode, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, ensureMemoryGitignore, envCandidates, evaluate, evaluateApex, evaluateFileSize, extractText, firstComment, firstHeading, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, frameworkSolidGate, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, isHtmlLike, isRalphMode, jaccardSimilar, lessonsFileFor, loadApexTaskState, loadDotenv, loadIndex, loadRefs, matchPatterns, mcpCacheKey, mcpCacheWrite, missingSeoElements, modeFor, nowStamp, parseBodyDesc, parseEnrichment, parseEntry, parseEnvFile, parseEnvInt, parseField, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, requiredArchSkill, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, scoreReferences, securityGuard, setStateField, skillTriggerGate, solidReadGate, splitTarget, stateFileFor, summarizeIndex, throttleMs, toRefMeta, ttlLabel, usesTailwindUtilities, walkUpFor, webfetchCacheWrite };
package/dist/index.mjs CHANGED
@@ -4,8 +4,8 @@ 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-C8Nxxyn_.mjs";
7
- import { A as detectCreationIntent, B as detectProjectType, D as MAX_EXA_RESULTS, E as frameworkSolidGate, F as freshnessGate, H as requiredArchSkill, I as solidReadGate, L as detectFramework, M as brainstormGate, N as docConsultedGate, O as MAX_TOKENS, P as evaluateApex, R as DEV_KEYWORDS, S as usesTailwindUtilities, T as SKILL_TRIGGERS, V as isApexCommand, a as firstHeading, b as detectRequiredSkills, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as detectClaudeMdProjectType, h as buildClaudeMdContext, i as firstComment, j as APEX_GATES, k as capVerbosity, l as PROJECT_INDICATORS, m as buildApexInstruction, n as missingSeoElements, o as parseEnrichment, p as DEV_VERBS, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, v as parseBodyDesc, x as skillTriggerGate, y as parseField, z as detectModularArchitecture } from "./validate-CjFtMZz0.mjs";
8
- import { A as PROJECT_INSTALL, C as PROTECTED_GIT_RE, D as securityGuard, E as CRITICAL_PATTERNS, F as countFrameworkCodeLines, I as countLines, L as evaluateFileSize, M as matchPatterns, N as PLUGINS_DIR, O as GIT_ASK, P as SOLID_REF, S as PROTECTED_FRAGMENTS, T as ASK_PATTERNS, _ as CODE_MUTATORS, a as registerGuard, b as SAFE_PREFIXES, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as ASK_WRITERS, h as bashWriteGuard, i as clearUserGuards, j as SYSTEM_INSTALL, k as GIT_BLOCKED, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as CODE_REDIRECT, w as protectedPathGuard, x as SESSION_STATE_FRAGMENT, y as FILE_REDIRECT } from "./evaluate-d7Pp8XJH.mjs";
7
+ import { A as MAX_EXA_RESULTS, B as detectFramework, D as frameworkSolidGate, E as SKILL_TRIGGERS, F as brainstormGate, G as requiredArchSkill, H as detectModularArchitecture, I as docConsultedGate, L as evaluateApex, M as capVerbosity, N as detectCreationIntent, P as APEX_GATES, R as freshnessGate, S as usesTailwindUtilities, U as detectProjectType, V as DEV_KEYWORDS, W as isApexCommand, a as firstHeading, b as detectRequiredSkills, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as detectClaudeMdProjectType, h as buildClaudeMdContext, i as firstComment, j as MAX_TOKENS, l as PROJECT_INDICATORS, m as buildApexInstruction, n as missingSeoElements, o as parseEnrichment, p as DEV_VERBS, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, v as parseBodyDesc, x as skillTriggerGate, y as parseField, z as solidReadGate } from "./validate-ebDjIyOa.mjs";
8
+ import { A as PROJECT_INSTALL, C as PROTECTED_GIT_RE, D as securityGuard, E as CRITICAL_PATTERNS, F as PLUGINS_DIR, I as SOLID_REF, L as countFrameworkCodeLines, M as SYSTEM_INSTALL, N as isRalphMode, O as GIT_ASK, P as matchPatterns, R as countLines, S as PROTECTED_FRAGMENTS, T as ASK_PATTERNS, _ as CODE_MUTATORS, a as registerGuard, b as SAFE_PREFIXES, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as ASK_WRITERS, h as bashWriteGuard, i as clearUserGuards, j as RALPH_SAFE, k as GIT_BLOCKED, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as CODE_REDIRECT, w as protectedPathGuard, x as SESSION_STATE_FRAGMENT, y as FILE_REDIRECT, z as evaluateFileSize } from "./evaluate-qYC5xClb.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
11
  import { t as formatPrompt } from "./types-ernB1Dy3.mjs";
@@ -13,6 +13,5 @@ import { a as nowStamp, c as stateFileFor, i as lessonsFileFor, l as throttleMs,
13
13
  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";
14
14
  import { t as incrementTrivialEditCounter } from "./freshness-BV3PQkDB.mjs";
15
15
  import { n as toRefMeta, t as loadRefs } from "./loader-AGz4nK7d.mjs";
16
- import { a as ensureStateDir, c as stateFilePath, i as apexStateDir, l as acquireLock, n as taskCreate, o as loadState, r as taskStart, s as saveState, t as taskComplete } from "./state-9lWvvWk8.mjs";
17
16
  import { a as formatPath, c as colors, d as GRADIENT_BLOCKS, f as PROGRESS_BAR_DEFAULTS, i as formatCost, l as progressiveColor, m as TIME_INTERVALS, n as generateProgressBar, o as formatTimeLeft, p as PROGRESS_CHARS, r as formatBasename, s as formatTokens, t as generateGradientBar, u as COLOR_THRESHOLDS } from "./statusline-D87eUNXl.mjs";
18
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DEV_VERBS, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, HOME_DIR, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PLUGINS_DIR, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, acquireLock, addRoot, apexStateDir, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, cacheLookup, cacheLookupMeta, cacheLookupSubstring, cacheLookupSubstringMeta, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectHarness, detectMode, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, ensureMemoryGitignore, ensureStateDir, envCandidates, evaluate, evaluateApex, evaluateFileSize, extractText, firstComment, firstHeading, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, frameworkSolidGate, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, isHtmlLike, jaccardSimilar, lessonsFileFor, loadApexTaskState, loadDotenv, loadIndex, loadRefs, loadState, matchPatterns, mcpCacheKey, mcpCacheWrite, missingSeoElements, modeFor, nowStamp, parseBodyDesc, parseEnrichment, parseEntry, parseEnvFile, parseEnvInt, parseField, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, requiredArchSkill, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, saveState, scoreReferences, securityGuard, setStateField, skillTriggerGate, solidReadGate, splitTarget, stateFileFor, stateFilePath, summarizeIndex, taskComplete, taskCreate, taskStart, throttleMs, toRefMeta, ttlLabel, usesTailwindUtilities, walkUpFor, webfetchCacheWrite };
17
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, CODE_MUTATORS, CODE_REDIRECT, COLOR_THRESHOLDS, CRITICAL_PATTERNS, DEFAULT_MAX_LINES, DEFAULT_TTL_SEC, DEV_KEYWORDS, DEV_VERBS, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GRADIENT_BLOCKS, GUARDS, HOME_DIR, JAVA_DECL_RE, MAX_EXA_RESULTS, MAX_LINES_ENV_KEY, MAX_TOKENS, PHP_DECL_RE, PLUGINS_DIR, PROGRESS_BAR_DEFAULTS, PROGRESS_CHARS, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, RALPH_SAFE, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, STATE_GITIGNORE, STATE_ROOT, SWIFT_PROTO_RE, SYSTEM_INSTALL, TIME_INTERVALS, TS_DECL_RE, TTL_ENV_KEY, addRoot, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, cacheLookup, cacheLookupMeta, cacheLookupSubstring, cacheLookupSubstringMeta, cachePath, cacheStore, capVerbosity, clearUserGuards, colors, compactJson, compactMarkdown, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectHarness, detectMode, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, ensureMemoryGitignore, envCandidates, evaluate, evaluateApex, evaluateFileSize, extractText, firstComment, firstHeading, formatBasename, formatCost, formatDocDeny, formatDocSatisfactionStatus, formatPath, formatPrompt, formatTimeLeft, formatTokens, frameworkSolidGate, freshnessGate, generateGradientBar, generateProgressBar, globToRe, incrementTrivialEditCounter, installGuard, interfaceSeparationGuard, isApexCommand, isCodeFile, isDocConsulted, isHtmlLike, isRalphMode, jaccardSimilar, lessonsFileFor, loadApexTaskState, loadDotenv, loadIndex, loadRefs, matchPatterns, mcpCacheKey, mcpCacheWrite, missingSeoElements, modeFor, nowStamp, parseBodyDesc, parseEnrichment, parseEntry, parseEnvFile, parseEnvInt, parseField, parseFrontmatter, progressiveColor, projectLayout, projectRoot, projectRootOrNull, protectedPathGuard, queryHash, readRoots, readState, registerGuard, registryFile, requiredArchSkill, resolveMaxLines, resolveSessions, resolveTtlSec, routeReferences, runGuards, scoreReferences, securityGuard, setStateField, skillTriggerGate, solidReadGate, splitTarget, stateFileFor, summarizeIndex, throttleMs, toRefMeta, ttlLabel, usesTailwindUtilities, walkUpFor, webfetchCacheWrite };
@@ -1,2 +1,2 @@
1
- import { $ as ASK_PATTERNS, A as FAIL_CLOSED, At as ProjectType, B as SWIFT_PROTO_RE, C as usesTailwindUtilities, Ct as SOLID_REF, D as MAX_TOKENS, Dt as detectFramework, E as MAX_EXA_RESULTS, Et as evaluateFileSize, F as installGuard, G as CODE_MUTATORS, H as interfaceSeparationGuard, I as GO_DECL_RE, J as SAFE_PREFIXES, K as CODE_REDIRECT, L as JAVA_DECL_RE, M as clearUserGuards, Mt as detectProjectType, N as registerGuard, Nt as isApexCommand, O as capVerbosity, Ot as DEV_KEYWORDS, P as runGuards, Pt as requiredArchSkill, Q as protectedPathGuard, R as PHP_DECL_RE, S as skillTriggerGate, St as PLUGINS_DIR, T as frameworkSolidGate, Tt as countLines, U as bashWriteGuard, V as TS_DECL_RE, W as ASK_WRITERS, X as PROTECTED_FRAGMENTS, Y as SESSION_STATE_FRAGMENT, Z as PROTECTED_GIT_RE, _ as DEV_VERBS, _t as GIT_BLOCKED, a as firstHeading, at as APEX_GATES, b as detectClaudeMdProjectType, bt as matchPatterns, c as parseEntry, ct as brainstormGate, d as EXCLUDE_DIRS, dt as freshnessGate, et as CRITICAL_PATTERNS, f as PROJECT_INDICATORS, ft as solidReadGate, g as loadApexTaskState, gt as GIT_ASK, h as buildApexTaskInjection, ht as PolicyResult, i as firstComment, it as GuardContext, j as GUARDS, jt as detectModularArchitecture, k as detectCreationIntent, kt as ModularArchitecture, l as parseBodyDesc, lt as docConsultedGate, m as buildApexTaskContext, mt as PolicyContext, n as missingSeoElements, nt as securityGuard, o as TreeEntry, ot as ApexContext, p as ApexTaskState, pt as evaluate, q as FILE_REDIRECT, r as descFromText, rt as Guard, s as parseEnrichment, st as ApexGate, t as isHtmlLike, tt as LabeledPattern, u as parseField, ut as evaluateApex, v as buildApexInstruction, vt as PROJECT_INSTALL, w as SKILL_TRIGGERS, wt as countFrameworkCodeLines, x as detectRequiredSkills, xt as FileSizeVerdict, y as buildClaudeMdContext, yt as SYSTEM_INSTALL, z as PY_MODEL_RE } from "../index-CVhw7eA0.mjs";
2
- export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexTaskState, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, DEV_VERBS, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, Guard, GuardContext, JAVA_DECL_RE, LabeledPattern, MAX_EXA_RESULTS, MAX_TOKENS, ModularArchitecture, PHP_DECL_RE, PLUGINS_DIR, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, type PolicyContext, type PolicyResult, ProjectType, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, TreeEntry, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, capVerbosity, clearUserGuards, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, firstComment, firstHeading, frameworkSolidGate, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, isHtmlLike, loadApexTaskState, matchPatterns, missingSeoElements, parseBodyDesc, parseEnrichment, parseEntry, parseField, protectedPathGuard, registerGuard, requiredArchSkill, runGuards, securityGuard, skillTriggerGate, solidReadGate, usesTailwindUtilities };
1
+ import { $ as ASK_PATTERNS, A as FAIL_CLOSED, At as DEV_KEYWORDS, B as SWIFT_PROTO_RE, C as usesTailwindUtilities, Ct as FileSizeVerdict, D as MAX_TOKENS, Dt as countLines, E as MAX_EXA_RESULTS, Et as countFrameworkCodeLines, F as installGuard, Ft as isApexCommand, G as CODE_MUTATORS, H as interfaceSeparationGuard, I as GO_DECL_RE, It as requiredArchSkill, J as SAFE_PREFIXES, K as CODE_REDIRECT, L as JAVA_DECL_RE, M as clearUserGuards, Mt as ProjectType, N as registerGuard, Nt as detectModularArchitecture, O as capVerbosity, Ot as evaluateFileSize, P as runGuards, Pt as detectProjectType, Q as protectedPathGuard, R as PHP_DECL_RE, S as skillTriggerGate, St as matchPatterns, T as frameworkSolidGate, Tt as SOLID_REF, U as bashWriteGuard, V as TS_DECL_RE, W as ASK_WRITERS, X as PROTECTED_FRAGMENTS, Y as SESSION_STATE_FRAGMENT, Z as PROTECTED_GIT_RE, _ as DEV_VERBS, _t as GIT_BLOCKED, a as firstHeading, at as APEX_GATES, b as detectClaudeMdProjectType, bt as SYSTEM_INSTALL, c as parseEntry, ct as brainstormGate, d as EXCLUDE_DIRS, dt as freshnessGate, et as CRITICAL_PATTERNS, f as PROJECT_INDICATORS, ft as solidReadGate, g as loadApexTaskState, gt as GIT_ASK, h as buildApexTaskInjection, ht as PolicyResult, i as firstComment, it as GuardContext, j as GUARDS, jt as ModularArchitecture, k as detectCreationIntent, kt as detectFramework, l as parseBodyDesc, lt as docConsultedGate, m as buildApexTaskContext, mt as PolicyContext, n as missingSeoElements, nt as securityGuard, o as TreeEntry, ot as ApexContext, p as ApexTaskState, pt as evaluate, q as FILE_REDIRECT, r as descFromText, rt as Guard, s as parseEnrichment, st as ApexGate, t as isHtmlLike, tt as LabeledPattern, u as parseField, ut as evaluateApex, v as buildApexInstruction, vt as PROJECT_INSTALL, w as SKILL_TRIGGERS, wt as PLUGINS_DIR, x as detectRequiredSkills, xt as isRalphMode, y as buildClaudeMdContext, yt as RALPH_SAFE, z as PY_MODEL_RE } from "../index-BqfOFKm7.mjs";
2
+ export { APEX_GATES, ASK_PATTERNS, ASK_WRITERS, ApexContext, ApexGate, ApexTaskState, CODE_MUTATORS, CODE_REDIRECT, CRITICAL_PATTERNS, DEV_KEYWORDS, DEV_VERBS, EXCLUDE_DIRS, FAIL_CLOSED, FILE_REDIRECT, FileSizeVerdict, GIT_ASK, GIT_BLOCKED, GO_DECL_RE, GUARDS, Guard, GuardContext, JAVA_DECL_RE, LabeledPattern, MAX_EXA_RESULTS, MAX_TOKENS, ModularArchitecture, PHP_DECL_RE, PLUGINS_DIR, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, type PolicyContext, type PolicyResult, ProjectType, RALPH_SAFE, SAFE_PREFIXES, SESSION_STATE_FRAGMENT, SKILL_TRIGGERS, SOLID_REF, SWIFT_PROTO_RE, SYSTEM_INSTALL, TS_DECL_RE, TreeEntry, bashWriteGuard, brainstormGate, buildApexInstruction, buildApexTaskContext, buildApexTaskInjection, buildClaudeMdContext, capVerbosity, clearUserGuards, countFrameworkCodeLines, countLines, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, firstComment, firstHeading, frameworkSolidGate, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, isHtmlLike, isRalphMode, loadApexTaskState, matchPatterns, missingSeoElements, parseBodyDesc, parseEnrichment, parseEntry, parseField, protectedPathGuard, registerGuard, requiredArchSkill, runGuards, securityGuard, skillTriggerGate, solidReadGate, usesTailwindUtilities };
@@ -1,4 +1,4 @@
1
- import { A as detectCreationIntent, B as detectProjectType, D as MAX_EXA_RESULTS, E as frameworkSolidGate, F as freshnessGate, H as requiredArchSkill, I as solidReadGate, L as detectFramework, M as brainstormGate, N as docConsultedGate, O as MAX_TOKENS, P as evaluateApex, R as DEV_KEYWORDS, S as usesTailwindUtilities, T as SKILL_TRIGGERS, V as isApexCommand, a as firstHeading, b as detectRequiredSkills, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as detectClaudeMdProjectType, h as buildClaudeMdContext, i as firstComment, j as APEX_GATES, k as capVerbosity, l as PROJECT_INDICATORS, m as buildApexInstruction, n as missingSeoElements, o as parseEnrichment, p as DEV_VERBS, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, v as parseBodyDesc, x as skillTriggerGate, y as parseField, z as detectModularArchitecture } from "../validate-CjFtMZz0.mjs";
2
- import { A as PROJECT_INSTALL, C as PROTECTED_GIT_RE, D as securityGuard, E as CRITICAL_PATTERNS, F as countFrameworkCodeLines, I as countLines, L as evaluateFileSize, M as matchPatterns, N as PLUGINS_DIR, O as GIT_ASK, P as SOLID_REF, S as PROTECTED_FRAGMENTS, T as ASK_PATTERNS, _ as CODE_MUTATORS, a as registerGuard, b as SAFE_PREFIXES, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as ASK_WRITERS, h as bashWriteGuard, i as clearUserGuards, j as SYSTEM_INSTALL, k as GIT_BLOCKED, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as CODE_REDIRECT, w as protectedPathGuard, x as SESSION_STATE_FRAGMENT, y as FILE_REDIRECT } from "../evaluate-d7Pp8XJH.mjs";
1
+ import { A as MAX_EXA_RESULTS, B as detectFramework, D as frameworkSolidGate, E as SKILL_TRIGGERS, F as brainstormGate, G as requiredArchSkill, H as detectModularArchitecture, I as docConsultedGate, L as evaluateApex, M as capVerbosity, N as detectCreationIntent, P as APEX_GATES, R as freshnessGate, S as usesTailwindUtilities, U as detectProjectType, V as DEV_KEYWORDS, W as isApexCommand, a as firstHeading, b as detectRequiredSkills, c as EXCLUDE_DIRS, d as buildApexTaskInjection, f as loadApexTaskState, g as detectClaudeMdProjectType, h as buildClaudeMdContext, i as firstComment, j as MAX_TOKENS, l as PROJECT_INDICATORS, m as buildApexInstruction, n as missingSeoElements, o as parseEnrichment, p as DEV_VERBS, r as descFromText, s as parseEntry, t as isHtmlLike, u as buildApexTaskContext, v as parseBodyDesc, x as skillTriggerGate, y as parseField, z as solidReadGate } from "../validate-ebDjIyOa.mjs";
2
+ import { A as PROJECT_INSTALL, C as PROTECTED_GIT_RE, D as securityGuard, E as CRITICAL_PATTERNS, F as PLUGINS_DIR, I as SOLID_REF, L as countFrameworkCodeLines, M as SYSTEM_INSTALL, N as isRalphMode, O as GIT_ASK, P as matchPatterns, R as countLines, S as PROTECTED_FRAGMENTS, T as ASK_PATTERNS, _ as CODE_MUTATORS, a as registerGuard, b as SAFE_PREFIXES, c as GO_DECL_RE, d as PY_MODEL_RE, f as SWIFT_PROTO_RE, g as ASK_WRITERS, h as bashWriteGuard, i as clearUserGuards, j as RALPH_SAFE, k as GIT_BLOCKED, l as JAVA_DECL_RE, m as interfaceSeparationGuard, n as FAIL_CLOSED, o as runGuards, p as TS_DECL_RE, r as GUARDS, s as installGuard, t as evaluate, u as PHP_DECL_RE, v as CODE_REDIRECT, w as protectedPathGuard, x as SESSION_STATE_FRAGMENT, y as FILE_REDIRECT, z as evaluateFileSize } from "../evaluate-qYC5xClb.mjs";
3
3
  import "../policy-la_KkjCS.mjs";
4
- 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, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_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, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, firstComment, firstHeading, frameworkSolidGate, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, isHtmlLike, loadApexTaskState, matchPatterns, missingSeoElements, parseBodyDesc, parseEnrichment, parseEntry, parseField, protectedPathGuard, registerGuard, requiredArchSkill, runGuards, securityGuard, skillTriggerGate, solidReadGate, usesTailwindUtilities };
4
+ 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, PROJECT_INDICATORS, PROJECT_INSTALL, PROTECTED_FRAGMENTS, PROTECTED_GIT_RE, PY_MODEL_RE, RALPH_SAFE, 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, descFromText, detectClaudeMdProjectType, detectCreationIntent, detectFramework, detectModularArchitecture, detectProjectType, detectRequiredSkills, docConsultedGate, evaluate, evaluateApex, evaluateFileSize, firstComment, firstHeading, frameworkSolidGate, freshnessGate, installGuard, interfaceSeparationGuard, isApexCommand, isHtmlLike, isRalphMode, loadApexTaskState, matchPatterns, missingSeoElements, parseBodyDesc, parseEnrichment, parseEntry, parseField, protectedPathGuard, 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-d7Pp8XJH.mjs";
2
+ import { t as evaluate } from "./evaluate-qYC5xClb.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
@@ -1,6 +1,6 @@
1
1
  import { t as Prompt } from "../types-D56jSgD9.mjs";
2
2
  import { t as RefMeta } from "../types-CY5qT2X1.mjs";
3
- import { t as AgentQuality } from "../session-state-D4F_Dub6.mjs";
3
+ import { t as AgentQuality } from "../session-state-V8Jp-KE5.mjs";
4
4
 
5
5
  //#region src/runtime/paths.d.ts
6
6
  /**
@@ -53,6 +53,7 @@ type Activity = {
53
53
  } | {
54
54
  kind: "ref";
55
55
  path: string;
56
+ ts?: number;
56
57
  };
57
58
  /** Apply an activity to a session's track and persist it (PostToolUse path). */
58
59
  declare function recordActivity(file: string, activity: Activity): Promise<void>;
@@ -96,6 +97,8 @@ interface GateInput {
96
97
  windowMs?: number;
97
98
  isReplaceAll?: boolean;
98
99
  agentType?: string;
100
+ /** Claude `agent_id` when the tool-use comes from a subagent (parity require-apex-agents.py:41 — subagents inherit the lead's brainstorm decision). */
101
+ agentId?: string;
99
102
  /** Absolute path to the session transcript (Claude `transcript_path`) for evidence-based freshness. */
100
103
  transcriptPath?: string;
101
104
  }
@@ -1,6 +1,6 @@
1
1
  import { r as projectLayout } from "../layout-C0jaaCQC.mjs";
2
2
  import { a as sanitizeSessionId, c as sessionsDir, i as loadSessionState, n as fuseHarnessHome, o as saveSessionState, r as fusengineCache, s as sessionStatePath, t as claudeHome } from "../home-state-mKZxP4oZ.mjs";
3
- import { $ as saveApexState, A as trackSkillRead, At as securityStateDir, B as writePluginMap, C as seoPostToolUse, Ct as defaultStateDir, D as postTrackingSideEffects, Dt as isoUtc, E as securityAdvisory, Et as normalizeEvent, F as dispatchLessons, G as mergeLines, H as isProject, I as lessonsFileFor, J as listChildren, K as countFiles, L as lessonsStateFileFor, M as dispatchLifecycle, Mt as todayUtc, N as aipilotPostToolUse, O as trackWatchResearch, Ot as loadSecurityState, P as dispatchAipilot, Q as cleanupSession, R as cartoSessionStart, S as postEditContext, St as taskContext, T as dispatchMemory, Tt as trackFile, U as writeTree, V as generateProjectMap, W as loadEnriched, X as trackSessionChanges, Y as postEditTypescript, Z as validateRulesLoaded, _ as preCommitGate, _t as trimLogFile, a as recordActivity, at as validateSolidGate, b as extractSymbols, bt as projectContext, c as MCP_TTL_MS, ct as detectSolidProfile, d as isMcpTool, dt as readRules, et as logToolFailure, f as queryOf, ft as runSessionStartCleanups, g as gate, gt as removeOldFiles, h as TRIVIAL_BUDGET, ht as purgeTtlTree, i as respond, it as validateTailwind, j as trackEnrichment, jt as securityStatePath, k as trackMcpResearch, kt as saveSecurityState, l as WEBFETCH_TTL_MS, lt as solidDetectStart, m as REQUIRED_AGENTS, mt as pruneEmptyDirs, n as activityFor, nt as trackAgentMemory, o as mcpPostStore, ot as checkFileSize, p as DEFAULT_WINDOW_MS, pt as sessionStartCore, q as getFileDesc, r as handlePre, rt as subagentCacheContext, s as mcpPreIntercept, st as countLoc, t as handleHook, tt as validateTeammateOutput, u as cacheQueryOf, ut as injectRules, v as detectDuplication, vt as devContext, w as seoPostToolUseResponse, wt as projectHash, x as lifecycleStdout, xt as promptSubmitContext, y as dryGate, yt as gitContext, z as generateEcosystemMap } from "../handle-vK4kMxfE.mjs";
3
+ import { $ as saveApexState, A as trackSkillRead, At as securityStateDir, B as writePluginMap, C as seoPostToolUse, Ct as defaultStateDir, D as postTrackingSideEffects, Dt as isoUtc, E as securityAdvisory, Et as normalizeEvent, F as dispatchLessons, G as mergeLines, H as isProject, I as lessonsFileFor, J as listChildren, K as countFiles, L as lessonsStateFileFor, M as dispatchLifecycle, Mt as todayUtc, N as aipilotPostToolUse, O as trackWatchResearch, Ot as loadSecurityState, P as dispatchAipilot, Q as cleanupSession, R as cartoSessionStart, S as postEditContext, St as taskContext, T as dispatchMemory, Tt as trackFile, U as writeTree, V as generateProjectMap, W as loadEnriched, X as trackSessionChanges, Y as postEditTypescript, Z as validateRulesLoaded, _ as preCommitGate, _t as trimLogFile, a as recordActivity, at as validateSolidGate, b as extractSymbols, bt as projectContext, c as MCP_TTL_MS, ct as detectSolidProfile, d as isMcpTool, dt as readRules, et as logToolFailure, f as queryOf, ft as runSessionStartCleanups, g as gate, gt as removeOldFiles, h as TRIVIAL_BUDGET, ht as purgeTtlTree, i as respond, it as validateTailwind, j as trackEnrichment, jt as securityStatePath, k as trackMcpResearch, kt as saveSecurityState, l as WEBFETCH_TTL_MS, lt as solidDetectStart, m as REQUIRED_AGENTS, mt as pruneEmptyDirs, n as activityFor, nt as trackAgentMemory, o as mcpPostStore, ot as checkFileSize, p as DEFAULT_WINDOW_MS, pt as sessionStartCore, q as getFileDesc, r as handlePre, rt as subagentCacheContext, s as mcpPreIntercept, st as countLoc, t as handleHook, tt as validateTeammateOutput, u as cacheQueryOf, ut as injectRules, v as detectDuplication, vt as devContext, w as seoPostToolUseResponse, wt as projectHash, x as lifecycleStdout, xt as promptSubmitContext, y as dryGate, yt as gitContext, z as generateEcosystemMap } from "../handle-CCV0ycdr.mjs";
4
4
  //#region src/runtime/storage.ts
5
5
  /**
6
6
  * The project's single state dir (`<root>/.harness`) — neutral + harness-agnostic,
@@ -7,6 +7,15 @@ type AgentQuality = "sufficient" | "insufficient";
7
7
  interface SessionTrack {
8
8
  authorizations: Record<string, AuthEntry>;
9
9
  refsRead: string[];
10
+ /**
11
+ * Epoch-ms timestamp of each reference read, keyed by `refsRead` path (parity
12
+ * track-solid-reads.py `solid_reads[].timestamp`). Optional: tracks persisted
13
+ * before this field existed only carry `refsRead`, and such paths count as
14
+ * read (backward compat). PARITY: only the SOLID-read gate TTL-checks these —
15
+ * Python TTL-izes SOLID reads exclusively (require-solid-read.py); the other
16
+ * refsRead consumers (skill-trigger/shadcn/tailwind/design) stay session-scoped.
17
+ */
18
+ refsReadAt?: Record<string, number>;
10
19
  agents: {
11
20
  name: string;
12
21
  ts: number;
@@ -19,8 +28,15 @@ interface SessionTrack {
19
28
  declare function emptyTrack(): SessionTrack;
20
29
  /** Record a doc consultation (Context7/Exa) for a framework in this session. Immutable. */
21
30
  declare function recordDoc(track: SessionTrack, framework: string, sessionId: string, source: string): SessionTrack;
22
- /** Record that a SOLID reference file was read (deduped). Immutable. */
23
- declare function recordRefRead(track: SessionTrack, path: string): SessionTrack;
31
+ /**
32
+ * Record that a SOLID reference file was read (deduped). Immutable. When `now`
33
+ * (epoch ms — the tool event's own timestamp, never a fresh `Date.now()`) is
34
+ * supplied, the read is stamped in `refsReadAt`, refreshed on re-reads so the
35
+ * LATEST read drives the SOLID TTL (parity track-solid-reads.py, which appends
36
+ * a timestamped entry per read; require-solid-read.py checks the most recent).
37
+ * Callers that omit `now` keep the legacy untimestamped behavior.
38
+ */
39
+ declare function recordRefRead(track: SessionTrack, path: string, now?: number): SessionTrack;
24
40
  /** Record an agent/tool call with a timestamp + optional quality. Immutable. */
25
41
  declare function recordAgent(track: SessionTrack, name: string, ts: number, quality?: AgentQuality): SessionTrack;
26
42
  /** True when ALL of `names` ran within `windowMs` with non-insufficient quality. */
@@ -32,11 +32,27 @@ function recordDoc(track, framework, sessionId, source) {
32
32
  }
33
33
  };
34
34
  }
35
- /** Record that a SOLID reference file was read (deduped). Immutable. */
36
- function recordRefRead(track, path) {
37
- return track.refsRead.includes(path) ? track : {
35
+ /**
36
+ * Record that a SOLID reference file was read (deduped). Immutable. When `now`
37
+ * (epoch ms the tool event's own timestamp, never a fresh `Date.now()`) is
38
+ * supplied, the read is stamped in `refsReadAt`, refreshed on re-reads so the
39
+ * LATEST read drives the SOLID TTL (parity track-solid-reads.py, which appends
40
+ * a timestamped entry per read; require-solid-read.py checks the most recent).
41
+ * Callers that omit `now` keep the legacy untimestamped behavior.
42
+ */
43
+ function recordRefRead(track, path, now) {
44
+ const refsRead = track.refsRead.includes(path) ? track.refsRead : [...track.refsRead, path];
45
+ if (now === void 0) return refsRead === track.refsRead ? track : {
46
+ ...track,
47
+ refsRead
48
+ };
49
+ return {
38
50
  ...track,
39
- refsRead: [...track.refsRead, path]
51
+ refsRead,
52
+ refsReadAt: {
53
+ ...track.refsReadAt,
54
+ [path]: now
55
+ }
40
56
  };
41
57
  }
42
58
  /** Record an agent/tool call with a timestamp + optional quality. Immutable. */
@@ -1,4 +1,4 @@
1
- import { a as recordAgent, c as recordRefRead, i as emptyTrack, l as recordTrivialEdit, n as SessionTrack, o as recordBrainstormRequired, r as agentsFresh, s as recordDoc, t as AgentQuality, u as trivialCount } from "../session-state-D4F_Dub6.mjs";
1
+ import { a as recordAgent, c as recordRefRead, i as emptyTrack, l as recordTrivialEdit, n as SessionTrack, o as recordBrainstormRequired, r as agentsFresh, s as recordDoc, t as AgentQuality, u as trivialCount } from "../session-state-V8Jp-KE5.mjs";
2
2
 
3
3
  //#region src/tracking/store.d.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { a as emptyTrack, c as recordDoc, d as trivialCount, i as agentsFresh, l as recordRefRead, n as saveTrack, o as recordAgent, s as recordBrainstormRequired, t as loadTrack, u as recordTrivialEdit } from "../store-CNjFenWe.mjs";
1
+ import { a as emptyTrack, c as recordDoc, d as trivialCount, i as agentsFresh, l as recordRefRead, n as saveTrack, o as recordAgent, s as recordBrainstormRequired, t as loadTrack, u as recordTrivialEdit } from "../store-ARx-GQSQ.mjs";
2
2
  export { agentsFresh, emptyTrack, loadTrack, recordAgent, recordBrainstormRequired, recordDoc, recordRefRead, recordTrivialEdit, saveTrack, trivialCount };
@@ -1,7 +1,7 @@
1
1
  import { r as resolveMaxLines } from "./limits-CHn8AIL1.mjs";
2
2
  import { c as ttlLabel, t as HOME_DIR } from "./dotenv-B9nM4cuQ.mjs";
3
3
  import { t as detectHarness } from "./harness-C8Nxxyn_.mjs";
4
- import { F as countFrameworkCodeLines, N as PLUGINS_DIR, P as SOLID_REF } from "./evaluate-d7Pp8XJH.mjs";
4
+ import { F as PLUGINS_DIR, I as SOLID_REF, L as countFrameworkCodeLines } from "./evaluate-qYC5xClb.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
7
  import { extname, join } from "node:path";
@@ -95,7 +95,7 @@ function detectProjectType(dir) {
95
95
  */
96
96
  function detectFramework(filePath, content) {
97
97
  if (/\.(tsx?|jsx?|vue|svelte)$/.test(filePath) || /from ['"]react|useState|className=/.test(content)) {
98
- if (/(page|layout|loading|error|route)\.(ts|tsx)$/.test(filePath) || /use client|use server/.test(content)) return "nextjs";
98
+ if (/(page|layout|loading|error|route|middleware)\.(ts|tsx)$/.test(filePath) || /use client|use server|NextRequest|NextResponse|from ['"]next|getServerSideProps|getStaticProps/.test(content)) return "nextjs";
99
99
  return "react";
100
100
  }
101
101
  if (/\.swift$/.test(filePath)) return "swift";
@@ -109,11 +109,26 @@ function detectFramework(filePath, content) {
109
109
  }
110
110
  //#endregion
111
111
  //#region src/policy/apex-gates.ts
112
- /** Gate: the routed SOLID references for this edit must have been read. */
112
+ /**
113
+ * True when the SOLID ref read at `path` still counts. Parity require-solid-read.py
114
+ * `_check_solid_read` (FUSE_ENFORCE_TTL_SEC, default 120s): a SOLID read older than
115
+ * the window has expired and must be redone. PARITY NOTE: the TTL applies ONLY to
116
+ * this gate — Python TTL-izes SOLID reads exclusively; the other refsRead consumers
117
+ * (skillTriggerGate, shadcn/tailwind/design gates) stay session-scoped, so this
118
+ * predicate must never leak into them. Backward compat: a path with no `refsReadAt`
119
+ * stamp (tracks recorded before the field existed) or a context without a clock
120
+ * (`now` absent) counts as read.
121
+ */
122
+ function refReadFresh(ctx, path, windowMs) {
123
+ const at = ctx.refsReadAt?.[path];
124
+ return at === void 0 || ctx.now === void 0 || ctx.now - at < windowMs;
125
+ }
126
+ /** Gate: the routed SOLID references for this edit must have been read within the TTL. */
113
127
  const solidReadGate = (ctx) => {
114
128
  if (!ctx.refs?.length) return null;
115
129
  const routed = routeReferences(ctx.refs, ctx.filePath, ctx.content);
116
- const ttl = ttlLabel(Math.round((ctx.windowMs ?? 120 * 1e3) / 1e3));
130
+ const windowMs = ctx.windowMs ?? 120 * 1e3;
131
+ const ttl = ttlLabel(Math.round(windowMs / 1e3));
117
132
  if (!routed) {
118
133
  const ref = SOLID_REF[ctx.framework] ?? "generic/";
119
134
  return {
@@ -123,7 +138,7 @@ const solidReadGate = (ctx) => {
123
138
  actions: [`Read ${PLUGINS_DIR}/${ref}SKILL.md`]
124
139
  };
125
140
  }
126
- const read = new Set(ctx.refsRead ?? []);
141
+ const read = new Set((ctx.refsRead ?? []).filter((p) => refReadFresh(ctx, p, windowMs)));
127
142
  const missing = !!routed.skillPath && read.has(routed.skillPath) ? [] : routed.required.map((r) => r.meta.filePath).filter((p) => !read.has(p));
128
143
  if (missing.length === 0) return null;
129
144
  const optional = routed.optional.map((r) => r.meta.filePath);
@@ -232,8 +247,8 @@ function capVerbosity(tool, input) {
232
247
  }
233
248
  //#endregion
234
249
  //#region src/policy/framework-solid-exclude.ts
235
- /** Build-output / dependency paths excluded from React/Next.js SOLID gating. */
236
- const JS_EXCLUDE_RE = /(node_modules|dist|build|\.next)/;
250
+ /** Build/dep paths excluded from React/Next.js SOLID gating — segment-anchored (parity `r"/(node_modules|dist|build|\.next)/"`), NOT a bare substring, so `distance.ts`/`rebuild/` stay gated. */
251
+ const JS_EXCLUDE_RE = /(^|\/)(node_modules|dist|build|\.next)(\/|$)/;
237
252
  /** Vendored dependency paths excluded from Laravel/PHP SOLID gating. */
238
253
  const PHP_EXCLUDE_RE = /\/vendor\//;
239
254
  /** Derived/build artifact paths excluded from Swift SOLID gating. */
@@ -945,6 +960,12 @@ function usesTailwindUtilities(filePath, content) {
945
960
  * @returns a `block` Prompt naming the missing sub-skills, or `null` when satisfied.
946
961
  */
947
962
  function skillTriggerGate(framework, content, refsRead, forcedSkill, cwd, filePath) {
963
+ if (forcedSkill === "fusecore" && !refsRead.some((r) => r.includes("skills/fusecore/"))) return {
964
+ kind: "block",
965
+ title: "FuseCore skill not consulted",
966
+ reason: "BLOCKED: FuseCore project detected. Read the FuseCore skill before writing code in FuseCore modules.",
967
+ actions: [`Read ${resolveSkillPath("fusecore")}`]
968
+ };
948
969
  let required = detectRequiredSkills(framework, content);
949
970
  if (framework !== "tailwind" && filePath && usesTailwindUtilities(filePath, content)) required = [...required, ...detectRequiredSkills("tailwind", content)];
950
971
  if (forcedSkill && !required.includes(forcedSkill)) required.push(forcedSkill);
@@ -1243,7 +1264,7 @@ function buildClaudeMdContext(prompt, cwd) {
1243
1264
  } catch {
1244
1265
  return null;
1245
1266
  }
1246
- if (!DEV_VERBS.test(prompt)) return `# CLAUDE.md\n${claudeContent}`;
1267
+ if (!DEV_VERBS.test(prompt) && !DEV_KEYWORDS.test(prompt)) return `# CLAUDE.md\n${claudeContent}`;
1247
1268
  return `${buildApexInstruction(detectClaudeMdProjectType(cwd), resolveMaxLines())}\n\n# CLAUDE.md\n${claudeContent}`;
1248
1269
  }
1249
1270
  //#endregion
@@ -1539,4 +1560,4 @@ function missingSeoElements(html) {
1539
1560
  return missing;
1540
1561
  }
1541
1562
  //#endregion
1542
- export { detectCreationIntent as A, detectProjectType as B, findMarketplacePlugins as C, MAX_EXA_RESULTS as D, frameworkSolidGate as E, freshnessGate as F, requiredArchSkill as H, solidReadGate as I, detectFramework as L, brainstormGate as M, docConsultedGate as N, MAX_TOKENS as O, evaluateApex as P, DEV_KEYWORDS as R, usesTailwindUtilities as S, SKILL_TRIGGERS as T, isApexCommand as V, scanPlugin as _, firstHeading as a, detectRequiredSkills as b, EXCLUDE_DIRS as c, buildApexTaskInjection as d, loadApexTaskState as f, detectClaudeMdProjectType as g, buildClaudeMdContext as h, firstComment as i, APEX_GATES as j, capVerbosity as k, PROJECT_INDICATORS as l, buildApexInstruction as m, missingSeoElements as n, parseEnrichment as o, DEV_VERBS as p, descFromText as r, parseEntry as s, isHtmlLike as t, buildApexTaskContext as u, parseBodyDesc as v, readPluginMeta as w, skillTriggerGate as x, parseField as y, detectModularArchitecture as z };
1563
+ export { MAX_EXA_RESULTS as A, detectFramework as B, resolveSkillPath as C, frameworkSolidGate as D, SKILL_TRIGGERS as E, brainstormGate as F, requiredArchSkill as G, detectModularArchitecture as H, docConsultedGate as I, evaluateApex as L, capVerbosity as M, detectCreationIntent as N, isExcludedJsPath as O, APEX_GATES as P, freshnessGate as R, usesTailwindUtilities as S, readPluginMeta as T, detectProjectType as U, DEV_KEYWORDS as V, isApexCommand as W, scanPlugin as _, firstHeading as a, detectRequiredSkills as b, EXCLUDE_DIRS as c, buildApexTaskInjection as d, loadApexTaskState as f, detectClaudeMdProjectType as g, buildClaudeMdContext as h, firstComment as i, MAX_TOKENS as j, isExcludedSwiftPath as k, PROJECT_INDICATORS as l, buildApexInstruction as m, missingSeoElements as n, parseEnrichment as o, DEV_VERBS as p, descFromText as r, parseEntry as s, isHtmlLike as t, buildApexTaskContext as u, parseBodyDesc as v, findMarketplacePlugins as w, skillTriggerGate as x, parseField as y, solidReadGate as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/harness",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
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",
@@ -59,11 +59,6 @@
59
59
  "types": "./dist/refs/index.d.mts",
60
60
  "import": "./dist/refs/index.mjs"
61
61
  },
62
- "./state": {
63
- "bun": "./src/state/index.ts",
64
- "types": "./dist/state/index.d.mts",
65
- "import": "./dist/state/index.mjs"
66
- },
67
62
  "./statusline": {
68
63
  "bun": "./src/statusline/index.ts",
69
64
  "types": "./dist/statusline/index.d.mts",
@@ -132,7 +127,7 @@
132
127
  "test": "bun test",
133
128
  "typecheck": "tsc --noEmit",
134
129
  "docs:api": "typedoc",
135
- "build": "tsdown src/index.ts src/config/index.ts src/util/index.ts src/detect/index.ts src/policy/index.ts src/prompt/index.ts src/memory/index.ts src/cache/index.ts src/freshness/index.ts src/refs/index.ts src/state/index.ts src/statusline/index.ts src/cli/index.ts src/cli/bin.ts src/init/index.ts src/tracking/index.ts src/runtime/index.ts src/adapters/claude/index.ts src/adapters/codex/index.ts src/adapters/cursor/index.ts src/adapters/cline/index.ts src/adapters/gemini/index.ts --dts --format esm --clean --out-dir dist",
130
+ "build": "tsdown src/index.ts src/config/index.ts src/util/index.ts src/detect/index.ts src/policy/index.ts src/prompt/index.ts src/memory/index.ts src/cache/index.ts src/freshness/index.ts src/refs/index.ts src/statusline/index.ts src/cli/index.ts src/cli/bin.ts src/init/index.ts src/tracking/index.ts src/runtime/index.ts src/adapters/claude/index.ts src/adapters/codex/index.ts src/adapters/cursor/index.ts src/adapters/cline/index.ts src/adapters/gemini/index.ts --dts --format esm --clean --out-dir dist",
136
131
  "prepublishOnly": "bun test && tsc --noEmit && bun run build"
137
132
  },
138
133
  "publishConfig": {
@@ -1,59 +0,0 @@
1
- import { t as AuthEntry } from "./doc-helpers-BNfYWvYv.mjs";
2
-
3
- //#region src/state/lock.d.ts
4
- /**
5
- * Acquire a directory-based lock (atomic `mkdir`, EEXIST = already held) with a timeout.
6
- * @returns a release function, or null if the lock could not be acquired in time.
7
- */
8
- declare function acquireLock(lockDir: string, timeoutMs?: number): Promise<(() => Promise<void>) | null>;
9
- //#endregion
10
- //#region src/state/apex-state.d.ts
11
- declare const DEFAULT_STATE: {
12
- $schema: string;
13
- description: string;
14
- target: Record<string, string>;
15
- authorizations: Record<string, AuthEntry & {
16
- doc_consulted?: string;
17
- }>;
18
- };
19
- /** APEX state shape. */
20
- type ApexState = typeof DEFAULT_STATE;
21
- /** APEX state directory under a home dir. */
22
- declare function apexStateDir(home?: string): string;
23
- /** Daily state file path: `<home>/.claude/logs/00-apex/<YYYY-MM-DD>-state.json`. */
24
- declare function stateFilePath(home?: string, today?: string): string;
25
- /** Ensure the state directory exists and return its path. */
26
- declare function ensureStateDir(home?: string): Promise<string>;
27
- /** Load APEX state, or a fresh default. */
28
- declare function loadState(path: string): Promise<ApexState>;
29
- /** Save APEX state. */
30
- declare function saveState(path: string, state: ApexState): Promise<void>;
31
- //#endregion
32
- //#region src/state/task-helpers.d.ts
33
- /** A task entry in task.json. */
34
- interface ApexTask {
35
- subject: string;
36
- description: string;
37
- status: string;
38
- phase: string;
39
- started_at?: string;
40
- completed_at?: string;
41
- created_at?: string;
42
- doc_consulted: Record<string, unknown>;
43
- files_modified: string[];
44
- blockedBy?: string[];
45
- }
46
- /** Structure of `.claude/apex/task.json`. */
47
- interface ApexTaskFile {
48
- current_task: string;
49
- created_at: string;
50
- tasks: Record<string, ApexTask>;
51
- }
52
- /** Add a new pending task. */
53
- declare function taskCreate(file: string, id: string, subject: string, desc: string): Promise<void>;
54
- /** Mark a task in_progress (creating a stub if absent). */
55
- declare function taskStart(file: string, id: string, subject?: string, desc?: string, blocked?: string): Promise<void>;
56
- /** Mark a task completed. */
57
- declare function taskComplete(file: string, id: string): Promise<void>;
58
- //#endregion
59
- export { taskStart as a, ensureStateDir as c, stateFilePath as d, acquireLock as f, taskCreate as i, loadState as l, ApexTaskFile as n, ApexState as o, taskComplete as r, apexStateDir as s, ApexTask as t, saveState as u };
@@ -1,2 +0,0 @@
1
- import { a as taskStart, c as ensureStateDir, d as stateFilePath, f as acquireLock, i as taskCreate, l as loadState, n as ApexTaskFile, o as ApexState, r as taskComplete, s as apexStateDir, t as ApexTask, u as saveState } from "../index-BA-SqNR7.mjs";
2
- export { ApexState, ApexTask, ApexTaskFile, acquireLock, apexStateDir, ensureStateDir, loadState, saveState, stateFilePath, taskComplete, taskCreate, taskStart };
@@ -1,2 +0,0 @@
1
- import { a as ensureStateDir, c as stateFilePath, i as apexStateDir, l as acquireLock, n as taskCreate, o as loadState, r as taskStart, s as saveState, t as taskComplete } from "../state-9lWvvWk8.mjs";
2
- export { acquireLock, apexStateDir, ensureStateDir, loadState, saveState, stateFilePath, taskComplete, taskCreate, taskStart };
@@ -1,104 +0,0 @@
1
- import { a as writeJsonFile, i as readJsonFile, n as ensureDir } from "./json-io-DisYd2fb.mjs";
2
- import { mkdir, rmdir } from "node:fs/promises";
3
- //#region src/state/lock.ts
4
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
5
- /**
6
- * Acquire a directory-based lock (atomic `mkdir`, EEXIST = already held) with a timeout.
7
- * @returns a release function, or null if the lock could not be acquired in time.
8
- */
9
- async function acquireLock(lockDir, timeoutMs = 5e3) {
10
- const start = Date.now();
11
- while (Date.now() - start < timeoutMs) try {
12
- await mkdir(lockDir, { recursive: false });
13
- return async () => {
14
- try {
15
- await rmdir(lockDir);
16
- } catch {}
17
- };
18
- } catch {
19
- await sleep(100);
20
- }
21
- return null;
22
- }
23
- //#endregion
24
- //#region src/state/apex-state.ts
25
- const DEFAULT_STATE = {
26
- $schema: "apex-state-v1",
27
- description: "APEX/SOLID state - sessions[] + 2min expiry",
28
- target: {},
29
- authorizations: {}
30
- };
31
- /** APEX state directory under a home dir. */
32
- function apexStateDir(home = process.env.HOME ?? "") {
33
- return `${home}/.claude/logs/00-apex`;
34
- }
35
- /** Daily state file path: `<home>/.claude/logs/00-apex/<YYYY-MM-DD>-state.json`. */
36
- function stateFilePath(home = process.env.HOME ?? "", today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)) {
37
- return `${apexStateDir(home)}/${today}-state.json`;
38
- }
39
- /** Ensure the state directory exists and return its path. */
40
- async function ensureStateDir(home) {
41
- const dir = apexStateDir(home);
42
- await ensureDir(dir);
43
- return dir;
44
- }
45
- /** Load APEX state, or a fresh default. */
46
- async function loadState(path) {
47
- return await readJsonFile(path) ?? { ...DEFAULT_STATE };
48
- }
49
- /** Save APEX state. */
50
- async function saveState(path, state) {
51
- await writeJsonFile(path, state);
52
- }
53
- //#endregion
54
- //#region src/state/task-helpers.ts
55
- /** Add a new pending task. */
56
- async function taskCreate(file, id, subject, desc) {
57
- const data = await readJsonFile(file);
58
- if (!data) return;
59
- data.tasks[id] = {
60
- subject,
61
- description: desc,
62
- status: "pending",
63
- phase: "pending",
64
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
65
- doc_consulted: {},
66
- files_modified: [],
67
- blockedBy: []
68
- };
69
- await writeJsonFile(file, data);
70
- }
71
- /** Mark a task in_progress (creating a stub if absent). */
72
- async function taskStart(file, id, subject, desc, blocked) {
73
- const data = await readJsonFile(file);
74
- if (!data) return;
75
- const task = data.tasks[id] ?? {
76
- subject: "",
77
- description: "",
78
- status: "in_progress",
79
- phase: "analyze",
80
- doc_consulted: {},
81
- files_modified: []
82
- };
83
- data.tasks[id] = task;
84
- data.current_task = id;
85
- task.status = "in_progress";
86
- task.phase = "analyze";
87
- task.started_at = (/* @__PURE__ */ new Date()).toISOString();
88
- if (subject) task.subject = subject;
89
- if (desc) task.description = desc;
90
- if (blocked) task.blockedBy = blocked.split(",");
91
- await writeJsonFile(file, data);
92
- }
93
- /** Mark a task completed. */
94
- async function taskComplete(file, id) {
95
- const data = await readJsonFile(file);
96
- const task = data?.tasks[id];
97
- if (!data || !task) return;
98
- task.status = "completed";
99
- task.phase = "completed";
100
- task.completed_at = (/* @__PURE__ */ new Date()).toISOString();
101
- await writeJsonFile(file, data);
102
- }
103
- //#endregion
104
- export { ensureStateDir as a, stateFilePath as c, apexStateDir as i, acquireLock as l, taskCreate as n, loadState as o, taskStart as r, saveState as s, taskComplete as t };