@pieai/pro-gov 0.3.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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/assets/docs/reference/adoption/adoption-playbook.md +215 -0
  4. package/assets/docs/reference/adoption/downstream-project-registry.md +78 -0
  5. package/assets/docs/reference/adoption/migration-v0.9.md +74 -0
  6. package/assets/docs/reference/adoption/project-relationship.md +128 -0
  7. package/assets/docs/reference/adoption/public-release-checklist.md +123 -0
  8. package/assets/docs/reference/adoption/site-publication-brief.md +86 -0
  9. package/assets/integrations/directed-development.md +36 -0
  10. package/assets/integrations/superpowers.md +52 -0
  11. package/assets/profiles/doc-only/manifest.yml +21 -0
  12. package/assets/profiles/doc-only/profile.md +37 -0
  13. package/assets/profiles/engineering-runtime/manifest.yml +22 -0
  14. package/assets/profiles/engineering-runtime/profile.md +39 -0
  15. package/assets/starter/.github/workflows/docs-check.yml +59 -0
  16. package/assets/starter/AGENTS.template.md +48 -0
  17. package/assets/starter/CLAUDE.template.md +6 -0
  18. package/assets/starter/docs/archive/.gitkeep +1 -0
  19. package/assets/starter/docs/canon/.gitkeep +1 -0
  20. package/assets/starter/docs/decisions/.gitkeep +1 -0
  21. package/assets/starter/docs/governance/agents-routing/doc-only-v0.9.md +83 -0
  22. package/assets/starter/docs/governance/agents-routing/engineering-runtime-v0.9.md +78 -0
  23. package/assets/starter/docs/governance/boundary.md +76 -0
  24. package/assets/starter/docs/governance/doc-agent-rules.md +71 -0
  25. package/assets/starter/docs/governance/doc-types.md +50 -0
  26. package/assets/starter/docs/governance/ssot-v0.9.md +166 -0
  27. package/assets/starter/docs/governance/templates/adr.md +24 -0
  28. package/assets/starter/docs/governance/templates/archive.md +23 -0
  29. package/assets/starter/docs/governance/templates/canon-entry.md +24 -0
  30. package/assets/starter/docs/governance/templates/plan.md +33 -0
  31. package/assets/starter/docs/governance/templates/policy.md +24 -0
  32. package/assets/starter/docs/governance/templates/reference.md +24 -0
  33. package/assets/starter/docs/governance/templates/spec.md +24 -0
  34. package/assets/starter/docs/plans/active/.gitkeep +1 -0
  35. package/assets/starter/docs/plans/completed/.gitkeep +1 -0
  36. package/assets/starter/docs/policy/best-practice-for-this-project.md +35 -0
  37. package/assets/starter/docs/reference/documentation-map.md +51 -0
  38. package/assets/starter/docs/reference/execution/current-work.md +36 -0
  39. package/assets/starter/docs/specs/active/.gitkeep +1 -0
  40. package/assets/starter/docs/specs/completed/.gitkeep +1 -0
  41. package/assets/starter/lefthook.template.yml +18 -0
  42. package/cli-guide.md +36 -0
  43. package/dist/cli.js +244 -0
  44. package/package.json +56 -0
