pan-wizard 3.8.0 → 3.12.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.
Files changed (72) hide show
  1. package/README.md +80 -9
  2. package/agents/pan-conductor.md +15 -3
  3. package/agents/pan-counterfactual.md +1 -2
  4. package/agents/pan-debugger.md +1 -2
  5. package/agents/pan-distiller.md +1 -2
  6. package/agents/pan-document_code.md +1 -0
  7. package/agents/pan-executor.md +1 -0
  8. package/agents/pan-experiment-runner.md +1 -2
  9. package/agents/pan-hardener.md +1 -2
  10. package/agents/pan-integration-checker.md +1 -2
  11. package/agents/pan-knowledge.md +1 -2
  12. package/agents/pan-meta-reviewer.md +1 -2
  13. package/agents/pan-optimizer.md +1 -0
  14. package/agents/pan-phase-researcher.md +1 -0
  15. package/agents/pan-plan-checker.md +1 -2
  16. package/agents/pan-planner.md +1 -0
  17. package/agents/pan-previewer.md +1 -2
  18. package/agents/pan-project-researcher.md +6 -0
  19. package/agents/pan-release.md +58 -0
  20. package/agents/pan-research-synthesizer.md +7 -0
  21. package/agents/pan-reviewer.md +2 -3
  22. package/agents/pan-roadmapper.md +1 -0
  23. package/agents/pan-verifier.md +1 -2
  24. package/assets/pan-avatar.png +0 -0
  25. package/assets/pan-developer.png +0 -0
  26. package/assets/pan-docs-header.png +0 -0
  27. package/assets/pan-hero.png +0 -0
  28. package/assets/pan-logo-2000-transparent.svg +11 -30
  29. package/assets/pan-logo-2000.svg +12 -43
  30. package/assets/pan-logo-lockup.svg +11 -0
  31. package/assets/pan-mark.svg +7 -0
  32. package/assets/pan-orchestration.png +0 -0
  33. package/assets/pan-readme-hero.png +0 -0
  34. package/assets/terminal.svg +39 -119
  35. package/bin/install-lib.cjs +661 -46
  36. package/bin/install.js +722 -116
  37. package/commands/pan/army.md +169 -0
  38. package/commands/pan/dashboard.md +25 -0
  39. package/commands/pan/experiment.md +2 -0
  40. package/commands/pan/focus-auto.md +32 -4
  41. package/commands/pan/hud.md +91 -0
  42. package/commands/pan/profile.md +2 -0
  43. package/hooks/dist/pan-cost-logger.js +22 -7
  44. package/package.json +5 -4
  45. package/pan-wizard-core/bin/lib/campaign.cjs +198 -0
  46. package/pan-wizard-core/bin/lib/commands-learnings.cjs +544 -0
  47. package/pan-wizard-core/bin/lib/commands.cjs +12 -523
  48. package/pan-wizard-core/bin/lib/constants.cjs +8 -0
  49. package/pan-wizard-core/bin/lib/core.cjs +80 -0
  50. package/pan-wizard-core/bin/lib/cost.cjs +62 -8
  51. package/pan-wizard-core/bin/lib/focus.cjs +13 -1
  52. package/pan-wizard-core/bin/lib/git.cjs +6 -1
  53. package/pan-wizard-core/bin/lib/hud.cjs +887 -0
  54. package/pan-wizard-core/bin/lib/lock.cjs +108 -0
  55. package/pan-wizard-core/bin/lib/milestone.cjs +3 -2
  56. package/pan-wizard-core/bin/lib/phase-remove.cjs +392 -0
  57. package/pan-wizard-core/bin/lib/phase.cjs +4 -369
  58. package/pan-wizard-core/bin/lib/runner.cjs +5 -0
  59. package/pan-wizard-core/bin/lib/squads.cjs +152 -0
  60. package/pan-wizard-core/bin/lib/state.cjs +10 -1
  61. package/pan-wizard-core/bin/lib/verify-deploy.cjs +181 -0
  62. package/pan-wizard-core/bin/lib/verify-drift.cjs +255 -0
  63. package/pan-wizard-core/bin/lib/verify-preflight.cjs +261 -0
  64. package/pan-wizard-core/bin/lib/verify-retro.cjs +177 -0
  65. package/pan-wizard-core/bin/lib/verify.cjs +10 -797
  66. package/pan-wizard-core/bin/lib/worktree.cjs +123 -0
  67. package/pan-wizard-core/bin/pan-tools.cjs +78 -0
  68. package/pan-wizard-core/learnings/universal/autonomous-loop.md +56 -0
  69. package/pan-wizard-core/workflows/plan-phase.md +11 -0
  70. package/scripts/build-plugin.js +105 -0
  71. package/scripts/install-git-hooks.js +64 -0
  72. package/scripts/release-check.js +13 -2
