@pareto4/pp-core 1.12.1 → 1.17.1
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/.claude-plugin/plugin.json +3 -3
- package/README.md +26 -9
- package/agents/pp-code-reviewer.md +3 -2
- package/agents/pp-debug-session-manager.md +9 -6
- package/agents/pp-executor.md +7 -21
- package/agents/pp-plan-checker.md +4 -4
- package/agents/pp-planner.md +23 -9
- package/agents/pp-vault-reviewer.md +274 -0
- package/agents/pp-verifier.md +7 -3
- package/bin/install.js +10 -3
- package/commands/pp-execute-phase.md +1 -3
- package/commands/pp-ns-review.md +2 -1
- package/commands/pp-plan-phase.md +1 -2
- package/commands/pp-vault-review.md +35 -0
- package/commands/pp-verify-work.md +1 -2
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update.js +0 -0
- package/hooks/dist/pp-cursor-session-start.js +1 -1
- package/hooks/dist/pp-statusline.js +1 -1
- package/hooks/dist/pp-update-banner.js +0 -0
- package/hooks/pp-check-update.js +0 -0
- package/hooks/pp-cursor-session-start.js +1 -1
- package/hooks/pp-statusline.js +1 -1
- package/hooks/pp-update-banner.js +0 -0
- package/package.json +14 -19
- package/pareto-skills/_shared/create-project-board.sh +0 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1 -1
- package/pp-core/bin/check-latest-version.cjs +0 -0
- package/pp-core/bin/detect-build-commands.sh +2 -2
- package/pp-core/bin/lib/capability-activation.cjs +83 -9
- package/pp-core/bin/lib/capability-registry.cjs +526 -22
- package/pp-core/bin/lib/capability-state.cjs +160 -4
- package/pp-core/bin/lib/capability-writer.cjs +19 -5
- package/pp-core/bin/lib/check-command-router.cjs +3867 -274
- package/pp-core/bin/lib/clusters.cjs +4 -0
- package/pp-core/bin/lib/command-aliases.cjs +0 -28
- package/pp-core/bin/lib/commands.cjs +9 -4
- package/pp-core/bin/lib/compose-bindings.cjs +253 -76
- package/pp-core/bin/lib/config-loader.cjs +7 -103
- package/pp-core/bin/lib/config-schema.cjs +1 -1
- package/pp-core/bin/lib/config.cjs +154 -62
- package/pp-core/bin/lib/decisions.cjs +104 -27
- package/pp-core/bin/lib/discovery-vault-check.cjs +246 -0
- package/pp-core/bin/lib/frontmatter.cjs +1 -1
- package/pp-core/bin/lib/git-base-branch.cjs +138 -10
- package/pp-core/bin/lib/git-provider.cjs +4 -4
- package/pp-core/bin/lib/init-command-router.cjs +5 -8
- package/pp-core/bin/lib/init-contract.cjs +653 -629
- package/pp-core/bin/lib/init-interactive.cjs +77 -21
- package/pp-core/bin/lib/init.cjs +24 -51
- package/pp-core/bin/lib/install-profiles.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +8 -0
- package/pp-core/bin/lib/loop-resolver.cjs +169 -47
- package/pp-core/bin/lib/org-profile.cjs +544 -53
- package/pp-core/bin/lib/package-identity.cjs +3 -3
- package/pp-core/bin/lib/phase-command-router.cjs +1 -23
- package/pp-core/bin/lib/phase-scope.cjs +1 -1
- package/pp-core/bin/lib/phase.cjs +11 -203
- package/pp-core/bin/lib/platform-bindings.cjs +40 -19
- package/pp-core/bin/lib/practices-review-check.cjs +15 -9
- package/pp-core/bin/lib/profile-output.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +104 -1
- package/pp-core/bin/lib/state.cjs +11 -85
- package/pp-core/bin/lib/template.cjs +1 -1
- package/pp-core/bin/lib/vault-audit.cjs +2594 -0
- package/pp-core/bin/lib/vault-command-router.cjs +2756 -60
- package/pp-core/bin/lib/vault-coordinates.cjs +13 -4
- package/pp-core/bin/lib/vault-index.cjs +699 -0
- package/pp-core/bin/lib/vault-mode.cjs +235 -0
- package/pp-core/bin/lib/vault-practices.cjs +1194 -89
- package/pp-core/bin/lib/vault-review.cjs +2102 -0
- package/pp-core/bin/lib/vault-seal.cjs +1936 -0
- package/pp-core/bin/lib/vault-standards.cjs +1505 -0
- package/pp-core/bin/lib/vault-trace.cjs +3184 -0
- package/pp-core/bin/lib/vault-update.cjs +242 -0
- package/pp-core/bin/lib/vault-write-back.cjs +78 -31
- package/pp-core/bin/lib/vault.cjs +2713 -634
- package/pp-core/bin/lib/verify.cjs +0 -11
- package/pp-core/bin/portable-timeout.sh +1 -1
- package/pp-core/bin/pp-tools.cjs +184 -37
- package/pp-core/bin/shared/config-defaults.manifest.json +0 -7
- package/pp-core/bin/shared/config-schema.manifest.json +0 -3
- package/pp-core/bin/shared/model-catalog.json +1 -0
- package/pp-core/bin/verify-reapply-patches.cjs +0 -0
- package/pp-core/org-profile.json +26 -0
- package/pp-core/references/autonomous-best-effort.md +8 -7
- package/pp-core/references/loop-hook-dispatch.md +0 -14
- package/pp-core/references/planner-gap-closure.md +0 -1
- package/pp-core/references/planner-tdd.md +0 -1
- package/pp-core/references/planner-vault-practices.md +31 -3
- package/pp-core/references/planner-vault-standards.md +320 -0
- package/pp-core/references/planning-config.md +0 -8
- package/pp-core/references/practice-arithmetic-contract.md +121 -0
- package/pp-core/references/tdd.md +0 -1
- package/pp-core/references/verifier-practice-verdicts.md +263 -0
- package/pp-core/templates/README.md +1 -0
- package/pp-core/templates/VAULT-REVIEW.md +202 -0
- package/pp-core/templates/phase-prompt.md +2 -6
- package/pp-core/templates/practices/README.md +137 -11
- package/pp-core/templates/project-charter.md +226 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +0 -0
- package/pp-core/workflows/add-tests.md +55 -0
- package/pp-core/workflows/audit-fix.md +63 -0
- package/pp-core/workflows/audit-milestone.md +1 -1
- package/pp-core/workflows/autonomous.md +85 -11
- package/pp-core/workflows/check-todos.md +13 -2
- package/pp-core/workflows/code-review-fix.md +59 -1
- package/pp-core/workflows/code-review.md +10 -1
- package/pp-core/workflows/complete-milestone.md +1 -1
- package/pp-core/workflows/debug.md +56 -2
- package/pp-core/workflows/discovery-sprint/prefill.md +21 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +46 -48
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +20 -24
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +1 -6
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -3
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +1 -1
- package/pp-core/workflows/discovery-sprint/vault-context.md +213 -0
- package/pp-core/workflows/discovery-sprint.md +7 -3
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +4 -4
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +43 -1
- package/pp-core/workflows/discovery-to-build.md +9 -1
- package/pp-core/workflows/discuss-phase.md +3 -10
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +329 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +3 -2
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -1
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +98 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +6 -8
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +115 -14
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +322 -18
- package/pp-core/workflows/execute-phase/steps/verifier-practice-payload.md +165 -0
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +163 -0
- package/pp-core/workflows/execute-phase.md +154 -110
- package/pp-core/workflows/execute-plan.md +58 -4
- package/pp-core/workflows/fast.md +53 -0
- package/pp-core/workflows/help/modes/full.md +1 -0
- package/pp-core/workflows/init/steps/client-context-capture.md +101 -0
- package/pp-core/workflows/init/steps/gitlab-provisioning.md +130 -0
- package/pp-core/workflows/init/steps/project-md-deferral-narration.md +66 -0
- package/pp-core/workflows/init/steps/reachability-outcome.md +70 -0
- package/pp-core/workflows/init.md +232 -272
- package/pp-core/workflows/new-project.md +31 -23
- package/pp-core/workflows/plan-phase.md +99 -43
- package/pp-core/workflows/quick.md +120 -2
- package/pp-core/workflows/secure-phase.md +1 -1
- package/pp-core/workflows/ship.md +57 -24
- package/pp-core/workflows/update.md +3 -3
- package/pp-core/workflows/validate-phase.md +60 -1
- package/pp-core/workflows/vault-review.md +325 -0
- package/pp-core/workflows/verify-work.md +13 -12
- package/scripts/changeset/cli.cjs +6 -5
- package/scripts/changeset/lint.cjs +0 -0
- package/scripts/changeset/new.cjs +33 -50
- package/scripts/dev-env.cjs +25 -85
- package/scripts/gen-capability-registry.cjs +199 -0
- package/scripts/gen-practice-arithmetic-contract.cjs +412 -0
- package/scripts/lib/allowlist-ratchet.cjs +1 -103
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
- package/scripts/lint-docs-required.cjs +0 -0
- package/scripts/lint-pr-check-project-dir.cjs +1 -3
- package/scripts/lint-test-file-count.allowlist.json +13 -2
- package/scripts/practice-arithmetic-contract.allow.json +35 -0
- package/scripts/prompt-injection-scan.sh +22 -15
- package/scripts/record-vault-mode-golden.cjs +89 -0
- package/scripts/release-channel.cjs +0 -0
- package/scripts/sync-manifest-versions.cjs +5 -4
- package/scripts/sync-rulesets.sh +1 -1
- package/scripts/update-size-baseline.cjs +30 -274
- package/scripts/vault-calibrate.cjs +996 -0
- package/scripts/verify-opengsd-sweep.cjs +3 -5
- package/scripts/workflow-size.cjs +9 -61
- package/pp-core/bin/lib/dispatch-plan.cjs +0 -472
- package/pp-core/bin/lib/install-run.cjs +0 -536
- package/pp-core/bin/lib/phase-tier.cjs +0 -467
- package/pp-core/bin/lib/plan-graph.cjs +0 -368
- package/pp-core/references/planner-plan-graph.md +0 -66
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +0 -45
- package/pp-core/workflows/execute-phase/steps/install-run.md +0 -29
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +0 -23
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +0 -72
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +0 -34
- package/scripts/lib/size-budget.cjs +0 -311
- package/scripts/lint-neutrality-names.cjs +0 -694
- package/scripts/lint-org-coordinates.allowlist.json +0 -35
- package/scripts/lint-org-coordinates.cjs +0 -426
|
@@ -15,6 +15,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.GIT_LOCATION_UNSET = exports.GIT_LOCATION_VARS = void 0;
|
|
18
19
|
exports.hookCommandNeedsPowerShellCallOperator = hookCommandNeedsPowerShellCallOperator;
|
|
19
20
|
exports.formatHookCommandForRuntime = formatHookCommandForRuntime;
|
|
20
21
|
exports.shellHookOmitsBashRunner = shellHookOmitsBashRunner;
|
|
@@ -36,6 +37,7 @@ exports.renderShellActionLines = renderShellActionLines;
|
|
|
36
37
|
exports.projectPathActionProjection = projectPathActionProjection;
|
|
37
38
|
exports.projectPersistentPathExportActions = projectPersistentPathExportActions;
|
|
38
39
|
exports.execGit = execGit;
|
|
40
|
+
exports.execGitLocal = execGitLocal;
|
|
39
41
|
exports.execNpm = execNpm;
|
|
40
42
|
exports.execTool = execTool;
|
|
41
43
|
exports.probeTty = probeTty;
|
|
@@ -412,10 +414,24 @@ function _spawnResult(result, program) {
|
|
|
412
414
|
error: result.error ?? null,
|
|
413
415
|
};
|
|
414
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Run git bounded and non-interactive; never throws (`_spawnResult` maps a
|
|
419
|
+
* spawn error, a timeout or ENOBUFS to `exitCode: 1`).
|
|
420
|
+
*
|
|
421
|
+
* `input` (16-03) is written to git's stdin when given and nothing is passed
|
|
422
|
+
* otherwise, so every existing call behaves exactly as before. SEAL-01 passes
|
|
423
|
+
* revisions for `rev-list --stdin` through it rather than as argv, because a
|
|
424
|
+
* Windows command line is capped at 32767 characters (CreateProcess) and a
|
|
425
|
+
* long-lived project can record more anchors than that holds (16-RESEARCH
|
|
426
|
+
* Pitfall 6).
|
|
427
|
+
*/
|
|
415
428
|
function execGit(args, opts = {}) {
|
|
416
429
|
// Non-interactive defaults: a hung credential prompt or terminal-input
|
|
417
430
|
// probe must surface as a timeout, not block the tool forever. Callers
|
|
418
|
-
// can override via opts.env.
|
|
431
|
+
// can override via opts.env. A key whose opts.env value is `undefined`
|
|
432
|
+
// is UNSET for this call rather than inherited: spawnSync ignores an
|
|
433
|
+
// undefined env value (260915-mzx R2, proven by the inherited-GIT_DIR arm
|
|
434
|
+
// in tests/vault.test.cjs running real git).
|
|
419
435
|
const env = {
|
|
420
436
|
...process.env,
|
|
421
437
|
GIT_TERMINAL_PROMPT: '0',
|
|
@@ -429,9 +445,96 @@ function execGit(args, opts = {}) {
|
|
|
429
445
|
stdio: 'pipe',
|
|
430
446
|
timeout: opts.timeout ?? 10_000,
|
|
431
447
|
windowsHide: true,
|
|
448
|
+
...(opts.input !== undefined ? { input: opts.input } : {}),
|
|
432
449
|
});
|
|
433
450
|
return _spawnResult(result, 'git');
|
|
434
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* The repository-location variables: the ones through which git decides WHICH
|
|
454
|
+
* repository, work tree, index, object store, config file, ref namespace and
|
|
455
|
+
* history shape a command answers for (D-116, 16-UAT test 8). A git hook exports
|
|
456
|
+
* `GIT_DIR`; an agent shell may leave any of them pointing at another checkout. A
|
|
457
|
+
* vault git invocation must answer for the repository it names by cwd or argv,
|
|
458
|
+
* whatever the caller inherited.
|
|
459
|
+
*
|
|
460
|
+
* The list is git's, not hand-built (D-121, code review iteration 4 CR-01/WR-01):
|
|
461
|
+
* every name `git rev-parse --local-env-vars` prints (git 2.55.0) MINUS the stated
|
|
462
|
+
* keep-list `GIT_CONFIG_PARAMETERS` and `GIT_CONFIG_COUNT` — the `GIT_CONFIG_*`
|
|
463
|
+
* channel D-117 keeps, with its `GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n` pairs, for
|
|
464
|
+
* the suite's hermetic config and the golden harness's insteadOf rewrite — PLUS
|
|
465
|
+
* three names git does not list but that move discovery or the ref namespace
|
|
466
|
+
* (`GIT_CEILING_DIRECTORIES`, `GIT_DISCOVERY_ACROSS_FILESYSTEM`, `GIT_NAMESPACE`).
|
|
467
|
+
* It stays a static tuple: the engine never shells out to git to build it, and a
|
|
468
|
+
* test compares it against the live git so a name a future git adds cannot arrive
|
|
469
|
+
* unremarked.
|
|
470
|
+
*
|
|
471
|
+
* Four of them move an ancestry answer inside ONE repository (measured, git
|
|
472
|
+
* 2.55.0): `GIT_SHALLOW_FILE` naming the second of three commits dropped
|
|
473
|
+
* `rev-list --count HEAD` from 3 to 2 and flipped `merge-base --is-ancestor
|
|
474
|
+
* <first> HEAD` to no; `GIT_REPLACE_REF_BASE` naming a planted `refs/evil/`
|
|
475
|
+
* replacement of HEAD made `rev-parse HEAD^` answer the first commit;
|
|
476
|
+
* `GIT_NO_REPLACE_OBJECTS=1` hides a repository's own `refs/replace/` entries the
|
|
477
|
+
* same way; `GIT_GRAFT_FILE` naming an ungoverned commit made it a root, and the
|
|
478
|
+
* strict `check vault.trace` then answered clean over it (CR-01). `GIT_CONFIG` is
|
|
479
|
+
* a location variable, not transport: it names ONE config file and is read only
|
|
480
|
+
* by the `git config` command, for reads and writes alike, so inherited it sent
|
|
481
|
+
* promote's identity step into a foreign file (WR-01). This tuple is the only
|
|
482
|
+
* enumeration: `GIT_LOCATION_UNSET` is derived from it.
|
|
483
|
+
*/
|
|
484
|
+
exports.GIT_LOCATION_VARS = Object.freeze([
|
|
485
|
+
'GIT_DIR',
|
|
486
|
+
'GIT_WORK_TREE',
|
|
487
|
+
'GIT_COMMON_DIR',
|
|
488
|
+
'GIT_INDEX_FILE',
|
|
489
|
+
'GIT_OBJECT_DIRECTORY',
|
|
490
|
+
'GIT_ALTERNATE_OBJECT_DIRECTORIES',
|
|
491
|
+
'GIT_PREFIX',
|
|
492
|
+
'GIT_CEILING_DIRECTORIES',
|
|
493
|
+
'GIT_DISCOVERY_ACROSS_FILESYSTEM',
|
|
494
|
+
'GIT_NAMESPACE',
|
|
495
|
+
'GIT_SHALLOW_FILE',
|
|
496
|
+
'GIT_REPLACE_REF_BASE',
|
|
497
|
+
'GIT_NO_REPLACE_OBJECTS',
|
|
498
|
+
'GIT_GRAFT_FILE',
|
|
499
|
+
'GIT_IMPLICIT_WORK_TREE',
|
|
500
|
+
'GIT_CONFIG',
|
|
501
|
+
]);
|
|
502
|
+
/**
|
|
503
|
+
* The overlay `execGitLocal` applies: every `GIT_LOCATION_VARS` member as an own
|
|
504
|
+
* property equal to `undefined` (spawnSync treats an undefined env value as unset).
|
|
505
|
+
* Derived from the tuple, never written out, so there is one list. Exported only
|
|
506
|
+
* for a spawn that cannot go through `execGitLocal` — the `glab` clone, which
|
|
507
|
+
* runs through `execTool` and whose own git child inherits this environment
|
|
508
|
+
* (D-116).
|
|
509
|
+
*/
|
|
510
|
+
exports.GIT_LOCATION_UNSET = Object.freeze(Object.fromEntries(exports.GIT_LOCATION_VARS.map((name) => [name, undefined])));
|
|
511
|
+
/**
|
|
512
|
+
* Run git exactly as `execGit` does, with every inherited repository-location
|
|
513
|
+
* variable (`GIT_LOCATION_VARS`) unset — the one owner of the environment of a
|
|
514
|
+
* vault git invocation (D-116, D-117). "Local" means the repository is chosen by
|
|
515
|
+
* cwd or argv and never by the environment, which is why the URL-addressed
|
|
516
|
+
* transport invocations (clones, `ls-remote`) use it too: git still reads the
|
|
517
|
+
* config of the repository the environment selects, and a clone refuses an
|
|
518
|
+
* inherited `GIT_WORK_TREE` and writes into an inherited `GIT_INDEX_FILE`.
|
|
519
|
+
*
|
|
520
|
+
* It is location-only, not the whole `GIT_*` prefix: transport (`GIT_SSH_COMMAND`,
|
|
521
|
+
* `GIT_ASKPASS`, the credential-helper family) is kept for the base-branch
|
|
522
|
+
* ladder's remote tier, every clone and the promote push; the `GIT_CONFIG_*`
|
|
523
|
+
* channel (`GIT_CONFIG_PARAMETERS`, `GIT_CONFIG_COUNT` and its pairs, the keep-list
|
|
524
|
+
* D-117/D-121 name) is kept because it keeps the suite's reads hermetic and carries
|
|
525
|
+
* the golden harness's insteadOf rewrite to its local bare vault; the legacy
|
|
526
|
+
* one-file `GIT_CONFIG` is a location variable and is unset. The two reads that
|
|
527
|
+
* must depend on no inherited git variable at all (certify, the cache resolver)
|
|
528
|
+
* keep the whole-prefix `scrubbedGitEnv` in `src/vault.cts`, a superset of this
|
|
529
|
+
* overlay.
|
|
530
|
+
*
|
|
531
|
+
* The overlay is applied LAST, over any caller `opts.env`, so no call site can
|
|
532
|
+
* re-point the repository; `cwd`, `timeout` and `input` are forwarded unchanged.
|
|
533
|
+
*/
|
|
534
|
+
function execGitLocal(args, opts = {}) {
|
|
535
|
+
const env = { ...(opts.env || {}), ...exports.GIT_LOCATION_UNSET };
|
|
536
|
+
return execGit(args, { ...opts, env });
|
|
537
|
+
}
|
|
435
538
|
function execNpm(args, opts = {}) {
|
|
436
539
|
const result = node_child_process_1.default.spawnSync('npm', args, {
|
|
437
540
|
cwd: opts.cwd,
|
|
@@ -19,7 +19,7 @@ const configLoaderMod = require("./config-loader.cjs");
|
|
|
19
19
|
const { loadConfig } = configLoaderMod;
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
21
|
const phaseIdMod = require("./phase-id.cjs");
|
|
22
|
-
const { escapeRegex
|
|
22
|
+
const { escapeRegex } = phaseIdMod;
|
|
23
23
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
24
|
const roadmapParserMod = require("./roadmap-parser.cjs");
|
|
25
25
|
const { getDeclaredMilestoneInfo, getMilestonePhaseFilter, extractCurrentMilestone, getClosedMilestonePhaseDirFilter } = roadmapParserMod;
|
|
@@ -76,9 +76,9 @@ function cmdStateLoad(cwd, raw) {
|
|
|
76
76
|
const configExists = node_fs_1.default.existsSync(node_path_1.default.join(planDir, 'config.json'));
|
|
77
77
|
const roadmapExists = node_fs_1.default.existsSync(node_path_1.default.join(planDir, 'ROADMAP.md'));
|
|
78
78
|
const stateExists = stateRaw.length > 0;
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
// so this module's load graph is unchanged.
|
|
79
|
+
// VAULT-EGRESS-1: the emitted config is display-safe for its one coordinate key (the
|
|
80
|
+
// shared-tier repo), through config.cjs's projection; `config` itself stays raw. Lazily
|
|
81
|
+
// required so this module's load graph is unchanged.
|
|
82
82
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
83
83
|
const { redactConfigCoordinates } = require('./config.cjs');
|
|
84
84
|
const result = {
|
|
@@ -181,23 +181,17 @@ function cmdStatePatch(cwd, patches, raw) {
|
|
|
181
181
|
const shouldResync = shouldResyncStateProgress(Object.keys(patches));
|
|
182
182
|
// Use atomic read-modify-write to prevent lost updates from concurrent agents
|
|
183
183
|
const fmReport = readModifyWriteStateMd(statePath, (content) => {
|
|
184
|
-
// Patch the BODY only, as cmdStateUpdate does. The plain-line pattern is
|
|
185
|
-
// case-insensitive, so on the whole file `Status` matched the frontmatter
|
|
186
|
-
// `status:` line first; the re-derivation then restored it from the untouched
|
|
187
|
-
// body, and the verb reported a write it never made.
|
|
188
|
-
let body = stripFrontmatter(content);
|
|
189
|
-
const head = content.slice(0, content.length - body.length);
|
|
190
184
|
for (const [field, value] of Object.entries(patches)) {
|
|
191
|
-
const result = (0, state_document_cjs_1.stateReplaceField)(
|
|
185
|
+
const result = (0, state_document_cjs_1.stateReplaceField)(content, field, value);
|
|
192
186
|
if (result) {
|
|
193
|
-
|
|
187
|
+
content = result;
|
|
194
188
|
results.updated.push(field);
|
|
195
189
|
}
|
|
196
190
|
else {
|
|
197
191
|
results.failed.push(field);
|
|
198
192
|
}
|
|
199
193
|
}
|
|
200
|
-
return
|
|
194
|
+
return content;
|
|
201
195
|
}, cwd, { resync: shouldResync });
|
|
202
196
|
output({ ...results, frontmatter_updated: fmReport.frontmatter_updated }, raw, results.updated.length > 0 ? 'true' : 'false');
|
|
203
197
|
}
|
|
@@ -1285,20 +1279,7 @@ function cmdStateSnapshot(cwd, raw) {
|
|
|
1285
1279
|
* or the first Built phase of a milestone would be counted Complete.
|
|
1286
1280
|
*/
|
|
1287
1281
|
function roadmapCompletedPhases(roadmapRaw, roadmapScope) {
|
|
1288
|
-
// The phases the current milestone's scope names. A progress table may also carry a
|
|
1289
|
-
// shipped milestone's rows (the template's milestone-grouped layout keeps them, with a
|
|
1290
|
-
// Milestone column): those rows grant nothing to this milestone.
|
|
1291
|
-
const scopedIds = new Set();
|
|
1292
|
-
const headingPattern = /#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi;
|
|
1293
|
-
let hm;
|
|
1294
|
-
while ((hm = headingPattern.exec(roadmapScope)) !== null) {
|
|
1295
|
-
if (/\d/.test(hm[1]))
|
|
1296
|
-
scopedIds.add(normalizePhaseName(hm[1]));
|
|
1297
|
-
}
|
|
1298
1282
|
const fromText = (text) => {
|
|
1299
|
-
const table = countCompleteProgressRows(text, scopedIds);
|
|
1300
|
-
if (table !== null)
|
|
1301
|
-
return table;
|
|
1302
1283
|
const derived = deriveProgressFromRoadmap(text);
|
|
1303
1284
|
if (derived.completedPhases !== null)
|
|
1304
1285
|
return derived.completedPhases;
|
|
@@ -1309,51 +1290,6 @@ function roadmapCompletedPhases(roadmapRaw, roadmapScope) {
|
|
|
1309
1290
|
return scoped;
|
|
1310
1291
|
return fromText(extractCurrentMilestone(roadmapRaw));
|
|
1311
1292
|
}
|
|
1312
|
-
/**
|
|
1313
|
-
* Column-aware read of a ROADMAP progress table: the header row names the `Phase` and
|
|
1314
|
-
* `Status` columns, so a table with a Milestone column (pp-core/templates/roadmap.md's
|
|
1315
|
-
* milestone-grouped layout) is read as well as the four-column one. Counts the data
|
|
1316
|
-
* rows whose Status cell is `Complete`, among the rows whose phase is in `phaseIds`
|
|
1317
|
-
* (all rows when `phaseIds` is empty). Returns null when no such table is present, or
|
|
1318
|
-
* when the table lists none of `phaseIds` — a table that says nothing about this
|
|
1319
|
-
* milestone's phases is silence, not a grant of zero.
|
|
1320
|
-
*/
|
|
1321
|
-
function countCompleteProgressRows(text, phaseIds) {
|
|
1322
|
-
const cellsOf = (line) => {
|
|
1323
|
-
const t = line.trim();
|
|
1324
|
-
if (!t.startsWith('|'))
|
|
1325
|
-
return null;
|
|
1326
|
-
return t.replace(/^\|/, '').replace(/\|$/, '').split('|').map((c) => c.trim());
|
|
1327
|
-
};
|
|
1328
|
-
const lines = text.split(/\r?\n/);
|
|
1329
|
-
for (let i = 0; i + 1 < lines.length; i++) {
|
|
1330
|
-
const header = cellsOf(lines[i]);
|
|
1331
|
-
if (!header)
|
|
1332
|
-
continue;
|
|
1333
|
-
const phaseCol = header.findIndex((c) => /^phase$/i.test(c));
|
|
1334
|
-
const statusCol = header.findIndex((c) => /^status$/i.test(c));
|
|
1335
|
-
const separator = cellsOf(lines[i + 1]);
|
|
1336
|
-
if (phaseCol === -1 || statusCol === -1 || !separator || !separator.every((c) => /^:?-+:?$/.test(c)))
|
|
1337
|
-
continue;
|
|
1338
|
-
let listed = 0;
|
|
1339
|
-
let complete = 0;
|
|
1340
|
-
for (let j = i + 2; j < lines.length; j++) {
|
|
1341
|
-
const cells = cellsOf(lines[j]);
|
|
1342
|
-
if (!cells)
|
|
1343
|
-
break;
|
|
1344
|
-
const id = cells[phaseCol] ?? '';
|
|
1345
|
-
if (!/^\d/.test(id))
|
|
1346
|
-
continue;
|
|
1347
|
-
if (phaseIds.size > 0 && !phaseIds.has(normalizePhaseName(id)))
|
|
1348
|
-
continue;
|
|
1349
|
-
listed++;
|
|
1350
|
-
if (/^complete$/i.test(cells[statusCol] ?? ''))
|
|
1351
|
-
complete++;
|
|
1352
|
-
}
|
|
1353
|
-
return listed > 0 ? complete : null;
|
|
1354
|
-
}
|
|
1355
|
-
return null;
|
|
1356
|
-
}
|
|
1357
1293
|
/**
|
|
1358
1294
|
* Read the milestone-scoped ROADMAP once and return the two counts the progress
|
|
1359
1295
|
* block takes from it: the digit-bearing phase headings (single source of truth
|
|
@@ -2406,23 +2342,13 @@ function updatePerformanceMetricsSection(content, cwd, phaseNum, planCount, summ
|
|
|
2406
2342
|
const byPhaseMatch = content.match(byPhaseTablePattern);
|
|
2407
2343
|
if (byPhaseMatch) {
|
|
2408
2344
|
let tableBody = byPhaseMatch[2].trim();
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
const wanted = normalizePhaseName(String(phaseNum));
|
|
2413
|
-
const lines = tableBody.split('\n');
|
|
2414
|
-
const rowIdx = lines.findIndex((line) => {
|
|
2415
|
-
const cell = /^\|\s*([^|]*?)\s*\|/.exec(line);
|
|
2416
|
-
return cell !== null && /^[A-Za-z0-9.-]+$/.test(cell[1]) && normalizePhaseName(cell[1]) === wanted;
|
|
2417
|
-
});
|
|
2418
|
-
if (rowIdx !== -1) {
|
|
2345
|
+
const phaseRowPattern = new RegExp(`^\\|\\s*${escapeRegex(String(phaseNum))}\\s*\\|.*$`, 'm');
|
|
2346
|
+
const newRow = `| ${phaseNum} | ${summaryCount} | - | - |`;
|
|
2347
|
+
if (phaseRowPattern.test(tableBody)) {
|
|
2419
2348
|
// Update existing row
|
|
2420
|
-
|
|
2421
|
-
lines[rowIdx] = `| ${rowId} | ${summaryCount} | - | - |`;
|
|
2422
|
-
tableBody = lines.join('\n');
|
|
2349
|
+
tableBody = tableBody.replace(phaseRowPattern, newRow);
|
|
2423
2350
|
}
|
|
2424
2351
|
else {
|
|
2425
|
-
const newRow = `| ${phaseNum} | ${summaryCount} | - | - |`;
|
|
2426
2352
|
// Remove placeholder row and add new row
|
|
2427
2353
|
tableBody = tableBody.replace(/^\|\s*-\s*\|\s*-\s*\|\s*-\s*\|\s*-\s*\|$/m, '').trim();
|
|
2428
2354
|
tableBody = tableBody ? tableBody + '\n' + newRow : newRow;
|
|
@@ -79,7 +79,7 @@ function cmdTemplateFill(cwd, templateType, options, raw) {
|
|
|
79
79
|
if (!options.phase) {
|
|
80
80
|
error('--phase required');
|
|
81
81
|
}
|
|
82
|
-
// D-02 (todo "template-fill-writes-into-an-archived-
|
|
82
|
+
// PBI 75323 / quick 261009-gvf D-02 (todo "template-fill-writes-into-an-archived-
|
|
83
83
|
// phase-directory"): a writer never resolves into a closed milestone's archive. The
|
|
84
84
|
// phase-scope owner hands back a live match only; an archive this phase still names
|
|
85
85
|
// (current milestone, or no longer on the ROADMAP) is refused naming the archive, and a
|