@walwal-harness/cli 7.1.27 → 7.1.29
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 +26 -1
- package/apps/harness-dashboard/app/api/stream/route.ts +4 -0
- package/apps/harness-dashboard/app/globals.css +138 -8
- package/apps/harness-dashboard/app/layout.tsx +1 -5
- package/apps/harness-dashboard/app/page.tsx +3 -7
- package/apps/harness-dashboard/components/Scene.tsx +1788 -599
- package/apps/harness-dashboard/lib/__tests__/harness-state.test.ts +84 -0
- package/apps/harness-dashboard/lib/harness-state.ts +132 -16
- package/apps/harness-dashboard/lib/types.ts +15 -0
- package/apps/harness-dashboard/package-lock.json +1519 -53
- package/apps/harness-dashboard/package.json +2 -0
- package/assets/templates/AGENTS.md.template +6 -5
- package/bin/init.js +273 -41
- package/commands/goal.md +10 -8
- package/commands/hot-fix.md +12 -10
- package/commands/submission.md +12 -9
- package/package.json +1 -1
- package/scripts/harness-company-complete.sh +30 -0
package/README.md
CHANGED
|
@@ -55,7 +55,21 @@ What `init` installs:
|
|
|
55
55
|
| `.harness/events.jsonl` | Structured append-only runtime event stream |
|
|
56
56
|
| `.harness/todos/state.json` | Machine-readable CXX todo queues |
|
|
57
57
|
| `.harness/todos/events.jsonl` | Structured todo transition history |
|
|
58
|
-
| `AGENTS.md`
|
|
58
|
+
| `AGENTS.md` + `CLAUDE.md` symlink | Project AI operating rules |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Project Docs Merge
|
|
63
|
+
|
|
64
|
+
`AGENTS.md` is the source of truth for project AI operating rules. `CLAUDE.md` is normalized to a symlink that points at `AGENTS.md`.
|
|
65
|
+
|
|
66
|
+
Install and migrate preserve existing project instructions:
|
|
67
|
+
|
|
68
|
+
- Existing `AGENTS.md` is not replaced. The harness adds or updates a marked section between `<!-- walwal-harness:agents:start -->` and `<!-- walwal-harness:agents:end -->`.
|
|
69
|
+
- The top of `AGENTS.md` gets a small walwal-harness enabled marker so agents know the harness section applies.
|
|
70
|
+
- Existing `CLAUDE.md` file content is appended into `AGENTS.md` under a `preserved-claude` marked section, then `CLAUDE.md` is replaced with a symlink to `AGENTS.md`.
|
|
71
|
+
- Re-running `init`, `init --force`, or `migrate` is idempotent: marked sections are replaced, not duplicated.
|
|
72
|
+
- Existing docs and symlink targets are backed up under `.harness/archive/pre-harness-backup/` or the migration backup directory before modification.
|
|
59
73
|
|
|
60
74
|
---
|
|
61
75
|
|
|
@@ -70,6 +84,7 @@ Owner /goal → CEO → [COO] → [CDO] → CTO → [dev workers] → CQO → [e
|
|
|
70
84
|
1. CEO reads Owner request, writes `ceo.md`, routes to relevant CXX.
|
|
71
85
|
2. Each CXX writes its own `{cxx}.md`, hires workers, collects evidence.
|
|
72
86
|
3. CEO aggregates CXX outputs and reports to Owner.
|
|
87
|
+
4. Every goal/submission/hot-fix mission has `mission-state.json` with `lifecycle` and `active`.
|
|
73
88
|
|
|
74
89
|
### Hot Fix
|
|
75
90
|
|
|
@@ -181,6 +196,12 @@ bash scripts/harness-company-complete.sh . mission-complete
|
|
|
181
196
|
|
|
182
197
|
This sets `company_state.state = "idle"`, `conductor.state = "completed"`, `next_agent = "none"`, and `owner_prompt.status = "completed"` so dashboards, runners, and hooks agree that auto-mode can stop.
|
|
183
198
|
|
|
199
|
+
It also closes structured work state:
|
|
200
|
+
|
|
201
|
+
- active/pending/paused todos in `.harness/todos/state.json` become `done`
|
|
202
|
+
- active `mission-state.json` files become `{"lifecycle":"complete","active":false}`
|
|
203
|
+
- the dashboard stops treating recent worker report mtimes as live activity after runtime completion
|
|
204
|
+
|
|
184
205
|
Existing users should update and migrate from the target project:
|
|
185
206
|
|
|
186
207
|
```bash
|
|
@@ -204,6 +225,8 @@ npx walwal-harness init --force --project-root /path/to/project
|
|
|
204
225
|
Features:
|
|
205
226
|
|
|
206
227
|
- **Company Harness Observatory** — glass/aurora process monitor showing active CXX todos, workers, incidents, missions, and current loop state
|
|
228
|
+
- **Layer Activity by CXX/Worker** — Layer Activity rows match the heatmap hierarchy, grouping each CXX with its workers and sorting groups by remaining work first, completed groups next, empty CXX groups last
|
|
229
|
+
- **Explicit Mission Lifecycle** — goal/submission/hot-fix directories use `mission-state.json`; `init`, `init --force`, and `migrate` backfill missing lifecycle files for existing projects
|
|
207
230
|
- **Structured Runtime State** — `/goal`, `/submission`, and `/hot-fix` append to `.harness/events.jsonl` and update `.harness/todos/state.json`; `migrate` backfills these files for existing projects
|
|
208
231
|
- **Split Workspace** — full-viewport left/right panes keep Org Tree + Mission Timeline beside the selected mission detail; both panes scroll independently with hidden scrollbars, and the detail pane resets to top on selection changes
|
|
209
232
|
- **Org Tree** — live status of Owner → CEO → CXX → Workers hierarchy, with worker cards created only from hired `hr-roster.json` entries backed by `.harness/shared/HR-Resource/{worker}/SKILL.md`; running hired workers are highlighted under their owning CXX
|
|
@@ -259,6 +282,8 @@ harness-hiring → register and onboard worker
|
|
|
259
282
|
|
|
260
283
|
| Version | Summary |
|
|
261
284
|
|---|---|
|
|
285
|
+
| 7.1.29 | Idempotent AGENTS/CLAUDE doc merge with marked harness sections, mission lifecycle backfill for init/migrate, completion closes todos and mission-state, and Layer Activity now lists CXX/worker rows sorted by remaining work |
|
|
286
|
+
| 7.1.28 | Dashboard APM rewrite: top header consolidation, Knowledge Base panel (gotchas/conventions), Layer Activity (CEO/CXX/Worker TODO·DONE·Remain via goal-scope inference), Recent Report list (worker mtime desc), Cadence strip with click-to-prompt tooltip in local timezone, heatmap click-tooltip with empty-cell guard, Document Viewer expand-to-50vw with docmeta hidden, Command Log bubble popover |
|
|
262
287
|
| 7.1.19 | `migrate` now carries OPS verification rules into existing installs: runtime.verification merge, HARNESS refresh, and AGENTS migration block |
|
|
263
288
|
| 7.1.18 | OPS watches CQO runnable verification and production incidents; Implementation Notes stay in the same role/worker report |
|
|
264
289
|
| 7.1.17 | Dashboard: fix /submission and /hot-fix missions displaying as /goal; runtime strip shows live owner command in mission flow tab |
|
|
@@ -47,8 +47,12 @@ export async function GET(request: Request) {
|
|
|
47
47
|
send();
|
|
48
48
|
|
|
49
49
|
const handle = watchHarness(root, () => send());
|
|
50
|
+
// Local-only data source — push a fresh snapshot every second on top
|
|
51
|
+
// of file-watch events so the dashboard never goes more than 1s stale.
|
|
52
|
+
const tick = setInterval(() => send(), 1000);
|
|
50
53
|
|
|
51
54
|
const cleanup = async () => {
|
|
55
|
+
clearInterval(tick);
|
|
52
56
|
try {
|
|
53
57
|
await handle.close();
|
|
54
58
|
} catch {
|
|
@@ -26,6 +26,113 @@ body {
|
|
|
26
26
|
display: none;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* hide scrollbars globally — scroll still works via wheel/drag/touch */
|
|
30
|
+
* {
|
|
31
|
+
scrollbar-width: none;
|
|
32
|
+
-ms-overflow-style: none;
|
|
33
|
+
}
|
|
34
|
+
*::-webkit-scrollbar {
|
|
35
|
+
width: 0;
|
|
36
|
+
height: 0;
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* document viewer aside expand/minimize */
|
|
41
|
+
.doc-aside {
|
|
42
|
+
width: 380px;
|
|
43
|
+
transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
44
|
+
}
|
|
45
|
+
.doc-aside.expanded {
|
|
46
|
+
width: 50vw;
|
|
47
|
+
}
|
|
48
|
+
.doc-toggle-icon {
|
|
49
|
+
transition: transform 280ms ease;
|
|
50
|
+
display: inline-block;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* panel / inset shells (translated from mockup) */
|
|
54
|
+
.panel-shell {
|
|
55
|
+
border-radius: 6px;
|
|
56
|
+
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
57
|
+
background: #0b1328;
|
|
58
|
+
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
|
|
59
|
+
transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
|
|
60
|
+
}
|
|
61
|
+
.panel-shell:hover {
|
|
62
|
+
border-color: rgba(34, 211, 238, 0.25);
|
|
63
|
+
box-shadow: 0 16px 50px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(34, 211, 238, 0.1);
|
|
64
|
+
}
|
|
65
|
+
.inset-shell {
|
|
66
|
+
border-radius: 4px;
|
|
67
|
+
border: 1px solid rgba(15, 23, 42, 0.9);
|
|
68
|
+
background: #071022;
|
|
69
|
+
transition: border-color 200ms ease, transform 160ms ease;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ==== Dynamic / animated bits ==== */
|
|
73
|
+
|
|
74
|
+
/* Panel mount fade-in (used on initial render) */
|
|
75
|
+
@keyframes fade-in-up {
|
|
76
|
+
from { opacity: 0; transform: translateY(6px); }
|
|
77
|
+
to { opacity: 1; transform: translateY(0); }
|
|
78
|
+
}
|
|
79
|
+
.fade-in {
|
|
80
|
+
animation: fade-in-up 360ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* List item slide-in (Recent Report cards) */
|
|
84
|
+
@keyframes slide-in-fade {
|
|
85
|
+
from { opacity: 0; transform: translateX(-6px); }
|
|
86
|
+
to { opacity: 1; transform: translateX(0); }
|
|
87
|
+
}
|
|
88
|
+
.slide-in {
|
|
89
|
+
animation: slide-in-fade 280ms ease-out both;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Heatmap cell baseline transition */
|
|
93
|
+
.heat-cell {
|
|
94
|
+
transition: transform 140ms ease, filter 140ms ease, border-color 140ms ease;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Cadence cell soft pulse when count is at peak */
|
|
98
|
+
@keyframes cad-pulse {
|
|
99
|
+
0%, 100% { filter: brightness(1); }
|
|
100
|
+
50% { filter: brightness(1.4); }
|
|
101
|
+
}
|
|
102
|
+
.cad-peak {
|
|
103
|
+
animation: cad-pulse 1800ms ease-in-out infinite;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Tooltip / popover enter */
|
|
107
|
+
@keyframes pop-in {
|
|
108
|
+
from { opacity: 0; transform: scale(0.96) translateY(4px); }
|
|
109
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
110
|
+
}
|
|
111
|
+
.pop-in {
|
|
112
|
+
animation: pop-in 180ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Stacked bar segment width tween */
|
|
116
|
+
.stack-seg {
|
|
117
|
+
will-change: flex-grow;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Worker bar inner shimmer for active CXX (very subtle) */
|
|
121
|
+
@keyframes shimmer-sweep {
|
|
122
|
+
0% { background-position: -200% 0; }
|
|
123
|
+
100% { background-position: 200% 0; }
|
|
124
|
+
}
|
|
125
|
+
.shimmer {
|
|
126
|
+
background-image: linear-gradient(
|
|
127
|
+
100deg,
|
|
128
|
+
rgba(255, 255, 255, 0) 30%,
|
|
129
|
+
rgba(255, 255, 255, 0.18) 50%,
|
|
130
|
+
rgba(255, 255, 255, 0) 70%
|
|
131
|
+
);
|
|
132
|
+
background-size: 200% 100%;
|
|
133
|
+
animation: shimmer-sweep 3.2s linear infinite;
|
|
134
|
+
}
|
|
135
|
+
|
|
29
136
|
.glass-panel {
|
|
30
137
|
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
31
138
|
background:
|
|
@@ -47,12 +154,35 @@ body {
|
|
|
47
154
|
|
|
48
155
|
.isometric-stage {
|
|
49
156
|
background:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
linear-gradient(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
157
|
+
radial-gradient(circle at 48% 42%, rgba(34, 211, 238, 0.18), transparent 20rem),
|
|
158
|
+
radial-gradient(circle at 78% 24%, rgba(99, 102, 241, 0.14), transparent 18rem),
|
|
159
|
+
radial-gradient(circle at 20% 84%, rgba(16, 185, 129, 0.12), transparent 22rem),
|
|
160
|
+
linear-gradient(135deg, rgba(2, 6, 23, 0.94), rgba(8, 13, 26, 0.98));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@keyframes apm-request-fall {
|
|
164
|
+
0% {
|
|
165
|
+
opacity: 0;
|
|
166
|
+
top: -12px;
|
|
167
|
+
transform: translateX(-50%) scale(0.75);
|
|
168
|
+
}
|
|
169
|
+
12% {
|
|
170
|
+
opacity: 1;
|
|
171
|
+
}
|
|
172
|
+
82% {
|
|
173
|
+
opacity: 1;
|
|
174
|
+
}
|
|
175
|
+
100% {
|
|
176
|
+
opacity: 0;
|
|
177
|
+
top: 184px;
|
|
178
|
+
transform: translateX(-50%) scale(1.15);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.apm-falling-dot {
|
|
183
|
+
top: -12px;
|
|
184
|
+
animation-name: apm-request-fall;
|
|
185
|
+
animation-timing-function: linear;
|
|
186
|
+
animation-iteration-count: infinite;
|
|
187
|
+
box-shadow: 0 0 14px currentColor;
|
|
58
188
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import type { Metadata } from "next";
|
|
3
3
|
import "./globals.css";
|
|
4
|
-
import { Header } from "@/components/Header";
|
|
5
4
|
import { resolveHarnessRoot } from "@/lib/harness-root";
|
|
6
5
|
|
|
7
6
|
export async function generateMetadata(): Promise<Metadata> {
|
|
@@ -20,10 +19,7 @@ export default function RootLayout({
|
|
|
20
19
|
}) {
|
|
21
20
|
return (
|
|
22
21
|
<html lang="ko">
|
|
23
|
-
<body>
|
|
24
|
-
<Header />
|
|
25
|
-
{children}
|
|
26
|
-
</body>
|
|
22
|
+
<body>{children}</body>
|
|
27
23
|
</html>
|
|
28
24
|
);
|
|
29
25
|
}
|
|
@@ -10,26 +10,22 @@ export default function Page() {
|
|
|
10
10
|
const banner = snapshot.errorBanner;
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
|
-
<main className="
|
|
13
|
+
<main className="h-[100dvh]">
|
|
14
14
|
{banner && (
|
|
15
15
|
<div
|
|
16
16
|
role="alert"
|
|
17
17
|
data-testid="error-banner"
|
|
18
|
-
className={`mx-
|
|
18
|
+
className={`mx-3 mt-2 rounded border px-3 py-2 text-xs ${
|
|
19
19
|
banner.level === "error"
|
|
20
20
|
? "border-aura-alert/60 bg-aura-alert/10 text-aura-alert"
|
|
21
21
|
: "border-aura-talking/60 bg-aura-talking/10 text-aura-talking"
|
|
22
22
|
}`}
|
|
23
23
|
>
|
|
24
24
|
<div>{banner.message_ko}</div>
|
|
25
|
-
<div className="
|
|
25
|
+
<div className="mt-1 text-[10px] opacity-60">{banner.message_en}</div>
|
|
26
26
|
</div>
|
|
27
27
|
)}
|
|
28
28
|
<Scene snapshot={snapshot} />
|
|
29
|
-
<footer className="mx-auto max-w-[1280px] px-6 pb-8 text-xs text-gray-500 font-mono flex items-center justify-between">
|
|
30
|
-
<span>Sprint 1 / Phase C-1 — Foundation</span>
|
|
31
|
-
<span data-testid="snapshot-ts">{snapshot.ts}</span>
|
|
32
|
-
</footer>
|
|
33
29
|
</main>
|
|
34
30
|
);
|
|
35
31
|
}
|