pi-crew 0.10.6 → 0.11.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/CHANGELOG.md +215 -0
- package/README.md +0 -1
- package/dist/index.mjs +30623 -29844
- package/package.json +170 -169
- package/schema.json +10 -0
- package/scripts/watch-agent-transcript.mjs +120 -0
- package/skills/real-test-pi-crew/REPORT-TEMPLATE.md +2 -0
- package/skills/real-test-pi-crew/SKILL.md +181 -1
- package/src/config/config-validation.ts +0 -2
- package/src/config/defaults.ts +0 -1
- package/src/config/types.ts +0 -5
- package/src/extension/crew-input-router.ts +2 -0
- package/src/extension/crew-vibes/config.ts +1 -77
- package/src/extension/crew-vibes/index.ts +36 -330
- package/src/extension/crew-vibes/render.ts +1 -106
- package/src/extension/help.ts +1 -2
- package/src/extension/register.ts +7 -2
- package/src/extension/registration/command-registration.ts +5 -1
- package/src/extension/registration/commands/manage.ts +5 -4
- package/src/extension/registration/commands/schedules.ts +212 -0
- package/src/extension/registration/commands/shared.ts +56 -2
- package/src/extension/registration/lifecycle-handlers.ts +16 -2
- package/src/extension/registration/schedule-toast-bridge.ts +109 -0
- package/src/extension/registration/subagent-tools.ts +16 -6
- package/src/extension/registration/team-tool.ts +10 -3
- package/src/extension/registration/terminal-status-wiring.ts +172 -0
- package/src/extension/registration/viewers.ts +72 -1
- package/src/extension/team-tool/handle-schedule.ts +120 -1
- package/src/extension/team-tool/handle-settings.ts +14 -2
- package/src/runtime/scheduling/scheduler.ts +120 -6
- package/src/runtime/settings-store.ts +28 -2
- package/src/runtime/task-display.ts +1 -1
- package/src/schema/config-schema.ts +4 -0
- package/src/state/coordination/locks.ts +17 -2
- package/src/ui/adaptive-card.ts +65 -0
- package/src/ui/agents-jobs-browser.ts +791 -0
- package/src/ui/card-colors.ts +36 -7
- package/src/ui/dashboard-panes/agents-pane.ts +52 -17
- package/src/ui/dashboard-panes/cancellation-pane.ts +0 -42
- package/src/ui/dashboard-panes/health-pane.ts +7 -5
- package/src/ui/dashboard-panes/mailbox-pane.ts +22 -6
- package/src/ui/dashboard-panes/metrics-pane.ts +15 -7
- package/src/ui/dashboard-panes/pane-theme.ts +21 -0
- package/src/ui/dashboard-panes/plan-pane.ts +63 -30
- package/src/ui/dashboard-panes/progress-pane.ts +3 -2
- package/src/ui/dashboard-panes/schedules-pane.ts +177 -0
- package/src/ui/dashboard-panes/transcript-pane.ts +11 -5
- package/src/ui/dwf-phase-display.ts +3 -20
- package/src/ui/format-helpers.ts +22 -0
- package/src/ui/inline-panel/crew-editor.ts +32 -9
- package/src/ui/inline-panel/index.ts +66 -4
- package/src/ui/key-utils.ts +3 -0
- package/src/ui/keybinding-map.ts +286 -34
- package/src/ui/live-conversation-overlay.ts +176 -46
- package/src/ui/live-run-sidebar.ts +134 -55
- package/src/ui/mascot.ts +34 -17
- package/src/ui/overlays/agent-picker-overlay.ts +81 -26
- package/src/ui/overlays/confirm-overlay.ts +55 -28
- package/src/ui/overlays/help-overlay.ts +108 -53
- package/src/ui/overlays/mailbox-compose-overlay.ts +89 -49
- package/src/ui/overlays/mailbox-detail-overlay.ts +137 -57
- package/src/ui/powerbar-publisher.ts +0 -1
- package/src/ui/rail.ts +333 -0
- package/src/ui/run-dashboard.ts +344 -72
- package/src/ui/settings-overlay.ts +84 -42
- package/src/ui/terminal-status.ts +7 -1
- package/src/ui/theme-adapter.ts +0 -45
- package/src/ui/theme-discovery.ts +12 -6
- package/src/ui/tool-progress-formatter.ts +126 -8
- package/src/ui/tool-renderers/brief-mode.ts +8 -66
- package/src/ui/tool-renderers/index.ts +372 -521
- package/src/ui/transcript-viewer.ts +33 -14
- package/src/ui/widget/index.ts +86 -133
- package/src/ui/widget/task-list.ts +64 -32
- package/src/ui/widget/widget-formatters.ts +3 -399
- package/src/ui/widget/widget-model.ts +28 -7
- package/src/ui/widget/widget-renderer.ts +298 -265
- package/src/ui/widget/widget-types.ts +0 -9
- package/src/utils/relative-time.ts +33 -0
- package/src/utils/visual.ts +0 -4
- package/src/extension/crew-vibes/figures.ts +0 -101
- package/src/extension/crew-vibes/font-detect.ts +0 -71
- package/src/extension/crew-vibes/footer.ts +0 -313
- package/src/extension/crew-vibes/speed.ts +0 -286
- package/src/ui/dock-footer.ts +0 -49
- package/src/ui/dynamic-border.ts +0 -35
- package/src/ui/loaders.ts +0 -6
- package/src/ui/overlay-stack.ts +0 -148
package/package.json
CHANGED
|
@@ -1,171 +1,172 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
2
|
+
"name": "pi-crew",
|
|
3
|
+
"version": "0.11.1",
|
|
4
|
+
"description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
|
|
5
|
+
"author": "baphuongna",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.0.0"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/baphuongna/pi-crew.git"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/baphuongna/pi-crew#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/baphuongna/pi-crew/issues"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"bin": {
|
|
20
|
+
"pi-crew": "install.mjs"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"pi-package",
|
|
24
|
+
"pi",
|
|
25
|
+
"pi-coding-agent",
|
|
26
|
+
"teams",
|
|
27
|
+
"agents",
|
|
28
|
+
"multi-agent",
|
|
29
|
+
"orchestration"
|
|
30
|
+
],
|
|
31
|
+
"files": [
|
|
32
|
+
"src/",
|
|
33
|
+
"!src/benchmark",
|
|
34
|
+
"dist/index.mjs",
|
|
35
|
+
"index.ts",
|
|
36
|
+
"install.mjs",
|
|
37
|
+
"agents/",
|
|
38
|
+
"teams/",
|
|
39
|
+
"workflows/",
|
|
40
|
+
"skills/**",
|
|
41
|
+
"themes/",
|
|
42
|
+
"assets/crew-vibes.ttf",
|
|
43
|
+
"scripts/clean-strip-types.mjs",
|
|
44
|
+
"scripts/postinstall.mjs",
|
|
45
|
+
"scripts/install-crew-vibes-font.mjs",
|
|
46
|
+
"scripts/build-crew-vibes-font.py",
|
|
47
|
+
"scripts/pty_probe.py",
|
|
48
|
+
"README.md",
|
|
49
|
+
"AGENTS.md",
|
|
50
|
+
"docs/actions-reference.md",
|
|
51
|
+
"docs/commands-reference.md",
|
|
52
|
+
"docs/troubleshooting.md",
|
|
53
|
+
"docs/usage.md",
|
|
54
|
+
"docs/architecture.md",
|
|
55
|
+
"docs/dynamic-workflows.md",
|
|
56
|
+
"docs/runtime-flow.md",
|
|
57
|
+
"docs/resource-formats.md",
|
|
58
|
+
"docs/publishing.md",
|
|
59
|
+
"docs/migration-v0.4-v0.5.md",
|
|
60
|
+
"tsconfig.json",
|
|
61
|
+
"schema.json",
|
|
62
|
+
"types/",
|
|
63
|
+
"CHANGELOG.md",
|
|
64
|
+
"LICENSE",
|
|
65
|
+
"NOTICE.md",
|
|
66
|
+
"scripts/resource-sampler.mjs",
|
|
67
|
+
"scripts/analyze-run.mjs",
|
|
68
|
+
"scripts/watch-agent-transcript.mjs"
|
|
69
|
+
],
|
|
70
|
+
"scripts": {
|
|
71
|
+
"check": "npm run ci",
|
|
72
|
+
"ci": "npm run check:lockfile-sync && npm run typecheck && npm run lint && npm run format:check && npm run check:conflict-markers && npm run check:decision-drift && npm run check:env-vars && npm run check:event-types && npm run check:lazy-imports && npm run check:wc-gate && npm run check:bundle-staleness && npm run build:bundle && npm run check:bundle-size && npm run test:bundle && npm test && npm pack --dry-run",
|
|
73
|
+
"ci:fast": "npm run check:lockfile-sync && npm run typecheck && npm run lint && npm run format:check && npm run check:conflict-markers && npm run check:decision-drift && npm run check:env-vars && npm run check:event-types && npm run check:lazy-imports && npm run check:wc-gate && npm run check:bundle-staleness && npm run build:bundle && npm run check:bundle-size && npm run test:bundle && npm run test:critical && npm pack --dry-run",
|
|
74
|
+
"check:lockfile-sync": "node scripts/check-lockfile-sync.mjs",
|
|
75
|
+
"check:lazy-imports": "node scripts/check-lazy-imports.mjs",
|
|
76
|
+
"check:bundle-staleness": "node scripts/check-bundle-staleness.mjs",
|
|
77
|
+
"check:bundle-size": "node scripts/check-bundle-size.mjs",
|
|
78
|
+
"check:conflict-markers": "node scripts/check-conflict-markers.mjs",
|
|
79
|
+
"check:decision-drift": "node scripts/check-decision-drift.mjs",
|
|
80
|
+
"check:env-vars": "node scripts/check-env-vars.mjs",
|
|
81
|
+
"check:event-types": "node scripts/check-event-types-registry.mjs",
|
|
82
|
+
"typecheck": "tsc --noEmit && node --experimental-strip-types -e \"await import('./index.ts'); console.log('strip-types import ok')\"",
|
|
83
|
+
"lint": "biome check --linter-enabled=true --formatter-enabled=false --max-diagnostics=50 .",
|
|
84
|
+
"format:check": "biome format .",
|
|
85
|
+
"test": "npm run test:unit && npm run test:integration",
|
|
86
|
+
"test:full": "npm run test:unit && npm run test:integration && npm run test:integration:slow",
|
|
87
|
+
"test:unit": "node scripts/test-runner.mjs --test-concurrency=4 --test-timeout=180000 --test-force-exit 'test/unit/**/*.test.ts'",
|
|
88
|
+
"test:critical": "node scripts/test-runner.mjs --test-concurrency=4 --test-timeout=30000 --test-force-exit test/unit/runtime/broker/crew-broker-handshake.test.ts test/unit/runtime/broker/crew-broker-stale-socket.test.ts test/unit/runtime/broker/crew-broker-feature-flag.test.ts test/unit/runtime/broker/crew-broker-server-gate.test.ts test/unit/runtime/broker/crew-broker-client-fallback.test.ts test/unit/runtime/broker/crew-broker-mailbox-observer.test.ts test/unit/runtime/broker/crew-broker-close-during-reconnect.test.ts test/unit/runtime/broker/crew-broker-steer-dedup.test.ts test/unit/runtime/broker/crew-broker-symlink-steering.test.ts test/unit/ui/keybinding-map.parity.test.ts test/unit/ui/pi-tui-dispatch-probe.test.ts test/unit/utils/session-utils-extract.test.ts test/unit/config/config-schema-sync.test.ts test/unit/runtime/child-pi/child-pi-env-spread.test.ts",
|
|
89
|
+
"test:watch": "node scripts/test-runner.mjs --watch --test-concurrency=4 --test-timeout=30000 'test/unit/**/*.test.ts'",
|
|
90
|
+
"test:integration": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=300000 test/integration/*.test.ts",
|
|
91
|
+
"test:integration:slow": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=600000 test/integration/slow/*.test.ts",
|
|
92
|
+
"test:system": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=180000 --test-force-exit test/system/*.e2e.test.ts",
|
|
93
|
+
"test:smoke": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=180000 test/smoke/*.smoke.ts",
|
|
94
|
+
"test:spike": "node scripts/test-runner.mjs --test-concurrency=2 --test-timeout=120000 --test-force-exit test/runtime/scratchpad/*.test.ts",
|
|
95
|
+
"test:functional": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=120000 test/functional/pi-crew-functional.test.ts",
|
|
96
|
+
"test:platform": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=60000 test/platform/*.test.ts",
|
|
97
|
+
"build:bundle": "node scripts/build-bundle.mjs",
|
|
98
|
+
"test:bundle": "node --experimental-strip-types --test --test-force-exit test/unit/bundle-load.test.ts",
|
|
99
|
+
"watch:bundle": "node scripts/watch-bundle.mjs",
|
|
100
|
+
"build:bundle:once": "node scripts/watch-bundle.mjs --once",
|
|
101
|
+
"dev": "node scripts/dev-runner.mjs",
|
|
102
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
103
|
+
"install:crew-font": "node scripts/install-crew-vibes-font.mjs",
|
|
104
|
+
"build:crew-font": "python scripts/build-crew-vibes-font.py",
|
|
105
|
+
"bench": "node scripts/run-bench.mjs",
|
|
106
|
+
"bench:check": "node scripts/bench-check.mjs",
|
|
107
|
+
"test:new": "node scripts/test-runner.mjs --test-concurrency=4 --test-timeout=30000 'test/unit/**/*.test.ts'",
|
|
108
|
+
"test:changed": "node scripts/test-changed.mjs",
|
|
109
|
+
"bench:capture": "node scripts/run-bench.mjs && node -e \"require('node:fs').copyFileSync('test/bench/results.json','test/bench/baseline.json')\"",
|
|
110
|
+
"profile:startup": "node scripts/profile-startup.mjs",
|
|
111
|
+
"smoke:pi": "pi install .",
|
|
112
|
+
"smoke:release": "node scripts/release-smoke.mjs",
|
|
113
|
+
"prepack": "node scripts/clean-strip-types.mjs",
|
|
114
|
+
"test:fast": "npm run test:critical && npm run test:bundle",
|
|
115
|
+
"check:wc-gate": "node scripts/wc-gate.mjs"
|
|
116
|
+
},
|
|
117
|
+
"exports": {
|
|
118
|
+
"./schema.json": "./schema.json",
|
|
119
|
+
"./workflow": {
|
|
120
|
+
"types": "./types/dwf.d.ts"
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"pi": {
|
|
124
|
+
"extensions": [
|
|
125
|
+
"./index.ts"
|
|
126
|
+
],
|
|
127
|
+
"skills": [
|
|
128
|
+
"./skills"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"peerDependencies": {
|
|
132
|
+
"@earendil-works/pi-agent-core": "*",
|
|
133
|
+
"@earendil-works/pi-ai": "*",
|
|
134
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
135
|
+
"@earendil-works/pi-tui": "*"
|
|
136
|
+
},
|
|
137
|
+
"dependencies": {
|
|
138
|
+
"@sinclair/typebox": "^0.34.50",
|
|
139
|
+
"acorn": "^8.17.0",
|
|
140
|
+
"ajv": "^8.20.0",
|
|
141
|
+
"cli-highlight": "^2.1.11",
|
|
142
|
+
"diff": "^5.2.0",
|
|
143
|
+
"esbuild": "^0.28.1",
|
|
144
|
+
"jiti": "^2.7.0",
|
|
145
|
+
"yaml": "^2.9.0"
|
|
146
|
+
},
|
|
147
|
+
"devDependencies": {
|
|
148
|
+
"@biomejs/biome": "^2.5.3",
|
|
149
|
+
"@earendil-works/pi-agent-core": "^0.84.0",
|
|
150
|
+
"@earendil-works/pi-ai": "^0.84.0",
|
|
151
|
+
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
152
|
+
"@earendil-works/pi-tui": "^0.84.0",
|
|
153
|
+
"@types/node": "^25.9.5",
|
|
154
|
+
"tsx": "^4.23.0",
|
|
155
|
+
"typescript": "^7.0.2"
|
|
156
|
+
},
|
|
157
|
+
"peerDependenciesMeta": {
|
|
158
|
+
"@earendil-works/pi-agent-core": {
|
|
159
|
+
"optional": true
|
|
160
|
+
},
|
|
161
|
+
"@earendil-works/pi-ai": {
|
|
162
|
+
"optional": true
|
|
163
|
+
},
|
|
164
|
+
"@earendil-works/pi-coding-agent": {
|
|
165
|
+
"optional": true
|
|
166
|
+
},
|
|
167
|
+
"@earendil-works/pi-tui": {
|
|
168
|
+
"optional": true
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"readmeFilename": "README.md"
|
|
171
172
|
}
|
package/schema.json
CHANGED
|
@@ -344,6 +344,11 @@
|
|
|
344
344
|
"minimum": 1,
|
|
345
345
|
"maximum": 50
|
|
346
346
|
},
|
|
347
|
+
"inlinePanel": {
|
|
348
|
+
"type": "boolean",
|
|
349
|
+
"default": true,
|
|
350
|
+
"description": "Show the inline agent panel above the editor (editor-wrapper agent rows)."
|
|
351
|
+
},
|
|
347
352
|
"powerbar": {
|
|
348
353
|
"type": "boolean"
|
|
349
354
|
},
|
|
@@ -377,6 +382,11 @@
|
|
|
377
382
|
"type": "boolean",
|
|
378
383
|
"default": true
|
|
379
384
|
},
|
|
385
|
+
"autoCloseDashboardMs": {
|
|
386
|
+
"type": "integer",
|
|
387
|
+
"minimum": 0,
|
|
388
|
+
"description": "Auto-close delay for the run dashboard once the run reaches a terminal state (ms)."
|
|
389
|
+
},
|
|
380
390
|
"showModel": {
|
|
381
391
|
"type": "boolean",
|
|
382
392
|
"default": true,
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Watch a pi session transcript (JSONL stream events) and print one readable
|
|
3
|
+
// line per message — the "session subagent" pane companion for the Agents &
|
|
4
|
+
// Jobs browser (`p` key). Unlike `tail -F` on the raw file, every line here is
|
|
5
|
+
// a formatted summary (role badge + preview), so a tmux/herdr pane shows WHAT
|
|
6
|
+
// the agent is doing, not walls of JSON.
|
|
7
|
+
//
|
|
8
|
+
// Usage: node watch-agent-transcript.mjs <transcript.jsonl>
|
|
9
|
+
import { open as openFile } from "node:fs/promises";
|
|
10
|
+
import { basename } from "node:path";
|
|
11
|
+
|
|
12
|
+
const path = process.argv[2];
|
|
13
|
+
if (!path) {
|
|
14
|
+
console.error("usage: node watch-agent-transcript.mjs <transcript.jsonl>");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const WIDTH = Math.min(200, Number(process.env.COLUMNS || 160) || 160);
|
|
19
|
+
|
|
20
|
+
function oneLine(text) {
|
|
21
|
+
return String(text ?? "")
|
|
22
|
+
.replace(/\s+/g, " ")
|
|
23
|
+
.trim();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function clip(text, max = WIDTH - 10) {
|
|
27
|
+
const s = oneLine(text);
|
|
28
|
+
return s.length > max ? `${s.slice(0, max - 1)}…` : s;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function stamp(iso) {
|
|
32
|
+
const m = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})/.exec(iso ?? "");
|
|
33
|
+
return m ? `${m[2]}` : "";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function renderEvent(evt) {
|
|
37
|
+
if (evt.type === "session") return "── session start ──";
|
|
38
|
+
if (evt.type === "agent_start") return "── agent start ──";
|
|
39
|
+
if (evt.type !== "message_end" || !evt.message) return null;
|
|
40
|
+
const msg = evt.message;
|
|
41
|
+
const who =
|
|
42
|
+
msg.role === "assistant" ? "🤖" : msg.role === "user" ? "👤" : msg.role === "toolResult" ? "📤" : (msg.role ?? "?");
|
|
43
|
+
const parts = Array.isArray(msg.content) ? msg.content : [{ type: "text", text: String(msg.content ?? "") }];
|
|
44
|
+
const out = [];
|
|
45
|
+
for (const part of parts) {
|
|
46
|
+
if (part.type === "thinking") out.push(`💭 ${clip(part.thinking, 120)}`);
|
|
47
|
+
else if (part.type === "text") out.push(`💬 ${clip(part.text)}`);
|
|
48
|
+
else if (part.type === "tool_use") {
|
|
49
|
+
const input = typeof part.input === "object" ? JSON.stringify(part.input) : String(part.input ?? "");
|
|
50
|
+
out.push(`🔧 ${part.name ?? "tool"} ${clip(input, 100)}`);
|
|
51
|
+
} else if (part.type === "tool_result") {
|
|
52
|
+
const content = typeof part.content === "string" ? part.content : JSON.stringify(part.content ?? "");
|
|
53
|
+
out.push(`📤 ${clip(content, 120)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (out.length === 0) return null;
|
|
57
|
+
return `${stamp(evt.timestamp ?? msg.timestamp) || " "} ${who} ${out.join(" │ ")}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Clear the pane first — herdr/tmux panes boot via the shell, so the echoed
|
|
61
|
+
// prompt + full node command would otherwise sit above the watcher output.
|
|
62
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
63
|
+
console.log(`── watching ${basename(path)} ──`);
|
|
64
|
+
|
|
65
|
+
let offset = 0;
|
|
66
|
+
let buffer = "";
|
|
67
|
+
const POLL_MS = 400;
|
|
68
|
+
let waitingSince = 0;
|
|
69
|
+
let lastWaitingLog = 0;
|
|
70
|
+
|
|
71
|
+
function logWaiting(now) {
|
|
72
|
+
if (!waitingSince) waitingSince = now;
|
|
73
|
+
if (now - lastWaitingLog >= 2500) {
|
|
74
|
+
const waitedS = Math.round((now - waitingSince) / 1000);
|
|
75
|
+
console.log(`… waiting for ${basename(path)} to appear (${waitedS}s)`);
|
|
76
|
+
lastWaitingLog = now;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function pump() {
|
|
81
|
+
try {
|
|
82
|
+
const fh = await openFile(path, "r");
|
|
83
|
+
try {
|
|
84
|
+
const stat = await fh.stat();
|
|
85
|
+
if (waitingSince) {
|
|
86
|
+
console.log(`✓ transcript appeared (waited ${Math.round((Date.now() - waitingSince) / 1000)}s)`);
|
|
87
|
+
waitingSince = 0;
|
|
88
|
+
}
|
|
89
|
+
if (stat.size < offset) offset = 0; // truncated/rotated
|
|
90
|
+
if (stat.size > offset) {
|
|
91
|
+
const len = stat.size - offset;
|
|
92
|
+
const buf = Buffer.alloc(len);
|
|
93
|
+
await fh.read(buf, 0, len, offset);
|
|
94
|
+
offset += len;
|
|
95
|
+
buffer += buf.toString("utf8");
|
|
96
|
+
const lines = buffer.split("\n");
|
|
97
|
+
buffer = lines.pop() ?? "";
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
const trimmed = line.trim();
|
|
100
|
+
if (!trimmed) continue;
|
|
101
|
+
try {
|
|
102
|
+
const rendered = renderEvent(JSON.parse(trimmed));
|
|
103
|
+
if (rendered) console.log(rendered);
|
|
104
|
+
} catch {
|
|
105
|
+
console.log(`· ${clip(trimmed)}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} finally {
|
|
110
|
+
await fh.close();
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
// File not there yet (cold-start window): visible waiting state so the
|
|
114
|
+
// pane explains itself instead of looking dead.
|
|
115
|
+
logWaiting(Date.now());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
setInterval(pump, POLL_MS);
|
|
120
|
+
await pump();
|
|
@@ -37,6 +37,8 @@ This artifact exists so past runs are verifiable (see SKILL.md "Output report").
|
|
|
37
37
|
| 10a surface E2E | ✅/❌/⏭️ | tmux 3/3 (spawn+self-close / kill-pane→degrade / doctor orphan) + herdr 3/3 — or skip reason per backend (no `$TMUX`/CI/no socket/in tmux for herdr) |
|
|
38
38
|
| 10b live surface run | ✅/❌/⏭️ | `visibleAgents='<set>'`, pane ids+titles during run, `worker.surface_spawned`/`worker.surface_closed` events (+ no `surface.degraded`), panes auto-closed. NOTE: `manifest.surface.panes` is `{}` at run END even on success (released on pane close) — engage-evidence is the EVENTS + `manifest.surface.provider`/`workerPids` |
|
|
39
39
|
| 10c herdr path | ✅/❌/⏭️ | ran in herdr pane / skipped (not in herdr pane) |
|
|
40
|
+
| 12 resource contracts | ✅/❌/⏭️ | 12a contracts `<pass>/<tests>` · 12b agents `<n>` / bad desc `0` / no routing `0` / strict-YAML fails `0` · 12c rendered agent lines `<n>`, all with `useWhen=` (budget-truncated by design) · 12d `<pass>/<tests>` |
|
|
41
|
+
| 13 real-run UI render | ✅/❌/⏭️ | runId `<id>` (real run, NOT fixtures); surfaces rendered: `<list>`; states: running/done/failed/focused/idle/narrow; invariant sweep `undefined` 0 · retired glyph 0 · `->` 0 · wire-format 0 · invented word 0 · bad plural 0; glyph-vs-state: spinner only while running ✅; hint survives @`<min width>` ✅; formats consistent (duration/usage/runId) ✅; catalog regenerated + 1 PNG inspected ✅ |
|
|
40
42
|
| 11 remediation regression | ✅/❌/⏭️ | sub-checks run + evidence: 11a buffered-site census `<n>` files (full test:unit `<pass>/<tests>` if run) · 11b wc-gate max `<n>`/2000 + in `ci` · 11c validator warn `<key>` → severity · 11d slow tier 3 files disjoint · 11e nightly SMOKE not-set · 11f reject format sites · 11g widgetPlacement bottom · 11h twins 3× green · 11i dead-export 0 + MUST_INCLUDE 5 · 11j committed-hash OK |
|
|
41
43
|
|
|
42
44
|
Legend: ✅ pass with evidence · ❌ fail (root cause below) · ⏭️ skipped (justify why)
|