@@ -73,8 +73,75 @@ const MODEL_PROFILES = {
73
73
  'pan-distiller': { quality: 'reasoning', balanced: 'fast', budget: 'fast' },
74
74
  // v3.7.0 self-improvement loop — observation-only watchdog
75
75
  'pan-experiment-runner': { quality: 'reasoning', balanced: 'fast', budget: 'fast' },
76
+ // ADR-0033 bot-army — Release squad
77
+ 'pan-release': { quality: 'reasoning', balanced: 'mid', budget: 'fast' },
76
78
  };
77
79
 
80
+ // ─── Effort Profiles (2026-06, adaptive-thinking era) ───────────────────────
81
+ //
82
+ // Per-agent base reasoning effort (low|medium|high|xhigh). `effort` is the
83
+ // primary within-model cost/intelligence dial on current models — it replaced
84
+ // fixed thinking budgets. The base values here mirror the `effort:`
85
+ // frontmatter shipped in agents/*.md (a drift test keeps them in sync).
86
+ //
87
+ // Profile modulation: `budget` steps effort down one level (floor: low) as
88
+ // its cost lever; `quality` and `balanced` keep the base. Per-agent override
89
+ // via config.json → effort_overrides.
90
+
91
+ const EFFORT_ORDER = ['low', 'medium', 'high', 'xhigh'];
92
+
93
+ const AGENT_BASE_EFFORT = {
94
+ // Heavy planning/orchestration/debugging — deepest reasoning
95
+ 'pan-planner': 'xhigh',
96
+ 'pan-conductor': 'xhigh',
97
+ 'pan-debugger': 'xhigh',
98
+ 'pan-plan-checker': 'xhigh',
99
+ // Execution and verification — thorough but bounded
100
+ 'pan-executor': 'high',
101
+ 'pan-roadmapper': 'high',
102
+ 'pan-verifier': 'high',
103
+ 'pan-integration-checker': 'high',
104
+ 'pan-hardener': 'high',
105
+ 'pan-counterfactual': 'high',
106
+ 'pan-previewer': 'high',
107
+ 'pan-experiment-runner': 'high',
108
+ 'pan-optimizer': 'high',
109
+ 'pan-release': 'high',
110
+ // Research/synthesis/review — moderate depth
111
+ 'pan-phase-researcher': 'medium',
112
+ 'pan-project-researcher': 'medium',
113
+ 'pan-research-synthesizer': 'medium',
114
+ 'pan-knowledge': 'medium',
115
+ 'pan-distiller': 'medium',
116
+ 'pan-meta-reviewer': 'medium',
117
+ 'pan-reviewer': 'medium',
118
+ // Mechanical documentation pass — fast and scoped
119
+ 'pan-document_code': 'low',
120
+ };
121
+
122
+ /**
123
+ * Resolve the reasoning effort level for an agent under the active profile.
124
+ * Priority: config.effort_overrides[agent] → base effort modulated by
125
+ * model_profile (budget steps down one level) → 'medium' for unknown agents.
126
+ *
127
+ * @param {string} cwd - Project root directory
128
+ * @param {string} agentType - e.g. "pan-planner"
129
+ * @returns {string} One of 'low' | 'medium' | 'high' | 'xhigh'
130
+ */
131
+ function resolveEffortInternal(cwd, agentType) {
132
+ const config = loadConfig(cwd);
133
+ const override = config.effort_overrides?.[agentType];
134
+ if (typeof override === 'string' && EFFORT_ORDER.includes(override.toLowerCase().trim())) {
135
+ return override.toLowerCase().trim();
136
+ }
137
+ const base = AGENT_BASE_EFFORT[agentType] || 'medium';
138
+ const profile = config.model_profile || 'balanced';
139
+ if (profile === 'budget') {
140
+ return EFFORT_ORDER[Math.max(0, EFFORT_ORDER.indexOf(base) - 1)];
141
+ }
142
+ return base;
143
+ }
144
+
78
145
  // ─── Output helpers ───────────────────────────────────────────────────────────
