@sienklogic/plan-build-run 2.34.0 → 2.38.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 (160) hide show
  1. package/CHANGELOG.md +683 -0
  2. package/dashboard/public/css/command-center.css +152 -65
  3. package/dashboard/public/css/explorer.css +22 -41
  4. package/dashboard/public/css/layout.css +119 -1
  5. package/dashboard/public/css/tokens.css +13 -0
  6. package/dashboard/src/components/Layout.tsx +32 -6
  7. package/dashboard/src/components/explorer/tabs/PhasesTab.tsx +11 -1
  8. package/dashboard/src/components/explorer/tabs/TodosTab.tsx +18 -2
  9. package/dashboard/src/components/partials/AttentionPanel.tsx +7 -1
  10. package/dashboard/src/components/partials/CurrentPhaseCard.tsx +26 -24
  11. package/dashboard/src/components/partials/QuickActions.tsx +21 -11
  12. package/dashboard/src/components/partials/StatCardGrid.tsx +67 -0
  13. package/dashboard/src/components/partials/StatusHeader.tsx +1 -0
  14. package/dashboard/src/routes/command-center.routes.tsx +8 -7
  15. package/dashboard/src/routes/index.routes.tsx +32 -29
  16. package/package.json +2 -2
  17. package/plugins/copilot-pbr/agents/audit.agent.md +129 -16
  18. package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +49 -1
  19. package/plugins/copilot-pbr/agents/debugger.agent.md +50 -1
  20. package/plugins/copilot-pbr/agents/dev-sync.agent.md +23 -0
  21. package/plugins/copilot-pbr/agents/executor.agent.md +153 -8
  22. package/plugins/copilot-pbr/agents/general.agent.md +46 -1
  23. package/plugins/copilot-pbr/agents/integration-checker.agent.md +55 -2
  24. package/plugins/copilot-pbr/agents/plan-checker.agent.md +50 -2
  25. package/plugins/copilot-pbr/agents/planner.agent.md +80 -1
  26. package/plugins/copilot-pbr/agents/researcher.agent.md +50 -2
  27. package/plugins/copilot-pbr/agents/synthesizer.agent.md +49 -1
  28. package/plugins/copilot-pbr/agents/verifier.agent.md +114 -13
  29. package/plugins/copilot-pbr/commands/test.md +5 -0
  30. package/plugins/copilot-pbr/hooks/hooks.json +11 -0
  31. package/plugins/copilot-pbr/plugin.json +1 -1
  32. package/plugins/copilot-pbr/references/agent-contracts.md +27 -0
  33. package/plugins/copilot-pbr/references/checkpoints.md +32 -1
  34. package/plugins/copilot-pbr/references/context-quality-tiers.md +45 -0
  35. package/plugins/copilot-pbr/references/pbr-tools-cli.md +115 -0
  36. package/plugins/copilot-pbr/references/questioning.md +21 -1
  37. package/plugins/copilot-pbr/references/verification-patterns.md +96 -18
  38. package/plugins/copilot-pbr/skills/audit/SKILL.md +19 -3
  39. package/plugins/copilot-pbr/skills/begin/SKILL.md +57 -4
  40. package/plugins/copilot-pbr/skills/build/SKILL.md +39 -2
  41. package/plugins/copilot-pbr/skills/config/SKILL.md +12 -2
  42. package/plugins/copilot-pbr/skills/debug/SKILL.md +12 -1
  43. package/plugins/copilot-pbr/skills/explore/SKILL.md +13 -2
  44. package/plugins/copilot-pbr/skills/health/SKILL.md +13 -5
  45. package/plugins/copilot-pbr/skills/import/SKILL.md +26 -1
  46. package/plugins/copilot-pbr/skills/milestone/SKILL.md +15 -3
  47. package/plugins/copilot-pbr/skills/plan/SKILL.md +50 -0
  48. package/plugins/copilot-pbr/skills/quick/SKILL.md +21 -0
  49. package/plugins/copilot-pbr/skills/review/SKILL.md +45 -0
  50. package/plugins/copilot-pbr/skills/scan/SKILL.md +20 -0
  51. package/plugins/copilot-pbr/skills/setup/SKILL.md +9 -1
  52. package/plugins/copilot-pbr/skills/shared/context-budget.md +10 -0
  53. package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +6 -0
  54. package/plugins/copilot-pbr/skills/test/SKILL.md +210 -0
  55. package/plugins/copilot-pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  56. package/plugins/copilot-pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
  57. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  58. package/plugins/cursor-pbr/agents/audit.md +52 -5
  59. package/plugins/cursor-pbr/agents/codebase-mapper.md +49 -1
  60. package/plugins/cursor-pbr/agents/debugger.md +50 -1
  61. package/plugins/cursor-pbr/agents/dev-sync.md +23 -0
  62. package/plugins/cursor-pbr/agents/executor.md +153 -8
  63. package/plugins/cursor-pbr/agents/general.md +46 -1
  64. package/plugins/cursor-pbr/agents/integration-checker.md +54 -1
  65. package/plugins/cursor-pbr/agents/plan-checker.md +49 -1
  66. package/plugins/cursor-pbr/agents/planner.md +80 -1
  67. package/plugins/cursor-pbr/agents/researcher.md +49 -1
  68. package/plugins/cursor-pbr/agents/synthesizer.md +49 -1
  69. package/plugins/cursor-pbr/agents/verifier.md +113 -12
  70. package/plugins/cursor-pbr/commands/test.md +5 -0
  71. package/plugins/cursor-pbr/hooks/hooks.json +9 -0
  72. package/plugins/cursor-pbr/references/agent-contracts.md +27 -0
  73. package/plugins/cursor-pbr/references/checkpoints.md +32 -1
  74. package/plugins/cursor-pbr/references/context-quality-tiers.md +45 -0
  75. package/plugins/cursor-pbr/references/pbr-tools-cli.md +115 -0
  76. package/plugins/cursor-pbr/references/questioning.md +21 -1
  77. package/plugins/cursor-pbr/references/verification-patterns.md +96 -18
  78. package/plugins/cursor-pbr/skills/audit/SKILL.md +19 -3
  79. package/plugins/cursor-pbr/skills/begin/SKILL.md +57 -4
  80. package/plugins/cursor-pbr/skills/build/SKILL.md +37 -2
  81. package/plugins/cursor-pbr/skills/config/SKILL.md +12 -2
  82. package/plugins/cursor-pbr/skills/debug/SKILL.md +12 -1
  83. package/plugins/cursor-pbr/skills/explore/SKILL.md +13 -2
  84. package/plugins/cursor-pbr/skills/health/SKILL.md +14 -5
  85. package/plugins/cursor-pbr/skills/import/SKILL.md +26 -1
  86. package/plugins/cursor-pbr/skills/milestone/SKILL.md +15 -3
  87. package/plugins/cursor-pbr/skills/plan/SKILL.md +50 -0
  88. package/plugins/cursor-pbr/skills/quick/SKILL.md +21 -0
  89. package/plugins/cursor-pbr/skills/review/SKILL.md +45 -0
  90. package/plugins/cursor-pbr/skills/scan/SKILL.md +20 -0
  91. package/plugins/cursor-pbr/skills/setup/SKILL.md +9 -1
  92. package/plugins/cursor-pbr/skills/shared/context-budget.md +10 -0
  93. package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +6 -0
  94. package/plugins/cursor-pbr/skills/test/SKILL.md +211 -0
  95. package/plugins/cursor-pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  96. package/plugins/cursor-pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
  97. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  98. package/plugins/pbr/agents/audit.md +45 -0
  99. package/plugins/pbr/agents/codebase-mapper.md +48 -0
  100. package/plugins/pbr/agents/debugger.md +49 -0
  101. package/plugins/pbr/agents/dev-sync.md +23 -0
  102. package/plugins/pbr/agents/executor.md +151 -6
  103. package/plugins/pbr/agents/general.md +45 -0
  104. package/plugins/pbr/agents/integration-checker.md +53 -0
  105. package/plugins/pbr/agents/plan-checker.md +48 -0
  106. package/plugins/pbr/agents/planner.md +78 -1
  107. package/plugins/pbr/agents/researcher.md +48 -0
  108. package/plugins/pbr/agents/synthesizer.md +48 -0
  109. package/plugins/pbr/agents/verifier.md +112 -11
  110. package/plugins/pbr/commands/test.md +5 -0
  111. package/plugins/pbr/hooks/hooks.json +9 -0
  112. package/plugins/pbr/references/agent-contracts.md +27 -0
  113. package/plugins/pbr/references/checkpoints.md +32 -0
  114. package/plugins/pbr/references/context-quality-tiers.md +45 -0
  115. package/plugins/pbr/references/pbr-tools-cli.md +115 -0
  116. package/plugins/pbr/references/questioning.md +21 -0
  117. package/plugins/pbr/references/verification-patterns.md +96 -17
  118. package/plugins/pbr/scripts/check-plan-format.js +13 -1
  119. package/plugins/pbr/scripts/check-state-sync.js +26 -7
  120. package/plugins/pbr/scripts/check-subagent-output.js +30 -2
  121. package/plugins/pbr/scripts/config-schema.json +11 -1
  122. package/plugins/pbr/scripts/context-bridge.js +265 -0
  123. package/plugins/pbr/scripts/lib/config.js +271 -0
  124. package/plugins/pbr/scripts/lib/core.js +587 -0
  125. package/plugins/pbr/scripts/lib/history.js +73 -0
  126. package/plugins/pbr/scripts/lib/init.js +166 -0
  127. package/plugins/pbr/scripts/lib/migrate.js +169 -0
  128. package/plugins/pbr/scripts/lib/phase.js +364 -0
  129. package/plugins/pbr/scripts/lib/roadmap.js +175 -0
  130. package/plugins/pbr/scripts/lib/state.js +397 -0
  131. package/plugins/pbr/scripts/lib/todo.js +300 -0
  132. package/plugins/pbr/scripts/pbr-tools.js +425 -1310
  133. package/plugins/pbr/scripts/post-write-dispatch.js +5 -4
  134. package/plugins/pbr/scripts/pre-write-dispatch.js +1 -1
  135. package/plugins/pbr/scripts/progress-tracker.js +1 -1
  136. package/plugins/pbr/scripts/suggest-compact.js +1 -1
  137. package/plugins/pbr/scripts/track-context-budget.js +53 -2
  138. package/plugins/pbr/scripts/validate-task.js +20 -28
  139. package/plugins/pbr/skills/audit/SKILL.md +19 -3
  140. package/plugins/pbr/skills/begin/SKILL.md +48 -2
  141. package/plugins/pbr/skills/build/SKILL.md +39 -2
  142. package/plugins/pbr/skills/config/SKILL.md +12 -2
  143. package/plugins/pbr/skills/debug/SKILL.md +12 -1
  144. package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +12 -1
  145. package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +12 -5
  146. package/plugins/pbr/skills/explore/SKILL.md +13 -2
  147. package/plugins/pbr/skills/health/SKILL.md +14 -3
  148. package/plugins/pbr/skills/help/SKILL.md +2 -0
  149. package/plugins/pbr/skills/import/SKILL.md +26 -1
  150. package/plugins/pbr/skills/milestone/SKILL.md +15 -3
  151. package/plugins/pbr/skills/plan/SKILL.md +52 -2
  152. package/plugins/pbr/skills/quick/SKILL.md +21 -0
  153. package/plugins/pbr/skills/review/SKILL.md +46 -0
  154. package/plugins/pbr/skills/scan/SKILL.md +20 -0
  155. package/plugins/pbr/skills/setup/SKILL.md +9 -1
  156. package/plugins/pbr/skills/shared/context-budget.md +10 -0
  157. package/plugins/pbr/skills/shared/universal-anti-patterns.md +6 -0
  158. package/plugins/pbr/skills/test/SKILL.md +212 -0
  159. package/plugins/pbr/templates/SUMMARY-complex.md.tmpl +95 -0
  160. package/plugins/pbr/templates/SUMMARY-minimal.md.tmpl +48 -0
