@pieai/pro-gov 0.9.2 → 0.9.3
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 +121 -72
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -60,7 +60,6 @@ function loadAgentAssetBundles(agentAssetsDir) {
|
|
|
60
60
|
|
|
61
61
|
// src/asset-npx/maintenance.ts
|
|
62
62
|
import { createHash } from "node:crypto";
|
|
63
|
-
import { spawnSync } from "node:child_process";
|
|
64
63
|
import {
|
|
65
64
|
cpSync,
|
|
66
65
|
existsSync as existsSync3,
|
|
@@ -72,6 +71,29 @@ import {
|
|
|
72
71
|
} from "node:fs";
|
|
73
72
|
import { join as join3, relative as relative2 } from "node:path";
|
|
74
73
|
import { tmpdir } from "node:os";
|
|
74
|
+
|
|
75
|
+
// src/command-runner.ts
|
|
76
|
+
import {
|
|
77
|
+
spawnSync
|
|
78
|
+
} from "node:child_process";
|
|
79
|
+
function spawnPlatformSync(command2, args, options) {
|
|
80
|
+
if (process.platform !== "win32") return spawnSync(command2, args, options);
|
|
81
|
+
const commandLine = [command2, ...args].map(quoteWindowsArgument).join(" ");
|
|
82
|
+
return spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", `"${commandLine}"`], {
|
|
83
|
+
...options,
|
|
84
|
+
// The command line above is intentionally assembled for cmd.exe. Without
|
|
85
|
+
// this flag Node escapes its quotes before cmd.exe can parse them.
|
|
86
|
+
windowsVerbatimArguments: true
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function quoteWindowsArgument(value) {
|
|
90
|
+
if (value.length === 0 || /[\s"&|<>^]/.test(value)) {
|
|
91
|
+
return `"${value.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/asset-npx/maintenance.ts
|
|
75
97
|
function createNpxSkillsMaintenancePlan(options) {
|
|
76
98
|
assertNativeNpxRoot(options.npxRoot);
|
|
77
99
|
if (options.operation === "add" && !options.source) {
|
|
@@ -140,7 +162,8 @@ function buildNpxCommand(options) {
|
|
|
140
162
|
return command2;
|
|
141
163
|
}
|
|
142
164
|
function defaultRunner({ command: command2, cwd, timeoutMs }) {
|
|
143
|
-
const
|
|
165
|
+
const commandName = command2[0] ?? "npx";
|
|
166
|
+
const result = spawnPlatformSync(commandName, command2.slice(1), {
|
|
144
167
|
cwd,
|
|
145
168
|
encoding: "utf8",
|
|
146
169
|
timeout: timeoutMs
|
|
@@ -739,6 +762,13 @@ import { dirname as dirname4, join as join8, relative as relative5, resolve as r
|
|
|
739
762
|
// src/asset-targets/install-plan.ts
|
|
740
763
|
import { existsSync as existsSync7, lstatSync as lstatSync2, readFileSync as readFileSync4, readlinkSync, realpathSync as realpathSync2, statSync as statSync3 } from "node:fs";
|
|
741
764
|
import { basename, dirname as dirname3, join as join7, resolve } from "node:path";
|
|
765
|
+
|
|
766
|
+
// src/symlinks.ts
|
|
767
|
+
function normalizeSymlinkTarget(target) {
|
|
768
|
+
return target.replaceAll("\\", "/");
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// src/asset-targets/install-plan.ts
|
|
742
772
|
function createAssetInstallPlan(options) {
|
|
743
773
|
const placement = options.placement ?? "registry";
|
|
744
774
|
const assetsById = new Map(options.registry.assets.map((asset) => [asset.id, asset]));
|
|
@@ -1048,7 +1078,7 @@ function createLegacyClaudeAdoptions(options) {
|
|
|
1048
1078
|
const targetAbsolutePath = join7(options.targetDir, targetPath);
|
|
1049
1079
|
const compatibilityRootPath = join7(options.targetDir, ".claude/skills");
|
|
1050
1080
|
const canonicalRootPath = join7(options.targetDir, ".agents/skills");
|
|
1051
|
-
if (!lstatSync2(canonicalRootPath).isDirectory() || !lstatSync2(compatibilityRootPath).isSymbolicLink() || readlinkSync(compatibilityRootPath) !== "../.agents/skills" || realpathSync2(compatibilityRootPath) !== realpathSync2(canonicalRootPath)) {
|
|
1081
|
+
if (!lstatSync2(canonicalRootPath).isDirectory() || !lstatSync2(compatibilityRootPath).isSymbolicLink() || normalizeSymlinkTarget(readlinkSync(compatibilityRootPath)) !== "../.agents/skills" || realpathSync2(compatibilityRootPath) !== realpathSync2(canonicalRootPath)) {
|
|
1052
1082
|
throw new Error(
|
|
1053
1083
|
`Legacy Claude compatibility root is not the exact canonical alias for ${entry.id}.`
|
|
1054
1084
|
);
|
|
@@ -1289,7 +1319,7 @@ function validateAdoptedSymlink(targetDir, action) {
|
|
|
1289
1319
|
const compatibilityRootPath = join8(targetDir, action.compatibilityRootPath);
|
|
1290
1320
|
const targetAbsolutePath = join8(targetDir, action.targetPath);
|
|
1291
1321
|
const legacyAbsolutePath = join8(targetDir, action.legacyTargetPath);
|
|
1292
|
-
if (!lstatSync3(canonicalRootPath).isDirectory() || !lstatSync3(compatibilityRootPath).isSymbolicLink() || readlinkSync2(compatibilityRootPath) !== action.expectedCompatibilityRawTarget || realpathSync3(compatibilityRootPath) !== realpathSync3(canonicalRootPath)) {
|
|
1322
|
+
if (!lstatSync3(canonicalRootPath).isDirectory() || !lstatSync3(compatibilityRootPath).isSymbolicLink() || normalizeSymlinkTarget(readlinkSync2(compatibilityRootPath)) !== action.expectedCompatibilityRawTarget || realpathSync3(compatibilityRootPath) !== realpathSync3(canonicalRootPath)) {
|
|
1293
1323
|
throw new Error(
|
|
1294
1324
|
`Legacy Claude compatibility alias changed before apply: ${action.compatibilityRootPath}`
|
|
1295
1325
|
);
|
|
@@ -2217,7 +2247,6 @@ function printNpxUsage() {
|
|
|
2217
2247
|
}
|
|
2218
2248
|
|
|
2219
2249
|
// src/commands/doctor.ts
|
|
2220
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
2221
2250
|
import { existsSync as existsSync12 } from "node:fs";
|
|
2222
2251
|
import { createRequire } from "node:module";
|
|
2223
2252
|
import { dirname as dirname6, join as join12 } from "node:path";
|
|
@@ -2252,10 +2281,12 @@ function runDoctor(args) {
|
|
|
2252
2281
|
return runPackageDoctor(args);
|
|
2253
2282
|
}
|
|
2254
2283
|
function checkDocGov(options = {}) {
|
|
2255
|
-
const run = options.run ?? ((command2, args) =>
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2284
|
+
const run = options.run ?? ((command2, args) => {
|
|
2285
|
+
return spawnPlatformSync(command2, args, {
|
|
2286
|
+
encoding: "utf8",
|
|
2287
|
+
stdio: "ignore"
|
|
2288
|
+
});
|
|
2289
|
+
});
|
|
2259
2290
|
const dependencyCli = (options.resolveDependencyCli ?? resolveDocGovDependencyCli)();
|
|
2260
2291
|
if (!dependencyCli) {
|
|
2261
2292
|
const fromPath = run("doc-gov", ["--help"]);
|
|
@@ -2504,28 +2535,28 @@ var ROOT_DEFINITIONS = [
|
|
|
2504
2535
|
{
|
|
2505
2536
|
id: "pnpm-store",
|
|
2506
2537
|
label: "pnpm Store",
|
|
2507
|
-
relativePath: "Library/pnpm/store",
|
|
2538
|
+
relativePath: process.platform === "win32" ? "AppData/Local/pnpm/store" : "Library/pnpm/store",
|
|
2508
2539
|
kind: "package-cache",
|
|
2509
2540
|
note: "pnpm \u5185\u5BB9\u5BFB\u5740\u4ED3\u5E93\uFF1B\u6E05\u7406\u65F6\u53EA\u5EFA\u8BAE pnpm store prune\u3002"
|
|
2510
2541
|
},
|
|
2511
2542
|
{
|
|
2512
2543
|
id: "playwright",
|
|
2513
2544
|
label: "Playwright \u6D4F\u89C8\u5668",
|
|
2514
|
-
relativePath: "Library/Caches/ms-playwright",
|
|
2545
|
+
relativePath: process.platform === "win32" ? "AppData/Local/ms-playwright" : "Library/Caches/ms-playwright",
|
|
2515
2546
|
kind: "browser-cache",
|
|
2516
2547
|
note: "\u6D4B\u8BD5\u6D4F\u89C8\u5668\u4E8C\u8FDB\u5236\u7F13\u5B58\uFF1B\u7248\u672C\u5806\u79EF\u53EF\u80FD\u9020\u6210\u663E\u8457\u78C1\u76D8\u5360\u7528\u3002"
|
|
2517
2548
|
},
|
|
2518
2549
|
{
|
|
2519
2550
|
id: "claude-desktop",
|
|
2520
2551
|
label: "Claude Desktop",
|
|
2521
|
-
relativePath: "Library/Application Support/Claude",
|
|
2552
|
+
relativePath: process.platform === "win32" ? "AppData/Roaming/Claude" : "Library/Application Support/Claude",
|
|
2522
2553
|
kind: "ai-host",
|
|
2523
2554
|
note: "\u684C\u9762\u5E94\u7528\u8FD0\u884C\u6570\u636E\uFF0C\u9ED8\u8BA4\u53D7\u4FDD\u62A4\u3002"
|
|
2524
2555
|
},
|
|
2525
2556
|
{
|
|
2526
2557
|
id: "cursor-desktop",
|
|
2527
2558
|
label: "Cursor Desktop",
|
|
2528
|
-
relativePath: "Library/Application Support/Cursor",
|
|
2559
|
+
relativePath: process.platform === "win32" ? "AppData/Roaming/Cursor" : "Library/Application Support/Cursor",
|
|
2529
2560
|
kind: "ai-host",
|
|
2530
2561
|
note: "\u684C\u9762\u5E94\u7528\u8FD0\u884C\u6570\u636E\uFF0C\u9ED8\u8BA4\u53D7\u4FDD\u62A4\u3002"
|
|
2531
2562
|
}
|
|
@@ -2593,7 +2624,7 @@ function inspectHost(options = {}) {
|
|
|
2593
2624
|
function inspectAgentBrowser(options) {
|
|
2594
2625
|
const command2 = options.command ?? "agent-browser";
|
|
2595
2626
|
try {
|
|
2596
|
-
const
|
|
2627
|
+
const result = spawnPlatformSync(command2, ["--version"], {
|
|
2597
2628
|
encoding: "utf8",
|
|
2598
2629
|
stdio: ["ignore", "pipe", "ignore"],
|
|
2599
2630
|
// Host scans can run alongside the full portfolio test matrix. Keep the
|
|
@@ -2601,7 +2632,9 @@ function inspectAgentBrowser(options) {
|
|
|
2601
2632
|
// spawn the pinned CLI instead of misclassifying a slow start as an
|
|
2602
2633
|
// unparseable version.
|
|
2603
2634
|
timeout: 1e4
|
|
2604
|
-
})
|
|
2635
|
+
});
|
|
2636
|
+
if (result.error || result.status !== 0) throw result.error ?? new Error("command failed");
|
|
2637
|
+
const output = result.stdout.trim();
|
|
2605
2638
|
const installedVersion = output.match(/(?:^|\s)(\d+\.\d+\.\d+)(?:\s|$)/)?.[1];
|
|
2606
2639
|
if (!installedVersion) {
|
|
2607
2640
|
return {
|
|
@@ -2760,7 +2793,12 @@ function inspectFindings(homePath) {
|
|
|
2760
2793
|
id: "pnpm-store",
|
|
2761
2794
|
rootId: "pnpm-store",
|
|
2762
2795
|
label: "pnpm \u672A\u5F15\u7528\u5305\u5019\u9009",
|
|
2763
|
-
paths: [
|
|
2796
|
+
paths: [
|
|
2797
|
+
join14(
|
|
2798
|
+
homePath,
|
|
2799
|
+
process.platform === "win32" ? "AppData/Local/pnpm/store" : "Library/pnpm/store"
|
|
2800
|
+
)
|
|
2801
|
+
],
|
|
2764
2802
|
category: "cache",
|
|
2765
2803
|
confidence: "high",
|
|
2766
2804
|
disposition: "native-tool",
|
|
@@ -2772,7 +2810,13 @@ function inspectFindings(homePath) {
|
|
|
2772
2810
|
id: "playwright-browsers",
|
|
2773
2811
|
rootId: "playwright",
|
|
2774
2812
|
label: "Playwright \u6D4F\u89C8\u5668\u7248\u672C",
|
|
2775
|
-
paths: [
|
|
2813
|
+
paths: [
|
|
2814
|
+
join14(
|
|
2815
|
+
homePath,
|
|
2816
|
+
process.platform === "win32" ? "AppData/Local/ms-playwright" : "Library/Caches/ms-playwright"
|
|
2817
|
+
),
|
|
2818
|
+
join14(homePath, ".cache/ms-playwright")
|
|
2819
|
+
],
|
|
2776
2820
|
category: "duplicate-runtime",
|
|
2777
2821
|
confidence: "medium",
|
|
2778
2822
|
disposition: "native-tool",
|
|
@@ -2794,6 +2838,8 @@ function inspectFindings(homePath) {
|
|
|
2794
2838
|
});
|
|
2795
2839
|
}
|
|
2796
2840
|
function buildProtections(homePath) {
|
|
2841
|
+
const claudeDesktopPath = process.platform === "win32" ? "~/AppData/Roaming/Claude" : "~/Library/Application Support/Claude";
|
|
2842
|
+
const cursorDesktopPath = process.platform === "win32" ? "~/AppData/Roaming/Cursor" : "~/Library/Application Support/Cursor";
|
|
2797
2843
|
return [
|
|
2798
2844
|
{
|
|
2799
2845
|
label: "\u914D\u7F6E\u4E0E\u8EAB\u4EFD\u8FB9\u754C",
|
|
@@ -2812,7 +2858,7 @@ function buildProtections(homePath) {
|
|
|
2812
2858
|
},
|
|
2813
2859
|
{
|
|
2814
2860
|
label: "\u684C\u9762\u5BBF\u4E3B\u8FD0\u884C\u6570\u636E",
|
|
2815
|
-
paths: [
|
|
2861
|
+
paths: [claudeDesktopPath, cursorDesktopPath],
|
|
2816
2862
|
reason: "\u5E94\u7528\u6570\u636E\u5E93\u4E0E\u8FD0\u884C\u72B6\u6001\u6DF7\u5728\u5176\u4E2D\uFF0C\u4E0D\u80FD\u628A\u6574\u4E2A\u76EE\u5F55\u5F53\u7F13\u5B58\u3002"
|
|
2817
2863
|
}
|
|
2818
2864
|
].map((protection) => ({
|
|
@@ -2896,7 +2942,7 @@ function displayPath(path, homePath) {
|
|
|
2896
2942
|
const absolute = resolve3(path);
|
|
2897
2943
|
const withinHome = relative6(homePath, absolute);
|
|
2898
2944
|
if (withinHome === "") return "~";
|
|
2899
|
-
if (!withinHome.startsWith("..")) return `~/${withinHome}`;
|
|
2945
|
+
if (!withinHome.startsWith("..")) return `~/${withinHome.replaceAll("\\", "/")}`;
|
|
2900
2946
|
return absolute;
|
|
2901
2947
|
}
|
|
2902
2948
|
function undisplayPath(path, homePath) {
|
|
@@ -4789,7 +4835,7 @@ function formatLink(link) {
|
|
|
4789
4835
|
}
|
|
4790
4836
|
|
|
4791
4837
|
// src/lens/scan.ts
|
|
4792
|
-
import { spawnSync as
|
|
4838
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
4793
4839
|
import { existsSync as existsSync21, readFileSync as readFileSync13, statSync as statSync6 } from "node:fs";
|
|
4794
4840
|
import { homedir as homedir3 } from "node:os";
|
|
4795
4841
|
import { join as join22 } from "node:path";
|
|
@@ -4865,7 +4911,7 @@ function inspectCompatibilityLink(root, path, expectedRawTarget) {
|
|
|
4865
4911
|
if (stat.isDirectory()) return { ...base, status: "directory" };
|
|
4866
4912
|
return { ...base, status: "other" };
|
|
4867
4913
|
}
|
|
4868
|
-
const rawTarget = readlinkSync3(absolutePath);
|
|
4914
|
+
const rawTarget = normalizeSymlinkTarget(readlinkSync3(absolutePath));
|
|
4869
4915
|
const resolvedTarget = resolve6(dirname12(absolutePath), rawTarget);
|
|
4870
4916
|
const expectedPath = resolve6(dirname12(absolutePath), expectedRawTarget);
|
|
4871
4917
|
const targetStat = safeLstat2(resolvedTarget);
|
|
@@ -5071,7 +5117,7 @@ function readPackageJson(path) {
|
|
|
5071
5117
|
}
|
|
5072
5118
|
|
|
5073
5119
|
// src/repository-files.ts
|
|
5074
|
-
import { spawnSync as
|
|
5120
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
5075
5121
|
import { existsSync as existsSync20, readdirSync as readdirSync10 } from "node:fs";
|
|
5076
5122
|
import { isAbsolute as isAbsolute5, join as join21, posix as posix3, relative as relative9 } from "node:path";
|
|
5077
5123
|
var gitMaxBufferBytes = 64 * 1024 * 1024;
|
|
@@ -5154,7 +5200,7 @@ function isSafeRepositoryRelativePath(path) {
|
|
|
5154
5200
|
return path !== "" && path !== "." && !isAbsolute5(path) && !/^[a-zA-Z]:\//.test(path) && path !== ".." && !path.startsWith("../");
|
|
5155
5201
|
}
|
|
5156
5202
|
function runGit(root, args) {
|
|
5157
|
-
const result =
|
|
5203
|
+
const result = spawnSync2("git", ["-C", root, ...args], {
|
|
5158
5204
|
encoding: "utf8",
|
|
5159
5205
|
maxBuffer: gitMaxBufferBytes,
|
|
5160
5206
|
env: { ...process.env, LANG: "C", LC_ALL: "C" }
|
|
@@ -5237,7 +5283,7 @@ function readGitState(targetDir) {
|
|
|
5237
5283
|
};
|
|
5238
5284
|
}
|
|
5239
5285
|
function runGit2(targetDir, args) {
|
|
5240
|
-
const result =
|
|
5286
|
+
const result = spawnSync3("git", ["-C", targetDir, ...args], {
|
|
5241
5287
|
encoding: "utf8",
|
|
5242
5288
|
maxBuffer: 64 * 1024 * 1024
|
|
5243
5289
|
});
|
|
@@ -5415,7 +5461,7 @@ import { existsSync as existsSync33, readFileSync as readFileSync18 } from "node
|
|
|
5415
5461
|
import { join as join34 } from "node:path";
|
|
5416
5462
|
|
|
5417
5463
|
// src/portfolio/doctor.ts
|
|
5418
|
-
import { spawnSync as
|
|
5464
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
5419
5465
|
import { existsSync as existsSync24, readFileSync as readFileSync16 } from "node:fs";
|
|
5420
5466
|
import { createRequire as createRequire2 } from "node:module";
|
|
5421
5467
|
import { homedir as homedir4 } from "node:os";
|
|
@@ -5423,7 +5469,6 @@ import { dirname as dirname15, join as join25 } from "node:path";
|
|
|
5423
5469
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
5424
5470
|
|
|
5425
5471
|
// src/host-tooling/inventory.ts
|
|
5426
|
-
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
5427
5472
|
function inspectHostTooling(requirements, runner = defaultRunner2) {
|
|
5428
5473
|
const hosts = [];
|
|
5429
5474
|
const issues = [];
|
|
@@ -5497,7 +5542,7 @@ function parseHostPlugins(host, value) {
|
|
|
5497
5542
|
});
|
|
5498
5543
|
}
|
|
5499
5544
|
function defaultRunner2({ command: command2 }) {
|
|
5500
|
-
const result =
|
|
5545
|
+
const result = spawnPlatformSync(command2[0] ?? "", command2.slice(1), {
|
|
5501
5546
|
encoding: "utf8",
|
|
5502
5547
|
timeout: 1e4
|
|
5503
5548
|
});
|
|
@@ -5612,7 +5657,7 @@ function pathIsSymlink(path) {
|
|
|
5612
5657
|
}
|
|
5613
5658
|
|
|
5614
5659
|
// src/portfolio/version-policy.ts
|
|
5615
|
-
import { spawnSync as
|
|
5660
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
5616
5661
|
import { existsSync as existsSync23, lstatSync as lstatSync9, readFileSync as readFileSync15 } from "node:fs";
|
|
5617
5662
|
import { dirname as dirname14, join as join24 } from "node:path";
|
|
5618
5663
|
function inspectVersionPolicy(root, policy, projectType) {
|
|
@@ -5704,7 +5749,7 @@ function inspectRuntime(expectedName, expectedVersion) {
|
|
|
5704
5749
|
function readRuntimeVersion(name) {
|
|
5705
5750
|
if (name === "node") return process.versions.node;
|
|
5706
5751
|
if (name !== "deno") return void 0;
|
|
5707
|
-
const result =
|
|
5752
|
+
const result = spawnSync4("deno", ["--version"], { encoding: "utf8" });
|
|
5708
5753
|
if (result.status !== 0) return void 0;
|
|
5709
5754
|
return /^deno\s+(\d+\.\d+\.\d+)/m.exec(result.stdout)?.[1];
|
|
5710
5755
|
}
|
|
@@ -5922,7 +5967,7 @@ function runTargetChecks(target) {
|
|
|
5922
5967
|
];
|
|
5923
5968
|
return commands.map((command2) => {
|
|
5924
5969
|
if (!existsSync24(command2.cli)) return { name: command2.name, status: null };
|
|
5925
|
-
const result =
|
|
5970
|
+
const result = spawnSync5(process.execPath, [command2.cli, ...command2.args], {
|
|
5926
5971
|
cwd: target.path,
|
|
5927
5972
|
encoding: "utf8",
|
|
5928
5973
|
timeout: 3e4
|
|
@@ -5931,13 +5976,13 @@ function runTargetChecks(target) {
|
|
|
5931
5976
|
});
|
|
5932
5977
|
}
|
|
5933
5978
|
function inspectGit(path) {
|
|
5934
|
-
const inside =
|
|
5979
|
+
const inside = spawnSync5("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
5935
5980
|
cwd: path,
|
|
5936
5981
|
encoding: "utf8"
|
|
5937
5982
|
});
|
|
5938
5983
|
if (inside.status !== 0) return { isRepository: false, dirty: false };
|
|
5939
|
-
const status =
|
|
5940
|
-
const branch =
|
|
5984
|
+
const status = spawnSync5("git", ["status", "--porcelain"], { cwd: path, encoding: "utf8" });
|
|
5985
|
+
const branch = spawnSync5("git", ["branch", "--show-current"], { cwd: path, encoding: "utf8" });
|
|
5941
5986
|
return {
|
|
5942
5987
|
isRepository: true,
|
|
5943
5988
|
dirty: status.stdout.trim().length > 0,
|
|
@@ -6006,12 +6051,13 @@ function safeRealpath(path) {
|
|
|
6006
6051
|
}
|
|
6007
6052
|
function commandVersion(command2) {
|
|
6008
6053
|
try {
|
|
6009
|
-
const
|
|
6054
|
+
const result = spawnPlatformSync(command2, ["version"], {
|
|
6010
6055
|
encoding: "utf8",
|
|
6011
6056
|
stdio: ["ignore", "pipe", "ignore"],
|
|
6012
6057
|
timeout: 3e3
|
|
6013
6058
|
});
|
|
6014
|
-
|
|
6059
|
+
if (result.error || result.status !== 0) return void 0;
|
|
6060
|
+
return result.stdout.match(/\b\d+\.\d+\.\d+\b/)?.[0];
|
|
6015
6061
|
} catch {
|
|
6016
6062
|
return void 0;
|
|
6017
6063
|
}
|
|
@@ -6292,12 +6338,10 @@ function inspectGit2(root) {
|
|
|
6292
6338
|
}
|
|
6293
6339
|
|
|
6294
6340
|
// src/portfolio/ai-health/hosts.ts
|
|
6295
|
-
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
6296
6341
|
import { existsSync as existsSync28 } from "node:fs";
|
|
6297
6342
|
import { join as join28, resolve as resolve8, sep as sep3 } from "node:path";
|
|
6298
6343
|
|
|
6299
6344
|
// src/portfolio/ai-health/devspace.ts
|
|
6300
|
-
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
6301
6345
|
import { existsSync as existsSync27, statSync as statSync8 } from "node:fs";
|
|
6302
6346
|
import { join as join27, relative as relative10, resolve as resolve7, sep as sep2 } from "node:path";
|
|
6303
6347
|
function inspectDevSpaceHealth(options) {
|
|
@@ -6313,9 +6357,9 @@ function inspectDevSpaceHealth(options) {
|
|
|
6313
6357
|
5e3
|
|
6314
6358
|
);
|
|
6315
6359
|
const latestVersion = latestResult.ok ? latestResult.stdout.match(/\b\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b/)?.[0] : void 0;
|
|
6316
|
-
const processResult = run("pgrep", ["-f", "devspace serve"], 3e3);
|
|
6317
|
-
const pid = processResult.ok ? processResult.stdout.match(/\b\d+\b/)?.[0] : void 0;
|
|
6318
|
-
const processEnvironment = pid ? run("ps", ["eww", "-p", pid, "-o", "command="], 3e3) : void 0;
|
|
6360
|
+
const processResult = process.platform === "win32" ? run("tasklist", ["/FI", "IMAGENAME eq devspace.exe", "/FO", "CSV", "/NH"], 3e3) : run("pgrep", ["-f", "devspace serve"], 3e3);
|
|
6361
|
+
const pid = processResult.ok ? process.platform === "win32" ? processResult.stdout.match(/"devspace\.exe","(\d+)"/i)?.[1] : processResult.stdout.match(/\b\d+\b/)?.[0] : void 0;
|
|
6362
|
+
const processEnvironment = process.platform !== "win32" && pid ? run("ps", ["eww", "-p", pid, "-o", "command="], 3e3) : void 0;
|
|
6319
6363
|
const processToolMode = processEnvironment?.ok ? processEnvironment.stdout.match(
|
|
6320
6364
|
/(?:^|\s)DEVSPACE_TOOL_MODE=(minimal|full|codex)(?:\s|$)/
|
|
6321
6365
|
)?.[1] : void 0;
|
|
@@ -6327,9 +6371,9 @@ function inspectDevSpaceHealth(options) {
|
|
|
6327
6371
|
(repositoryPath) => allowedRoots.some((root) => isPathInside(repositoryPath, root))
|
|
6328
6372
|
) ? "complete" : "partial";
|
|
6329
6373
|
const bind = configExists && typeof configValue.host === "string" ? isLoopbackHost(configValue.host) ? "loopback" : "non-loopback" : "unknown";
|
|
6330
|
-
const directoryMode = existsSync27(configDirectory) ? modeString(statSync8(configDirectory).mode) : void 0;
|
|
6331
|
-
const fileMode = existsSync27(configPath) ? modeString(statSync8(configPath).mode) : void 0;
|
|
6332
|
-
const authMode = existsSync27(authPath) ? modeString(statSync8(authPath).mode) : void 0;
|
|
6374
|
+
const directoryMode = process.platform !== "win32" && existsSync27(configDirectory) ? modeString(statSync8(configDirectory).mode) : void 0;
|
|
6375
|
+
const fileMode = process.platform !== "win32" && existsSync27(configPath) ? modeString(statSync8(configPath).mode) : void 0;
|
|
6376
|
+
const authMode = process.platform !== "win32" && existsSync27(authPath) ? modeString(statSync8(authPath).mode) : void 0;
|
|
6333
6377
|
const update = installedVersion && latestVersion ? installedVersion === latestVersion ? "current" : "available" : "unknown";
|
|
6334
6378
|
const recommendations = [];
|
|
6335
6379
|
let status = "healthy";
|
|
@@ -6353,7 +6397,7 @@ function inspectDevSpaceHealth(options) {
|
|
|
6353
6397
|
if (doctor === "failed") unhealthy("devspace doctor \u672A\u901A\u8FC7\u3002");
|
|
6354
6398
|
if (portfolioCoverage === "partial") attention("DevSpace allowedRoots \u6CA1\u6709\u8986\u76D6\u5168\u90E8\u5DF2\u767B\u8BB0\u4ED3\u5E93\u3002");
|
|
6355
6399
|
if (installedResult.ok && !pid) attention("DevSpace \u5DF2\u5B89\u88C5\u4F46\u5F53\u524D\u6CA1\u6709\u8FD0\u884C\u3002");
|
|
6356
|
-
if (options.expectedToolMode && pid && processToolMode !== options.expectedToolMode) {
|
|
6400
|
+
if (options.expectedToolMode && pid && processToolMode !== void 0 && processToolMode !== options.expectedToolMode) {
|
|
6357
6401
|
attention(
|
|
6358
6402
|
`\u8FD0\u884C\u4E2D\u7684 DevSpace \u5DE5\u5177\u6A21\u5F0F\u4E3A ${processToolMode ?? "unknown"}\uFF0C\u671F\u671B ${options.expectedToolMode}\u3002`
|
|
6359
6403
|
);
|
|
@@ -6388,18 +6432,12 @@ function inspectDevSpaceHealth(options) {
|
|
|
6388
6432
|
};
|
|
6389
6433
|
}
|
|
6390
6434
|
function runDevSpaceCommand(command2, args, timeout) {
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
timeout
|
|
6398
|
-
})
|
|
6399
|
-
};
|
|
6400
|
-
} catch {
|
|
6401
|
-
return { ok: false, stdout: "" };
|
|
6402
|
-
}
|
|
6435
|
+
const result = spawnPlatformSync(command2, args, {
|
|
6436
|
+
encoding: "utf8",
|
|
6437
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
6438
|
+
timeout
|
|
6439
|
+
});
|
|
6440
|
+
return result.error || result.status !== 0 ? { ok: false, stdout: "" } : { ok: true, stdout: result.stdout };
|
|
6403
6441
|
}
|
|
6404
6442
|
function isLoopbackHost(host) {
|
|
6405
6443
|
return ["127.0.0.1", "localhost", "::1"].includes(host.trim().toLowerCase());
|
|
@@ -6490,16 +6528,16 @@ function inspectGrokProject(root, homeDir, grokVersion) {
|
|
|
6490
6528
|
});
|
|
6491
6529
|
if (!grokVersion) return empty("unavailable");
|
|
6492
6530
|
try {
|
|
6493
|
-
const
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
);
|
|
6531
|
+
const result = spawnPlatformSync("grok", ["inspect", "--json"], {
|
|
6532
|
+
cwd: root,
|
|
6533
|
+
encoding: "utf8",
|
|
6534
|
+
env: { ...process.env, HOME: homeDir, GROK_HOME: join28(homeDir, ".grok") },
|
|
6535
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
6536
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
6537
|
+
timeout: 8e3
|
|
6538
|
+
});
|
|
6539
|
+
if (result.error || result.status !== 0) return empty("failed");
|
|
6540
|
+
const value = JSON.parse(result.stdout);
|
|
6503
6541
|
if (!isRecord3(value)) return empty("failed");
|
|
6504
6542
|
const userClaudeNames = new Set(
|
|
6505
6543
|
jsonObjectKeys(join28(homeDir, MCP_DISCOVERY_PATHS.user.claudeCode), "mcpServers")
|
|
@@ -6587,6 +6625,7 @@ function inferGrokMcpScope(name, sourceType, sourcePath, root, homeDir, userClau
|
|
|
6587
6625
|
// src/portfolio/ai-health/secrets.ts
|
|
6588
6626
|
import { existsSync as existsSync29, lstatSync as lstatSync12, readdirSync as readdirSync12, statSync as statSync9 } from "node:fs";
|
|
6589
6627
|
import { join as join29, relative as relative11, sep as sep4 } from "node:path";
|
|
6628
|
+
var supportsPosixModes = process.platform !== "win32";
|
|
6590
6629
|
function inspectRepositorySecrets(root, id, secretsRoot, isRepository, environmentPolicy) {
|
|
6591
6630
|
const centralPath = join29(secretsRoot, id);
|
|
6592
6631
|
const centralRealPath = safeRealpath(centralPath);
|
|
@@ -6608,7 +6647,7 @@ function inspectRepositorySecrets(root, id, secretsRoot, isRepository, environme
|
|
|
6608
6647
|
});
|
|
6609
6648
|
return {
|
|
6610
6649
|
centralDirectory: existsSync29(centralPath) ? "present" : "absent",
|
|
6611
|
-
centralMode: existsSync29(centralPath) ? modeString(statSync9(centralPath).mode) : void 0,
|
|
6650
|
+
centralMode: supportsPosixModes && existsSync29(centralPath) ? modeString(statSync9(centralPath).mode) : void 0,
|
|
6612
6651
|
centralFiles: existsSync29(centralPath) ? collectCentralSecretFiles(centralPath) : [],
|
|
6613
6652
|
repositoryEnvFiles: envFiles
|
|
6614
6653
|
};
|
|
@@ -6637,7 +6676,7 @@ function collectEnvironmentFiles(root, current = root, depth = 0) {
|
|
|
6637
6676
|
if (!SKIP_ENV_DIRECTORIES.has(entry.name))
|
|
6638
6677
|
found.push(...collectEnvironmentFiles(root, join29(current, entry.name), depth + 1));
|
|
6639
6678
|
} else if (isEnvironmentFilename(entry.name) && !isProviderGeneratedEnvironmentFile(entry.name)) {
|
|
6640
|
-
found.push(relative11(root, join29(current, entry.name)));
|
|
6679
|
+
found.push(relative11(root, join29(current, entry.name)).replaceAll("\\", "/"));
|
|
6641
6680
|
}
|
|
6642
6681
|
}
|
|
6643
6682
|
} catch {
|
|
@@ -6652,7 +6691,11 @@ function collectCentralSecretFiles(root, current = root, depth = 0) {
|
|
|
6652
6691
|
for (const entry of readdirSync12(current, { withFileTypes: true })) {
|
|
6653
6692
|
const path = join29(current, entry.name);
|
|
6654
6693
|
if (entry.isDirectory()) found.push(...collectCentralSecretFiles(root, path, depth + 1));
|
|
6655
|
-
else
|
|
6694
|
+
else
|
|
6695
|
+
found.push({
|
|
6696
|
+
path: relative11(root, path).replaceAll("\\", "/"),
|
|
6697
|
+
mode: supportsPosixModes ? modeString(lstatSync12(path).mode) : "unknown"
|
|
6698
|
+
});
|
|
6656
6699
|
}
|
|
6657
6700
|
} catch {
|
|
6658
6701
|
return found;
|
|
@@ -6683,10 +6726,15 @@ function pointsInside(path, expectedRoot) {
|
|
|
6683
6726
|
return fromRoot === "" || fromRoot !== ".." && !fromRoot.startsWith(`..${sep4}`);
|
|
6684
6727
|
}
|
|
6685
6728
|
function hasUnsafeCentralSecretPermissions(secrets) {
|
|
6729
|
+
if (!supportsPosixModes) return false;
|
|
6686
6730
|
return secrets.centralDirectory === "present" && (secrets.centralMode !== "700" || secrets.centralFiles.some((file) => file.mode !== "600"));
|
|
6687
6731
|
}
|
|
6688
6732
|
function inspectSecretsRoot(path) {
|
|
6689
|
-
return existsSync29(path) ? {
|
|
6733
|
+
return existsSync29(path) ? {
|
|
6734
|
+
path,
|
|
6735
|
+
exists: true,
|
|
6736
|
+
...supportsPosixModes ? { mode: modeString(statSync9(path).mode) } : {}
|
|
6737
|
+
} : { path, exists: false };
|
|
6690
6738
|
}
|
|
6691
6739
|
|
|
6692
6740
|
// src/portfolio/ai-health/skills.ts
|
|
@@ -7925,9 +7973,10 @@ function findPortfolioAgentAssetsDir(manifest) {
|
|
|
7925
7973
|
}
|
|
7926
7974
|
function reportMissingPortfolioRegistry(loaded, json) {
|
|
7927
7975
|
const expectedPath = loaded.manifest?.executionEngine?.path ? join34(loaded.manifest.executionEngine.path, "agent-assets/registry.json") : "executionEngine.path/agent-assets/registry.json";
|
|
7976
|
+
const displayExpectedPath = expectedPath.replaceAll("\\", "/");
|
|
7928
7977
|
const issue = {
|
|
7929
7978
|
type: "missing-control-plane-registry",
|
|
7930
|
-
message: `Portfolio control-plane registry is required at ${
|
|
7979
|
+
message: `Portfolio control-plane registry is required at ${displayExpectedPath}; refusing the package fallback registry.`
|
|
7931
7980
|
};
|
|
7932
7981
|
if (json) {
|
|
7933
7982
|
console.log(
|
|
@@ -8022,7 +8071,7 @@ function runSync(args) {
|
|
|
8022
8071
|
continue;
|
|
8023
8072
|
}
|
|
8024
8073
|
if (file.kind === "symlink") {
|
|
8025
|
-
if (!stat.isSymbolicLink() || readlinkSync4(targetPath) !== file.linkTarget) {
|
|
8074
|
+
if (!stat.isSymbolicLink() || normalizeSymlinkTarget(readlinkSync4(targetPath)) !== file.linkTarget) {
|
|
8026
8075
|
console.log(`different: ${file.targetPath}`);
|
|
8027
8076
|
differences += 1;
|
|
8028
8077
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pieai/pro-gov",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
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.9.
|
|
38
|
+
"@pieai/doc-gov": "^0.9.3"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@pieai/swimmer-ui-kit": "1.3.2",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"dev": "tsx src/cli.ts",
|
|
56
|
-
"build": "node scripts/build
|
|
56
|
+
"build": "node scripts/build.mjs",
|
|
57
57
|
"pretest": "pnpm --filter @pieai/doc-gov build && pnpm build",
|
|
58
58
|
"test": "tsx --test src/*.test.ts src/**/*.test.ts",
|
|
59
59
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.dashboard.json --noEmit"
|