79
146
 
80
147
  /**
@@ -213,7 +280,13 @@ function loadConfig(cwd) {
213
280
  execution: parsed.execution || { default_mode: 'wave_order', rollback_snapshots: true, error_pattern_learning: true },
214
281
  focus: parsed.focus || { auto_commit: true },
215
282
  model_overrides: parsed.model_overrides || {},
283
+ effort_overrides: parsed.effort_overrides || {},
216
284
  routing: parsed.routing || { strategy: 'static', provider: 'auto' },
285
+ // ADR-0031: project build/verification commands. null = not configured
286
+ // (focus-auto --clean-seal then asks or skips rather than guessing).
287
+ build: parsed.build || null,
288
+ verification: parsed.verification || null,
289
+ concurrency: parsed.concurrency || { serial_build: false },
217
290
  };
218
291
  } catch { // Config missing or malformed — use defaults
219
292
  return {
@@ -223,7 +296,11 @@ function loadConfig(cwd) {
223
296
  execution: { default_mode: 'wave_order', rollback_snapshots: true, error_pattern_learning: true },
224
297
  focus: { auto_commit: true },
225
298
  model_overrides: {},
299
+ effort_overrides: {},
226
300
  routing: { strategy: 'static', provider: 'auto' },
301
+ build: null,
302
+ verification: null,
303
+ concurrency: { serial_build: false },
227
304
  };
228
305
  }
229
306
  }
@@ -860,6 +937,9 @@ function scanSourceTodos(cwd) {
860
937
 
861
938
  module.exports = {
862
939
  MODEL_PROFILES,
940
+ AGENT_BASE_EFFORT,
941
+ EFFORT_ORDER,
942
+ resolveEffortInternal,
863
943
  PROVIDER_MODELS,
864
944
  LEGACY_ALIASES,
865
945
  COST_MULTIPLIERS,
@@ -30,7 +30,7 @@
30
30
  * - hit rate: cache_read / (cache_read + input - cache_write) if any cache activity
31
31
  *
32
32
  * Rate table is approximate — real pricing comes from the provider's API.
33
- * Rates are US dollars per million tokens, indicative as of 2026-04. Users
33
+ * Rates are US dollars per million tokens, indicative as of 2026-06. Users
34
34
  * can override with `.planning/config.json` → `cost.rates`.
35
35
  */
36
36
 
@@ -48,21 +48,32 @@ const TOKENS_FILE = 'tokens.jsonl';
48
48
  * Override per-model in config.json → cost.rates.
49
49
  */
50
50
  const DEFAULT_RATES = {
51
- // Anthropic
52
- 'claude-opus-4-7': { input: 15.0, output: 75.0, cache_read: 1.5, cache_write: 18.75 },
53
- 'claude-opus-4-6': { input: 15.0, output: 75.0, cache_read: 1.5, cache_write: 18.75 },
51
+ // Anthropic — verified against platform pricing 2026-06. Opus 4.6+ is $5/$25
52
+ // (the old $15/$75 Opus pricing ended with the 4.5 generation). Cache rates
53
+ // follow Anthropic's convention: read 0.1× input, write 1.25× input.
54
+ 'claude-fable-5': { input: 10.0, output: 50.0, cache_read: 1.0, cache_write: 12.5 },
55
+ 'claude-opus-4-8': { input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25 },
56
+ 'claude-opus-4-7': { input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25 },
57
+ 'claude-opus-4-6': { input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25 },
54
58
  'claude-sonnet-4-6': { input: 3.0, output: 15.0, cache_read: 0.3, cache_write: 3.75 },
55
59
  'claude-haiku-4-5': { input: 1.0, output: 5.0, cache_read: 0.1, cache_write: 1.25 },
56
60
 
61
+ // OpenAI — verified against published pricing 2026-06 ($5/$30 standard tier).
62
+ // Prompt caching is a 90% input discount with no separate write charge, so
63
+ // cache_write bills at the plain input rate.
64
+ 'gpt-5.5': { input: 5.0, output: 30.0, cache_read: 0.5, cache_write: 5.0 },
65
+
57
66
  // Google Gemini — published rates (per million tokens, approximate; users can override via config.json → cost.rates).
58
- // 2.5 tier uses the <=200K-context tier; long-context calls may be billed at ~2x. Cache rates are Google's context-cache pricing (~25% of input rate).
67
+ // Pro tiers use the <=200K-context tier; long-context calls may be billed at ~2x. Cache rates are Google's context-cache pricing (~25% of input rate).
68
+ // (gemini-1.5-pro removed 2026-06: retired model; records for it fall back to tier rates.)
69
+ 'gemini-3.1-pro': { input: 2.00, output: 12.0, cache_read: 0.50, cache_write: 2.00 },
70
+ 'gemini-3.1-pro-preview': { input: 2.00, output: 12.0, cache_read: 0.50, cache_write: 2.00 },
59
71
  'gemini-2.5-pro': { input: 1.25, output: 10.0, cache_read: 0.3125, cache_write: 1.25 },
60
72
  'gemini-2.5-flash': { input: 0.30, output: 2.50, cache_read: 0.075, cache_write: 0.30 },
61
73
  'gemini-2.5-flash-lite': { input: 0.10, output: 0.40, cache_read: 0.025, cache_write: 0.10 },
62
- 'gemini-1.5-pro': { input: 1.25, output: 5.00, cache_read: 0.3125, cache_write: 1.25 },
63
74
 
64
- // Tier fallbacks when model id is unknown
65
- 'reasoning': { input: 15.0, output: 75.0, cache_read: 1.5, cache_write: 18.75 },
75
+ // Tier fallbacks when model id is unknown (reasoning tracks current Opus pricing)
76
+ 'reasoning': { input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25 },
66
77
  'mid': { input: 3.0, output: 15.0, cache_read: 0.3, cache_write: 3.75 },
67
78
  'fast': { input: 1.0, output: 5.0, cache_read: 0.1, cache_write: 1.25 },
68
79
  };
