@pieai/pro-gov 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -93,6 +93,7 @@ function createNpxSkillsMaintenancePlan(options) {
93
93
  if (options.operation === "update") {
94
94
  assertNoReportedPartialUpdateFailure(result.stdout, result.stderr);
95
95
  }
96
+ assertNoDeprecatedMattSkills(tempRoot);
96
97
  const after = snapshotFiles(tempRoot);
97
98
  const changes = diffSnapshots(before, after);
98
99
  return {
@@ -117,6 +118,16 @@ ${stderr}`.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g, "");
117
118
  throw new Error(`npx skills update reported a partial failure: ${failure[0]}`);
118
119
  }
119
120
  }
121
+ function assertNoDeprecatedMattSkills(npxRoot) {
122
+ const lockPath = join3(npxRoot, "skills-lock.json");
123
+ const lock = JSON.parse(readFileSync2(lockPath, "utf8"));
124
+ const deprecated = Object.entries(lock.skills ?? {}).filter(
125
+ ([, entry]) => entry.source === "mattpocock/skills" && entry.skillPath?.startsWith("skills/deprecated/")
126
+ ).map(([name]) => name).sort();
127
+ if (deprecated.length > 0) {
128
+ throw new Error(`npx skills plan contains deprecated mattpocock skills: ${deprecated.join(", ")}`);
129
+ }
130
+ }
120
131
  function assertNativeNpxRoot(npxRoot) {
121
132
  if (!existsSync3(join3(npxRoot, "skills-lock.json"))) {
122
133
  throw new Error(`npx skills root is missing skills-lock.json: ${npxRoot}`);
@@ -1638,7 +1649,7 @@ function printNpxUsage() {
1638
1649
 
1639
1650
  // src/commands/doctor.ts
1640
1651
  import { spawnSync as spawnSync2 } from "node:child_process";
1641
- import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
1652
+ import { existsSync as existsSync12 } from "node:fs";
1642
1653
  import { createRequire } from "node:module";
1643
1654
  import { dirname as dirname6, join as join12 } from "node:path";
1644
1655
  var REQUIRED_ASSETS = [
@@ -1650,11 +1661,9 @@ var REQUIRED_ASSETS = [
1650
1661
  "profiles/doc-only/profile.md"
1651
1662
  ];
1652
1663
  function runDoctor(_args) {
1653
- const strictHooks = _args.includes("--strict-hooks");
1654
1664
  const assets = listAssets();
1655
1665
  const assetPaths = new Set(assets.map((asset) => asset.path));
1656
1666
  const missing = REQUIRED_ASSETS.filter((assetPath) => !assetPaths.has(assetPath));
1657
- const hookIssues = strictHooks ? checkStrictHostHooks(process.cwd()) : [];
1658
1667
  console.log("pro-gov doctor");
1659
1668
  console.log(`assets: ${assets.length}`);
1660
1669
  if (missing.length > 0) {
@@ -1665,13 +1674,7 @@ function runDoctor(_args) {
1665
1674
  console.log("assets: required project-governance assets found");
1666
1675
  }
1667
1676
  console.log(checkDocGov());
1668
- for (const issue of hookIssues) {
1669
- console.error(issue);
1670
- }
1671
- if (strictHooks && hookIssues.length === 0) {
1672
- console.log("host-hooks: PGS Compound Gate hooks wired");
1673
- }
1674
- return missing.length > 0 || hookIssues.length > 0 ? 1 : 0;
1677
+ return missing.length > 0 ? 1 : 0;
1675
1678
  }
1676
1679
  function checkDocGov() {
1677
1680
  const fromPath = spawnSync2("doc-gov", ["--help"], {
@@ -1704,424 +1707,10 @@ function resolveDocGovDependencyCli() {
1704
1707
  return null;
1705
1708
  }
1706
1709
  }
1707
- function checkStrictHostHooks(root) {
1708
- if (!isEngineeringRuntimeProject(root)) {
1709
- return [];
1710
- }
1711
- const expected = [
1712
- { path: ".codex/hooks.json", host: "codex" },
1713
- { path: ".claude/settings.json", host: "claude-code" },
1714
- { path: ".agents/hooks.json", host: "antigravity" }
1715
- ];
1716
- const issues = [];
1717
- for (const entry of expected) {
1718
- const absolutePath = join12(root, entry.path);
1719
- if (!existsSync12(absolutePath)) {
1720
- issues.push(`host-hooks: missing ${entry.path}`);
1721
- continue;
1722
- }
1723
- const content = readFileSync8(absolutePath, "utf8");
1724
- if (!content.includes("pro-gov host-hook") || !content.includes(`--host ${entry.host}`)) {
1725
- issues.push(`host-hooks: ${entry.path} does not call pro-gov host-hook for ${entry.host}`);
1726
- }
1727
- if (entry.host === "antigravity" && !content.includes("PGS_HOST_HOOK_DEBUG=1")) {
1728
- issues.push(`host-hooks: ${entry.path} does not enable PGS_HOST_HOOK_DEBUG=1 for Antigravity diagnostics`);
1729
- }
1730
- }
1731
- return issues;
1732
- }
1733
- function isEngineeringRuntimeProject(root) {
1734
- return existsSync12(join12(root, "docs/governance/agents-routing/engineering-runtime-v0.9.md"));
1735
- }
1736
-
1737
- // src/commands/host-hook.ts
1738
- import { spawnSync as spawnSync3 } from "node:child_process";
1739
- import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "node:fs";
1740
- import { tmpdir as tmpdir2 } from "node:os";
1741
- import { basename as basename3, join as join13, resolve as resolve3 } from "node:path";
1742
-
1743
- // src/host-hooks/host-hook-runner.ts
1744
- import { closeSync, openSync, readFileSync as readFileSync9, readSync, statSync as statSync3 } from "node:fs";
1745
- var gateMarkerPattern = /Compound Gate:\s*(ran ce-compound|ran fallback capture|skipped)\s*->/i;
1746
- var completionSignalPatterns = [
1747
- /\b(done|completed|implemented|fixed|verified|validated|shipped|pushed|committed)\b/i,
1748
- /\b(tests?|typecheck|build|lint|doctor|pack)\b.*\b(pass|passed|green|succeed|succeeded|ok)\b/i,
1749
- /\b(changed|updated|modified|created|deleted|refactored)\b.*\b(files?|docs?|tests?|hooks?|configs?)\b/i,
1750
- /已完成|完成了|修好了|实现了|验证通过|测试通过|已经提交|已经推送|提交并推送|已提交|已推送/
1751
- ];
1752
- var negativeCompletionSignalPatterns = [
1753
- /\b(not done|not completed|not implemented|not fixed|did not complete|didn't complete|have not completed|haven't completed)\b/i,
1754
- /没有完成|未完成|还没完成|没有改动|未改动|没有修改|未修改/
1755
- ];
1756
- var compoundGateInstruction = [
1757
- "Before final reporting, pass the PGS Compound Gate.",
1758
- "If this completed work produced reusable learning, run compound-engineering:ce-compound and report:",
1759
- "Compound Gate: ran ce-compound -> <path>",
1760
- "If the Compound Engineering plugin is unavailable in this host, use PGS fallback capture:",
1761
- 'pro-gov learn capture --title "<learning title>" --summary "<reusable lesson>"',
1762
- "Compound Gate: ran fallback capture -> <path>",
1763
- "If there is no reusable learning, report:",
1764
- "Compound Gate: skipped -> <reason>"
1765
- ].join("\n");
1766
- var liteCompoundGateInstruction = [
1767
- "Pass the PGS Compound Gate before final reporting.",
1768
- "Report one line:",
1769
- "Compound Gate: ran ce-compound -> <path>",
1770
- "Compound Gate: ran fallback capture -> <path>",
1771
- "Compound Gate: skipped -> <reason>"
1772
- ].join("\n");
1773
- var maxTranscriptBytes = 2 * 1024 * 1024;
1774
- function evaluateHostHook(request) {
1775
- const mode = request.compoundGateMode ?? "off";
1776
- if (mode === "off") {
1777
- return { action: "allow" };
1778
- }
1779
- if (request.event !== "Stop" && request.event !== "SubagentStop") {
1780
- return { action: "allow" };
1781
- }
1782
- const input = normalizeStopInput(request.input);
1783
- if (input.stopHookActive) {
1784
- return { action: "allow" };
1785
- }
1786
- if (!input.lastAssistantMessage) {
1787
- return { action: "allow" };
1788
- }
1789
- if (gateMarkerPattern.test(input.lastAssistantMessage)) {
1790
- return { action: "allow" };
1791
- }
1792
- if (!looksLikeCompletedEngineeringWork(input.lastAssistantMessage)) {
1793
- return { action: "allow" };
1794
- }
1795
- return { action: "continue", reason: compoundGateInstructionForMode(mode) };
1796
- }
1797
- function compoundGateInstructionForMode(mode) {
1798
- return mode === "lite" ? liteCompoundGateInstruction : compoundGateInstruction;
1799
- }
1800
- function formatHostHookOutput(host, event, decision) {
1801
- if (decision.action === "allow") {
1802
- return {};
1803
- }
1804
- if (host === "codex") {
1805
- if (event === "Stop" || event === "SubagentStop") {
1806
- return { decision: "block", reason: decision.reason };
1807
- }
1808
- if (decision.action === "block") {
1809
- return {
1810
- hookSpecificOutput: {
1811
- hookEventName: event,
1812
- permissionDecision: "deny",
1813
- permissionDecisionReason: decision.reason
1814
- },
1815
- systemMessage: decision.reason
1816
- };
1817
- }
1818
- return { systemMessage: decision.reason };
1819
- }
1820
- if (host === "claude" || host === "claude-code") {
1821
- if (event === "Stop" || event === "SubagentStop") {
1822
- return { decision: "block", reason: decision.reason };
1823
- }
1824
- if (decision.action === "block") {
1825
- return {
1826
- hookSpecificOutput: {
1827
- hookEventName: event,
1828
- permissionDecision: "deny",
1829
- permissionDecisionReason: decision.reason
1830
- }
1831
- };
1832
- }
1833
- return { systemMessage: decision.reason };
1834
- }
1835
- if (host === "antigravity") {
1836
- if (event === "Stop" || event === "SubagentStop") {
1837
- return { decision: "continue", reason: decision.reason };
1838
- }
1839
- if (decision.action === "block") {
1840
- return { decision: "deny", reason: decision.reason };
1841
- }
1842
- return { decision: "allow", reason: decision.reason };
1843
- }
1844
- return {};
1845
- }
1846
- function normalizeStopInput(input) {
1847
- if (!isRecord(input)) {
1848
- return { lastAssistantMessage: void 0, stopHookActive: false };
1849
- }
1850
- return {
1851
- lastAssistantMessage: findString(input, ["last_assistant_message", "lastAssistantMessage", "message", "text"]) ?? findLastAssistantMessageFromTranscript(findString(input, ["agent_transcript_path", "agentTranscriptPath"])) ?? findLastAssistantMessageFromTranscript(findString(input, ["transcript_path", "transcriptPath"])),
1852
- stopHookActive: findBoolean(input, ["stop_hook_active", "stopHookActive"]) ?? false
1853
- };
1854
- }
1855
- function looksLikeCompletedEngineeringWork(message) {
1856
- if (negativeCompletionSignalPatterns.some((pattern) => pattern.test(message))) {
1857
- return false;
1858
- }
1859
- return completionSignalPatterns.some((pattern) => pattern.test(message));
1860
- }
1861
- function findString(input, keys) {
1862
- for (const key of keys) {
1863
- const value = input[key];
1864
- if (typeof value === "string" && value.trim().length > 0) {
1865
- return value;
1866
- }
1867
- }
1868
- return void 0;
1869
- }
1870
- function findBoolean(input, keys) {
1871
- for (const key of keys) {
1872
- const value = input[key];
1873
- if (typeof value === "boolean") {
1874
- return value;
1875
- }
1876
- }
1877
- return void 0;
1878
- }
1879
- function findLastAssistantMessageFromTranscript(path) {
1880
- if (!path || path.startsWith("~/")) {
1881
- return void 0;
1882
- }
1883
- let content;
1884
- try {
1885
- content = readTranscriptTail(path);
1886
- } catch {
1887
- return void 0;
1888
- }
1889
- const lines = content.split(/\r?\n/);
1890
- for (let index = lines.length - 1; index >= 0; index -= 1) {
1891
- const line = lines[index]?.trim();
1892
- if (!line) {
1893
- continue;
1894
- }
1895
- let record;
1896
- try {
1897
- record = JSON.parse(line);
1898
- } catch {
1899
- continue;
1900
- }
1901
- const message = extractAssistantText(record);
1902
- if (message) {
1903
- return message;
1904
- }
1905
- }
1906
- return void 0;
1907
- }
1908
- function readTranscriptTail(path) {
1909
- const size = statSync3(path).size;
1910
- if (size <= maxTranscriptBytes) {
1911
- return readFileSync9(path, "utf8");
1912
- }
1913
- const fd = openSync(path, "r");
1914
- try {
1915
- const buffer = Buffer.allocUnsafe(maxTranscriptBytes);
1916
- readSync(fd, buffer, 0, maxTranscriptBytes, size - maxTranscriptBytes);
1917
- return buffer.toString("utf8");
1918
- } finally {
1919
- closeSync(fd);
1920
- }
1921
- }
1922
- function extractAssistantText(value) {
1923
- if (!isRecord(value)) {
1924
- return void 0;
1925
- }
1926
- const nested = value.message;
1927
- const role = findString(value, ["role", "type"]);
1928
- if (isRecord(nested)) {
1929
- const nestedRole = findString(nested, ["role", "type"]);
1930
- if (nestedRole === "assistant") {
1931
- return extractTextContent(nested.content);
1932
- }
1933
- }
1934
- if (role === "assistant") {
1935
- return extractTextContent(value.content) ?? extractTextContent(value.text);
1936
- }
1937
- return void 0;
1938
- }
1939
- function extractTextContent(value) {
1940
- if (typeof value === "string" && value.trim().length > 0) {
1941
- return value;
1942
- }
1943
- if (!Array.isArray(value)) {
1944
- return void 0;
1945
- }
1946
- const parts = [];
1947
- for (const item of value) {
1948
- if (typeof item === "string") {
1949
- parts.push(item);
1950
- continue;
1951
- }
1952
- if (isRecord(item) && typeof item.text === "string") {
1953
- parts.push(item.text);
1954
- }
1955
- }
1956
- const text = parts.join("\n").trim();
1957
- return text.length > 0 ? text : void 0;
1958
- }
1959
- function isRecord(value) {
1960
- return typeof value === "object" && value !== null && !Array.isArray(value);
1961
- }
1962
-
1963
- // src/host-hooks/types.ts
1964
- function isHostHookHost(value) {
1965
- return value === "antigravity" || value === "claude" || value === "claude-code" || value === "codex";
1966
- }
1967
- function isHostHookEvent(value) {
1968
- return value === "PostToolUse" || value === "PreToolUse" || value === "Stop" || value === "SubagentStop" || value === "UserPromptSubmit";
1969
- }
1970
- function isCompoundGateMode(value) {
1971
- return value === "off" || value === "lite" || value === "strict";
1972
- }
1973
-
1974
- // src/commands/host-hook.ts
1975
- var defaultStdinTimeoutMs = 750;
1976
- var maxDebugRawInputBytes = 256 * 1024;
1977
- async function runHostHook(args) {
1978
- const host = readOption(args, "--host");
1979
- const event = readOption(args, "--event");
1980
- const compoundGateMode = readCompoundGateMode(args);
1981
- if (!isHostHookHost(host)) {
1982
- console.error("Expected --host <codex|claude-code|antigravity>");
1983
- return 1;
1984
- }
1985
- if (!isHostHookEvent(event)) {
1986
- console.error("Expected --event <Stop|SubagentStop|PreToolUse|PostToolUse|UserPromptSubmit>");
1987
- return 1;
1988
- }
1989
- const rawInput = await readStdinText(defaultStdinTimeoutMs);
1990
- const input = parseStdinJson(rawInput);
1991
- const decision = evaluateHostHook({ compoundGateMode, host, event, input });
1992
- const output = formatHostHookOutput(host, event, decision);
1993
- writeDebugLogIfRequested(args, {
1994
- compoundGateMode,
1995
- decision,
1996
- event,
1997
- host,
1998
- input,
1999
- output,
2000
- rawInput
2001
- });
2002
- console.log(`${JSON.stringify(output)}
2003
- `);
2004
- return 0;
2005
- }
2006
- function readCompoundGateMode(args) {
2007
- const value = readOption(args, "--compound-gate-mode") ?? process.env.PGS_COMPOUND_GATE_MODE ?? "off";
2008
- if (isCompoundGateMode(value)) return value;
2009
- return "off";
2010
- }
2011
- function readOption(args, name) {
2012
- const index = args.indexOf(name);
2013
- if (index < 0) return void 0;
2014
- return args[index + 1];
2015
- }
2016
- function parseStdinJson(raw) {
2017
- if (!raw) return {};
2018
- try {
2019
- return JSON.parse(raw);
2020
- } catch {
2021
- return {};
2022
- }
2023
- }
2024
- function readStdinText(timeoutMs) {
2025
- if (process.stdin.isTTY) {
2026
- return Promise.resolve("");
2027
- }
2028
- process.stdin.setEncoding("utf8");
2029
- return new Promise((resolveText) => {
2030
- let settled = false;
2031
- let content = "";
2032
- const settle = () => {
2033
- if (settled) return;
2034
- settled = true;
2035
- clearTimeout(timer);
2036
- process.stdin.off("data", onData);
2037
- process.stdin.off("end", settle);
2038
- process.stdin.off("error", settle);
2039
- process.stdin.pause();
2040
- resolveText(content.trim());
2041
- };
2042
- const onData = (chunk) => {
2043
- content += chunk.toString();
2044
- };
2045
- const timer = setTimeout(settle, timeoutMs);
2046
- timer.unref();
2047
- process.stdin.on("data", onData);
2048
- process.stdin.on("end", settle);
2049
- process.stdin.on("error", settle);
2050
- process.stdin.resume();
2051
- });
2052
- }
2053
- function writeDebugLogIfRequested(args, record) {
2054
- const explicitPath = readOption(args, "--debug-log");
2055
- const enabled = explicitPath !== void 0 || process.env.PGS_HOST_HOOK_DEBUG === "1";
2056
- if (!enabled) return;
2057
- const debugDir = explicitPath && explicitPath.trim().length > 0 ? explicitPath : defaultDebugDir();
2058
- try {
2059
- mkdirSync4(debugDir, { recursive: true });
2060
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2061
- const fileName = `${timestamp}-${process.pid}-${record.host}-${record.event}.json`;
2062
- writeFileSync3(
2063
- join13(debugDir, fileName),
2064
- `${JSON.stringify(
2065
- {
2066
- schemaVersion: 1,
2067
- cwd: process.cwd(),
2068
- compoundGateMode: record.compoundGateMode,
2069
- event: record.event,
2070
- host: record.host,
2071
- nodeVersion: process.version,
2072
- packageVersion: readPackageVersion(),
2073
- rawInput: truncateDebugRawInput(record.rawInput),
2074
- input: record.input,
2075
- decision: record.decision,
2076
- output: record.output
2077
- },
2078
- null,
2079
- 2
2080
- )}
2081
- `,
2082
- "utf8"
2083
- );
2084
- } catch {
2085
- }
2086
- }
2087
- function defaultDebugDir() {
2088
- const gitPath = spawnSync3("git", ["rev-parse", "--git-path", "pro-gov-hook-debug"], {
2089
- encoding: "utf8",
2090
- stdio: ["ignore", "pipe", "ignore"]
2091
- });
2092
- const value = gitPath.status === 0 ? gitPath.stdout.trim() : "";
2093
- if (value) {
2094
- return resolve3(process.cwd(), value);
2095
- }
2096
- return join13(tmpdir2(), "pro-gov-hook-debug", basename3(process.cwd()));
2097
- }
2098
- function readPackageVersion() {
2099
- const packageJsonPath = resolvePackageJsonPath();
2100
- if (!packageJsonPath) return void 0;
2101
- try {
2102
- const parsed = JSON.parse(readFileSync10(packageJsonPath, "utf8"));
2103
- return typeof parsed.version === "string" ? parsed.version : void 0;
2104
- } catch {
2105
- return void 0;
2106
- }
2107
- }
2108
- function resolvePackageJsonPath() {
2109
- const candidates = [
2110
- resolve3(process.cwd(), "packages/pro-gov/package.json"),
2111
- resolve3(process.cwd(), "node_modules/@pieai/pro-gov/package.json")
2112
- ];
2113
- return candidates.find((candidate) => existsSync13(candidate));
2114
- }
2115
- function truncateDebugRawInput(value) {
2116
- const buffer = Buffer.from(value);
2117
- if (buffer.byteLength <= maxDebugRawInputBytes) return value;
2118
- return `${buffer.subarray(0, maxDebugRawInputBytes).toString("utf8")}
2119
- [truncated]`;
2120
- }
2121
1710
 
2122
1711
  // src/commands/init.ts
2123
- import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "node:fs";
2124
- import { basename as basename4, dirname as dirname7, join as join14 } from "node:path";
1712
+ import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
1713
+ import { basename as basename3, dirname as dirname7, join as join13 } from "node:path";
2125
1714
 
2126
1715
  // src/commands/shared.ts
2127
1716
  function planStarterFiles(profile) {
@@ -2129,7 +1718,6 @@ function planStarterFiles(profile) {
2129
1718
  const targetPath = starterTargetPath(asset.path);
2130
1719
  if (!targetPath) return [];
2131
1720
  if (profile && isOtherProfileRouting(targetPath, profile)) return [];
2132
- if (profile && isEngineeringOnlyGuardrail(targetPath) && profile !== "engineering-runtime") return [];
2133
1721
  return [
2134
1722
  {
2135
1723
  sourcePath: asset.path,
@@ -2152,12 +1740,6 @@ function classifyOwnership(targetPath) {
2152
1740
  function isOtherProfileRouting(targetPath, profile) {
2153
1741
  return targetPath.startsWith("docs/governance/agents-routing/") && targetPath !== `docs/governance/agents-routing/${profile}-v0.9.md`;
2154
1742
  }
2155
- function isHostHookTargetPath(targetPath) {
2156
- return targetPath === ".codex/hooks.json" || targetPath === ".claude/settings.json" || targetPath === ".agents/hooks.json";
2157
- }
2158
- function isEngineeringOnlyGuardrail(targetPath) {
2159
- return isHostHookTargetPath(targetPath);
2160
- }
2161
1743
  function starterTargetPath(sourcePath) {
2162
1744
  if (sourcePath === "starter/AGENTS.template.md") return "AGENTS.md";
2163
1745
  if (sourcePath === "starter/CLAUDE.template.md") return "CLAUDE.md";
@@ -2196,7 +1778,7 @@ function runInit(args) {
2196
1778
  }
2197
1779
  function applyStarterFiles(files, profile) {
2198
1780
  const root = process.cwd();
2199
- const conflicts = files.filter((file) => existsSync14(join14(root, file.targetPath)));
1781
+ const conflicts = files.filter((file) => existsSync13(join13(root, file.targetPath)));
2200
1782
  if (conflicts.length > 0) {
2201
1783
  console.error("pro-gov init is refusing to overwrite existing project files:");
2202
1784
  for (const file of conflicts) console.error(` ${file.targetPath}`);
@@ -2204,11 +1786,11 @@ function applyStarterFiles(files, profile) {
2204
1786
  return 1;
2205
1787
  }
2206
1788
  for (const file of files) {
2207
- const targetPath = join14(root, file.targetPath);
2208
- mkdirSync5(dirname7(targetPath), { recursive: true });
2209
- const source = readFileSync11(file.absoluteSourcePath);
2210
- const content = file.targetPath === "AGENTS.md" ? renderAgentsTemplate(source.toString("utf8"), basename4(root), profile) : source;
2211
- writeFileSync4(targetPath, content);
1789
+ const targetPath = join13(root, file.targetPath);
1790
+ mkdirSync4(dirname7(targetPath), { recursive: true });
1791
+ const source = readFileSync8(file.absoluteSourcePath);
1792
+ const content = file.targetPath === "AGENTS.md" ? renderAgentsTemplate(source.toString("utf8"), basename3(root), profile) : source;
1793
+ writeFileSync3(targetPath, content);
2212
1794
  }
2213
1795
  console.log("pro-gov init APPLIED");
2214
1796
  console.log(`profile: ${profile}`);
@@ -2236,8 +1818,8 @@ function readFlag(args, flag) {
2236
1818
  }
2237
1819
 
2238
1820
  // src/learning/recall.ts
2239
- import { existsSync as existsSync15, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "node:fs";
2240
- import { basename as basename5, join as join15, relative as relative5 } from "node:path";
1821
+ import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "node:fs";
1822
+ import { basename as basename4, join as join14, relative as relative5 } from "node:path";
2241
1823
  function recallLearnings(root, options) {
2242
1824
  const query = options.query.trim();
2243
1825
  const terms = tokenize(query);
@@ -2259,14 +1841,14 @@ function recallLearnings(root, options) {
2259
1841
  }
2260
1842
  function loadLearningRecords(root) {
2261
1843
  const records = [];
2262
- const solutionsDir = join15(root, "docs/solutions");
2263
- if (existsSync15(solutionsDir)) {
1844
+ const solutionsDir = join14(root, "docs/solutions");
1845
+ if (existsSync14(solutionsDir)) {
2264
1846
  for (const path of listMarkdownFiles(solutionsDir)) {
2265
1847
  records.push(readLearningRecord(root, path));
2266
1848
  }
2267
1849
  }
2268
- const conceptsPath = join15(root, "CONCEPTS.md");
2269
- if (existsSync15(conceptsPath)) {
1850
+ const conceptsPath = join14(root, "CONCEPTS.md");
1851
+ if (existsSync14(conceptsPath)) {
2270
1852
  records.push(readLearningRecord(root, conceptsPath));
2271
1853
  }
2272
1854
  return records;
@@ -2274,7 +1856,7 @@ function loadLearningRecords(root) {
2274
1856
  function listMarkdownFiles(dir) {
2275
1857
  const files = [];
2276
1858
  for (const entry of readdirSync6(dir, { withFileTypes: true })) {
2277
- const absolutePath = join15(dir, entry.name);
1859
+ const absolutePath = join14(dir, entry.name);
2278
1860
  if (entry.isDirectory()) {
2279
1861
  files.push(...listMarkdownFiles(absolutePath));
2280
1862
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -2284,7 +1866,7 @@ function listMarkdownFiles(dir) {
2284
1866
  return files.sort();
2285
1867
  }
2286
1868
  function readLearningRecord(root, absolutePath) {
2287
- const content = readFileSync12(absolutePath, "utf8");
1869
+ const content = readFileSync9(absolutePath, "utf8");
2288
1870
  const parsed = splitFrontmatter(content);
2289
1871
  const body = parsed.body;
2290
1872
  return {
@@ -2316,7 +1898,7 @@ function findTitle(frontmatter, body) {
2316
1898
  return heading ? heading.slice(2).trim() : void 0;
2317
1899
  }
2318
1900
  function titleFromPath(path) {
2319
- return basename5(path, ".md").split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
1901
+ return basename4(path, ".md").split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2320
1902
  }
2321
1903
  function scoreRecord(record, terms) {
2322
1904
  const title = record.title.toLowerCase();
@@ -2367,92 +1949,55 @@ function cleanMarkdownLine(input) {
2367
1949
  }
2368
1950
 
2369
1951
  // src/learning/capture.ts
2370
- import { existsSync as existsSync16, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
2371
- import { join as join16, relative as relative6 } from "node:path";
2372
- function captureFallbackLearning(root, options) {
1952
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
1953
+ import { join as join15, relative as relative6 } from "node:path";
1954
+ function captureLearning(root, options) {
2373
1955
  const title = options.title.trim();
2374
1956
  const summary = options.summary.trim();
2375
1957
  if (!title) throw new Error("title is required");
2376
1958
  if (!summary) throw new Error("summary is required");
2377
1959
  const category = slugify(options.category ?? "workflow-issues") || "workflow-issues";
2378
- const moduleName = options.module?.trim() || "PGS fallback capture";
2379
- const dir = join16(root, "docs/solutions", category);
2380
- mkdirSync6(dir, { recursive: true });
2381
- const slug = slugify(title) || "fallback-learning";
2382
- const path = uniquePath(dir, slug);
2383
- const content = renderFallbackLearning({
2384
- title,
2385
- summary,
2386
- category,
2387
- moduleName
2388
- });
2389
- writeFileSync5(path, content);
1960
+ const moduleName = options.module?.trim() || "PGS learning capture";
1961
+ const dir = join15(root, "docs/solutions", category);
1962
+ mkdirSync5(dir, { recursive: true });
1963
+ const path = uniquePath(dir, slugify(title) || "learning");
1964
+ writeFileSync4(path, renderLearning({ title, summary, category, moduleName }));
2390
1965
  return {
2391
1966
  relativePath: normalizePath2(relative6(root, path)),
2392
1967
  title,
2393
- captureMode: "pgs-fallback"
1968
+ captureMode: "pgs-native"
2394
1969
  };
2395
1970
  }
2396
- function renderFallbackLearning(options) {
2397
- const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2398
- const problemType = options.category === "workflow-issues" ? "workflow_issue" : "knowledge";
1971
+ function renderLearning(options) {
2399
1972
  return [
2400
1973
  "---",
2401
1974
  `title: ${yamlString(options.title)}`,
2402
- `date: ${date}`,
1975
+ `date: ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`,
2403
1976
  `category: ${options.category}`,
2404
1977
  `module: ${yamlString(options.moduleName)}`,
2405
- `problem_type: ${problemType}`,
2406
- "component: development_workflow",
2407
- "severity: medium",
2408
- "capture_mode: pgs-fallback",
2409
- "applies_when:",
2410
- ' - "The Compound Engineering plugin or ce-compound skill is unavailable in the current host"',
2411
- ' - "Completed work produced reusable learning that should be recallable later"',
2412
- "tags: [compound-gate, fallback-capture, learning-recall]",
1978
+ "capture_mode: pgs-native",
1979
+ "tags: [learning-recall]",
2413
1980
  "---",
2414
1981
  "",
2415
1982
  `# ${options.title}`,
2416
1983
  "",
2417
- "## Context",
2418
- "",
2419
- "This record was captured with the PGS fallback capture path because the full",
2420
- "Compound Engineering `ce-compound` workflow was unavailable in the current",
2421
- "host. Prefer `ce-compound` when the plugin is installed; use this fallback",
2422
- "only to avoid losing reusable learning.",
2423
- "",
2424
1984
  "## Guidance",
2425
1985
  "",
2426
1986
  options.summary,
2427
1987
  "",
2428
- "## Why This Matters",
2429
- "",
2430
- "A Compound Gate that cannot write a learning record turns reusable experience",
2431
- "into a final-report sentence that future agents cannot reliably find. The",
2432
- "fallback keeps the learning searchable by `pro-gov learn recall` without",
2433
- "copying or replacing the Compound Engineering workflow.",
2434
- "",
2435
- "## When to Apply",
1988
+ "## Applies When",
2436
1989
  "",
2437
1990
  "- The work is complete and verified.",
2438
- "- The lesson is reusable across future sessions or projects.",
2439
- "- `compound-engineering:ce-compound` is not available in the current host.",
2440
- "- The learning is not already covered by an existing `docs/solutions/**` record.",
2441
- "",
2442
- "## Examples",
2443
- "",
2444
- "```text",
2445
- "Compound Gate: ran fallback capture -> docs/solutions/<category>/<file>.md",
2446
- "```",
1991
+ "- The lesson is non-obvious, reusable, and not already documented.",
2447
1992
  ""
2448
1993
  ].join("\n");
2449
1994
  }
