@pieai/pro-gov 0.3.10 → 0.3.11
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
|
@@ -155,6 +155,15 @@ host behavior contract is covered by PGS package tests against recorded
|
|
|
155
155
|
per-host Stop/SubagentStop fixtures. Open a fresh AI session after installing or
|
|
156
156
|
changing hooks; old sessions may not reload host configuration.
|
|
157
157
|
|
|
158
|
+
Antigravity hook commands enable `PGS_HOST_HOOK_DEBUG=1` by default in PGS
|
|
159
|
+
starters. The hook writes local diagnostics to `.git/pro-gov-hook-debug/` when
|
|
160
|
+
it is actually invoked, including the input summary, decision, and output JSON.
|
|
161
|
+
This directory lives inside Git's private metadata so it does not dirty the
|
|
162
|
+
worktree. If an Antigravity test does not create a diagnostic file, inspect
|
|
163
|
+
whether the host loaded `.agents/hooks.json` before changing PGS policy.
|
|
164
|
+
`.pro-gov/assets.json` is only an asset-install manifest; its `host` field does
|
|
165
|
+
not control runtime hook dispatch.
|
|
166
|
+
|
|
158
167
|
Ponytail can be installed as an optional complexity adviser. Keep its global mode
|
|
159
168
|
`off`; test `lite` in one isolated task before considering a stronger mode.
|
|
160
169
|
Ponytail must not remove requested scope, tests, safety, accessibility, or proof.
|
|
@@ -294,6 +294,12 @@ engineering runtime profile.
|
|
|
294
294
|
It proves the project has hook files that call `pro-gov host-hook`; PGS package
|
|
295
295
|
tests prove the expected Stop/SubagentStop behavior for the supported host
|
|
296
296
|
schemas. After installing or changing hooks, validate from a fresh AI session.
|
|
297
|
+
For Antigravity, a real invocation writes diagnostics under
|
|
298
|
+
`.git/pro-gov-hook-debug/` because the starter hook command sets
|
|
299
|
+
`PGS_HOST_HOOK_DEBUG=1`. Absence of a diagnostic file after a fresh
|
|
300
|
+
Antigravity session usually means the host did not load or run
|
|
301
|
+
`.agents/hooks.json`. The `.pro-gov/assets.json` `host` field records asset
|
|
302
|
+
placement only; it does not control runtime hook dispatch.
|
|
297
303
|
|
|
298
304
|
Engineering projects should also run their local verification ladder.
|
|
299
305
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"hooks": [
|
|
6
6
|
{
|
|
7
7
|
"type": "command",
|
|
8
|
-
"command": "cd \"$(git rev-parse --show-toplevel)\" && if [ -x ./node_modules/.bin/pro-gov ]; then ./node_modules/.bin/pro-gov host-hook --host antigravity --event Stop; elif [ -f packages/pro-gov/src/cli.ts ] && command -v pnpm >/dev/null 2>&1; then pnpm --silent --filter @pieai/pro-gov dev host-hook --host antigravity --event Stop; else npx --no-install @pieai/pro-gov host-hook --host antigravity --event Stop; fi",
|
|
8
|
+
"command": "cd \"$(git rev-parse --show-toplevel)\" && if [ -x ./node_modules/.bin/pro-gov ]; then PGS_HOST_HOOK_DEBUG=1 ./node_modules/.bin/pro-gov host-hook --host antigravity --event Stop; elif [ -f packages/pro-gov/src/cli.ts ] && command -v pnpm >/dev/null 2>&1; then PGS_HOST_HOOK_DEBUG=1 pnpm --silent --filter @pieai/pro-gov dev host-hook --host antigravity --event Stop; else PGS_HOST_HOOK_DEBUG=1 npx --no-install @pieai/pro-gov host-hook --host antigravity --event Stop; fi",
|
|
9
9
|
"timeout": 30
|
|
10
10
|
}
|
|
11
11
|
]
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"hooks": [
|
|
17
17
|
{
|
|
18
18
|
"type": "command",
|
|
19
|
-
"command": "cd \"$(git rev-parse --show-toplevel)\" && if [ -x ./node_modules/.bin/pro-gov ]; then ./node_modules/.bin/pro-gov host-hook --host antigravity --event SubagentStop; elif [ -f packages/pro-gov/src/cli.ts ] && command -v pnpm >/dev/null 2>&1; then pnpm --silent --filter @pieai/pro-gov dev host-hook --host antigravity --event SubagentStop; else npx --no-install @pieai/pro-gov host-hook --host antigravity --event SubagentStop; fi",
|
|
19
|
+
"command": "cd \"$(git rev-parse --show-toplevel)\" && if [ -x ./node_modules/.bin/pro-gov ]; then PGS_HOST_HOOK_DEBUG=1 ./node_modules/.bin/pro-gov host-hook --host antigravity --event SubagentStop; elif [ -f packages/pro-gov/src/cli.ts ] && command -v pnpm >/dev/null 2>&1; then PGS_HOST_HOOK_DEBUG=1 pnpm --silent --filter @pieai/pro-gov dev host-hook --host antigravity --event SubagentStop; else PGS_HOST_HOOK_DEBUG=1 npx --no-install @pieai/pro-gov host-hook --host antigravity --event SubagentStop; fi",
|
|
20
20
|
"timeout": 30
|
|
21
21
|
}
|
|
22
22
|
]
|
package/dist/cli.js
CHANGED
|
@@ -1628,6 +1628,9 @@ function checkStrictHostHooks(root) {
|
|
|
1628
1628
|
if (!content.includes("pro-gov host-hook") || !content.includes(`--host ${entry.host}`)) {
|
|
1629
1629
|
issues.push(`host-hooks: ${entry.path} does not call pro-gov host-hook for ${entry.host}`);
|
|
1630
1630
|
}
|
|
1631
|
+
if (entry.host === "antigravity" && !content.includes("PGS_HOST_HOOK_DEBUG=1")) {
|
|
1632
|
+
issues.push(`host-hooks: ${entry.path} does not enable PGS_HOST_HOOK_DEBUG=1 for Antigravity diagnostics`);
|
|
1633
|
+
}
|
|
1631
1634
|
}
|
|
1632
1635
|
return issues;
|
|
1633
1636
|
}
|
|
@@ -1636,7 +1639,10 @@ function isEngineeringRuntimeProject(root) {
|
|
|
1636
1639
|
}
|
|
1637
1640
|
|
|
1638
1641
|
// src/commands/host-hook.ts
|
|
1639
|
-
import {
|
|
1642
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
1643
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1644
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
1645
|
+
import { basename as basename3, join as join13, resolve as resolve2 } from "node:path";
|
|
1640
1646
|
|
|
1641
1647
|
// src/host-hooks/host-hook-runner.ts
|
|
1642
1648
|
import { closeSync, openSync, readFileSync as readFileSync9, readSync, statSync as statSync3 } from "node:fs";
|
|
@@ -1645,7 +1651,11 @@ var completionSignalPatterns = [
|
|
|
1645
1651
|
/\b(done|completed|implemented|fixed|verified|validated|shipped|pushed|committed)\b/i,
|
|
1646
1652
|
/\b(tests?|typecheck|build|lint|doctor|pack)\b.*\b(pass|passed|green|succeed|succeeded|ok)\b/i,
|
|
1647
1653
|
/\b(changed|updated|modified|created|deleted|refactored)\b.*\b(files?|docs?|tests?|hooks?|configs?)\b/i,
|
|
1648
|
-
|
|
1654
|
+
/已完成|完成了|修好了|实现了|验证通过|测试通过|已经提交|已经推送|提交并推送|已提交|已推送/
|
|
1655
|
+
];
|
|
1656
|
+
var negativeCompletionSignalPatterns = [
|
|
1657
|
+
/\b(not done|not completed|not implemented|not fixed|did not complete|didn't complete|have not completed|haven't completed)\b/i,
|
|
1658
|
+
/没有完成|未完成|还没完成|没有改动|未改动|没有修改|未修改/
|
|
1649
1659
|
];
|
|
1650
1660
|
var compoundGateInstruction = [
|
|
1651
1661
|
"Before final reporting, pass the PGS Compound Gate.",
|
|
@@ -1730,6 +1740,9 @@ function normalizeStopInput(input) {
|
|
|
1730
1740
|
};
|
|
1731
1741
|
}
|
|
1732
1742
|
function looksLikeCompletedEngineeringWork(message) {
|
|
1743
|
+
if (negativeCompletionSignalPatterns.some((pattern) => pattern.test(message))) {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1733
1746
|
return completionSignalPatterns.some((pattern) => pattern.test(message));
|
|
1734
1747
|
}
|
|
1735
1748
|
function findString(input, keys) {
|
|
@@ -1843,7 +1856,9 @@ function isHostHookEvent(value) {
|
|
|
1843
1856
|
}
|
|
1844
1857
|
|
|
1845
1858
|
// src/commands/host-hook.ts
|
|
1846
|
-
|
|
1859
|
+
var defaultStdinTimeoutMs = 750;
|
|
1860
|
+
var maxDebugRawInputBytes = 256 * 1024;
|
|
1861
|
+
async function runHostHook(args) {
|
|
1847
1862
|
const host = readOption(args, "--host");
|
|
1848
1863
|
const event = readOption(args, "--event");
|
|
1849
1864
|
if (!isHostHookHost(host)) {
|
|
@@ -1854,9 +1869,18 @@ function runHostHook(args) {
|
|
|
1854
1869
|
console.error("Expected --event <Stop|SubagentStop|PreToolUse|PostToolUse|UserPromptSubmit>");
|
|
1855
1870
|
return 1;
|
|
1856
1871
|
}
|
|
1857
|
-
const
|
|
1872
|
+
const rawInput = await readStdinText(defaultStdinTimeoutMs);
|
|
1873
|
+
const input = parseStdinJson(rawInput);
|
|
1858
1874
|
const decision = evaluateHostHook({ host, event, input });
|
|
1859
1875
|
const output = formatHostHookOutput(host, event, decision);
|
|
1876
|
+
writeDebugLogIfRequested(args, {
|
|
1877
|
+
decision,
|
|
1878
|
+
event,
|
|
1879
|
+
host,
|
|
1880
|
+
input,
|
|
1881
|
+
output,
|
|
1882
|
+
rawInput
|
|
1883
|
+
});
|
|
1860
1884
|
console.log(`${JSON.stringify(output)}
|
|
1861
1885
|
`);
|
|
1862
1886
|
return 0;
|
|
@@ -1866,8 +1890,7 @@ function readOption(args, name) {
|
|
|
1866
1890
|
if (index < 0) return void 0;
|
|
1867
1891
|
return args[index + 1];
|
|
1868
1892
|
}
|
|
1869
|
-
function
|
|
1870
|
-
const raw = readFileSync10(0, "utf8").trim();
|
|
1893
|
+
function parseStdinJson(raw) {
|
|
1871
1894
|
if (!raw) return {};
|
|
1872
1895
|
try {
|
|
1873
1896
|
return JSON.parse(raw);
|
|
@@ -1875,10 +1898,106 @@ function readStdinJson() {
|
|
|
1875
1898
|
return {};
|
|
1876
1899
|
}
|
|
1877
1900
|
}
|
|
1901
|
+
function readStdinText(timeoutMs) {
|
|
1902
|
+
if (process.stdin.isTTY) {
|
|
1903
|
+
return Promise.resolve("");
|
|
1904
|
+
}
|
|
1905
|
+
process.stdin.setEncoding("utf8");
|
|
1906
|
+
return new Promise((resolveText) => {
|
|
1907
|
+
let settled = false;
|
|
1908
|
+
let content = "";
|
|
1909
|
+
const settle = () => {
|
|
1910
|
+
if (settled) return;
|
|
1911
|
+
settled = true;
|
|
1912
|
+
clearTimeout(timer);
|
|
1913
|
+
process.stdin.off("data", onData);
|
|
1914
|
+
process.stdin.off("end", settle);
|
|
1915
|
+
process.stdin.off("error", settle);
|
|
1916
|
+
process.stdin.pause();
|
|
1917
|
+
resolveText(content.trim());
|
|
1918
|
+
};
|
|
1919
|
+
const onData = (chunk) => {
|
|
1920
|
+
content += chunk.toString();
|
|
1921
|
+
};
|
|
1922
|
+
const timer = setTimeout(settle, timeoutMs);
|
|
1923
|
+
timer.unref();
|
|
1924
|
+
process.stdin.on("data", onData);
|
|
1925
|
+
process.stdin.on("end", settle);
|
|
1926
|
+
process.stdin.on("error", settle);
|
|
1927
|
+
process.stdin.resume();
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1930
|
+
function writeDebugLogIfRequested(args, record) {
|
|
1931
|
+
const explicitPath = readOption(args, "--debug-log");
|
|
1932
|
+
const enabled = explicitPath !== void 0 || process.env.PGS_HOST_HOOK_DEBUG === "1";
|
|
1933
|
+
if (!enabled) return;
|
|
1934
|
+
const debugDir = explicitPath && explicitPath.trim().length > 0 ? explicitPath : defaultDebugDir();
|
|
1935
|
+
try {
|
|
1936
|
+
mkdirSync4(debugDir, { recursive: true });
|
|
1937
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1938
|
+
const fileName = `${timestamp}-${process.pid}-${record.host}-${record.event}.json`;
|
|
1939
|
+
writeFileSync3(
|
|
1940
|
+
join13(debugDir, fileName),
|
|
1941
|
+
`${JSON.stringify(
|
|
1942
|
+
{
|
|
1943
|
+
schemaVersion: 1,
|
|
1944
|
+
cwd: process.cwd(),
|
|
1945
|
+
event: record.event,
|
|
1946
|
+
host: record.host,
|
|
1947
|
+
nodeVersion: process.version,
|
|
1948
|
+
packageVersion: readPackageVersion(),
|
|
1949
|
+
rawInput: truncateDebugRawInput(record.rawInput),
|
|
1950
|
+
input: record.input,
|
|
1951
|
+
decision: record.decision,
|
|
1952
|
+
output: record.output
|
|
1953
|
+
},
|
|
1954
|
+
null,
|
|
1955
|
+
2
|
|
1956
|
+
)}
|
|
1957
|
+
`,
|
|
1958
|
+
"utf8"
|
|
1959
|
+
);
|
|
1960
|
+
} catch {
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
function defaultDebugDir() {
|
|
1964
|
+
const gitPath = spawnSync3("git", ["rev-parse", "--git-path", "pro-gov-hook-debug"], {
|
|
1965
|
+
encoding: "utf8",
|
|
1966
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1967
|
+
});
|
|
1968
|
+
const value = gitPath.status === 0 ? gitPath.stdout.trim() : "";
|
|
1969
|
+
if (value) {
|
|
1970
|
+
return resolve2(process.cwd(), value);
|
|
1971
|
+
}
|
|
1972
|
+
return join13(tmpdir2(), "pro-gov-hook-debug", basename3(process.cwd()));
|
|
1973
|
+
}
|
|
1974
|
+
function readPackageVersion() {
|
|
1975
|
+
const packageJsonPath = resolvePackageJsonPath();
|
|
1976
|
+
if (!packageJsonPath) return void 0;
|
|
1977
|
+
try {
|
|
1978
|
+
const parsed = JSON.parse(readFileSync10(packageJsonPath, "utf8"));
|
|
1979
|
+
return typeof parsed.version === "string" ? parsed.version : void 0;
|
|
1980
|
+
} catch {
|
|
1981
|
+
return void 0;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
function resolvePackageJsonPath() {
|
|
1985
|
+
const candidates = [
|
|
1986
|
+
resolve2(process.cwd(), "packages/pro-gov/package.json"),
|
|
1987
|
+
resolve2(process.cwd(), "node_modules/@pieai/pro-gov/package.json")
|
|
1988
|
+
];
|
|
1989
|
+
return candidates.find((candidate) => existsSync13(candidate));
|
|
1990
|
+
}
|
|
1991
|
+
function truncateDebugRawInput(value) {
|
|
1992
|
+
const buffer = Buffer.from(value);
|
|
1993
|
+
if (buffer.byteLength <= maxDebugRawInputBytes) return value;
|
|
1994
|
+
return `${buffer.subarray(0, maxDebugRawInputBytes).toString("utf8")}
|
|
1995
|
+
[truncated]`;
|
|
1996
|
+
}
|
|
1878
1997
|
|
|
1879
1998
|
// src/commands/init.ts
|
|
1880
|
-
import { existsSync as
|
|
1881
|
-
import { basename as
|
|
1999
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2000
|
+
import { basename as basename4, dirname as dirname7, join as join14 } from "node:path";
|
|
1882
2001
|
|
|
1883
2002
|
// src/commands/shared.ts
|
|
1884
2003
|
function planStarterFiles(profile) {
|
|
@@ -1950,7 +2069,7 @@ function runInit(args) {
|
|
|
1950
2069
|
}
|
|
1951
2070
|
function applyStarterFiles(files, profile) {
|
|
1952
2071
|
const root = process.cwd();
|
|
1953
|
-
const conflicts = files.filter((file) =>
|
|
2072
|
+
const conflicts = files.filter((file) => existsSync14(join14(root, file.targetPath)));
|
|
1954
2073
|
if (conflicts.length > 0) {
|
|
1955
2074
|
console.error("pro-gov init is refusing to overwrite existing project files:");
|
|
1956
2075
|
for (const file of conflicts) console.error(` ${file.targetPath}`);
|
|
@@ -1958,11 +2077,11 @@ function applyStarterFiles(files, profile) {
|
|
|
1958
2077
|
return 1;
|
|
1959
2078
|
}
|
|
1960
2079
|
for (const file of files) {
|
|
1961
|
-
const targetPath =
|
|
1962
|
-
|
|
2080
|
+
const targetPath = join14(root, file.targetPath);
|
|
2081
|
+
mkdirSync5(dirname7(targetPath), { recursive: true });
|
|
1963
2082
|
const source = readFileSync11(file.absoluteSourcePath);
|
|
1964
|
-
const content = file.targetPath === "AGENTS.md" ? renderAgentsTemplate(source.toString("utf8"),
|
|
1965
|
-
|
|
2083
|
+
const content = file.targetPath === "AGENTS.md" ? renderAgentsTemplate(source.toString("utf8"), basename4(root), profile) : source;
|
|
2084
|
+
writeFileSync4(targetPath, content);
|
|
1966
2085
|
}
|
|
1967
2086
|
console.log("pro-gov init APPLIED");
|
|
1968
2087
|
console.log(`profile: ${profile}`);
|
|
@@ -1990,12 +2109,12 @@ function readFlag(args, flag) {
|
|
|
1990
2109
|
}
|
|
1991
2110
|
|
|
1992
2111
|
// src/commands/lens.ts
|
|
1993
|
-
import { mkdirSync as
|
|
2112
|
+
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "node:fs";
|
|
1994
2113
|
import { dirname as dirname9 } from "node:path";
|
|
1995
2114
|
|
|
1996
2115
|
// src/lens/audit.ts
|
|
1997
|
-
import { existsSync as
|
|
1998
|
-
import { basename as
|
|
2116
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "node:fs";
|
|
2117
|
+
import { basename as basename5, dirname as dirname8, join as join15 } from "node:path";
|
|
1999
2118
|
var REQUIRED_ARTIFACTS = [
|
|
2000
2119
|
"manifest.md",
|
|
2001
2120
|
"raw/project-lens/architecture-lens.md",
|
|
@@ -2015,20 +2134,20 @@ function createProjectLensAuditPackage(targetDir, auditDir) {
|
|
|
2015
2134
|
version: 1,
|
|
2016
2135
|
target: {
|
|
2017
2136
|
path: targetDir,
|
|
2018
|
-
name:
|
|
2137
|
+
name: basename5(targetDir) || "target"
|
|
2019
2138
|
},
|
|
2020
2139
|
requiredArtifacts: [...REQUIRED_ARTIFACTS]
|
|
2021
2140
|
};
|
|
2022
|
-
|
|
2023
|
-
writeJson(
|
|
2141
|
+
mkdirSync6(auditDir, { recursive: true });
|
|
2142
|
+
writeJson(join15(auditDir, "audit.contract.json"), contract);
|
|
2024
2143
|
for (const artifactPath of REQUIRED_ARTIFACTS) {
|
|
2025
|
-
writeTemplate(
|
|
2144
|
+
writeTemplate(join15(auditDir, artifactPath), renderArtifactTemplate(artifactPath, contract));
|
|
2026
2145
|
}
|
|
2027
2146
|
return contract;
|
|
2028
2147
|
}
|
|
2029
2148
|
function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
2030
|
-
const contractPath =
|
|
2031
|
-
if (!
|
|
2149
|
+
const contractPath = join15(auditDir, "audit.contract.json");
|
|
2150
|
+
if (!existsSync15(contractPath)) {
|
|
2032
2151
|
return {
|
|
2033
2152
|
ok: false,
|
|
2034
2153
|
auditDir,
|
|
@@ -2075,8 +2194,8 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
|
2075
2194
|
}
|
|
2076
2195
|
}
|
|
2077
2196
|
for (const artifactPath of REQUIRED_ARTIFACTS) {
|
|
2078
|
-
const absolutePath =
|
|
2079
|
-
if (!
|
|
2197
|
+
const absolutePath = join15(auditDir, artifactPath);
|
|
2198
|
+
if (!existsSync15(absolutePath)) {
|
|
2080
2199
|
issues.push({ type: "missing-required-artifact", path: artifactPath });
|
|
2081
2200
|
continue;
|
|
2082
2201
|
}
|
|
@@ -2096,13 +2215,13 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
|
2096
2215
|
};
|
|
2097
2216
|
}
|
|
2098
2217
|
function writeJson(path, value) {
|
|
2099
|
-
|
|
2100
|
-
|
|
2218
|
+
mkdirSync6(dirname8(path), { recursive: true });
|
|
2219
|
+
writeFileSync5(path, `${JSON.stringify(value, null, 2)}
|
|
2101
2220
|
`);
|
|
2102
2221
|
}
|
|
2103
2222
|
function writeTemplate(path, content) {
|
|
2104
|
-
|
|
2105
|
-
|
|
2223
|
+
mkdirSync6(dirname8(path), { recursive: true });
|
|
2224
|
+
writeFileSync5(path, content);
|
|
2106
2225
|
}
|
|
2107
2226
|
function renderArtifactTemplate(artifactPath, contract) {
|
|
2108
2227
|
const title = artifactPath.replace(/\.md$/, "").split("/").map((part) => part.replaceAll("-", " ")).join(" / ");
|
|
@@ -2339,9 +2458,9 @@ function bulletList(values) {
|
|
|
2339
2458
|
}
|
|
2340
2459
|
|
|
2341
2460
|
// src/lens/scan.ts
|
|
2342
|
-
import { spawnSync as
|
|
2343
|
-
import { existsSync as
|
|
2344
|
-
import { join as
|
|
2461
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
2462
|
+
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
|
|
2463
|
+
import { join as join16, relative as relative5 } from "node:path";
|
|
2345
2464
|
var ignoredDirectories = /* @__PURE__ */ new Set([
|
|
2346
2465
|
".git",
|
|
2347
2466
|
".next",
|
|
@@ -2358,22 +2477,22 @@ function scanProjectLensTarget(targetDir, options = {}) {
|
|
|
2358
2477
|
return {
|
|
2359
2478
|
targetDir,
|
|
2360
2479
|
aiEntryFiles: ["AGENTS.md", "CLAUDE.md"].filter(
|
|
2361
|
-
(file) =>
|
|
2480
|
+
(file) => existsSync16(join16(targetDir, file))
|
|
2362
2481
|
),
|
|
2363
2482
|
aiConfigFiles: [],
|
|
2364
2483
|
packageJson,
|
|
2365
2484
|
docs: {
|
|
2366
|
-
hasDocsDirectory:
|
|
2485
|
+
hasDocsDirectory: existsSync16(join16(targetDir, "docs")),
|
|
2367
2486
|
markdownFileCount: markdownFiles.length,
|
|
2368
2487
|
governanceFiles: markdownFiles.filter((file) => file.startsWith("docs/governance/") || file.startsWith("docs/policy/")).sort()
|
|
2369
2488
|
},
|
|
2370
2489
|
git: readGitState(targetDir),
|
|
2371
|
-
largeFiles: files.map((file) => ({ path: file, bytes: statSync4(
|
|
2490
|
+
largeFiles: files.map((file) => ({ path: file, bytes: statSync4(join16(targetDir, file)).size })).filter((file) => file.bytes >= largeFileBytes).sort((a, b) => b.bytes - a.bytes || a.path.localeCompare(b.path)).slice(0, 25)
|
|
2372
2491
|
};
|
|
2373
2492
|
}
|
|
2374
2493
|
function readPackageJson(targetDir) {
|
|
2375
|
-
const packageJsonPath =
|
|
2376
|
-
if (!
|
|
2494
|
+
const packageJsonPath = join16(targetDir, "package.json");
|
|
2495
|
+
if (!existsSync16(packageJsonPath)) return void 0;
|
|
2377
2496
|
try {
|
|
2378
2497
|
const packageJson = JSON.parse(readFileSync13(packageJsonPath, "utf8"));
|
|
2379
2498
|
return {
|
|
@@ -2398,7 +2517,7 @@ function readGitState(targetDir) {
|
|
|
2398
2517
|
};
|
|
2399
2518
|
}
|
|
2400
2519
|
function runGit(targetDir, args) {
|
|
2401
|
-
const result =
|
|
2520
|
+
const result = spawnSync4("git", ["-C", targetDir, ...args], {
|
|
2402
2521
|
encoding: "utf8"
|
|
2403
2522
|
});
|
|
2404
2523
|
if (result.status !== 0) return { ok: false };
|
|
@@ -2410,13 +2529,13 @@ function listProjectFiles(targetDir) {
|
|
|
2410
2529
|
return files.sort();
|
|
2411
2530
|
}
|
|
2412
2531
|
function collectFiles2(rootDir, currentDir, files) {
|
|
2413
|
-
if (!
|
|
2532
|
+
if (!existsSync16(currentDir)) return;
|
|
2414
2533
|
for (const entry of readdirSync6(currentDir, { withFileTypes: true })) {
|
|
2415
2534
|
if (entry.isDirectory()) {
|
|
2416
2535
|
if (ignoredDirectories.has(entry.name)) continue;
|
|
2417
|
-
collectFiles2(rootDir,
|
|
2536
|
+
collectFiles2(rootDir, join16(currentDir, entry.name), files);
|
|
2418
2537
|
} else if (entry.isFile()) {
|
|
2419
|
-
files.push(toUnixPath4(relative5(rootDir,
|
|
2538
|
+
files.push(toUnixPath4(relative5(rootDir, join16(currentDir, entry.name))));
|
|
2420
2539
|
}
|
|
2421
2540
|
}
|
|
2422
2541
|
}
|
|
@@ -2468,8 +2587,8 @@ function runLensReport(args) {
|
|
|
2468
2587
|
}
|
|
2469
2588
|
const report = scanProjectLensTarget(options.value.targetDir);
|
|
2470
2589
|
const markdown = renderProjectLensMarkdownReport(report);
|
|
2471
|
-
|
|
2472
|
-
|
|
2590
|
+
mkdirSync7(dirname9(options.value.outPath), { recursive: true });
|
|
2591
|
+
writeFileSync6(options.value.outPath, markdown);
|
|
2473
2592
|
console.log(`report: ${options.value.outPath}`);
|
|
2474
2593
|
return 0;
|
|
2475
2594
|
}
|
|
@@ -2572,12 +2691,12 @@ function printUsage2() {
|
|
|
2572
2691
|
}
|
|
2573
2692
|
|
|
2574
2693
|
// src/commands/portfolio.ts
|
|
2575
|
-
import { existsSync as
|
|
2576
|
-
import { join as
|
|
2694
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
2695
|
+
import { join as join17 } from "node:path";
|
|
2577
2696
|
|
|
2578
2697
|
// src/portfolio/manifest.ts
|
|
2579
|
-
import { existsSync as
|
|
2580
|
-
import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as
|
|
2698
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "node:fs";
|
|
2699
|
+
import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
|
|
2581
2700
|
function loadPortfolioManifest(configPath) {
|
|
2582
2701
|
let parsed;
|
|
2583
2702
|
try {
|
|
@@ -2593,7 +2712,7 @@ function loadPortfolioManifest(configPath) {
|
|
|
2593
2712
|
]
|
|
2594
2713
|
};
|
|
2595
2714
|
}
|
|
2596
|
-
const normalized = resolveManifestPaths(parsed, dirname10(
|
|
2715
|
+
const normalized = resolveManifestPaths(parsed, dirname10(resolve3(configPath)));
|
|
2597
2716
|
const issues = validatePortfolioManifest(normalized);
|
|
2598
2717
|
return {
|
|
2599
2718
|
configPath,
|
|
@@ -2607,7 +2726,7 @@ function resolveManifestPaths(value, configDir) {
|
|
|
2607
2726
|
if (!isRecord2(endpoint) || typeof endpoint.path !== "string" || isAbsolute3(endpoint.path)) {
|
|
2608
2727
|
return endpoint;
|
|
2609
2728
|
}
|
|
2610
|
-
return { ...endpoint, path:
|
|
2729
|
+
return { ...endpoint, path: resolve3(configDir, endpoint.path) };
|
|
2611
2730
|
};
|
|
2612
2731
|
return {
|
|
2613
2732
|
...value,
|
|
@@ -2735,7 +2854,7 @@ function validateEndpoint(value, field, issues) {
|
|
|
2735
2854
|
});
|
|
2736
2855
|
return;
|
|
2737
2856
|
}
|
|
2738
|
-
if (!
|
|
2857
|
+
if (!existsSync17(value.path)) {
|
|
2739
2858
|
issues.push({
|
|
2740
2859
|
type: "missing-path",
|
|
2741
2860
|
id: typeof value.id === "string" ? value.id : void 0,
|
|
@@ -3010,8 +3129,8 @@ function isHost2(value) {
|
|
|
3010
3129
|
return value === "codex" || value === "claude-code" || value === "gemini-cli" || value === "antigravity";
|
|
3011
3130
|
}
|
|
3012
3131
|
function findPortfolioAgentAssetsDir(manifest) {
|
|
3013
|
-
const agentAssetsDir = manifest?.executionEngine?.path ?
|
|
3014
|
-
return agentAssetsDir &&
|
|
3132
|
+
const agentAssetsDir = manifest?.executionEngine?.path ? join17(manifest.executionEngine.path, "agent-assets") : void 0;
|
|
3133
|
+
return agentAssetsDir && existsSync18(join17(agentAssetsDir, "registry.json")) ? agentAssetsDir : void 0;
|
|
3015
3134
|
}
|
|
3016
3135
|
function printUsage3() {
|
|
3017
3136
|
console.error("Usage:");
|
|
@@ -3021,8 +3140,8 @@ function printUsage3() {
|
|
|
3021
3140
|
}
|
|
3022
3141
|
|
|
3023
3142
|
// src/commands/sync.ts
|
|
3024
|
-
import { existsSync as
|
|
3025
|
-
import { join as
|
|
3143
|
+
import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
|
|
3144
|
+
import { join as join18 } from "node:path";
|
|
3026
3145
|
function runSync(args) {
|
|
3027
3146
|
if (!args.includes("--check")) {
|
|
3028
3147
|
console.error("pro-gov sync is read-only and requires --check.");
|
|
@@ -3049,8 +3168,8 @@ function runSync(args) {
|
|
|
3049
3168
|
console.log("pro-gov sync check");
|
|
3050
3169
|
console.log(`profile: ${profile}`);
|
|
3051
3170
|
for (const file of planStarterFiles(profile)) {
|
|
3052
|
-
const targetPath =
|
|
3053
|
-
if (!
|
|
3171
|
+
const targetPath = join18(process.cwd(), file.targetPath);
|
|
3172
|
+
if (!existsSync19(targetPath)) {
|
|
3054
3173
|
if (file.ownership === "optional-guardrail") continue;
|
|
3055
3174
|
console.log(`missing: ${file.targetPath}`);
|
|
3056
3175
|
differences += 1;
|
|
@@ -3073,7 +3192,7 @@ function runSync(args) {
|
|
|
3073
3192
|
}
|
|
3074
3193
|
function inferInstalledProfile(root) {
|
|
3075
3194
|
const installed = ["engineering-runtime", "doc-only"].filter(
|
|
3076
|
-
(profile) =>
|
|
3195
|
+
(profile) => existsSync19(join18(root, `docs/governance/agents-routing/${profile}-v0.9.md`))
|
|
3077
3196
|
);
|
|
3078
3197
|
return installed.length === 1 ? installed[0] : void 0;
|
|
3079
3198
|
}
|
|
@@ -3107,27 +3226,22 @@ var COMMANDS = [
|
|
|
3107
3226
|
"doctor"
|
|
3108
3227
|
];
|
|
3109
3228
|
var [command, subcommand] = process.argv.slice(2);
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
}
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
} else if (command === "sync") {
|
|
3124
|
-
process.exitCode = runSync(process.argv.slice(3));
|
|
3125
|
-
} else if (command === "doctor") {
|
|
3126
|
-
process.exitCode = runDoctor(process.argv.slice(3));
|
|
3127
|
-
} else {
|
|
3229
|
+
process.exitCode = await main();
|
|
3230
|
+
async function main() {
|
|
3231
|
+
if (!command || command === "--help" || command === "-h") {
|
|
3232
|
+
printHelp();
|
|
3233
|
+
return command ? 0 : 1;
|
|
3234
|
+
}
|
|
3235
|
+
if (command === "assets") return runAssets(process.argv.slice(3));
|
|
3236
|
+
if (command === "lens") return runLens(process.argv.slice(3));
|
|
3237
|
+
if (command === "portfolio") return runPortfolio(process.argv.slice(3));
|
|
3238
|
+
if (command === "host-hook") return runHostHook(process.argv.slice(3));
|
|
3239
|
+
if (command === "init") return runInit(process.argv.slice(3));
|
|
3240
|
+
if (command === "sync") return runSync(process.argv.slice(3));
|
|
3241
|
+
if (command === "doctor") return runDoctor(process.argv.slice(3));
|
|
3128
3242
|
console.error(`Unknown command: ${[command, subcommand].filter(Boolean).join(" ")}`);
|
|
3129
3243
|
printHelp();
|
|
3130
|
-
|
|
3244
|
+
return 1;
|
|
3131
3245
|
}
|
|
3132
3246
|
function printHelp() {
|
|
3133
3247
|
console.log("pro-gov \u2014 project-level distribution kit for Project Governance System");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pieai/pro-gov",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Project-level distribution kit for Project Governance System.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@pieai/doc-gov": "^0.3.
|
|
38
|
+
"@pieai/doc-gov": "^0.3.11"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "24.13.2",
|