package/dist/cli.js ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/assets.ts
4
+ import { existsSync, readdirSync } from "node:fs";
5
+ import { dirname, join, relative } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ var packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
+ var sourceRoot = join(packageRoot, "..", "..");
9
+ var packagedAssetsRoot = join(packageRoot, "assets");
10
+ var assetRoots = [
11
+ "starter",
12
+ "profiles",
13
+ "integrations",
14
+ "docs/reference/adoption"
15
+ ];
16
+ function listAssets() {
17
+ const root = existsSync(packagedAssetsRoot) ? packagedAssetsRoot : sourceRoot;
18
+ return assetRoots.flatMap((assetRoot) => {
19
+ const absoluteRoot = join(root, assetRoot);
20
+ if (!existsSync(absoluteRoot)) return [];
21
+ return listFiles(absoluteRoot).map((absolutePath) => ({
22
+ absolutePath,
23
+ path: toUnixPath(relative(root, absolutePath))
24
+ }));
25
+ }).sort((a, b) => a.path.localeCompare(b.path));
26
+ }
27
+ function isValidProfile(profile) {
28
+ return profile === "engineering-runtime" || profile === "doc-only";
29
+ }
30
+ function listFiles(dir) {
31
+ const files = [];
32
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
33
+ const absolutePath = join(dir, entry.name);
34
+ if (entry.isDirectory()) {
35
+ files.push(...listFiles(absolutePath));
36
+ } else if (entry.isFile()) {
37
+ files.push(absolutePath);
38
+ }
39
+ }
40
+ return files.sort();
41
+ }
42
+ function toUnixPath(path) {
43
+ return path.replaceAll("\\", "/");
44
+ }
45
+
46
+ // src/commands/assets.ts
47
+ function runAssets(args) {
48
+ const [subcommand2] = args;
49
+ if (subcommand2 !== "list") {
50
+ console.error("Usage: pro-gov assets list");
51
+ return 1;
52
+ }
53
+ for (const asset of listAssets()) {
54
+ console.log(asset.path);
55
+ }
56
+ return 0;
57
+ }
58
+
59
+ // src/commands/doctor.ts
60
+ import { spawnSync } from "node:child_process";
61
+ import { existsSync as existsSync2 } from "node:fs";
62
+ import { createRequire } from "node:module";
63
+ import { dirname as dirname2, join as join2 } from "node:path";
64
+ var REQUIRED_ASSETS = [
65
+ "starter/AGENTS.template.md",
66
+ "starter/docs/governance/ssot-v0.9.md",
67
+ "starter/docs/governance/agents-routing/engineering-runtime-v0.9.md",
68
+ "starter/docs/governance/agents-routing/doc-only-v0.9.md",
69
+ "profiles/engineering-runtime/profile.md",
70
+ "profiles/doc-only/profile.md"
71
+ ];
72
+ function runDoctor(_args) {
73
+ const assets = listAssets();
74
+ const assetPaths = new Set(assets.map((asset) => asset.path));
75
+ const missing = REQUIRED_ASSETS.filter((assetPath) => !assetPaths.has(assetPath));
76
+ console.log("pro-gov doctor");
77
+ console.log(`assets: ${assets.length}`);
78
+ if (missing.length > 0) {
79
+ for (const assetPath of missing) {
80
+ console.error(`missing packaged asset: ${assetPath}`);
81
+ }
82
+ } else {
83
+ console.log("assets: required project-governance assets found");
84
+ }
85
+ console.log(checkDocGov());
86
+ return missing.length > 0 ? 1 : 0;
87
+ }
88
+ function checkDocGov() {
89
+ const fromPath = spawnSync("doc-gov", ["--help"], {
90
+ encoding: "utf8",
91
+ stdio: "ignore"
92
+ });
93
+ if (!fromPath.error && fromPath.status === 0) {
94
+ return "doc-gov: available on PATH";
95
+ }
96
+ const dependencyCli = resolveDocGovDependencyCli();
97
+ if (!dependencyCli) {
98
+ return "doc-gov: not found; install @pieai/doc-gov beside @pieai/pro-gov for validation.";
99
+ }
100
+ const fromDependency = spawnSync(process.execPath, [dependencyCli, "--help"], {
101
+ encoding: "utf8",
102
+ stdio: "ignore"
103
+ });
104
+ if (!fromDependency.error && fromDependency.status === 0) {
105
+ return "doc-gov: available via package dependency";
106
+ }
107
+ return `doc-gov: dependency found but returned status ${fromDependency.status ?? "unknown"}`;
108
+ }
109
+ function resolveDocGovDependencyCli() {
110
+ try {
111
+ const require2 = createRequire(import.meta.url);
112
+ const packageJsonPath = require2.resolve("@pieai/doc-gov/package.json");
113
+ const cliPath = join2(dirname2(packageJsonPath), "dist/cli.js");
114
+ return existsSync2(cliPath) ? cliPath : null;
115
+ } catch {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ // src/commands/shared.ts
121
+ function planStarterFiles(profile) {
122
+ return listAssets().flatMap((asset) => {
123
+ const targetPath = starterTargetPath(asset.path);
124
+ if (!targetPath) return [];
125
+ if (profile && isOtherProfileRouting(targetPath, profile)) return [];
126
+ return [
127
+ {
128
+ sourcePath: asset.path,
129
+ targetPath,
130
+ absoluteSourcePath: asset.absolutePath
131
+ }
132
+ ];
133
+ }).sort((a, b) => a.targetPath.localeCompare(b.targetPath));
134
+ }
135
+ function isOtherProfileRouting(targetPath, profile) {
136
+ return targetPath.startsWith("docs/governance/agents-routing/") && targetPath !== `docs/governance/agents-routing/${profile}-v0.9.md`;
137
+ }
138
+ function starterTargetPath(sourcePath) {
139
+ if (sourcePath === "starter/AGENTS.template.md") return "AGENTS.md";
140
+ if (sourcePath === "starter/CLAUDE.template.md") return "CLAUDE.md";
141
+ if (sourcePath === "starter/lefthook.template.yml") return "lefthook.yml";
142
+ if (!sourcePath.startsWith("starter/")) return null;
143
+ return sourcePath.slice("starter/".length);
144
+ }
145
+
146
+ // src/commands/init.ts
147
+ function runInit(args) {
148
+ const profile = readFlag(args, "--profile");
149
+ const dryRun = args.includes("--dry-run");
150
+ if (!dryRun) {
151
+ console.error("pro-gov init requires --dry-run in this first read-only release.");
152
+ return 1;
153
+ }
154
+ if (!profile) {
155
+ console.error("Missing required flag: --profile <engineering-runtime|doc-only>");
156
+ return 1;
157
+ }
158
+ if (!isValidProfile(profile)) {
159
+ console.error(`Invalid profile: ${profile}`);
160
+ return 1;
161
+ }
162
+ console.log("pro-gov init DRY RUN");
163
+ console.log(`profile: ${profile}`);
164
+ console.log("");
165
+ console.log("Planned starter files:");
166
+ for (const file of planStarterFiles(profile)) {
167
+ console.log(` ${file.targetPath} <- ${file.sourcePath}`);
168
+ }
169
+ return 0;
170
+ }
171
+ function readFlag(args, flag) {
172
+ const index = args.indexOf(flag);
173
+ if (index === -1) return null;
174
+ const value = args[index + 1];
175
+ if (!value || value.startsWith("--")) return null;
176
+ return value;
177
+ }
178
+
179
+ // src/commands/sync.ts
180
+ import { existsSync as existsSync3, readFileSync } from "node:fs";
181
+ import { join as join3 } from "node:path";
182
+ function runSync(args) {
183
+ if (!args.includes("--check")) {
184
+ console.error("pro-gov sync requires --check in this first read-only release.");
185
+ return 1;
186
+ }
187
+ let differences = 0;
188
+ console.log("pro-gov sync check");
189
+ for (const file of planStarterFiles()) {
190
+ const targetPath = join3(process.cwd(), file.targetPath);
191
+ if (!existsSync3(targetPath)) {
192
+ console.log(`missing: ${file.targetPath}`);
193
+ differences += 1;
194
+ continue;
195
+ }
196
+ const source = readFileSync(file.absoluteSourcePath, "utf8");
197
+ const target = readFileSync(targetPath, "utf8");
198
+ if (source !== target) {
199
+ console.log(`different: ${file.targetPath}`);
200
+ differences += 1;
201
+ }
202
+ }
203
+ if (differences > 0) {
204
+ console.error(`sync check found ${differences} difference(s).`);
205
+ return 1;
206
+ }
207
+ console.log("sync check passed: starter files match packaged assets.");
208
+ return 0;
209
+ }
210
+
211
+ // src/cli.ts
212
+ var COMMANDS = [
213
+ "assets list",
214
+ "init --profile <engineering-runtime|doc-only> --dry-run",
215
+ "sync --check",
216
+ "doctor"
217
+ ];
218
+ var [command, subcommand] = process.argv.slice(2);
219
+ if (!command || command === "--help" || command === "-h") {
220
+ printHelp();
221
+ process.exitCode = command ? 0 : 1;
222
+ } else if (command === "assets" && subcommand === "list") {
223
+ process.exitCode = runAssets(process.argv.slice(3));
224
+ } else if (command === "init") {
225
+ process.exitCode = runInit(process.argv.slice(3));
226
+ } else if (command === "sync") {
227
+ process.exitCode = runSync(process.argv.slice(3));
228
+ } else if (command === "doctor") {
229
+ process.exitCode = runDoctor(process.argv.slice(3));
230
+ } else {
231
+ console.error(`Unknown command: ${[command, subcommand].filter(Boolean).join(" ")}`);
232
+ printHelp();
233
+ process.exitCode = 1;
234
+ }
235
+ function printHelp() {
236
+ console.log("pro-gov \u2014 project-level distribution kit for Project Governance System");
237
+ console.log("");
238
+ console.log("Usage: pro-gov <command> [args...]");
239
+ console.log("");
240
+ console.log("Commands:");
241
+ for (const command2 of COMMANDS) {
242
+ console.log(` ${command2}`);
243
+ }
244
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@pieai/pro-gov",
3
+ "version": "0.3.3",
4
+ "description": "Project-level distribution kit for Project Governance System.",
5
+ "keywords": [
6
+ "ai-agents",
7
+ "governance",
8
+ "project-management",
9
+ "documentation",
10
+ "cli"
11
+ ],
12
+ "homepage": "https://github.com/PieAIStudio/ProjectGovernanceSystem#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/PieAIStudio/ProjectGovernanceSystem/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "PieAI <PIEAI@hotmail.com>",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/PieAIStudio/ProjectGovernanceSystem.git",
21
+ "directory": "packages/pro-gov"
22
+ },
23
+ "bin": {
24
+ "pro-gov": "dist/cli.js"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "assets",
29
+ "README.md",
30
+ "LICENSE",
31
+ "cli-guide.md"
32
+ ],
33
+ "type": "module",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "dependencies": {
38
+ "@pieai/doc-gov": "^0.3.3"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "25.0.0",
42
+ "esbuild": "0.27.7",
43
+ "tsx": "4.21.0",
44
+ "typescript": "6.0.3"
45
+ },
46
+ "engines": {
47
+ "node": ">=22.12.0"
48
+ },
49
+ "scripts": {
50
+ "dev": "tsx src/cli.ts",
51
+ "build": "node scripts/copy-assets.mjs && node node_modules/esbuild/bin/esbuild src/cli.ts --bundle --platform=node --format=esm --target=node22 --banner:js=\"#!/usr/bin/env node\" --outfile=dist/cli.js && chmod +x dist/cli.js",
52
+ "pretest": "pnpm --filter @pieai/doc-gov build && pnpm build",
53
+ "test": "tsx --test src/**/*.test.ts",
54
+ "typecheck": "tsc -p tsconfig.json --noEmit"
55
+ }
56
+ }