@sienklogic/plan-build-run 2.27.2 → 2.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dashboard/bin/cli.js +3 -3
  3. package/dashboard/package.json +8 -5
  4. package/dashboard/public/css/command-center.css +382 -0
  5. package/dashboard/public/css/layout.css +481 -254
  6. package/dashboard/public/css/tokens.css +70 -61
  7. package/dashboard/public/js/sse-client.js +52 -82
  8. package/dashboard/public/js/theme-toggle.js +19 -14
  9. package/dashboard/src/components/Layout.tsx +99 -0
  10. package/dashboard/src/components/partials/ActivityStream.tsx +58 -0
  11. package/dashboard/src/components/partials/AttentionPanel.tsx +48 -0
  12. package/dashboard/src/components/partials/CurrentPhaseCard.tsx +50 -0
  13. package/dashboard/src/components/partials/PhaseTimeline.tsx +38 -0
  14. package/dashboard/src/components/partials/ProgressRing.tsx +51 -0
  15. package/dashboard/src/components/partials/QuickActions.tsx +30 -0
  16. package/dashboard/src/components/partials/StatusHeader.tsx +45 -0
  17. package/dashboard/src/global.d.ts +10 -0
  18. package/dashboard/src/index.tsx +134 -0
  19. package/dashboard/src/middleware/current-phase.ts +23 -0
  20. package/dashboard/src/routes/command-center.routes.tsx +69 -0
  21. package/dashboard/src/routes/index.routes.tsx +106 -0
  22. package/dashboard/src/services/dashboard.service.d.ts +39 -0
  23. package/dashboard/src/services/sse.service.ts +34 -0
  24. package/dashboard/src/services/todo.service.d.ts +21 -0
  25. package/dashboard/src/services/watcher.service.ts +35 -0
  26. package/dashboard/src/sse-handler.tsx +37 -0
  27. package/dashboard/src/watcher-setup.ts +25 -0
  28. package/package.json +1 -1
  29. package/plugins/copilot-pbr/plugin.json +1 -1
  30. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  31. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  32. package/dashboard/src/services/sse.service.js +0 -58
  33. package/dashboard/src/services/watcher.service.js +0 -48
@@ -0,0 +1,25 @@
1
+ import { createWatcher, type WatchEvent } from './services/watcher.service.js';
2
+ import { broadcast } from './services/sse.service.js';
3
+ import type { FSWatcher } from 'chokidar';
4
+
5
+ /**
6
+ * Start the file watcher for the project's .planning/ directory.
7
+ *
8
+ * On every file-change event, optionally invalidates caches (via the
9
+ * onCacheInvalidate callback) and broadcasts an SSE 'file-change' event
10
+ * to all connected clients.
11
+ *
12
+ * @param projectDir - Absolute path to the project root directory
13
+ * @param onCacheInvalidate - Optional callback to clear service-level caches
14
+ * @returns The FSWatcher instance (call .close() for graceful shutdown)
15
+ */
16
+ export function startWatcher(
17
+ projectDir: string,
18
+ onCacheInvalidate?: () => void
19
+ ): FSWatcher {
20
+ const watcher = createWatcher(projectDir, async (event: WatchEvent) => {
21
+ onCacheInvalidate?.();
22
+ await broadcast('file-change', event);
23
+ });
24
+ return watcher;
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sienklogic/plan-build-run",
3
- "version": "2.27.2",
3
+ "version": "2.29.0",
4
4
  "description": "Plan it, Build it, Run it — structured development workflow for Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.27.2",
4
+ "version": "2.29.0",
5
5
  "description": "Plan-Build-Run — Structured development workflow for GitHub Copilot CLI. Solves context rot through disciplined agent delegation, structured planning, atomic execution, and goal-backward verification.",
6
6
  "author": {
7
7
  "name": "SienkLogic",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.27.2",
4
+ "version": "2.29.0",
5
5
  "description": "Plan-Build-Run — Structured development workflow for Cursor. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
6
6
  "author": {
7
7
  "name": "SienkLogic",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pbr",
3
- "version": "2.27.2",
3
+ "version": "2.29.0",
4
4
  "description": "Plan-Build-Run — Structured development workflow for Claude Code. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
5
5
  "author": {
6
6
  "name": "SienkLogic",
@@ -1,58 +0,0 @@
1
- /**
2
- * SSE (Server-Sent Events) service.
3
- * Manages a Set of active client response objects and provides
4
- * broadcast functionality to send events to all connected browsers.
5
- */
6
-
7
- /** @type {Set<import('http').ServerResponse>} */
8
- const clients = new Set();
9
-
10
- /**
11
- * Register a client response object for SSE broadcasting.
12
- * @param {import('http').ServerResponse} res
13
- */
14
- export function addClient(res) {
15
- clients.add(res);
16
- }
17
-
18
- /**
19
- * Remove a client response object (called on disconnect).
20
- * @param {import('http').ServerResponse} res
21
- */
22
- export function removeClient(res) {
23
- clients.delete(res);
24
- }
25
-
26
- /**
27
- * Broadcast an SSE event to all connected clients.
28
- * Clients that throw on write are automatically removed.
29
- * @param {string} eventType - SSE event name (e.g. 'file-change')
30
- * @param {object} data - Payload to JSON-serialize in the data field
31
- */
32
- export function broadcast(eventType, data) {
33
- const id = Date.now();
34
- const message = `event: ${eventType}\ndata: ${JSON.stringify(data)}\nid: ${id}\n\n`;
35
-
36
- for (const client of clients) {
37
- try {
38
- client.write(message);
39
- } catch {
40
- clients.delete(client);
41
- }
42
- }
43
- }
44
-
45
- /**
46
- * Return the number of currently connected clients.
47
- * @returns {number}
48
- */
49
- export function getClientCount() {
50
- return clients.size;
51
- }
52
-
53
- /**
54
- * Remove all clients. Used in tests to reset state between test cases.
55
- */
56
- export function clearClients() {
57
- clients.clear();
58
- }
@@ -1,48 +0,0 @@
1
- import chokidar from 'chokidar';
2
- import { join, relative } from 'node:path';
3
-
4
- /**
5
- * Create a chokidar file watcher for the .planning/ directory.
6
- *
7
- * Watches **\/*.md files with awaitWriteFinish to debounce editor saves.
8
- * Calls onChange with a normalized event object on add, change, and unlink.
9
- *
10
- * @param {string} watchPath - Absolute path to the project directory
11
- * @param {(event: {path: string, type: string, timestamp: number}) => void} onChange
12
- * @returns {import('chokidar').FSWatcher}
13
- */
14
- export function createWatcher(watchPath, onChange) {
15
- const planningDir = join(watchPath, '.planning');
16
-
17
- const watcher = chokidar.watch(join(planningDir, '**/*.md'), {
18
- ignored: [
19
- '**/node_modules/**',
20
- '**/.git/**'
21
- ],
22
- persistent: true,
23
- ignoreInitial: true,
24
- awaitWriteFinish: {
25
- stabilityThreshold: 500,
26
- pollInterval: 100
27
- }
28
- });
29
-
30
- const handleEvent = (type) => (filePath) => {
31
- const relativePath = relative(watchPath, filePath);
32
- onChange({
33
- path: relativePath,
34
- type,
35
- timestamp: Date.now()
36
- });
37
- };
38
-
39
- watcher.on('add', handleEvent('add'));
40
- watcher.on('change', handleEvent('change'));
41
- watcher.on('unlink', handleEvent('unlink'));
42
-
43
- watcher.on('error', (error) => {
44
- console.error('Watcher error:', error.message);
45
- });
46
-
47
- return watcher;
48
- }