@pieai/pro-gov 0.3.14 → 0.3.15
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 +6 -0
- package/assets/docs/reference/adoption/adoption-playbook.md +5 -1
- package/assets/docs/reference/adoption/recommended-agent-tooling.md +11 -0
- package/assets/integrations/compound-engineering.md +23 -2
- package/assets/integrations/superpowers.md +1 -0
- package/assets/starter/AGENTS.template.md +2 -1
- package/assets/starter/docs/governance/templates/donor-map.md +82 -0
- package/cli-guide.md +19 -0
- package/dist/cli.js +236 -56
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -159,9 +159,15 @@ the final report to include either:
|
|
|
159
159
|
|
|
160
160
|
```text
|
|
161
161
|
Compound Gate: ran ce-compound -> <path>
|
|
162
|
+
Compound Gate: ran fallback capture -> <path>
|
|
162
163
|
Compound Gate: skipped -> <reason>
|
|
163
164
|
```
|
|
164
165
|
|
|
166
|
+
Use `ran fallback capture` only when the Compound Engineering plugin or
|
|
167
|
+
`ce-compound` skill is unavailable in the current host. It writes a minimal
|
|
168
|
+
`docs/solutions/**` learning record through `pro-gov learn capture`; it does
|
|
169
|
+
not replace or copy the full CE workflow.
|
|
170
|
+
|
|
165
171
|
Use `pro-gov doctor --strict-hooks` after syncing an engineering project to
|
|
166
172
|
verify that the host configs are wired. This is a wiring check: it proves the
|
|
167
173
|
project calls `pro-gov host-hook` for Codex, Claude Code, and Antigravity. The
|
|
@@ -209,7 +209,10 @@ If a project needs local external-workflow guidance, keep it thin in `AGENTS.md`
|
|
|
209
209
|
For engineering projects, keep Superpowers as the default engineering workflow.
|
|
210
210
|
Use Compound Engineering by default only as the post-work Compound Gate:
|
|
211
211
|
`ce-compound` captures reusable lessons when they exist; otherwise the agent
|
|
212
|
-
reports a skip reason.
|
|
212
|
+
reports a skip reason. If the current host cannot load the CE plugin, use
|
|
213
|
+
`pro-gov learn capture` as the fallback capture path and report
|
|
214
|
+
`Compound Gate: ran fallback capture -> <path>`. Full CE workflows require an
|
|
215
|
+
explicit user request.
|
|
213
216
|
|
|
214
217
|
Use PGS Learning Recall before non-trivial work:
|
|
215
218
|
|
|
@@ -228,6 +231,7 @@ skipped:
|
|
|
228
231
|
|
|
229
232
|
```text
|
|
230
233
|
Compound Gate: ran ce-compound -> <path>
|
|
234
|
+
Compound Gate: ran fallback capture -> <path>
|
|
231
235
|
Compound Gate: skipped -> <reason>
|
|
232
236
|
```
|
|
233
237
|
|
|
@@ -76,6 +76,7 @@ Compound Gate:
|
|
|
76
76
|
Superpowers completes verified work
|
|
77
77
|
-> decide with CE criteria whether reusable learning exists
|
|
78
78
|
-> run ce-compound or report a skip reason
|
|
79
|
+
-> if CE is unavailable in this host, run pro-gov learn capture as fallback
|
|
79
80
|
```
|
|
80
81
|
|
|
81
82
|
PGS Learning Recall is the matching pre-work step:
|
|
@@ -87,6 +88,16 @@ pro-gov learn recall --query "<task summary>"
|
|
|
87
88
|
It searches `docs/solutions/**` and `CONCEPTS.md` so agents can reuse prior
|
|
88
89
|
lessons without making Compound Engineering the default execution workflow.
|
|
89
90
|
|
|
91
|
+
The fallback path is deliberately smaller than CE:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pro-gov learn capture --title "<learning title>" --summary "<reusable lesson>"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Use it only when the CE plugin or skill is unavailable in the current host. It
|
|
98
|
+
keeps the lesson searchable by Learning Recall without copying CE's full
|
|
99
|
+
workflow into PGS.
|
|
100
|
+
|
|
90
101
|
Do not make routine tasks choose between Superpowers and Compound Engineering as
|
|
91
102
|
competing default engineering processes. Use CE's full `ce-plan`, `ce-work`, or
|
|
92
103
|
`lfg` flow only when the user explicitly asks for it.
|
|
@@ -57,11 +57,14 @@ Every completed non-trivial engineering task must pass the Compound Gate:
|
|
|
57
57
|
```text
|
|
58
58
|
Was there reusable learning?
|
|
59
59
|
-> yes: run compound-engineering:ce-compound
|
|
60
|
+
-> yes, but CE is unavailable: run pro-gov learn capture
|
|
60
61
|
-> no: report "Compound Gate: skipped" and give the reason
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
Use Compound Engineering's own capture criteria
|
|
64
|
-
|
|
64
|
+
Use Compound Engineering's own capture criteria when CE is available. PGS
|
|
65
|
+
fallback capture exists only so hosts without the CE plugin can still preserve a
|
|
66
|
+
searchable lesson. It is a minimal backup path, not a copied CE workflow and not
|
|
67
|
+
a separate default process.
|
|
65
68
|
|
|
66
69
|
Run `ce-compound` when the completed work produced a reusable lesson, such as:
|
|
67
70
|
|
|
@@ -81,6 +84,23 @@ Skip compounding when the work was:
|
|
|
81
84
|
The skip must be explicit in the final report. This prevents agents from
|
|
82
85
|
forgetting the gate while avoiding a low-value knowledge dump.
|
|
83
86
|
|
|
87
|
+
If `compound-engineering:ce-compound` is unavailable in the current host, write
|
|
88
|
+
a minimal fallback record:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pro-gov learn capture \
|
|
92
|
+
--title "<learning title>" \
|
|
93
|
+
--summary "<the reusable lesson future agents should recall>"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The fallback record should capture only verified, reusable learning. It should
|
|
97
|
+
not document unfinished work, trivial changes, or lessons already covered by an
|
|
98
|
+
existing `docs/solutions/**` record. Report it as:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
Compound Gate: ran fallback capture -> docs/solutions/<category>/<file>.md
|
|
102
|
+
```
|
|
103
|
+
|
|
84
104
|
## When CE May Own The Main Flow
|
|
85
105
|
|
|
86
106
|
Use the full Compound Engineering flow only when the user explicitly names it,
|
|
@@ -137,6 +157,7 @@ When a task finishes, report one of:
|
|
|
137
157
|
|
|
138
158
|
```text
|
|
139
159
|
Compound Gate: ran ce-compound -> docs/solutions/<category>/<file>.md
|
|
160
|
+
Compound Gate: ran fallback capture -> docs/solutions/<category>/<file>.md
|
|
140
161
|
Compound Gate: skipped -> <reason>
|
|
141
162
|
```
|
|
142
163
|
|
|
@@ -47,6 +47,7 @@ Ponytail, when explicitly enabled for a task, may advise on:
|
|
|
47
47
|
Compound Engineering, by default, owns:
|
|
48
48
|
|
|
49
49
|
- post-work knowledge capture through `ce-compound`;
|
|
50
|
+
- fallback capture through `pro-gov learn capture` only when CE is unavailable;
|
|
50
51
|
- `docs/solutions/**` learning records and their CE frontmatter;
|
|
51
52
|
- CE-owned external artifacts when the user explicitly invokes CE workflows.
|
|
52
53
|
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
- Engineering projects may use Superpowers, Directed Development, GStack, or other external workflows only inside the selected lane; do not copy upstream integration guides into the target project by default.
|
|
44
44
|
- For engineering projects, Superpowers is the default engineering workflow. Compound Engineering is used by default only as the post-work Compound Gate through `ce-compound`; full CE workflows require an explicit user request.
|
|
45
45
|
- For engineering projects, PGS Learning Recall is the pre-work companion to that post-work gate: recall existing lessons first, then do the work, then decide whether a new lesson should be compounded.
|
|
46
|
-
- Engineering projects should have PGS Stop hooks wired for Codex, Claude Code, and Antigravity. Before final reporting after completed engineering work, report `Compound Gate: ran ce-compound -> <path
|
|
46
|
+
- Engineering projects should have PGS Stop hooks wired for Codex, Claude Code, and Antigravity. Before final reporting after completed engineering work, report `Compound Gate: ran ce-compound -> <path>`, `Compound Gate: ran fallback capture -> <path>`, or `Compound Gate: skipped -> <reason>`.
|
|
47
|
+
- Use fallback capture only when the current host cannot load Compound Engineering; run `pro-gov learn capture --title "<learning title>" --summary "<reusable lesson>"` so Learning Recall can find the lesson later.
|
|
47
48
|
- Doc-only projects should say that Superpowers TDD and Directed Development are not enabled by default.
|
|
48
49
|
- External workflow systems such as Superpowers or GStack run inside the lane selected by this router. They must not replace this project router.
|
|
49
50
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: REPLACE-ME
|
|
3
|
+
title: Replace Me Donor Map
|
|
4
|
+
type: reference
|
|
5
|
+
status: draft
|
|
6
|
+
canonical: false
|
|
7
|
+
owner: ai-assisted
|
|
8
|
+
created: YYYY-MM-DD
|
|
9
|
+
last_reviewed: YYYY-MM-DD
|
|
10
|
+
domain: architecture
|
|
11
|
+
tags:
|
|
12
|
+
- donor-map
|
|
13
|
+
- provenance
|
|
14
|
+
pinned: false
|
|
15
|
+
related: []
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# REPLACE-ME: Replace Me Donor Map
|
|
19
|
+
|
|
20
|
+
This reference isolates what this product may reuse from the donor repository.
|
|
21
|
+
The donor is a source of parts, not a product template: research broadly,
|
|
22
|
+
isolate a donor map, and promote only current-phase needs.
|
|
23
|
+
|
|
24
|
+
## Donor Ref
|
|
25
|
+
|
|
26
|
+
- Source repository: `https://github.com/replace-me/replace-me`
|
|
27
|
+
- Intake commit (immutable pin for copied files): `<full 40-char SHA>`
|
|
28
|
+
- Research branch/ref: `main`
|
|
29
|
+
- Research commit: `<full 40-char SHA>`
|
|
30
|
+
- Latest stable tag observed during intake: `vX.Y.Z`
|
|
31
|
+
|
|
32
|
+
Copied files stay pinned to their original intake commit and hashes. Updating
|
|
33
|
+
the research pin never silently re-sources copied files.
|
|
34
|
+
|
|
35
|
+
## License And Provenance Readout
|
|
36
|
+
|
|
37
|
+
State the donor's code license, the license of every asset family taken, and
|
|
38
|
+
where each claim comes from (`LICENSE`, `CREDITS`, `README`). Explicitly name
|
|
39
|
+
anything that is not portable: paid packs, account-bound purchases, or
|
|
40
|
+
trademarked content.
|
|
41
|
+
|
|
42
|
+
## Direct Reuse
|
|
43
|
+
|
|
44
|
+
Immutable files copied byte-for-byte from the pinned intake commit. One row
|
|
45
|
+
per file.
|
|
46
|
+
|
|
47
|
+
| Id | Donor source path | Target path | License | SHA-256 | Bytes | Provenance |
|
|
48
|
+
| --- | --- | --- | --- | --- | ---: | --- |
|
|
49
|
+
| `replace-me` | `path/in/donor` | `path/in/product` | CC0-1.0 | `<sha256>` | 0 | `<claim source>` |
|
|
50
|
+
|
|
51
|
+
## Adapted And Pattern Reuse
|
|
52
|
+
|
|
53
|
+
Donor code rewritten for this product, and donor disciplines adopted without
|
|
54
|
+
copying code. One row per item.
|
|
55
|
+
|
|
56
|
+
| Donor source | Reuse class | Local adaptation |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| `path/in/donor` | adapted code / adapted pattern / pattern | What this product keeps, changes, and rejects. |
|
|
59
|
+
|
|
60
|
+
## Not Available From The Donor
|
|
61
|
+
|
|
62
|
+
Product responsibilities the donor does not solve. Listing them prevents false
|
|
63
|
+
confidence that the donor already handles them.
|
|
64
|
+
|
|
65
|
+
## Future Candidates, Not Promoted
|
|
66
|
+
|
|
67
|
+
Observed in the donor, deliberately not taken in the current phase, plus the
|
|
68
|
+
condition that would revisit each item.
|
|
69
|
+
|
|
70
|
+
## Rejected Donor Items
|
|
71
|
+
|
|
72
|
+
What must not cross into this product, and why: license risk, product-identity
|
|
73
|
+
mismatch, scale mismatch, or wholesale-transplant risk.
|
|
74
|
+
|
|
75
|
+
## Verification Contract
|
|
76
|
+
|
|
77
|
+
The command that re-verifies pinned commit, source paths, licenses, per-file
|
|
78
|
+
SHA-256, byte sizes, and manifest coverage after any donated-file change:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
replace-me-verifier
|
|
82
|
+
```
|
package/cli-guide.md
CHANGED
|
@@ -21,6 +21,7 @@ pro-gov portfolio plan --config /path/to/portfolio.json --target web-app --json
|
|
|
21
21
|
pro-gov portfolio assets-check --config /path/to/portfolio.json --json
|
|
22
22
|
pro-gov portfolio doctor --config /path/to/portfolio.json --json
|
|
23
23
|
pro-gov learn recall --query "release downstream sync" --target .
|
|
24
|
+
pro-gov learn capture --title "Fallback learning" --summary "Reusable lesson..." --target .
|
|
24
25
|
pro-gov lens inspect --target .
|
|
25
26
|
pro-gov lens report --target . --out .pro-gov/lens-report.md
|
|
26
27
|
pro-gov lens audit init --target /path/to/project --out audits/project/2026-07-01
|
|
@@ -50,6 +51,24 @@ lessons for the current task. Use it before non-trivial implementation,
|
|
|
50
51
|
debugging, release, architecture, or portfolio-sync work. It is read-only and
|
|
51
52
|
does not require a full local PGS checkout.
|
|
52
53
|
|
|
54
|
+
`learn capture` is the fallback capture path for hosts where the Compound
|
|
55
|
+
Engineering plugin or `ce-compound` skill is unavailable. Prefer CE when it is
|
|
56
|
+
installed. Use fallback capture only after verified completed work produced a
|
|
57
|
+
reusable lesson that is not already covered by an existing `docs/solutions/**`
|
|
58
|
+
record:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pro-gov learn capture \
|
|
62
|
+
--title "Use fallback capture when CE is unavailable" \
|
|
63
|
+
--summary "Capture the reusable lesson through PGS fallback capture so Learning Recall can find it later."
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then report:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
Compound Gate: ran fallback capture -> docs/solutions/<category>/<file>.md
|
|
70
|
+
```
|
|
71
|
+
|
|
53
72
|
Full upstream-checkout commands:
|
|
54
73
|
|
|
55
74
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -1742,7 +1742,7 @@ import { basename as basename3, join as join13, resolve as resolve3 } from "node
|
|
|
1742
1742
|
|
|
1743
1743
|
// src/host-hooks/host-hook-runner.ts
|
|
1744
1744
|
import { closeSync, openSync, readFileSync as readFileSync9, readSync, statSync as statSync3 } from "node:fs";
|
|
1745
|
-
var gateMarkerPattern = /Compound Gate:\s*(ran ce-compound|skipped)\s*->/i;
|
|
1745
|
+
var gateMarkerPattern = /Compound Gate:\s*(ran ce-compound|ran fallback capture|skipped)\s*->/i;
|
|
1746
1746
|
var completionSignalPatterns = [
|
|
1747
1747
|
/\b(done|completed|implemented|fixed|verified|validated|shipped|pushed|committed)\b/i,
|
|
1748
1748
|
/\b(tests?|typecheck|build|lint|doctor|pack)\b.*\b(pass|passed|green|succeed|succeeded|ok)\b/i,
|
|
@@ -1757,6 +1757,9 @@ var compoundGateInstruction = [
|
|
|
1757
1757
|
"Before final reporting, pass the PGS Compound Gate.",
|
|
1758
1758
|
"If this completed work produced reusable learning, run compound-engineering:ce-compound and report:",
|
|
1759
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>",
|
|
1760
1763
|
"If there is no reusable learning, report:",
|
|
1761
1764
|
"Compound Gate: skipped -> <reason>"
|
|
1762
1765
|
].join("\n");
|
|
@@ -2335,10 +2338,111 @@ function cleanMarkdownLine(input) {
|
|
|
2335
2338
|
return input.replace(/^#+\s*/, "").trim();
|
|
2336
2339
|
}
|
|
2337
2340
|
|
|
2341
|
+
// src/learning/capture.ts
|
|
2342
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
2343
|
+
import { join as join16, relative as relative6 } from "node:path";
|
|
2344
|
+
function captureFallbackLearning(root, options) {
|
|
2345
|
+
const title = options.title.trim();
|
|
2346
|
+
const summary = options.summary.trim();
|
|
2347
|
+
if (!title) throw new Error("title is required");
|
|
2348
|
+
if (!summary) throw new Error("summary is required");
|
|
2349
|
+
const category = slugify(options.category ?? "workflow-issues") || "workflow-issues";
|
|
2350
|
+
const moduleName = options.module?.trim() || "PGS fallback capture";
|
|
2351
|
+
const dir = join16(root, "docs/solutions", category);
|
|
2352
|
+
mkdirSync6(dir, { recursive: true });
|
|
2353
|
+
const slug = slugify(title) || "fallback-learning";
|
|
2354
|
+
const path = uniquePath(dir, slug);
|
|
2355
|
+
const content = renderFallbackLearning({
|
|
2356
|
+
title,
|
|
2357
|
+
summary,
|
|
2358
|
+
category,
|
|
2359
|
+
moduleName
|
|
2360
|
+
});
|
|
2361
|
+
writeFileSync5(path, content);
|
|
2362
|
+
return {
|
|
2363
|
+
relativePath: normalizePath2(relative6(root, path)),
|
|
2364
|
+
title,
|
|
2365
|
+
captureMode: "pgs-fallback"
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
function renderFallbackLearning(options) {
|
|
2369
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2370
|
+
const problemType = options.category === "workflow-issues" ? "workflow_issue" : "knowledge";
|
|
2371
|
+
return [
|
|
2372
|
+
"---",
|
|
2373
|
+
`title: ${yamlString(options.title)}`,
|
|
2374
|
+
`date: ${date}`,
|
|
2375
|
+
`category: ${options.category}`,
|
|
2376
|
+
`module: ${yamlString(options.moduleName)}`,
|
|
2377
|
+
`problem_type: ${problemType}`,
|
|
2378
|
+
"component: development_workflow",
|
|
2379
|
+
"severity: medium",
|
|
2380
|
+
"capture_mode: pgs-fallback",
|
|
2381
|
+
"applies_when:",
|
|
2382
|
+
' - "The Compound Engineering plugin or ce-compound skill is unavailable in the current host"',
|
|
2383
|
+
' - "Completed work produced reusable learning that should be recallable later"',
|
|
2384
|
+
"tags: [compound-gate, fallback-capture, learning-recall]",
|
|
2385
|
+
"---",
|
|
2386
|
+
"",
|
|
2387
|
+
`# ${options.title}`,
|
|
2388
|
+
"",
|
|
2389
|
+
"## Context",
|
|
2390
|
+
"",
|
|
2391
|
+
"This record was captured with the PGS fallback capture path because the full",
|
|
2392
|
+
"Compound Engineering `ce-compound` workflow was unavailable in the current",
|
|
2393
|
+
"host. Prefer `ce-compound` when the plugin is installed; use this fallback",
|
|
2394
|
+
"only to avoid losing reusable learning.",
|
|
2395
|
+
"",
|
|
2396
|
+
"## Guidance",
|
|
2397
|
+
"",
|
|
2398
|
+
options.summary,
|
|
2399
|
+
"",
|
|
2400
|
+
"## Why This Matters",
|
|
2401
|
+
"",
|
|
2402
|
+
"A Compound Gate that cannot write a learning record turns reusable experience",
|
|
2403
|
+
"into a final-report sentence that future agents cannot reliably find. The",
|
|
2404
|
+
"fallback keeps the learning searchable by `pro-gov learn recall` without",
|
|
2405
|
+
"copying or replacing the Compound Engineering workflow.",
|
|
2406
|
+
"",
|
|
2407
|
+
"## When to Apply",
|
|
2408
|
+
"",
|
|
2409
|
+
"- The work is complete and verified.",
|
|
2410
|
+
"- The lesson is reusable across future sessions or projects.",
|
|
2411
|
+
"- `compound-engineering:ce-compound` is not available in the current host.",
|
|
2412
|
+
"- The learning is not already covered by an existing `docs/solutions/**` record.",
|
|
2413
|
+
"",
|
|
2414
|
+
"## Examples",
|
|
2415
|
+
"",
|
|
2416
|
+
"```text",
|
|
2417
|
+
"Compound Gate: ran fallback capture -> docs/solutions/<category>/<file>.md",
|
|
2418
|
+
"```",
|
|
2419
|
+
""
|
|
2420
|
+
].join("\n");
|
|
2421
|
+
}
|
|
2422
|
+
function uniquePath(dir, slug) {
|
|
2423
|
+
let index = 1;
|
|
2424
|
+
let candidate = join16(dir, `${slug}.md`);
|
|
2425
|
+
while (existsSync16(candidate)) {
|
|
2426
|
+
index += 1;
|
|
2427
|
+
candidate = join16(dir, `${slug}-${index}.md`);
|
|
2428
|
+
}
|
|
2429
|
+
return candidate;
|
|
2430
|
+
}
|
|
2431
|
+
function slugify(input) {
|
|
2432
|
+
return input.toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
2433
|
+
}
|
|
2434
|
+
function yamlString(input) {
|
|
2435
|
+
return JSON.stringify(input);
|
|
2436
|
+
}
|
|
2437
|
+
function normalizePath2(path) {
|
|
2438
|
+
return path.split("\\").join("/");
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2338
2441
|
// src/commands/learn.ts
|
|
2339
2442
|
function runLearn(args) {
|
|
2340
2443
|
const [subcommand2, ...rest] = args;
|
|
2341
2444
|
if (subcommand2 === "recall") return runLearnRecall(rest);
|
|
2445
|
+
if (subcommand2 === "capture") return runLearnCapture(rest);
|
|
2342
2446
|
printUsage2();
|
|
2343
2447
|
return 1;
|
|
2344
2448
|
}
|
|
@@ -2367,6 +2471,32 @@ function runLearnRecall(args) {
|
|
|
2367
2471
|
}
|
|
2368
2472
|
return 0;
|
|
2369
2473
|
}
|
|
2474
|
+
function runLearnCapture(args) {
|
|
2475
|
+
const options = parseCaptureOptions(args);
|
|
2476
|
+
if (!options.ok) {
|
|
2477
|
+
console.error(options.error);
|
|
2478
|
+
printUsage2();
|
|
2479
|
+
return 1;
|
|
2480
|
+
}
|
|
2481
|
+
let result;
|
|
2482
|
+
try {
|
|
2483
|
+
result = captureFallbackLearning(options.value.targetDir, {
|
|
2484
|
+
title: options.value.title,
|
|
2485
|
+
summary: options.value.summary,
|
|
2486
|
+
category: options.value.category,
|
|
2487
|
+
module: options.value.module
|
|
2488
|
+
});
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
2491
|
+
return 1;
|
|
2492
|
+
}
|
|
2493
|
+
if (options.value.json) {
|
|
2494
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2495
|
+
return 0;
|
|
2496
|
+
}
|
|
2497
|
+
console.log(`Learning Capture: ${result.relativePath}`);
|
|
2498
|
+
return 0;
|
|
2499
|
+
}
|
|
2370
2500
|
function parseRecallOptions(args) {
|
|
2371
2501
|
let targetDir = process.cwd();
|
|
2372
2502
|
let query = "";
|
|
@@ -2410,6 +2540,54 @@ function parseRecallOptions(args) {
|
|
|
2410
2540
|
}
|
|
2411
2541
|
return { ok: true, value: { targetDir, query, limit, json } };
|
|
2412
2542
|
}
|
|
2543
|
+
function parseCaptureOptions(args) {
|
|
2544
|
+
let targetDir = process.cwd();
|
|
2545
|
+
let title = "";
|
|
2546
|
+
let summary = "";
|
|
2547
|
+
let category = "workflow-issues";
|
|
2548
|
+
let module;
|
|
2549
|
+
let json = false;
|
|
2550
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
2551
|
+
const arg = args[index];
|
|
2552
|
+
if (arg === "--target") {
|
|
2553
|
+
const value = readFlagValue(args, index, "--target");
|
|
2554
|
+
if (!value.ok) return value;
|
|
2555
|
+
targetDir = value.value;
|
|
2556
|
+
index += 1;
|
|
2557
|
+
} else if (arg === "--title") {
|
|
2558
|
+
const value = readFlagValue(args, index, "--title");
|
|
2559
|
+
if (!value.ok) return value;
|
|
2560
|
+
title = value.value;
|
|
2561
|
+
index += 1;
|
|
2562
|
+
} else if (arg === "--summary") {
|
|
2563
|
+
const value = readFlagValue(args, index, "--summary");
|
|
2564
|
+
if (!value.ok) return value;
|
|
2565
|
+
summary = value.value;
|
|
2566
|
+
index += 1;
|
|
2567
|
+
} else if (arg === "--category") {
|
|
2568
|
+
const value = readFlagValue(args, index, "--category");
|
|
2569
|
+
if (!value.ok) return value;
|
|
2570
|
+
category = value.value;
|
|
2571
|
+
index += 1;
|
|
2572
|
+
} else if (arg === "--module") {
|
|
2573
|
+
const value = readFlagValue(args, index, "--module");
|
|
2574
|
+
if (!value.ok) return value;
|
|
2575
|
+
module = value.value;
|
|
2576
|
+
index += 1;
|
|
2577
|
+
} else if (arg === "--json") {
|
|
2578
|
+
json = true;
|
|
2579
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
2580
|
+
return { ok: false, error: "Usage requested" };
|
|
2581
|
+
} else if (arg.startsWith("--")) {
|
|
2582
|
+
return { ok: false, error: `Unknown option: ${arg}` };
|
|
2583
|
+
} else {
|
|
2584
|
+
return { ok: false, error: `Unexpected argument: ${arg}` };
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
if (!title.trim()) return { ok: false, error: "Missing required --title <text>" };
|
|
2588
|
+
if (!summary.trim()) return { ok: false, error: "Missing required --summary <text>" };
|
|
2589
|
+
return { ok: true, value: { targetDir, title, summary, category, module, json } };
|
|
2590
|
+
}
|
|
2413
2591
|
function readFlagValue(args, index, flag) {
|
|
2414
2592
|
const value = args[index + 1];
|
|
2415
2593
|
if (!value || value.startsWith("--")) {
|
|
@@ -2419,15 +2597,16 @@ function readFlagValue(args, index, flag) {
|
|
|
2419
2597
|
}
|
|
2420
2598
|
function printUsage2() {
|
|
2421
2599
|
console.error("Usage: pro-gov learn recall --query <text> [--target <path>] [--limit <n>] [--json]");
|
|
2600
|
+
console.error("Usage: pro-gov learn capture --title <text> --summary <text> [--category <slug>] [--target <path>] [--json]");
|
|
2422
2601
|
}
|
|
2423
2602
|
|
|
2424
2603
|
// src/commands/lens.ts
|
|
2425
|
-
import { mkdirSync as
|
|
2604
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "node:fs";
|
|
2426
2605
|
import { dirname as dirname9 } from "node:path";
|
|
2427
2606
|
|
|
2428
2607
|
// src/lens/audit.ts
|
|
2429
|
-
import { existsSync as
|
|
2430
|
-
import { basename as basename6, dirname as dirname8, join as
|
|
2608
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "node:fs";
|
|
2609
|
+
import { basename as basename6, dirname as dirname8, join as join17 } from "node:path";
|
|
2431
2610
|
var REQUIRED_ARTIFACTS = [
|
|
2432
2611
|
"manifest.md",
|
|
2433
2612
|
"raw/project-lens/architecture-lens.md",
|
|
@@ -2451,16 +2630,16 @@ function createProjectLensAuditPackage(targetDir, auditDir) {
|
|
|
2451
2630
|
},
|
|
2452
2631
|
requiredArtifacts: [...REQUIRED_ARTIFACTS]
|
|
2453
2632
|
};
|
|
2454
|
-
|
|
2455
|
-
writeJson(
|
|
2633
|
+
mkdirSync7(auditDir, { recursive: true });
|
|
2634
|
+
writeJson(join17(auditDir, "audit.contract.json"), contract);
|
|
2456
2635
|
for (const artifactPath of REQUIRED_ARTIFACTS) {
|
|
2457
|
-
writeTemplate(
|
|
2636
|
+
writeTemplate(join17(auditDir, artifactPath), renderArtifactTemplate(artifactPath, contract));
|
|
2458
2637
|
}
|
|
2459
2638
|
return contract;
|
|
2460
2639
|
}
|
|
2461
2640
|
function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
2462
|
-
const contractPath =
|
|
2463
|
-
if (!
|
|
2641
|
+
const contractPath = join17(auditDir, "audit.contract.json");
|
|
2642
|
+
if (!existsSync17(contractPath)) {
|
|
2464
2643
|
return {
|
|
2465
2644
|
ok: false,
|
|
2466
2645
|
auditDir,
|
|
@@ -2507,8 +2686,8 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
|
2507
2686
|
}
|
|
2508
2687
|
}
|
|
2509
2688
|
for (const artifactPath of REQUIRED_ARTIFACTS) {
|
|
2510
|
-
const absolutePath =
|
|
2511
|
-
if (!
|
|
2689
|
+
const absolutePath = join17(auditDir, artifactPath);
|
|
2690
|
+
if (!existsSync17(absolutePath)) {
|
|
2512
2691
|
issues.push({ type: "missing-required-artifact", path: artifactPath });
|
|
2513
2692
|
continue;
|
|
2514
2693
|
}
|
|
@@ -2528,13 +2707,13 @@ function checkProjectLensAuditPackage(auditDir, options = {}) {
|
|
|
2528
2707
|
};
|
|
2529
2708
|
}
|
|
2530
2709
|
function writeJson(path, value) {
|
|
2531
|
-
|
|
2532
|
-
|
|
2710
|
+
mkdirSync7(dirname8(path), { recursive: true });
|
|
2711
|
+
writeFileSync6(path, `${JSON.stringify(value, null, 2)}
|
|
2533
2712
|
`);
|
|
2534
2713
|
}
|
|
2535
2714
|
function writeTemplate(path, content) {
|
|
2536
|
-
|
|
2537
|
-
|
|
2715
|
+
mkdirSync7(dirname8(path), { recursive: true });
|
|
2716
|
+
writeFileSync6(path, content);
|
|
2538
2717
|
}
|
|
2539
2718
|
function renderArtifactTemplate(artifactPath, contract) {
|
|
2540
2719
|
const title = artifactPath.replace(/\.md$/, "").split("/").map((part) => part.replaceAll("-", " ")).join(" / ");
|
|
@@ -2772,8 +2951,8 @@ function bulletList(values) {
|
|
|
2772
2951
|
|
|
2773
2952
|
// src/lens/scan.ts
|
|
2774
2953
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
2775
|
-
import { existsSync as
|
|
2776
|
-
import { join as
|
|
2954
|
+
import { existsSync as existsSync18, readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
2955
|
+
import { join as join18, relative as relative7 } from "node:path";
|
|
2777
2956
|
var ignoredDirectories = /* @__PURE__ */ new Set([
|
|
2778
2957
|
".git",
|
|
2779
2958
|
".next",
|
|
@@ -2790,22 +2969,22 @@ function scanProjectLensTarget(targetDir, options = {}) {
|
|
|
2790
2969
|
return {
|
|
2791
2970
|
targetDir,
|
|
2792
2971
|
aiEntryFiles: ["AGENTS.md", "CLAUDE.md"].filter(
|
|
2793
|
-
(file) =>
|
|
2972
|
+
(file) => existsSync18(join18(targetDir, file))
|
|
2794
2973
|
),
|
|
2795
2974
|
aiConfigFiles: [],
|
|
2796
2975
|
packageJson,
|
|
2797
2976
|
docs: {
|
|
2798
|
-
hasDocsDirectory:
|
|
2977
|
+
hasDocsDirectory: existsSync18(join18(targetDir, "docs")),
|
|
2799
2978
|
markdownFileCount: markdownFiles.length,
|
|
2800
2979
|
governanceFiles: markdownFiles.filter((file) => file.startsWith("docs/governance/") || file.startsWith("docs/policy/")).sort()
|
|
2801
2980
|
},
|
|
2802
2981
|
git: readGitState(targetDir),
|
|
2803
|
-
largeFiles: files.map((file) => ({ path: file, bytes: statSync4(
|
|
2982
|
+
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)
|
|
2804
2983
|
};
|
|
2805
2984
|
}
|
|
2806
2985
|
function readPackageJson(targetDir) {
|
|
2807
|
-
const packageJsonPath =
|
|
2808
|
-
if (!
|
|
2986
|
+
const packageJsonPath = join18(targetDir, "package.json");
|
|
2987
|
+
if (!existsSync18(packageJsonPath)) return void 0;
|
|
2809
2988
|
try {
|
|
2810
2989
|
const packageJson = JSON.parse(readFileSync14(packageJsonPath, "utf8"));
|
|
2811
2990
|
return {
|
|
@@ -2842,13 +3021,13 @@ function listProjectFiles(targetDir) {
|
|
|
2842
3021
|
return files.sort();
|
|
2843
3022
|
}
|
|
2844
3023
|
function collectFiles2(rootDir, currentDir, files) {
|
|
2845
|
-
if (!
|
|
3024
|
+
if (!existsSync18(currentDir)) return;
|
|
2846
3025
|
for (const entry of readdirSync7(currentDir, { withFileTypes: true })) {
|
|
2847
3026
|
if (entry.isDirectory()) {
|
|
2848
3027
|
if (ignoredDirectories.has(entry.name)) continue;
|
|
2849
|
-
collectFiles2(rootDir,
|
|
3028
|
+
collectFiles2(rootDir, join18(currentDir, entry.name), files);
|
|
2850
3029
|
} else if (entry.isFile()) {
|
|
2851
|
-
files.push(toUnixPath4(
|
|
3030
|
+
files.push(toUnixPath4(relative7(rootDir, join18(currentDir, entry.name))));
|
|
2852
3031
|
}
|
|
2853
3032
|
}
|
|
2854
3033
|
}
|
|
@@ -2900,8 +3079,8 @@ function runLensReport(args) {
|
|
|
2900
3079
|
}
|
|
2901
3080
|
const report = scanProjectLensTarget(options.value.targetDir);
|
|
2902
3081
|
const markdown = renderProjectLensMarkdownReport(report);
|
|
2903
|
-
|
|
2904
|
-
|
|
3082
|
+
mkdirSync8(dirname9(options.value.outPath), { recursive: true });
|
|
3083
|
+
writeFileSync7(options.value.outPath, markdown);
|
|
2905
3084
|
console.log(`report: ${options.value.outPath}`);
|
|
2906
3085
|
return 0;
|
|
2907
3086
|
}
|
|
@@ -3004,11 +3183,11 @@ function printUsage3() {
|
|
|
3004
3183
|
}
|
|
3005
3184
|
|
|
3006
3185
|
// src/commands/portfolio.ts
|
|
3007
|
-
import { existsSync as
|
|
3008
|
-
import { join as
|
|
3186
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
3187
|
+
import { join as join21 } from "node:path";
|
|
3009
3188
|
|
|
3010
3189
|
// src/portfolio/manifest.ts
|
|
3011
|
-
import { existsSync as
|
|
3190
|
+
import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
|
|
3012
3191
|
import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
|
|
3013
3192
|
function loadPortfolioManifest(configPath) {
|
|
3014
3193
|
let parsed;
|
|
@@ -3173,7 +3352,7 @@ function validateEndpoint(value, field, issues) {
|
|
|
3173
3352
|
});
|
|
3174
3353
|
return;
|
|
3175
3354
|
}
|
|
3176
|
-
if (!
|
|
3355
|
+
if (!existsSync19(value.path)) {
|
|
3177
3356
|
issues.push({
|
|
3178
3357
|
type: "missing-path",
|
|
3179
3358
|
id: typeof value.id === "string" ? value.id : void 0,
|
|
@@ -3244,9 +3423,9 @@ function isRecord2(value) {
|
|
|
3244
3423
|
|
|
3245
3424
|
// src/portfolio/doctor.ts
|
|
3246
3425
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
3247
|
-
import { existsSync as
|
|
3426
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
|
|
3248
3427
|
import { createRequire as createRequire2 } from "node:module";
|
|
3249
|
-
import { dirname as dirname11, join as
|
|
3428
|
+
import { dirname as dirname11, join as join20 } from "node:path";
|
|
3250
3429
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
3251
3430
|
|
|
3252
3431
|
// src/host-tooling/inventory.ts
|
|
@@ -3337,13 +3516,13 @@ function isRecord3(value) {
|
|
|
3337
3516
|
}
|
|
3338
3517
|
|
|
3339
3518
|
// src/portfolio/asset-state.ts
|
|
3340
|
-
import { existsSync as
|
|
3341
|
-
import { join as
|
|
3519
|
+
import { existsSync as existsSync20, lstatSync as lstatSync5, readFileSync as readFileSync16 } from "node:fs";
|
|
3520
|
+
import { join as join19 } from "node:path";
|
|
3342
3521
|
function comparePortfolioAssetState(options) {
|
|
3343
3522
|
const expectedManifest = readPlanDocument(options.expectedPlan, ".pro-gov/assets.json");
|
|
3344
3523
|
const expectedLock = readPlanDocument(options.expectedPlan, ".pro-gov/assets.lock.json");
|
|
3345
|
-
const currentManifest = readJsonFile(
|
|
3346
|
-
const currentLock = readJsonFile(
|
|
3524
|
+
const currentManifest = readJsonFile(join19(options.targetDir, ".pro-gov/assets.json"));
|
|
3525
|
+
const currentLock = readJsonFile(join19(options.targetDir, ".pro-gov/assets.lock.json"));
|
|
3347
3526
|
const issues = [];
|
|
3348
3527
|
if (!sameStrings(currentManifest?.bundleIds, expectedManifest?.bundleIds)) {
|
|
3349
3528
|
issues.push({
|
|
@@ -3366,7 +3545,7 @@ function comparePortfolioAssetState(options) {
|
|
|
3366
3545
|
const expectedTargets = new Set((expectedLock?.assets ?? []).map((entry) => entry.targetPath));
|
|
3367
3546
|
for (const entry of currentLock?.assets ?? []) {
|
|
3368
3547
|
if (expectedTargets.has(entry.targetPath)) continue;
|
|
3369
|
-
const targetAbsolutePath =
|
|
3548
|
+
const targetAbsolutePath = join19(options.targetDir, entry.targetPath);
|
|
3370
3549
|
if (!pathIsSymlink(targetAbsolutePath)) continue;
|
|
3371
3550
|
issues.push({
|
|
3372
3551
|
type: "orphaned-managed-symlink",
|
|
@@ -3388,7 +3567,7 @@ function readPlanDocument(plan, targetPath) {
|
|
|
3388
3567
|
}
|
|
3389
3568
|
}
|
|
3390
3569
|
function readJsonFile(path) {
|
|
3391
|
-
if (!
|
|
3570
|
+
if (!existsSync20(path)) return void 0;
|
|
3392
3571
|
try {
|
|
3393
3572
|
return JSON.parse(readFileSync16(path, "utf8"));
|
|
3394
3573
|
} catch {
|
|
@@ -3439,11 +3618,11 @@ function inspectPortfolio(options) {
|
|
|
3439
3618
|
function inspectTarget(options) {
|
|
3440
3619
|
const { target } = options;
|
|
3441
3620
|
const issues = [];
|
|
3442
|
-
const packageJson = readJson2(
|
|
3621
|
+
const packageJson = readJson2(join20(target.path, "package.json"));
|
|
3443
3622
|
const packages = {};
|
|
3444
3623
|
for (const packageName of ["@pieai/pro-gov", "@pieai/doc-gov"]) {
|
|
3445
3624
|
const declared = packageJson?.devDependencies?.[packageName] ?? packageJson?.dependencies?.[packageName];
|
|
3446
|
-
const installedPackage = readJson2(
|
|
3625
|
+
const installedPackage = readJson2(join20(target.path, "node_modules", packageName, "package.json"));
|
|
3447
3626
|
const installed = installedPackage?.version;
|
|
3448
3627
|
const expected = options.expectedPackageVersions[packageName];
|
|
3449
3628
|
packages[packageName] = { declared, installed, expected };
|
|
@@ -3497,7 +3676,7 @@ function inspectTarget(options) {
|
|
|
3497
3676
|
type: "asset-lock-drift",
|
|
3498
3677
|
message: error instanceof Error ? error.message : String(error)
|
|
3499
3678
|
});
|
|
3500
|
-
if (!
|
|
3679
|
+
if (!existsSync21(join20(target.path, ".pro-gov/assets.json"))) {
|
|
3501
3680
|
issues.push({ type: "bundle-drift", message: "Target asset manifest is missing." });
|
|
3502
3681
|
}
|
|
3503
3682
|
}
|
|
@@ -3512,15 +3691,15 @@ function inspectTarget(options) {
|
|
|
3512
3691
|
};
|
|
3513
3692
|
}
|
|
3514
3693
|
function readTargetAssetHost(targetDir) {
|
|
3515
|
-
const lockfile = readJson2(
|
|
3694
|
+
const lockfile = readJson2(join20(targetDir, ".pro-gov/assets.lock.json"));
|
|
3516
3695
|
return isAssetRegistryHost(lockfile?.host) ? lockfile.host : void 0;
|
|
3517
3696
|
}
|
|
3518
3697
|
function isAssetRegistryHost(value) {
|
|
3519
3698
|
return value === "codex" || value === "claude-code" || value === "gemini-cli" || value === "antigravity";
|
|
3520
3699
|
}
|
|
3521
3700
|
function runTargetChecks(target) {
|
|
3522
|
-
const proGovCli =
|
|
3523
|
-
const docGovCli =
|
|
3701
|
+
const proGovCli = join20(target.path, "node_modules/@pieai/pro-gov/dist/cli.js");
|
|
3702
|
+
const docGovCli = join20(target.path, "node_modules/@pieai/doc-gov/dist/cli.js");
|
|
3524
3703
|
const commands = [
|
|
3525
3704
|
{
|
|
3526
3705
|
name: "pro-gov doctor",
|
|
@@ -3531,7 +3710,7 @@ function runTargetChecks(target) {
|
|
|
3531
3710
|
{ name: "doc-gov scan --check", cli: docGovCli, args: ["scan", "--check"] }
|
|
3532
3711
|
];
|
|
3533
3712
|
return commands.map((command2) => {
|
|
3534
|
-
if (!
|
|
3713
|
+
if (!existsSync21(command2.cli)) return { name: command2.name, status: null };
|
|
3535
3714
|
const result = spawnSync6(process.execPath, [command2.cli, ...command2.args], {
|
|
3536
3715
|
cwd: target.path,
|
|
3537
3716
|
encoding: "utf8",
|
|
@@ -3572,14 +3751,14 @@ function getExpectedPackageVersions() {
|
|
|
3572
3751
|
function findOwnPackageJson() {
|
|
3573
3752
|
let current = dirname11(fileURLToPath3(import.meta.url));
|
|
3574
3753
|
for (let depth = 0; depth < 5; depth += 1) {
|
|
3575
|
-
const candidate =
|
|
3576
|
-
if (
|
|
3754
|
+
const candidate = join20(current, "package.json");
|
|
3755
|
+
if (existsSync21(candidate)) return candidate;
|
|
3577
3756
|
current = dirname11(current);
|
|
3578
3757
|
}
|
|
3579
3758
|
return "";
|
|
3580
3759
|
}
|
|
3581
3760
|
function readJson2(path) {
|
|
3582
|
-
if (!path || !
|
|
3761
|
+
if (!path || !existsSync21(path)) return void 0;
|
|
3583
3762
|
try {
|
|
3584
3763
|
return JSON.parse(readFileSync17(path, "utf8"));
|
|
3585
3764
|
} catch {
|
|
@@ -3898,8 +4077,8 @@ function isHost2(value) {
|
|
|
3898
4077
|
return value === "codex" || value === "claude-code" || value === "gemini-cli" || value === "antigravity";
|
|
3899
4078
|
}
|
|
3900
4079
|
function findPortfolioAgentAssetsDir(manifest) {
|
|
3901
|
-
const agentAssetsDir = manifest?.executionEngine?.path ?
|
|
3902
|
-
return agentAssetsDir &&
|
|
4080
|
+
const agentAssetsDir = manifest?.executionEngine?.path ? join21(manifest.executionEngine.path, "agent-assets") : void 0;
|
|
4081
|
+
return agentAssetsDir && existsSync22(join21(agentAssetsDir, "registry.json")) ? agentAssetsDir : void 0;
|
|
3903
4082
|
}
|
|
3904
4083
|
function printUsage4() {
|
|
3905
4084
|
console.error("Usage:");
|
|
@@ -3910,8 +4089,8 @@ function printUsage4() {
|
|
|
3910
4089
|
}
|
|
3911
4090
|
|
|
3912
4091
|
// src/commands/sync.ts
|
|
3913
|
-
import { existsSync as
|
|
3914
|
-
import { join as
|
|
4092
|
+
import { existsSync as existsSync23, readFileSync as readFileSync18 } from "node:fs";
|
|
4093
|
+
import { join as join22 } from "node:path";
|
|
3915
4094
|
function runSync(args) {
|
|
3916
4095
|
if (!args.includes("--check")) {
|
|
3917
4096
|
console.error("pro-gov sync is read-only and requires --check.");
|
|
@@ -3938,8 +4117,8 @@ function runSync(args) {
|
|
|
3938
4117
|
console.log("pro-gov sync check");
|
|
3939
4118
|
console.log(`profile: ${profile}`);
|
|
3940
4119
|
for (const file of planStarterFiles(profile)) {
|
|
3941
|
-
const targetPath =
|
|
3942
|
-
if (!
|
|
4120
|
+
const targetPath = join22(process.cwd(), file.targetPath);
|
|
4121
|
+
if (!existsSync23(targetPath)) {
|
|
3943
4122
|
if (file.ownership === "optional-guardrail") continue;
|
|
3944
4123
|
console.log(`missing: ${file.targetPath}`);
|
|
3945
4124
|
differences += 1;
|
|
@@ -3962,7 +4141,7 @@ function runSync(args) {
|
|
|
3962
4141
|
}
|
|
3963
4142
|
function inferInstalledProfile(root) {
|
|
3964
4143
|
const installed = ["engineering-runtime", "doc-only"].filter(
|
|
3965
|
-
(profile) =>
|
|
4144
|
+
(profile) => existsSync23(join22(root, `docs/governance/agents-routing/${profile}-v0.9.md`))
|
|
3966
4145
|
);
|
|
3967
4146
|
return installed.length === 1 ? installed[0] : void 0;
|
|
3968
4147
|
}
|
|
@@ -3987,6 +4166,7 @@ var COMMANDS = [
|
|
|
3987
4166
|
"portfolio assets-check --config <path> [--target <id|all>] [--json]",
|
|
3988
4167
|
"portfolio doctor --config <path> [--target <id|all>] [--json]",
|
|
3989
4168
|
"learn recall --query <text> [--target <path>] [--limit <n>] [--json]",
|
|
4169
|
+
"learn capture --title <text> --summary <text> [--category <slug>] [--target <path>] [--json]",
|
|
3990
4170
|
"lens scan [--target <path>] [--json]",
|
|
3991
4171
|
"lens inspect [--target <path>] [--format text|json]",
|
|
3992
4172
|
"lens report --target <path> --out <path>",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pieai/pro-gov",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
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.15"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "24.13.2",
|