pan-wizard 3.27.0 → 3.29.0
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 +48 -48
- package/agents/pan-previewer.md +1 -1
- package/bin/install-lib.cjs +580 -18
- package/bin/install.js +25 -44
- package/commands/pan/army.md +1 -1
- package/commands/pan/cost.md +14 -2
- package/commands/pan/preview.md +2 -2
- package/hooks/dist/pan-check-update.js +4 -0
- package/hooks/dist/pan-cost-logger.js +322 -43
- package/hooks/dist/pan-trace-logger.js +275 -32
- package/package.json +8 -2
- package/pan-wizard-core/bin/lib/commands.cjs +3 -1
- package/pan-wizard-core/bin/lib/constants.cjs +39 -0
- package/pan-wizard-core/bin/lib/context-budget.cjs +80 -0
- package/pan-wizard-core/bin/lib/cost-rebuild.cjs +511 -0
- package/pan-wizard-core/bin/lib/cost.cjs +174 -18
- package/pan-wizard-core/bin/lib/foreign-planning.cjs +56 -0
- package/pan-wizard-core/bin/lib/git.cjs +5 -1
- package/pan-wizard-core/bin/lib/hud.cjs +5 -3
- package/pan-wizard-core/bin/lib/hygiene.cjs +52 -24
- package/pan-wizard-core/bin/lib/init.cjs +8 -0
- package/pan-wizard-core/bin/lib/memory.cjs +14 -8
- package/pan-wizard-core/bin/lib/optimize.cjs +78 -2
- package/pan-wizard-core/bin/lib/utils.cjs +22 -0
- package/pan-wizard-core/bin/lib/verify.cjs +46 -12
- package/pan-wizard-core/bin/pan-tools.cjs +8 -1
- package/pan-wizard-core/mcp/server.cjs +92 -8
- package/pan-wizard-core/mcp/tool-registry.cjs +50 -3
- package/pan-wizard-core/references/model-profiles.md +2 -2
- package/pan-wizard-core/workflows/health.md +2 -0
- package/pan-zcode/README.md +1 -1
- package/scripts/build-agent-plugin.js +220 -0
- package/scripts/build-plugin.js +48 -3
- package/scripts/coverage-gate.cjs +257 -0
- package/scripts/generate-skills-docs.py +1 -1
- package/scripts/install-git-hooks.js +5 -0
- package/scripts/mutation-probe.cjs +272 -0
- package/scripts/release-check.js +80 -13
- package/scripts/test-quality-lint.cjs +240 -0
- package/scripts/test-surface.cjs +335 -0
package/bin/install.js
CHANGED
|
@@ -46,7 +46,7 @@ const pkg = require('../package.json');
|
|
|
46
46
|
// phrased by capability, not by name; these are the "switch to this" examples
|
|
47
47
|
// that keep the advice actionable. Nothing in PAN gates on these values.
|
|
48
48
|
const RECOMMENDED_MODELS = {
|
|
49
|
-
flagship: 'claude-fable-5',
|
|
49
|
+
flagship: 'claude-fable-5-1',
|
|
50
50
|
reasoningTier: 'claude-opus-5 / claude-opus-4-8',
|
|
51
51
|
};
|
|
52
52
|
|
|
@@ -565,21 +565,15 @@ function copyCommandsAsUnifiedSkills(srcDir, skillsDir, prefix, pathPrefix, core
|
|
|
565
565
|
fs.mkdirSync(skillDir, { recursive: true });
|
|
566
566
|
|
|
567
567
|
let content = fs.readFileSync(srcPath, 'utf8');
|
|
568
|
-
//
|
|
569
|
-
//
|
|
570
|
-
//
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
578
|
-
content = content.replace(/\.\/\.claude\//g, `./${getDirName(runtime)}/`);
|
|
579
|
-
// Not every runtime puts a `pan-tools` bin on PATH — invoke via node.
|
|
580
|
-
const panToolsPath = `${corePrefix}pan-wizard-core/bin/pan-tools.cjs`;
|
|
581
|
-
content = content.replace(/\bpan-tools\b(?=\s+[a-z])/g, `node ${panToolsPath}`);
|
|
582
|
-
content = processAttribution(content, getCommitAttribution(runtime));
|
|
568
|
+
// The path rewrite lives in install-lib (rewriteUnifiedSkillCommandContent)
|
|
569
|
+
// because the Agent Plugins bundle builder runs the SAME function — one
|
|
570
|
+
// converter, several call sites, never a second copy (ADR-0028, ADR-0045).
|
|
571
|
+
content = lib.rewriteUnifiedSkillCommandContent(content, {
|
|
572
|
+
corePrefix,
|
|
573
|
+
pathPrefix,
|
|
574
|
+
projectDirPrefix: `./${getDirName(runtime)}/`,
|
|
575
|
+
attribution: getCommitAttribution(runtime),
|
|
576
|
+
});
|
|
583
577
|
content = convertClaudeCommandToUnifiedSkill(content, skillName);
|
|
584
578
|
|
|
585
579
|
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), content);
|
|
@@ -670,17 +664,14 @@ function copySharedCore(srcDir, destDir, corePrefix, runtimePathPrefix, runtime)
|
|
|
670
664
|
recurse(srcPath, destPath);
|
|
671
665
|
} else if (entry.name.endsWith('.md')) {
|
|
672
666
|
try {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
content =
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
682
|
-
content = processAttribution(content, getCommitAttribution(runtime));
|
|
683
|
-
content = convertSlashCommandsToCopilotSkillMentions(content);
|
|
667
|
+
// Shared with the Agent Plugins bundle builder (install-lib) — see
|
|
668
|
+
// rewriteSharedCoreMarkdown for the rewrite order and rationale.
|
|
669
|
+
const content = lib.rewriteSharedCoreMarkdown(fs.readFileSync(srcPath, 'utf8'), {
|
|
670
|
+
corePrefix,
|
|
671
|
+
pathPrefix: runtimePathPrefix,
|
|
672
|
+
projectDirPrefix: `./${dirName}/`,
|
|
673
|
+
attribution: getCommitAttribution(runtime),
|
|
674
|
+
});
|
|
684
675
|
fs.writeFileSync(destPath, content);
|
|
685
676
|
} catch (err) {
|
|
686
677
|
pushInstallWarning('copySharedCore(md)', destPath, err);
|
|
@@ -728,21 +719,13 @@ function stripInternalFromLearningsIndex(indexPath) {
|
|
|
728
719
|
if (err.code !== 'ENOENT') pushInstallWarning('stripInternalLearnings', 'learnings/index.json', err);
|
|
729
720
|
return;
|
|
730
721
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
if (
|
|
735
|
-
|
|
736
|
-
parsed.topics = kept;
|
|
737
|
-
if (parsed.totals && typeof parsed.totals === 'object') {
|
|
738
|
-
parsed.totals.topics = kept.length;
|
|
739
|
-
parsed.totals.patterns = kept.reduce((n, t) => n + (Array.isArray(t.patterns) ? t.patterns.length : 0), 0);
|
|
740
|
-
parsed.totals.size_bytes = kept.reduce((n, t) => n + (t.size_bytes || 0), 0);
|
|
741
|
-
parsed.totals.size_tokens_est = kept.reduce((n, t) => n + (t.size_tokens_est || 0), 0);
|
|
742
|
-
}
|
|
722
|
+
// The transform is pure and shared with the bundle builders (install-lib):
|
|
723
|
+
// null means "not an index" or "nothing internal to drop" — both no-ops here.
|
|
724
|
+
const stripped = lib.stripInternalLearningsTopics(parsed);
|
|
725
|
+
if (!stripped) return;
|
|
743
726
|
|
|
744
727
|
try {
|
|
745
|
-
fs.writeFileSync(indexPath, JSON.stringify(
|
|
728
|
+
fs.writeFileSync(indexPath, JSON.stringify(stripped, null, 2) + '\n');
|
|
746
729
|
} catch (err) {
|
|
747
730
|
pushInstallWarning('stripInternalLearnings', 'learnings/index.json', err);
|
|
748
731
|
}
|
|
@@ -2230,10 +2213,8 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
2230
2213
|
fs.mkdirSync(agentsRefDir, { recursive: true });
|
|
2231
2214
|
const agentsSrc = path.join(src, 'agents');
|
|
2232
2215
|
for (const f of fs.readdirSync(agentsSrc).filter(n => n.endsWith('.md'))) {
|
|
2233
|
-
|
|
2234
|
-
content =
|
|
2235
|
-
content = content.replace(/\.\/\.claude\/pan-wizard-core\//g, `${corePrefix}pan-wizard-core/`);
|
|
2236
|
-
content = convertSlashCommandsToCopilotSkillMentions(content);
|
|
2216
|
+
// Shared with the Agent Plugins bundle builder (install-lib).
|
|
2217
|
+
const content = lib.rewriteAgentReferenceCopy(fs.readFileSync(path.join(agentsSrc, f), 'utf8'), corePrefix);
|
|
2237
2218
|
fs.writeFileSync(path.join(agentsRefDir, f), content);
|
|
2238
2219
|
}
|
|
2239
2220
|
} catch (e) {
|
package/commands/pan/army.md
CHANGED
|
@@ -92,7 +92,7 @@ Every cap the conductor enforces applies to the campaign, scaled up:
|
|
|
92
92
|
| `--push` | off | Push approved merges to origin (still human-gated). |
|
|
93
93
|
| `--clean-seal` | off | One clean build + full verification after the last item (commands from config). |
|
|
94
94
|
| `--schedule` | off | Arm a self-resuming campaign at this cadence (`hourly`/`daily`/`weekly`/`Nh`/`Nd`) instead of running once — writes the schedule descriptor (ADR-0034). Pair with `--daily-budget`. |
|
|
95
|
-
| `--daily-budget` | 300 | Per-day point budget for a scheduled campaign. Advisory by default (an indicator of the day's spend); it only pauses the day's run when `
|
|
95
|
+
| `--daily-budget` | 300 | Per-day point budget for a scheduled campaign. Advisory by default (an indicator of the day's spend); it only pauses the day's run when `enforce_budget: true` is set by hand in the schedule descriptor (`schedule.json`); no flag or config key sets it. |
|
|
96
96
|
| `--dry-run` | off | Plan + squad delegation preview only; STOP. |
|
|
97
97
|
| `--continue` / `--stop` / `--status` | — | Resume / halt / report from `.planning/orchestration/` + focus-auto state. |
|
|
98
98
|
|
package/commands/pan/cost.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: pan:cost
|
|
3
3
|
group: Observability
|
|
4
4
|
description: Show token usage and estimated cost across PAN commands and agents
|
|
5
|
-
argument-hint: "[report|append|clear] [--format json|table|chart] [--since YYYY-MM-DD] [--until YYYY-MM-DD]"
|
|
5
|
+
argument-hint: "[report|append|clear|rebuild] [--format json|table|chart] [--since YYYY-MM-DD] [--until YYYY-MM-DD] [--apply] [--no-main-thread]"
|
|
6
6
|
allowed-tools:
|
|
7
7
|
- Read
|
|
8
8
|
- Bash
|
|
@@ -45,7 +45,10 @@ pan-tools cost report [--format json|table|chart] [--since YYYY-MM-DD] [--until
|
|
|
45
45
|
"cache_read_tokens": 50000,
|
|
46
46
|
"cache_write_tokens": 5000,
|
|
47
47
|
"cost_usd": 2.1234,
|
|
48
|
-
"cost_unknown": 0
|
|
48
|
+
"cost_unknown": 0,
|
|
49
|
+
"suspect_excluded": 0,
|
|
50
|
+
"empty_excluded": 0,
|
|
51
|
+
"malformed_skipped": 0
|
|
49
52
|
},
|
|
50
53
|
"cache_hit_rate_pct": 40.5,
|
|
51
54
|
"by_agent": { "pan-planner": { "calls": 8, "input": 50000, ... } },
|
|
@@ -78,6 +81,15 @@ Delete the cost log. Useful at the start of a billing cycle.
|
|
|
78
81
|
pan-tools cost clear
|
|
79
82
|
```
|
|
80
83
|
|
|
84
|
+
### `rebuild`
|
|
85
|
+
|
|
86
|
+
Rebuild the ledger from Claude Code's own transcripts (session file plus the per-agent files under `<session>/subagents/`, Workflow-tool subagents one level down). Rows written by hooks before v3.29 booked a slice of the parent session to whichever subagent stopped and counted turns once per content block; the rebuild replaces them with one exact row per agent transcript, typed from the main thread's `Agent` calls, plus one row per session for the main thread's own usage (`--no-main-thread` omits it). Rows whose session transcript is gone, and caller-appended rows, are kept. Dry-run by default — show the user the per-session before → after (and any `warnings`), then apply only on their say-so; the previous ledger is kept beside the new one as `tokens.jsonl.rebuilt-<date>` (a later copy never overwrites an earlier one). Run it **before** `/pan:hygiene --apply` on a poisoned ledger: quarantine moves the whole file aside, and a rebuild afterwards has no rows left to keep. The main-thread row is dated to the session's last record, so `--since`/`--until` windows and the per-day view see a session's own usage on its final day.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
pan-tools cost rebuild # dry run
|
|
90
|
+
pan-tools cost rebuild --apply # write the rebuilt ledger
|
|
91
|
+
```
|
|
92
|
+
|
|
81
93
|
</subcommands>
|
|
82
94
|
|
|
83
95
|
<rate_table>
|
package/commands/pan/preview.md
CHANGED
|
@@ -34,9 +34,9 @@ Consolidates Spec B v1's architect + simulate + predict-milestone into one entry
|
|
|
34
34
|
**What it does:**
|
|
35
35
|
1. `pan-tools preview phase <N>` returns `{files_mentioned, test_files_mentioned, risk_signals, risk_score, plans[], status}`.
|
|
36
36
|
2. Spawn `pan-previewer` with the payload as `<preview_input>`.
|
|
37
|
-
3. Agent writes `.planning/phases/<
|
|
37
|
+
3. Agent writes `.planning/phases/<NN-slug>/preview.md` with files touched / tests at risk / migration steps / risk assessment / bottom line.
|
|
38
38
|
|
|
39
|
-
**Output:** `.planning/phases/<
|
|
39
|
+
**Output:** `.planning/phases/<NN-slug>/preview.md`
|
|
40
40
|
|
|
41
41
|
### `phases` — Cross-phase dependency graph
|
|
42
42
|
|
|
@@ -113,6 +113,10 @@ function defaultFetchLatest() {
|
|
|
113
113
|
encoding: 'utf8',
|
|
114
114
|
timeout: 10000,
|
|
115
115
|
windowsHide: true,
|
|
116
|
+
// Own the silence here rather than relying on the caller's stdio: 'ignore'. npm
|
|
117
|
+
// writes registry and PATH failures to stderr, and a hook that lets them through
|
|
118
|
+
// puts its own diagnostics in front of the user mid-session.
|
|
119
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
116
120
|
}).trim();
|
|
117
121
|
}
|
|
118
122
|
|