@@ -81,6 +92,15 @@ function resolveRate(model, tier, configRates) {
81
92
  if (tier && configRates[tier]) return configRates[tier];
82
93
  }
83
94
  if (model && DEFAULT_RATES[model]) return DEFAULT_RATES[model];
95
+ // Transcript/hook-captured ids are versioned ("claude-opus-4-8-20260301",
96
+ // "claude-fable-5[1m]") while the table uses family keys — prefix-match,
97
+ // longest key first so the most specific family wins.
98
+ if (model) {
99
+ const families = Object.keys(DEFAULT_RATES)
100
+ .filter(k => model.startsWith(k))
101
+ .sort((a, b) => b.length - a.length);
102
+ if (families.length > 0) return DEFAULT_RATES[families[0]];
103
+ }
84
104
  if (tier && DEFAULT_RATES[tier]) return DEFAULT_RATES[tier];
85
105
  return null;
86
106
  }
@@ -342,6 +362,37 @@ function cmdCostClear(cwd, raw) {
342
362
  }
343
363
  }
344
364
 
365
+ // ─── Rate-table staleness ───────────────────────────────────────────────────
366
+
367
+ // Date DEFAULT_RATES was last verified against published provider pricing.
368
+ // Bump this whenever the table is re-verified; `models check` flags the table
369
+ // once it is older than RATES_STALE_AFTER_DAYS (provider prices move faster
370
+ // than PAN releases do).
371
+ const RATES_VERIFIED_AT = '2026-06-10';
372
+ const RATES_STALE_AFTER_DAYS = 180;
373
+ const RATE_TIERS = ['reasoning', 'mid', 'fast'];
374
+
375
+ function checkRatesStaleness(now = new Date()) {
376
+ const verified = new Date(RATES_VERIFIED_AT + 'T00:00:00Z');
377
+ const ageDays = Math.floor((now.getTime() - verified.getTime()) / 86400000);
378
+ return {
379
+ rates_verified_at: RATES_VERIFIED_AT,
380
+ age_days: ageDays,
381
+ stale_after_days: RATES_STALE_AFTER_DAYS,
382
+ stale: ageDays > RATES_STALE_AFTER_DAYS,
383
+ models: Object.keys(DEFAULT_RATES).filter(k => !RATE_TIERS.includes(k)),
384
+ tiers: RATE_TIERS,
385
+ };
386
+ }
387
+
388
+ function cmdModelsCheck(raw) {
389
+ const result = checkRatesStaleness();
390
+ const human = result.stale
391
+ ? `Rate table verified ${result.rates_verified_at} (${result.age_days} days ago) — STALE: re-verify provider pricing and bump RATES_VERIFIED_AT in cost.cjs`
392
+ : `Rate table verified ${result.rates_verified_at} (${result.age_days} days ago) — OK`;
393
+ output(result, raw, human);
394
+ }
395
+
345
396
  module.exports = {
346
397
  computeCost,
347
398
  appendRecord,
@@ -350,10 +401,13 @@ module.exports = {
350
401
  renderTable,
351
402
  renderChart,
352
403
  resolveRate,
404
+ checkRatesStaleness,
353
405
  cmdCostReport,
354
406
  cmdCostAppend,
355
407
  cmdCostClear,
408
+ cmdModelsCheck,
356
409
  METRICS_DIR,
357
410
  TOKENS_FILE,
358
411
  DEFAULT_RATES,
412
+ RATES_VERIFIED_AT,
359
413
  };
@@ -14,7 +14,7 @@ const {
14
14
  FOCUS_MODES, FOCUS_TIERS, FOCUS_DIR,
15
15
  BUDGET_LIMIT_BUGFIX, BUDGET_LIMIT_FULL, STABILITY_RATIO, FEATURE_RATIO,
16
16
  DIMINISHING_RETURNS_THRESHOLD,
17
- AUTO_RUN_FILE, FOCUS_CATEGORIES, CATEGORY_PRIORITY_RANGE, CATEGORY_DEFAULTS,
17
+ AUTO_RUN_FILE, FOCUS_CATEGORIES, FOCUS_SOURCES, CATEGORY_PRIORITY_RANGE, CATEGORY_DEFAULTS,
18
18
  DEFAULT_MAX_CYCLES, DEFAULT_TOTAL_BUDGET,
19
19
  BUDGET_MIN, BUDGET_MAX, MAX_CYCLES_MIN, MAX_CYCLES_MAX, TOTAL_BUDGET_MIN, TOTAL_BUDGET_MAX,
20
20
  AUTORUN_STATUSES, DOC_SYNC_FILES, COMMAND_RENAME_MAP,
@@ -829,6 +829,14 @@ function focusAutoInit(cwd, raw, getVal, hasFlag) {
829
829
  return error(`Category must be one of: ${FOCUS_CATEGORIES.join(', ')}`);
830
830
  }
831
831
 
832
+ // ADR-0031: work source — 'scan' (category code-scan, default) or 'backlog'
833
+ // (rank actionable roadmap.md / requirements.md items). Category applies to
834
+ // scan mode; backlog mode ranks the whole actionable backlog.
835
+ const source = getVal('--source', 'scan');
836
+ if (!FOCUS_SOURCES.includes(source)) {
837
+ return error(`Source must be one of: ${FOCUS_SOURCES.join(', ')}`);
838
+ }
839
+
832
840
  const existing = readAutoRun(cwd);
833
841
  if (existing && (existing.status === AUTORUN_STATUSES.IN_PROGRESS || existing.status === AUTORUN_STATUSES.INITIALIZED)) {
834
842
  return error('Auto-run already in progress. Use --stop to end it, or --continue to resume.');
@@ -848,8 +856,12 @@ function focusAutoInit(cwd, raw, getVal, hasFlag) {
848
856
  const runData = {
849
857
  run_id: generateRunId(cwd),
850
858
  status: AUTORUN_STATUSES.INITIALIZED,
859
+ source: source,
851
860
  category: category,
852
861
  mode: mode,
862
+ parallel_research: hasFlag('--parallel-research'),
863
+ parallel_verify: hasFlag('--parallel-verify'),
864
+ clean_seal: hasFlag('--clean-seal'),
853
865
  budget_per_cycle: budget,
854
866
  max_cycles: maxCycles,
855
867
  total_budget: totalBudget,
@@ -272,7 +272,12 @@ function cmdGitTag(cwd, sub, opts, raw) {
272
272
  }
273
273
  if (sub === 'create') {
274
274
  if (!name) { error('--name required for tag create'); }
275
- const args = message ? ['tag', '-m', message, name] : ['tag', name];
275
+ // tag.gpgsign=true in user config would force signing (and fail outright
276
+ // for lightweight tags) in non-interactive runs — PAN tags are automation
277
+ // markers, so signing is explicitly disabled.
278
+ const args = message
279
+ ? ['-c', 'tag.gpgsign=false', 'tag', '-m', message, name]
280
+ : ['-c', 'tag.gpgsign=false', 'tag', name];
276
281
  const r = execGit(cwd, args);
277
282
  if (r.exitCode !== 0) {
278
283
  output({ created: false, tag: name, detail: r.stderr }, raw, 'tag create failed');