@@ -0,0 +1,271 @@
1
+ /**
2
+ * lib/config.js — Config operations for Plan-Build-Run tools.
3
+ *
4
+ * Handles loading, caching, validating, and resolving depth profiles
5
+ * for .planning/config.json.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { validateObject } = require('./core');
11
+ const { CURRENT_SCHEMA_VERSION } = require('./migrate');
12
+
13
+ // --- Cached config loader ---
14
+
15
+ let _configCache = null;
16
+ let _configMtime = 0;
17
+ let _configPath = null;
18
+
19
+ /**
20
+ * Load config.json with in-process mtime-based caching.
21
+ * Returns the parsed config object, or null if not found / parse error.
22
+ * Cache invalidates when file mtime changes or path differs.
23
+ *
24
+ * @param {string} [dir] - Path to .planning directory (defaults to PBR_PROJECT_ROOT/.planning or cwd/.planning)
25
+ * @returns {object|null} Parsed config or null
26
+ */
27
+ function configLoad(dir) {
28
+ const planningDir = dir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
29
+ const configPath = path.join(planningDir, 'config.json');
30
+ try {
31
+ if (!fs.existsSync(configPath)) return null;
32
+ const stat = fs.statSync(configPath);
33
+ const mtime = stat.mtimeMs;
34
+ if (_configCache && mtime === _configMtime && configPath === _configPath) {
35
+ return _configCache;
36
+ }
37
+ _configCache = JSON.parse(fs.readFileSync(configPath, 'utf8'));
38
+ _configMtime = mtime;
39
+ _configPath = configPath;
40
+ return _configCache;
41
+ } catch (_e) {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Clear the configLoad() in-process cache.
48
+ * Useful in tests where multiple temp directories are used in rapid succession.
49
+ */
50
+ function configClearCache() {
51
+ _configCache = null;
52
+ _configMtime = 0;
53
+ _configPath = null;
54
+ }
55
+
56
+ /**
57
+ * Validate config.json against schema. Accepts a preloaded config object
58
+ * or reads from the default planningDir.
59
+ *
60
+ * @param {object} [preloadedConfig] - Pre-parsed config object. If omitted, reads from disk.
61
+ * @param {string} [planningDir] - Path to .planning directory (used when reading from disk)
62
+ * @returns {{ valid: boolean, errors: string[], warnings: string[] }}
63
+ */
64
+ function configValidate(preloadedConfig, planningDir) {
65
+ let config;
66
+ if (preloadedConfig) {
67
+ config = preloadedConfig;
68
+ } else {
69
+ const dir = planningDir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
70
+ const configPath = path.join(dir, 'config.json');
71
+ if (!fs.existsSync(configPath)) {
72
+ return { valid: false, errors: ['config.json not found'], warnings: [] };
73
+ }
74
+
75
+ try {
76
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
77
+ } catch (e) {
78
+ return { valid: false, errors: [`config.json is not valid JSON: ${e.message}`], warnings: [] };
79
+ }
80
+ }
81
+
82
+ const schema = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'config-schema.json'), 'utf8'));
83
+ const warnings = [];
84
+ const errors = [];
85
+
86
+ validateObject(config, schema, '', errors, warnings);
87
+
88
+ // Schema version check — detect outdated or future config format
89
+ if (config.schema_version && config.schema_version > CURRENT_SCHEMA_VERSION) {
90
+ warnings.push(`config.json schema_version (${config.schema_version}) is newer than this PBR version supports (${CURRENT_SCHEMA_VERSION}). Some fields may be ignored. Consider updating PBR.`);
91
+ } else if (!config.schema_version || config.schema_version < CURRENT_SCHEMA_VERSION) {
92
+ warnings.push(`config.json schema is outdated. Run: node pbr-tools.js migrate`);
93
+ }
94
+
95
+ // Semantic conflict detection — logical contradictions that pass schema validation
96
+ // Clear contradictions -> errors; ambiguous/preference issues -> warnings
97
+ if (config.mode === 'autonomous' && config.gates) {
98
+ const activeGates = Object.entries(config.gates || {}).filter(([, v]) => v === true).map(([k]) => k);
99
+ if (activeGates.length > 0) {
100
+ errors.push(`mode=autonomous with active gates (${activeGates.join(', ')}): gates are unreachable in autonomous mode`);
101
+ }
102
+ }
103
+ if (config.features && config.features.auto_continue && config.mode === 'interactive') {
104
+ warnings.push('features.auto_continue=true with mode=interactive: auto_continue only fires in autonomous mode');
105
+ }
106
+ if (config.parallelization) {
107
+ if (config.parallelization.enabled === false && config.parallelization.plan_level === true) {
108
+ warnings.push('parallelization.enabled=false with plan_level=true: plan_level is ignored when parallelization is disabled');
109
+ }
110
+ if (config.parallelization.max_concurrent_agents === 1 && config.teams && config.teams.coordination) {
111
+ errors.push('parallelization.max_concurrent_agents=1 with teams.coordination set: teams require concurrent agents to be useful');
112
+ }
113
+ }
114
+
115
+ return {
116
+ valid: errors.length === 0,
117
+ errors,
118
+ warnings
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Built-in depth profile defaults. These define the effective settings
124
+ * for each depth level. User config.depth_profiles overrides these.
125
+ */
126
+ const DEPTH_PROFILE_DEFAULTS = {
127
+ quick: {
128
+ 'features.research_phase': false,
129
+ 'features.plan_checking': false,
130
+ 'features.goal_verification': false,
131
+ 'features.inline_verify': false,
132
+ 'scan.mapper_count': 2,
133
+ 'scan.mapper_areas': ['tech', 'arch'],
134
+ 'debug.max_hypothesis_rounds': 3
135
+ },
136
+ standard: {
137
+ 'features.research_phase': true,
138
+ 'features.plan_checking': true,
139
+ 'features.goal_verification': true,
140
+ 'features.inline_verify': false,
141
+ 'scan.mapper_count': 4,
142
+ 'scan.mapper_areas': ['tech', 'arch', 'quality', 'concerns'],
143
+ 'debug.max_hypothesis_rounds': 5
144
+ },
145
+ comprehensive: {
146
+ 'features.research_phase': true,
147
+ 'features.plan_checking': true,
148
+ 'features.goal_verification': true,
149
+ 'features.inline_verify': true,
150
+ 'scan.mapper_count': 4,
151
+ 'scan.mapper_areas': ['tech', 'arch', 'quality', 'concerns'],
152
+ 'debug.max_hypothesis_rounds': 10
153
+ }
154
+ };
155
+
156
+ /**
157
+ * Resolve the effective depth profile for the current config.
158
+ * Merges built-in defaults with any user overrides from config.depth_profiles.
159
+ *
160
+ * @param {object|null} config - Parsed config.json (from configLoad). If null, returns 'standard' defaults.
161
+ * @returns {{ depth: string, profile: object }} The resolved depth name and flattened profile settings.
162
+ */
163
+ function resolveDepthProfile(config) {
164
+ const depth = (config && config.depth) || 'standard';
165
+ const defaults = DEPTH_PROFILE_DEFAULTS[depth] || DEPTH_PROFILE_DEFAULTS.standard;
166
+
167
+ // Merge user overrides if present
168
+ const userOverrides = (config && config.depth_profiles && config.depth_profiles[depth]) || {};
169
+ const profile = { ...defaults, ...userOverrides };
170
+
171
+ return { depth, profile };
172
+ }
173
+
174
+ // --- User-level defaults ---
175
+
176
+ const USER_DEFAULTS_PATH = path.join(
177
+ process.env.HOME || process.env.USERPROFILE || '',
178
+ '.claude',
179
+ 'pbr-defaults.json'
180
+ );
181
+
182
+ /**
183
+ * Load user-level defaults from ~/.claude/pbr-defaults.json.
184
+ * Returns null if file doesn't exist or is invalid.
185
+ *
186
+ * @returns {object|null} User defaults or null
187
+ */
188
+ function loadUserDefaults() {
189
+ try {
190
+ if (!fs.existsSync(USER_DEFAULTS_PATH)) return null;
191
+ return JSON.parse(fs.readFileSync(USER_DEFAULTS_PATH, 'utf8'));
192
+ } catch (_e) {
193
+ return null;
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Save current project config as user-level defaults.
199
+ * Only saves portable keys (excludes project-specific state).
200
+ *
201
+ * @param {object} config - Current project config.json contents
202
+ * @returns {{ saved: boolean, path: string, keys: string[] }}
203
+ */
204
+ function saveUserDefaults(config) {
205
+ const portableKeys = [
206
+ 'mode', 'depth', 'context_strategy',
207
+ 'features', 'models', 'parallelization',
208
+ 'planning', 'git', 'gates', 'safety',
209
+ 'hooks', 'dashboard', 'status_line'
210
+ ];
211
+
212
+ const defaults = {};
213
+ for (const key of portableKeys) {
214
+ if (config[key] !== undefined) {
215
+ defaults[key] = config[key];
216
+ }
217
+ }
218
+
219
+ const dir = path.dirname(USER_DEFAULTS_PATH);
220
+ if (!fs.existsSync(dir)) {
221
+ fs.mkdirSync(dir, { recursive: true });
222
+ }
223
+ fs.writeFileSync(USER_DEFAULTS_PATH, JSON.stringify(defaults, null, 2), 'utf8');
224
+
225
+ return {
226
+ saved: true,
227
+ path: USER_DEFAULTS_PATH,
228
+ keys: Object.keys(defaults)
229
+ };
230
+ }
231
+
232
+ /**
233
+ * Deep-merge user defaults into a base config.
234
+ * User defaults provide values only where the base config doesn't already set them.
235
+ * For nested objects, merges recursively. Scalars from base take precedence.
236
+ *
237
+ * @param {object} base - The base config (project defaults from setup)
238
+ * @param {object} userDefaults - User-level defaults from ~/.claude/pbr-defaults.json
239
+ * @returns {object} Merged config
240
+ */
241
+ function mergeUserDefaults(base, userDefaults) {
242
+ if (!userDefaults) return base;
243
+
244
+ const result = { ...base };
245
+ for (const [key, value] of Object.entries(userDefaults)) {
246
+ if (result[key] === undefined) {
247
+ // Key not in base — use user default
248
+ result[key] = value;
249
+ } else if (
250
+ typeof value === 'object' && value !== null && !Array.isArray(value) &&
251
+ typeof result[key] === 'object' && result[key] !== null && !Array.isArray(result[key])
252
+ ) {
253
+ // Both are objects — merge recursively (base values take precedence)
254
+ result[key] = mergeUserDefaults(result[key], value);
255
+ }
256
+ // Scalar in base already set — base wins
257
+ }
258
+ return result;
259
+ }
260
+
261
+ module.exports = {
262
+ configLoad,
263
+ configClearCache,
264
+ configValidate,
265
+ resolveDepthProfile,
266
+ DEPTH_PROFILE_DEFAULTS,
267
+ loadUserDefaults,
268
+ saveUserDefaults,
269
+ mergeUserDefaults,
270
+ USER_DEFAULTS_PATH
271
+ };