2450
1995
  function uniquePath(dir, slug) {
2451
1996
  let index = 1;
2452
- let candidate = join16(dir, `${slug}.md`);
2453
- while (existsSync16(candidate)) {
1997
+ let candidate = join15(dir, `${slug}.md`);
1998
+ while (existsSync15(candidate)) {
2454
1999
  index += 1;
2455
- candidate = join16(dir, `${slug}-${index}.md`);
2000
+ candidate = join15(dir, `${slug}-${index}.md`);
2456
2001
  }
2457
2002
  return candidate;
2458
2003
  }
@@ -2508,7 +2053,7 @@ function runLearnCapture(args) {
2508
2053
  }
2509
2054
  let result;
2510
2055
  try {
2511
- result = captureFallbackLearning(options.value.targetDir, {
2056
+ result = captureLearning(options.value.targetDir, {
2512
2057
  title: options.value.title,
2513
2058
  summary: options.value.summary,
2514
2059
  category: options.value.category,
@@ -2629,20 +2174,18 @@ function printUsage2() {
2629
2174
  }
2630
2175
 
2631
2176
  // src/commands/lens.ts
2632
- import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "node:fs";
2177
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "node:fs";
2633
2178
  import { dirname as dirname9 } from "node:path";
2634
2179
 
2635
2180
  // src/lens/audit.ts
2636
- import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "node:fs";
2637
- import { basename as basename6, dirname as dirname8, join as join17 } from "node:path";
2181
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "node:fs";
2182
+ import { basename as basename5, dirname as dirname8, join as join16 } from "node:path";
2638
2183
  var REQUIRED_ARTIFACTS = [
2639
2184
  "manifest.md",
2640
2185
  "raw/project-lens/architecture-lens.md",
2641
2186
  "raw/project-lens/truth-surface-audit.md",
2642
2187
  "raw/project-lens/technology-strategy.md",
2643
- "raw/ponytail/ponytail-audit.md",
2644
- "raw/ponytail/ponytail-debt.md",
2645
- "raw/ponytail/ponytail-gain.md",
2188
+ "raw/project-lens/simplicity-review.md",
2646
2189
  "raw/target/target-state.md",
2647
2190
  "raw/target/commands.md",
2648
2191
  "raw/target/sources.md",
@@ -2654,20 +2197,20 @@ function createProjectLensAuditPackage(targetDir, auditDir) {
2654
2197
  version: 1,
2655
2198
  target: {
2656
2199
  path: targetDir,
2657
- name: basename6(targetDir) || "target"
2200
+ name: basename5(targetDir) || "target"
2658
2201
  },
2659
2202
  requiredArtifacts: [...REQUIRED_ARTIFACTS]
2660
2203
  };
2661
- mkdirSync7(auditDir, { recursive: true });
2662
- writeJson(join17(auditDir, "audit.contract.json"), contract);
2204
+ mkdirSync6(auditDir, { recursive: true });
2205
+ writeJson(join16(auditDir, "audit.contract.json"), contract);
2663
2206
  for (const artifactPath of REQUIRED_ARTIFACTS) {
2664
- writeTemplate(join17(auditDir, artifactPath), renderArtifactTemplate(artifactPath, contract));
2207
+ writeTemplate(join16(auditDir, artifactPath), renderArtifactTemplate(artifactPath, contract));
2665
2208
  }
2666
2209
  return contract;
2667
2210
  }
2668
2211
  function checkProjectLensAuditPackage(auditDir, options = {}) {
2669
- const contractPath = join17(auditDir, "audit.contract.json");
2670
- if (!existsSync17(contractPath)) {
2212
+ const contractPath = join16(auditDir, "audit.contract.json");
2213
+ if (!existsSync16(contractPath)) {
2671
2214
  return {
2672
2215
  ok: false,
2673
2216
  auditDir,
@@ -2681,7 +2224,7 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
2681
2224
  }
2682
2225
  let contract;
2683
2226
  try {
2684
- contract = JSON.parse(readFileSync13(contractPath, "utf8"));
2227
+ contract = JSON.parse(readFileSync10(contractPath, "utf8"));
2685
2228
  } catch (error) {
2686
2229
  return {
2687
2230
  ok: false,
@@ -2714,12 +2257,12 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
2714
2257
  }
2715
2258
  }
2716
2259
  for (const artifactPath of REQUIRED_ARTIFACTS) {
2717
- const absolutePath = join17(auditDir, artifactPath);
2718
- if (!existsSync17(absolutePath)) {
2260
+ const absolutePath = join16(auditDir, artifactPath);
2261
+ if (!existsSync16(absolutePath)) {
2719
2262
  issues.push({ type: "missing-required-artifact", path: artifactPath });
2720
2263
  continue;
2721
2264
  }
2722
- const content = readFileSync13(absolutePath, "utf8");
2265
+ const content = readFileSync10(absolutePath, "utf8");
2723
2266
  if (isPendingArtifact(content)) {
2724
2267
  issues.push({ type: "artifact-not-complete", path: artifactPath });
2725
2268
  } else if (hasTemplateBody(content)) {
@@ -2735,13 +2278,13 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
2735
2278
  };
2736
2279
  }
2737
2280
  function writeJson(path, value) {
2738
- mkdirSync7(dirname8(path), { recursive: true });
2739
- writeFileSync6(path, `${JSON.stringify(value, null, 2)}
2281
+ mkdirSync6(dirname8(path), { recursive: true });
2282
+ writeFileSync5(path, `${JSON.stringify(value, null, 2)}
2740
2283
  `);
2741
2284
  }
2742
2285
  function writeTemplate(path, content) {
2743
- mkdirSync7(dirname8(path), { recursive: true });
2744
- writeFileSync6(path, content);
2286
+ mkdirSync6(dirname8(path), { recursive: true });
2287
+ writeFileSync5(path, content);
2745
2288
  }
2746
2289
  function renderArtifactTemplate(artifactPath, contract) {
2747
2290
  const title = artifactPath.replace(/\.md$/, "").split("/").map((part) => part.replaceAll("-", " ")).join(" / ");
@@ -2797,7 +2340,6 @@ function renderArtifactGuardrailHint(artifactPath) {
2797
2340
  }
2798
2341
  function artifactProducer(artifactPath) {
2799
2342
  if (artifactPath.startsWith("raw/project-lens/")) return "project-lens";
2800
- if (artifactPath.startsWith("raw/ponytail/")) return "ponytail";
2801
2343
  if (artifactPath.startsWith("raw/target/")) return "target-evidence";
2802
2344
  if (artifactPath.startsWith("synthesis/")) return "synthesis";
2803
2345
  return "audit";
@@ -2831,8 +2373,8 @@ var REQUIRED_METHOD_RECORDS = {
2831
2373
  match: /^Project Lens method source:/im
2832
2374
  },
2833
2375
  {
2834
- label: "Ponytail method source:",
2835
- match: /^Ponytail method source:/im
2376
+ label: "Simplicity review method source:",
2377
+ match: /^Simplicity review method source:/im
2836
2378
  }
2837
2379
  ],
2838
2380
  "synthesis/decision-index.md": [
@@ -2910,6 +2452,10 @@ function formatProjectLensAuditCheckText(result) {
2910
2452
  function formatProjectLensInspection(report) {
2911
2453
  return [
2912
2454
  `target: ${report.targetDir}`,
2455
+ `scan-scope: ${report.scanScope.mode}`,
2456
+ `candidate-files: ${report.scanScope.candidateFileCount}`,
2457
+ `included-files: ${report.scanScope.includedFileCount}`,
2458
+ `excluded-files: ${report.scanScope.excludedFileCount}`,
2913
2459
  `ai-entry-files: ${formatList(report.aiEntryFiles)}`,
2914
2460
  `ai-config-files: ${formatList(report.aiConfigFiles)}`,
2915
2461
  `package-scripts: ${formatList(report.packageJson?.scripts ?? [])}`,
@@ -2931,6 +2477,10 @@ function renderProjectLensMarkdownReport(report) {
2931
2477
  `- Target: \`${report.targetDir}\``,
2932
2478
  `- Generated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
2933
2479
  "- Scope: local read-only evidence for AI-assisted project review",
2480
+ `- Evidence mode: ${report.scanScope.mode}`,
2481
+ `- Candidate files: ${report.scanScope.candidateFileCount}`,
2482
+ `- Included files: ${report.scanScope.includedFileCount}`,
2483
+ `- Excluded vendor/cache files: ${report.scanScope.excludedFileCount}`,
2934
2484
  "",
2935
2485
  "## AI Entry Files",
2936
2486
  "",
@@ -2978,9 +2528,9 @@ function bulletList(values) {
2978
2528
  }
2979
2529
 
2980
2530
  // src/lens/scan.ts
2981
- import { spawnSync as spawnSync4 } from "node:child_process";
2982
- import { existsSync as existsSync18, readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
2983
- import { join as join18, relative as relative7 } from "node:path";
2531
+ import { spawnSync as spawnSync3 } from "node:child_process";
2532
+ import { existsSync as existsSync17, readdirSync as readdirSync7, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
2533
+ import { join as join17, relative as relative7 } from "node:path";
2984
2534
  var ignoredDirectories = /* @__PURE__ */ new Set([
2985
2535
  ".git",
2986
2536
  ".next",
@@ -2991,30 +2541,39 @@ var ignoredDirectories = /* @__PURE__ */ new Set([
2991
2541
  ]);
2992
2542
  function scanProjectLensTarget(targetDir, options = {}) {
2993
2543
  const largeFileBytes = options.largeFileBytes ?? 5e4;
2994
- const files = listProjectFiles(targetDir);
2995
- const markdownFiles = files.filter((file) => file.endsWith(".md"));
2544
+ const candidateFiles = listProjectFiles(targetDir);
2545
+ const files = candidateFiles.filter(isFirstPartyEvidenceFile);
2546
+ const markdownFiles = files.filter(
2547
+ (file) => file.startsWith("docs/") && file.endsWith(".md")
2548
+ );
2996
2549
  const packageJson = readPackageJson(targetDir);
2997
2550
  return {
2998
2551
  targetDir,
2552
+ scanScope: {
2553
+ mode: "first-party",
2554
+ candidateFileCount: candidateFiles.length,
2555
+ includedFileCount: files.length,
2556
+ excludedFileCount: candidateFiles.length - files.length
2557
+ },
2999
2558
  aiEntryFiles: ["AGENTS.md", "CLAUDE.md"].filter(
3000
- (file) => existsSync18(join18(targetDir, file))
2559
+ (file) => existsSync17(join17(targetDir, file))
3001
2560
  ),
3002
2561
  aiConfigFiles: [],
3003
2562
  packageJson,
3004
2563
  docs: {
3005
- hasDocsDirectory: existsSync18(join18(targetDir, "docs")),
2564
+ hasDocsDirectory: existsSync17(join17(targetDir, "docs")),
3006
2565
  markdownFileCount: markdownFiles.length,
3007
2566
  governanceFiles: markdownFiles.filter((file) => file.startsWith("docs/governance/") || file.startsWith("docs/policy/")).sort()
3008
2567
  },
3009
2568
  git: readGitState(targetDir),
3010
- largeFiles: files.map((file) => ({ path: file, bytes: statSync4(join18(targetDir, file)).size })).filter((file) => file.bytes >= largeFileBytes).sort((a, b) => b.bytes - a.bytes || a.path.localeCompare(b.path)).slice(0, 25)
2569
+ largeFiles: files.map((file) => ({ path: file, bytes: statSync3(join17(targetDir, file)).size })).filter((file) => file.bytes >= largeFileBytes).sort((a, b) => b.bytes - a.bytes || a.path.localeCompare(b.path)).slice(0, 25)
3011
2570
  };
3012
2571
  }
3013
2572
  function readPackageJson(targetDir) {
3014
- const packageJsonPath = join18(targetDir, "package.json");
3015
- if (!existsSync18(packageJsonPath)) return void 0;
2573
+ const packageJsonPath = join17(targetDir, "package.json");
2574
+ if (!existsSync17(packageJsonPath)) return void 0;
3016
2575
  try {
3017
- const packageJson = JSON.parse(readFileSync14(packageJsonPath, "utf8"));
2576
+ const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf8"));
3018
2577
  return {
3019
2578
  scripts: Object.keys(packageJson.scripts ?? {}).sort(),
3020
2579
  dependencies: Object.keys(packageJson.dependencies ?? {}).sort(),
@@ -3037,25 +2596,46 @@ function readGitState(targetDir) {
3037
2596
  };
3038
2597
  }
3039
2598
  function runGit(targetDir, args) {
3040
- const result = spawnSync4("git", ["-C", targetDir, ...args], {
2599
+ const result = spawnSync3("git", ["-C", targetDir, ...args], {
3041
2600
  encoding: "utf8"
3042
2601
  });
3043
2602
  if (result.status !== 0) return { ok: false };
3044
2603
  return { ok: true, stdout: result.stdout.trim() };
3045
2604
  }
3046
2605
  function listProjectFiles(targetDir) {
2606
+ const gitFiles = runGit(targetDir, [
2607
+ "ls-files",
2608
+ "--cached",
2609
+ "--others",
2610
+ "--exclude-standard",
2611
+ "-z"
2612
+ ]);
2613
+ if (gitFiles.ok) {
2614
+ return gitFiles.stdout.split("\0").filter(Boolean).map(toUnixPath4).filter((file) => existsSync17(join17(targetDir, file))).sort();
2615
+ }
3047
2616
  const files = [];
3048
2617
  collectFiles2(targetDir, targetDir, files);
3049
2618
  return files.sort();
3050
2619
  }
2620
+ var excludedEvidencePrefixes = [
2621
+ ".agents/manual-skills/",
2622
+ ".agents/skills/",
2623
+ "agent-assets/skills/npx-skills/",
2624
+ "third-party/",
2625
+ "third_party/",
2626
+ "vendor/"
2627
+ ];
2628
+ function isFirstPartyEvidenceFile(file) {
2629
+ return !excludedEvidencePrefixes.some((prefix) => file.startsWith(prefix));
2630
+ }
3051
2631
  function collectFiles2(rootDir, currentDir, files) {
3052
- if (!existsSync18(currentDir)) return;
2632
+ if (!existsSync17(currentDir)) return;
3053
2633
  for (const entry of readdirSync7(currentDir, { withFileTypes: true })) {
3054
2634
  if (entry.isDirectory()) {
3055
2635
  if (ignoredDirectories.has(entry.name)) continue;
3056
- collectFiles2(rootDir, join18(currentDir, entry.name), files);
2636
+ collectFiles2(rootDir, join17(currentDir, entry.name), files);
3057
2637
  } else if (entry.isFile()) {
3058
- files.push(toUnixPath4(relative7(rootDir, join18(currentDir, entry.name))));
2638
+ files.push(toUnixPath4(relative7(rootDir, join17(currentDir, entry.name))));
3059
2639
  }
3060
2640
  }
3061
2641
  }
@@ -3107,8 +2687,8 @@ function runLensReport(args) {
3107
2687
  }
3108
2688
  const report = scanProjectLensTarget(options.value.targetDir);
3109
2689
  const markdown = renderProjectLensMarkdownReport(report);
3110
- mkdirSync8(dirname9(options.value.outPath), { recursive: true });
3111
- writeFileSync7(options.value.outPath, markdown);
2690
+ mkdirSync7(dirname9(options.value.outPath), { recursive: true });
2691
+ writeFileSync6(options.value.outPath, markdown);
3112
2692
  console.log(`report: ${options.value.outPath}`);
3113
2693
  return 0;
3114
2694
  }
@@ -3211,16 +2791,16 @@ function printUsage3() {
3211
2791
  }
3212
2792
 
3213
2793
  // src/commands/portfolio.ts
3214
- import { existsSync as existsSync22 } from "node:fs";
3215
- import { join as join21 } from "node:path";
2794
+ import { existsSync as existsSync21 } from "node:fs";
2795
+ import { join as join20 } from "node:path";
3216
2796
 
3217
2797
  // src/portfolio/manifest.ts
3218
- import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
3219
- import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
2798
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
2799
+ import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
3220
2800
  function loadPortfolioManifest(configPath) {
3221
2801
  let parsed;
3222
2802
  try {
3223
- parsed = JSON.parse(readFileSync15(configPath, "utf8"));
2803
+ parsed = JSON.parse(readFileSync12(configPath, "utf8"));
3224
2804
  } catch (error) {
3225
2805
  return {
3226
2806
  configPath,
@@ -3232,7 +2812,7 @@ function loadPortfolioManifest(configPath) {
3232
2812
  ]
3233
2813
  };
3234
2814
  }
3235
- const normalized = resolveManifestPaths(parsed, dirname10(resolve4(configPath)));
2815
+ const normalized = resolveManifestPaths(parsed, dirname10(resolve3(configPath)));
3236
2816
  const issues = validatePortfolioManifest(normalized);
3237
2817
  return {
3238
2818
  configPath,
@@ -3241,12 +2821,12 @@ function loadPortfolioManifest(configPath) {
3241
2821
  };
3242
2822
  }
3243
2823
  function resolveManifestPaths(value, configDir) {
3244
- if (!isRecord2(value)) return value;
2824
+ if (!isRecord(value)) return value;
3245
2825
  const resolveEndpoint = (endpoint) => {
3246
- if (!isRecord2(endpoint) || typeof endpoint.path !== "string" || isAbsolute3(endpoint.path)) {
2826
+ if (!isRecord(endpoint) || typeof endpoint.path !== "string" || isAbsolute3(endpoint.path)) {
3247
2827
  return endpoint;
3248
2828
  }
3249
- return { ...endpoint, path: resolve4(configDir, endpoint.path) };
2829
+ return { ...endpoint, path: resolve3(configDir, endpoint.path) };
3250
2830
  };
3251
2831
  return {
3252
2832
  ...value,
@@ -3257,7 +2837,7 @@ function resolveManifestPaths(value, configDir) {
3257
2837
  }
3258
2838
  function validatePortfolioManifest(value) {
3259
2839
  const issues = [];
3260
- if (!isRecord2(value)) {
2840
+ if (!isRecord(value)) {
3261
2841
  return [
3262
2842
  {
3263
2843
  type: "invalid-field",
@@ -3299,7 +2879,7 @@ function validatePortfolioManifest(value) {
3299
2879
  }
3300
2880
  const seenTargetIds = /* @__PURE__ */ new Set();
3301
2881
  for (const target of value.targets) {
3302
- if (!isRecord2(target)) {
2882
+ if (!isRecord(target)) {
3303
2883
  issues.push({
3304
2884
  type: "invalid-field",
3305
2885
  field: "targets",
@@ -3356,7 +2936,7 @@ function validateAllowedFields(value, location, allowedFields, issues) {
3356
2936
  }
3357
2937
  function validateEndpoint(value, field, issues) {
3358
2938
  if (value === void 0) return;
3359
- if (!isRecord2(value)) {
2939
+ if (!isRecord(value)) {
3360
2940
  issues.push({
3361
2941
  type: "invalid-field",
3362
2942
  field,
@@ -3380,7 +2960,7 @@ function validateEndpoint(value, field, issues) {
3380
2960
  });
3381
2961
  return;
3382
2962
  }
3383
- if (!existsSync19(value.path)) {
2963
+ if (!existsSync18(value.path)) {
3384
2964
  issues.push({
3385
2965
  type: "missing-path",
3386
2966
  id: typeof value.id === "string" ? value.id : void 0,
@@ -3412,7 +2992,7 @@ function validateHostTooling(value, issues) {
3412
2992
  }
3413
2993
  const seenHosts = /* @__PURE__ */ new Set();
3414
2994
  for (const entry of value) {
3415
- if (!isRecord2(entry)) {
2995
+ if (!isRecord(entry)) {
3416
2996
  issues.push({
3417
2997
  type: "invalid-field",
3418
2998
  field: "hostTooling",
@@ -3445,19 +3025,19 @@ function validateHostTooling(value, issues) {
3445
3025
  }
3446
3026
  }
3447
3027
  }
3448
- function isRecord2(value) {
3028
+ function isRecord(value) {
3449
3029
  return typeof value === "object" && value !== null && !Array.isArray(value);
3450
3030
  }
3451
3031
 
3452
3032
  // src/portfolio/doctor.ts
3453
- import { spawnSync as spawnSync6 } from "node:child_process";
3454
- import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
3033
+ import { spawnSync as spawnSync5 } from "node:child_process";
3034
+ import { existsSync as existsSync20, readFileSync as readFileSync14 } from "node:fs";
3455
3035
  import { createRequire as createRequire2 } from "node:module";
3456
- import { dirname as dirname11, join as join20 } from "node:path";
3036
+ import { dirname as dirname11, join as join19 } from "node:path";
3457
3037
  import { fileURLToPath as fileURLToPath3 } from "node:url";
3458
3038
 
3459
3039
  // src/host-tooling/inventory.ts
3460
- import { spawnSync as spawnSync5 } from "node:child_process";
3040
+ import { spawnSync as spawnSync4 } from "node:child_process";
3461
3041
  function inspectHostTooling(requirements, runner = defaultRunner2) {
3462
3042
  const hosts = [];
3463
3043
  const issues = [];
@@ -3515,10 +3095,10 @@ function inspectHostTooling(requirements, runner = defaultRunner2) {
3515
3095
  return { hosts, issues };
3516
3096
  }
3517
3097
  function parseHostPlugins(host, value) {
3518
- const entries = host === "codex" ? isRecord3(value) && Array.isArray(value.installed) ? value.installed : void 0 : Array.isArray(value) ? value : void 0;
3098
+ const entries = host === "codex" ? isRecord2(value) && Array.isArray(value.installed) ? value.installed : void 0 : Array.isArray(value) ? value : void 0;
3519
3099
  if (!entries) throw new Error("expected a plugin array");
3520
3100
  return entries.flatMap((entry) => {
3521
- if (!isRecord3(entry)) return [];
3101
+ if (!isRecord2(entry)) return [];
3522
3102
  const id = host === "codex" ? entry.pluginId : entry.id;
3523
3103
  if (typeof id !== "string") return [];
3524
3104
  return [{
@@ -3529,7 +3109,7 @@ function parseHostPlugins(host, value) {
3529
3109
  });
3530
3110
  }
3531
3111
  function defaultRunner2({ command: command2 }) {
3532
- const result = spawnSync5(command2[0] ?? "", command2.slice(1), {
3112
+ const result = spawnSync4(command2[0] ?? "", command2.slice(1), {
3533
3113
  encoding: "utf8",
3534
3114
  timeout: 1e4
3535
3115
  });
@@ -3539,18 +3119,18 @@ function defaultRunner2({ command: command2 }) {
3539
3119
  stderr: result.stderr || result.error?.message || ""
3540
3120
  };
3541
3121
  }
3542
- function isRecord3(value) {
3122
+ function isRecord2(value) {
3543
3123
  return typeof value === "object" && value !== null && !Array.isArray(value);
3544
3124
  }
3545
3125
 
3546
3126
  // src/portfolio/asset-state.ts
3547
- import { existsSync as existsSync20, lstatSync as lstatSync5, readFileSync as readFileSync16 } from "node:fs";
3548
- import { join as join19 } from "node:path";
3127
+ import { existsSync as existsSync19, lstatSync as lstatSync5, readFileSync as readFileSync13 } from "node:fs";
3128
+ import { join as join18 } from "node:path";
3549
3129
  function comparePortfolioAssetState(options) {
3550
3130
  const expectedManifest = readPlanDocument(options.expectedPlan, ".pro-gov/assets.json");
3551
3131
  const expectedLock = readPlanDocument(options.expectedPlan, ".pro-gov/assets.lock.json");
3552
- const currentManifest = readJsonFile(join19(options.targetDir, ".pro-gov/assets.json"));
3553
- const currentLock = readJsonFile(join19(options.targetDir, ".pro-gov/assets.lock.json"));
3132
+ const currentManifest = readJsonFile(join18(options.targetDir, ".pro-gov/assets.json"));
3133
+ const currentLock = readJsonFile(join18(options.targetDir, ".pro-gov/assets.lock.json"));
3554
3134
  const issues = [];
3555
3135
  if (!sameStrings(currentManifest?.bundleIds, expectedManifest?.bundleIds)) {
3556
3136
  issues.push({
@@ -3573,7 +3153,7 @@ function comparePortfolioAssetState(options) {
3573
3153
  const expectedTargets = new Set((expectedLock?.assets ?? []).map((entry) => entry.targetPath));
3574
3154
  for (const entry of currentLock?.assets ?? []) {
3575
3155
  if (expectedTargets.has(entry.targetPath)) continue;
3576
- const targetAbsolutePath = join19(options.targetDir, entry.targetPath);
3156
+ const targetAbsolutePath = join18(options.targetDir, entry.targetPath);
3577
3157
  if (!pathIsSymlink(targetAbsolutePath)) continue;
3578
3158
  issues.push({
3579
3159
  type: "orphaned-managed-symlink",
@@ -3595,9 +3175,9 @@ function readPlanDocument(plan, targetPath) {
3595
3175
  }
3596
3176
  }
3597
3177
  function readJsonFile(path) {
3598
- if (!existsSync20(path)) return void 0;
3178
+ if (!existsSync19(path)) return void 0;
3599
3179
  try {
3600
- return JSON.parse(readFileSync16(path, "utf8"));
3180
+ return JSON.parse(readFileSync13(path, "utf8"));
3601
3181
  } catch {
3602
3182
  return void 0;
3603
3183
  }
@@ -3646,11 +3226,11 @@ function inspectPortfolio(options) {
3646
3226
  function inspectTarget(options) {
3647
3227
  const { target } = options;
3648
3228
  const issues = [];
3649
- const packageJson = readJson2(join20(target.path, "package.json"));
3229
+ const packageJson = readJson2(join19(target.path, "package.json"));
3650
3230
  const packages = {};
3651
3231
  for (const packageName of ["@pieai/pro-gov", "@pieai/doc-gov"]) {
3652
3232
  const declared = packageJson?.devDependencies?.[packageName] ?? packageJson?.dependencies?.[packageName];
3653
- const installedPackage = readJson2(join20(target.path, "node_modules", packageName, "package.json"));
3233
+ const installedPackage = readJson2(join19(target.path, "node_modules", packageName, "package.json"));
3654
3234
  const installed = installedPackage?.version;
3655
3235
  const expected = options.expectedPackageVersions[packageName];
3656
3236
  packages[packageName] = { declared, installed, expected };
@@ -3704,7 +3284,7 @@ function inspectTarget(options) {
3704
3284
  type: "asset-lock-drift",
3705
3285
  message: error instanceof Error ? error.message : String(error)
3706
3286
  });
3707
- if (!existsSync21(join20(target.path, ".pro-gov/assets.json"))) {
3287
+ if (!existsSync20(join19(target.path, ".pro-gov/assets.json"))) {
3708
3288
  issues.push({ type: "bundle-drift", message: "Target asset manifest is missing." });
3709
3289
  }
3710
3290
  }
@@ -3719,27 +3299,27 @@ function inspectTarget(options) {
3719
3299
  };
3720
3300
  }
3721
3301
  function readTargetAssetHost(targetDir) {
3722
- const lockfile = readJson2(join20(targetDir, ".pro-gov/assets.lock.json"));
3302
+ const lockfile = readJson2(join19(targetDir, ".pro-gov/assets.lock.json"));
3723
3303
  return isAssetRegistryHost(lockfile?.host) ? lockfile.host : void 0;
3724
3304
  }
3725
3305
  function isAssetRegistryHost(value) {
3726
3306
  return value === "codex" || value === "claude-code" || value === "gemini-cli" || value === "antigravity";
3727
3307
  }
3728
3308
  function runTargetChecks(target) {
3729
- const proGovCli = join20(target.path, "node_modules/@pieai/pro-gov/dist/cli.js");
3730
- const docGovCli = join20(target.path, "node_modules/@pieai/doc-gov/dist/cli.js");
3309
+ const proGovCli = join19(target.path, "node_modules/@pieai/pro-gov/dist/cli.js");
3310
+ const docGovCli = join19(target.path, "node_modules/@pieai/doc-gov/dist/cli.js");
3731
3311
  const commands = [
3732
3312
  {
3733
3313
  name: "pro-gov doctor",
3734
3314
  cli: proGovCli,
3735
- args: target.profile === "engineering-runtime" ? ["doctor", "--strict-hooks"] : ["doctor"]
3315
+ args: ["doctor"]
3736
3316
  },
3737
3317
  { name: "doc-gov router-check", cli: docGovCli, args: ["router-check"] },
3738
3318
  { name: "doc-gov scan --check", cli: docGovCli, args: ["scan", "--check"] }
3739
3319
  ];
3740
3320
  return commands.map((command2) => {
3741
- if (!existsSync21(command2.cli)) return { name: command2.name, status: null };
3742
- const result = spawnSync6(process.execPath, [command2.cli, ...command2.args], {
3321
+ if (!existsSync20(command2.cli)) return { name: command2.name, status: null };
3322
+ const result = spawnSync5(process.execPath, [command2.cli, ...command2.args], {
3743
3323
  cwd: target.path,
3744
3324
  encoding: "utf8",
3745
3325
  timeout: 3e4
@@ -3748,13 +3328,13 @@ function runTargetChecks(target) {
3748
3328
  });
3749
3329
  }
3750
3330
  function inspectGit(path) {
3751
- const inside = spawnSync6("git", ["rev-parse", "--is-inside-work-tree"], {
3331
+ const inside = spawnSync5("git", ["rev-parse", "--is-inside-work-tree"], {
3752
3332
  cwd: path,
3753
3333
  encoding: "utf8"
3754
3334
  });
3755
3335
  if (inside.status !== 0) return { isRepository: false, dirty: false };
3756
- const status = spawnSync6("git", ["status", "--porcelain"], { cwd: path, encoding: "utf8" });
3757
- const branch = spawnSync6("git", ["branch", "--show-current"], { cwd: path, encoding: "utf8" });
3336
+ const status = spawnSync5("git", ["status", "--porcelain"], { cwd: path, encoding: "utf8" });
3337
+ const branch = spawnSync5("git", ["branch", "--show-current"], { cwd: path, encoding: "utf8" });
3758
3338
  return {
3759
3339
  isRepository: true,
3760
3340
  dirty: status.stdout.trim().length > 0,
@@ -3779,16 +3359,16 @@ function getExpectedPackageVersions() {
3779
3359
  function findOwnPackageJson() {
3780
3360
  let current = dirname11(fileURLToPath3(import.meta.url));
3781
3361
  for (let depth = 0; depth < 5; depth += 1) {
3782
- const candidate = join20(current, "package.json");
3783
- if (existsSync21(candidate)) return candidate;
3362
+ const candidate = join19(current, "package.json");
3363
+ if (existsSync20(candidate)) return candidate;
3784
3364
  current = dirname11(current);
3785
3365
  }
3786
3366
  return "";
3787
3367
  }
3788
3368
  function readJson2(path) {
3789
- if (!path || !existsSync21(path)) return void 0;
3369
+ if (!path || !existsSync20(path)) return void 0;
3790
3370
  try {
3791
- return JSON.parse(readFileSync17(path, "utf8"));
3371
+ return JSON.parse(readFileSync14(path, "utf8"));
3792
3372
  } catch {
3793
3373
  return void 0;
3794
3374
  }
@@ -4105,8 +3685,8 @@ function isHost2(value) {
4105
3685
  return value === "codex" || value === "claude-code" || value === "gemini-cli" || value === "antigravity";
4106
3686
  }
4107
3687
  function findPortfolioAgentAssetsDir(manifest) {
4108
- const agentAssetsDir = manifest?.executionEngine?.path ? join21(manifest.executionEngine.path, "agent-assets") : void 0;
4109
- return agentAssetsDir && existsSync22(join21(agentAssetsDir, "registry.json")) ? agentAssetsDir : void 0;
3688
+ const agentAssetsDir = manifest?.executionEngine?.path ? join20(manifest.executionEngine.path, "agent-assets") : void 0;
3689
+ return agentAssetsDir && existsSync21(join20(agentAssetsDir, "registry.json")) ? agentAssetsDir : void 0;
4110
3690
  }
4111
3691
  function printUsage4() {
4112
3692
  console.error("Usage:");
@@ -4117,69 +3697,12 @@ function printUsage4() {
4117
3697
  }
4118
3698
 
4119
3699
  // src/commands/sync.ts
4120
- import { existsSync as existsSync23, mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync8 } from "node:fs";
4121
- import { dirname as dirname12, join as join22 } from "node:path";
4122
- import { isDeepStrictEqual } from "node:util";
4123
-
4124
- // src/host-hooks/config-merge.ts
4125
- var MANAGED_EVENTS = ["Stop", "SubagentStop"];
4126
- function mergeHostHookConfig(targetPath, current, template) {
4127
- const currentRecord = asRecord(current);
4128
- const templateRecord = asRecord(template);
4129
- if (targetPath === ".agents/hooks.json") {
4130
- return {
4131
- ...currentRecord,
4132
- "pgs-compound-gate": templateRecord["pgs-compound-gate"]
4133
- };
4134
- }
4135
- const host = targetPath === ".codex/hooks.json" ? "codex" : "claude-code";
4136
- const currentHooks = asRecord(currentRecord.hooks);
4137
- const templateHooks = asRecord(templateRecord.hooks);
4138
- const mergedHooks = { ...currentHooks };
4139
- for (const event of MANAGED_EVENTS) {
4140
- const currentEntries = asArray(currentHooks[event]);
4141
- const templateEntries = asArray(templateHooks[event]);
4142
- mergedHooks[event] = replaceManagedEntries(currentEntries, templateEntries, host, event);
4143
- }
4144
- return {
4145
- ...currentRecord,
4146
- hooks: mergedHooks
4147
- };
4148
- }
4149
- function replaceManagedEntries(currentEntries, templateEntries, host, event) {
4150
- const result = [];
4151
- let insertedTemplate = false;
4152
- for (const entry of currentEntries) {
4153
- if (isManagedEntry(entry, host, event)) {
4154
- if (!insertedTemplate) {
4155
- result.push(...templateEntries);
4156
- insertedTemplate = true;
4157
- }
4158
- continue;
4159
- }
4160
- result.push(entry);
4161
- }
4162
- if (!insertedTemplate) result.push(...templateEntries);
4163
- return result;
4164
- }
4165
- function isManagedEntry(entry, host, event) {
4166
- const serialized = JSON.stringify(entry);
4167
- return serialized.includes("pro-gov host-hook") && serialized.includes(`--host ${host}`) && serialized.includes(`--event ${event}`);
4168
- }
4169
- function asRecord(value) {
4170
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
4171
- return value;
4172
- }
4173
- function asArray(value) {
4174
- return Array.isArray(value) ? value : [];
4175
- }
4176
-
4177
- // src/commands/sync.ts
3700
+ import { existsSync as existsSync22, readFileSync as readFileSync15 } from "node:fs";
3701
+ import { join as join21 } from "node:path";
4178
3702
  function runSync(args) {
4179
3703
  const check = args.includes("--check");
4180
- const applyHostHooks = args.includes("--apply-host-hooks");
4181
- if (check === applyHostHooks) {
4182
- console.error("pro-gov sync requires exactly one of --check or --apply-host-hooks.");
3704
+ if (!check) {
3705
+ console.error("pro-gov sync requires --check.");
4183
3706
  return 1;
4184
3707
  }
4185
3708
  const requestedProfile = readFlag2(args, "--profile");
@@ -4199,13 +3722,12 @@ function runSync(args) {
4199
3722
  );
4200
3723
  return 1;
4201
3724
  }
4202
- if (applyHostHooks) return applyHostHookConfigs(profile);
4203
3725
  let differences = 0;
4204
3726
  console.log("pro-gov sync check");
4205
3727
  console.log(`profile: ${profile}`);
4206
3728
  for (const file of planStarterFiles(profile)) {
4207
- const targetPath = join22(process.cwd(), file.targetPath);
4208
- if (!existsSync23(targetPath)) {
3729
+ const targetPath = join21(process.cwd(), file.targetPath);
3730
+ if (!existsSync22(targetPath)) {
4209
3731
  if (file.ownership === "optional-guardrail") continue;
4210
3732
  console.log(`missing: ${file.targetPath}`);
4211
3733
  differences += 1;
@@ -4213,8 +3735,8 @@ function runSync(args) {
4213
3735
  }
4214
3736
  if (file.ownership === "optional-guardrail") continue;
4215
3737
  if (file.ownership === "project-local-seed") continue;
4216
- const source = readFileSync18(file.absoluteSourcePath, "utf8");
4217
- const target = readFileSync18(targetPath, "utf8");
3738
+ const source = readFileSync15(file.absoluteSourcePath, "utf8");
3739
+ const target = readFileSync15(targetPath, "utf8");
4218
3740
  if (!matchesExpectedContent(file.targetPath, source, target)) {
4219
3741
  console.log(`different: ${file.targetPath}`);
4220
3742
  differences += 1;
@@ -4227,52 +3749,11 @@ function runSync(args) {
4227
3749
  console.log("sync check passed: starter files match packaged assets.");
4228
3750
  return 0;
4229
3751
  }
4230
- function applyHostHookConfigs(profile) {
4231
- if (profile !== "engineering-runtime") {
4232
- console.error("Host hooks are installed only for the engineering-runtime profile.");
4233
- return 1;
4234
- }
4235
- const root = process.cwd();
4236
- const updates = [];
4237
- try {
4238
- for (const file of planStarterFiles(profile)) {
4239
- if (!isHostHookTargetPath(file.targetPath)) continue;
4240
- const path = join22(root, file.targetPath);
4241
- const template = JSON.parse(readFileSync18(file.absoluteSourcePath, "utf8"));
4242
- const targetExists = existsSync23(path);
4243
- const current = targetExists ? JSON.parse(readFileSync18(path, "utf8")) : {};
4244
- const merged = mergeHostHookConfig(file.targetPath, current, template);
4245
- if (targetExists && isDeepStrictEqual(current, merged)) continue;
4246
- updates.push({ path, content: `${JSON.stringify(merged, null, 2)}
4247
- ` });
4248
- }
4249
- } catch (error) {
4250
- console.error(`Cannot merge host hook configuration: ${errorMessage(error)}`);
4251
- console.error("No host hook files were written.");
4252
- return 1;
4253
- }
4254
- for (const update of updates) {
4255
- mkdirSync9(dirname12(update.path), { recursive: true });
4256
- writeFileSync8(update.path, update.content);
4257
- }
4258
- console.log(`host hooks applied: ${updates.length}`);
4259
- console.log("Project-owned host config keys and non-PGS hook entries were preserved.");
4260
- return 0;
4261
- }
4262
3752
  function matchesExpectedContent(targetPath, source, target) {
4263
- if (!isHostHookTargetPath(targetPath)) {
4264
- if (targetPath.endsWith(".md")) {
4265
- return normalizeMarkdownTablePadding(source) === normalizeMarkdownTablePadding(target);
4266
- }
4267
- return source === target;
4268
- }
4269
- try {
4270
- const current = JSON.parse(target);
4271
- const template = JSON.parse(source);
4272
- return isDeepStrictEqual(current, mergeHostHookConfig(targetPath, current, template));
4273
- } catch {
4274
- return false;
3753
+ if (targetPath.endsWith(".md")) {
3754
+ return normalizeMarkdownTablePadding(source) === normalizeMarkdownTablePadding(target);
4275
3755
  }
3756
+ return source === target;
4276
3757
  }
4277
3758
  function normalizeMarkdownTablePadding(content) {
4278
3759
  return content.split("\n").map((line) => {
@@ -4289,7 +3770,7 @@ function normalizeMarkdownTableCell(cell) {
4289
3770
  }
4290
3771
  function inferInstalledProfile(root) {
4291
3772
  const installed = ["engineering-runtime", "doc-only"].filter(
4292
- (profile) => existsSync23(join22(root, `docs/governance/agents-routing/${profile}-v0.9.md`))
3773
+ (profile) => existsSync22(join21(root, `docs/governance/agents-routing/${profile}-v0.9.md`))
4293
3774
  );
4294
3775
  return installed.length === 1 ? installed[0] : void 0;
4295
3776
  }
@@ -4298,9 +3779,6 @@ function readFlag2(args, flag) {
4298
3779
  const value = index >= 0 ? args[index + 1] : void 0;
4299
3780
  return value && !value.startsWith("--") ? value : void 0;
4300
3781
  }
4301
- function errorMessage(error) {
4302
- return error instanceof Error ? error.message : String(error);
4303
- }
4304
3782
 
4305
3783
  // src/cli.ts
4306
3784
  var COMMANDS = [
@@ -4323,9 +3801,8 @@ var COMMANDS = [
4323
3801
  "lens report --target <path> --out <path>",
4324
3802
  "lens audit init --target <path> --out <path>",
4325
3803
  "lens audit check --dir <path> [--json]",
4326
- "host-hook --host <codex|claude-code|antigravity> --event <Stop|SubagentStop|...> [--compound-gate-mode off|lite|strict]",
4327
3804
  "init --profile <engineering-runtime|doc-only> <--dry-run|--apply>",
4328
- "sync <--check|--apply-host-hooks> [--profile <engineering-runtime|doc-only>]",
3805
+ "sync --check [--profile <engineering-runtime|doc-only>]",
4329
3806
  "doctor"
4330
3807
  ];
4331
3808
  var [command, subcommand] = process.argv.slice(2);
@@ -4339,7 +3816,6 @@ async function main() {
4339
3816
  if (command === "learn") return runLearn(process.argv.slice(3));
4340
3817
  if (command === "lens") return runLens(process.argv.slice(3));
4341
3818
  if (command === "portfolio") return runPortfolio(process.argv.slice(3));
4342
- if (command === "host-hook") return runHostHook(process.argv.slice(3));
4343
3819
  if (command === "init") return runInit(process.argv.slice(3));
4344
3820
  if (command === "sync") return runSync(process.argv.slice(3));
4345
3821
  if (command === "doctor") return runDoctor(process.argv.slice(3));