@walwal-harness/cli 7.1.40 → 7.1.42
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/HR-Resource/cdo/SKILL.md +9 -1
- package/HR-Resource/ceo/SKILL.md +33 -2
- package/HR-Resource/coo/SKILL.md +9 -1
- package/HR-Resource/cqo/SKILL.md +9 -1
- package/HR-Resource/cto/SKILL.md +10 -2
- package/HR-Resource/ops/SKILL.md +12 -4
- package/HR-Resource/ops-prompt-inspector/SKILL.md +11 -6
- package/HR-Resource/ops-prompt-inspector/assets/prompt-inspector-static.js +180 -0
- package/HR-Resource/ops-prompt-inspector/scripts/setup.py +66 -3
- package/apps/harness-dashboard/app/api/metrics/route.ts +17 -0
- package/apps/harness-dashboard/app/api/wake/route.ts +41 -0
- package/apps/harness-dashboard/app/brick.css +482 -0
- package/apps/harness-dashboard/app/layout.tsx +13 -0
- package/apps/harness-dashboard/app/page.tsx +2 -2
- package/apps/harness-dashboard/components/Scene.tsx +690 -36
- package/apps/harness-dashboard/components/brick/BrickDashboard.tsx +149 -0
- package/apps/harness-dashboard/components/brick/reports.tsx +291 -0
- package/apps/harness-dashboard/components/brick/tweaks.tsx +738 -0
- package/apps/harness-dashboard/components/brick/ui.tsx +463 -0
- package/apps/harness-dashboard/components/brick/views-graph.tsx +305 -0
- package/apps/harness-dashboard/components/brick/views-grid.tsx +543 -0
- package/apps/harness-dashboard/components/brick/views-timeline.tsx +238 -0
- package/apps/harness-dashboard/lib/__tests__/harness-state.test.ts +1 -202
- package/apps/harness-dashboard/lib/__tests__/sandbox-e2e.test.ts +490 -0
- package/apps/harness-dashboard/lib/brick/adapter.ts +423 -0
- package/apps/harness-dashboard/lib/brick/contract.ts +247 -0
- package/apps/harness-dashboard/lib/harness-state.ts +107 -796
- package/apps/harness-dashboard/lib/metrics/sampler.ts +545 -0
- package/apps/harness-dashboard/lib/types.ts +22 -222
- package/apps/harness-dashboard/playwright.config.ts +26 -7
- package/assets/templates/AGENTS-ko.md.template +1 -1
- package/assets/templates/AGENTS.md.template +12 -2
- package/assets/templates/HARNESS.md +2 -0
- package/assets/templates/company-pipeline-manifest.json +5 -14
- package/assets/templates/worker-report.md.template +38 -0
- package/bin/init.js +2 -1
- package/commands/goal.md +4 -2
- package/commands/hot-fix.md +1 -1
- package/commands/submission.md +1 -1
- package/package.json +1 -1
- package/scripts/conductor-tick.sh +12 -0
- package/scripts/harness-agenda.sh +105 -0
- package/scripts/harness-company-block.sh +89 -0
- package/scripts/harness-company-complete.sh +17 -8
- package/scripts/harness-company-cycle.sh +54 -0
- package/scripts/harness-progress-set.sh +8 -2
- package/scripts/harness-stop.sh +76 -0
- package/scripts/harness-wake-control.sh +151 -0
- package/scripts/harness-wake.sh +5 -0
- package/scripts/harness-worker-dispatch.sh +31 -7
- package/apps/harness-dashboard/components/Drawer.tsx +0 -146
- package/apps/harness-dashboard/components/Header.tsx +0 -40
- package/apps/harness-dashboard/components/MissionTimeline.tsx +0 -214
- package/apps/harness-dashboard/components/OrgTree.tsx +0 -459
- package/apps/harness-dashboard/components/drawer/AgentLogTab.tsx +0 -56
- package/apps/harness-dashboard/components/drawer/DesignPreviewTab.tsx +0 -160
- package/apps/harness-dashboard/components/drawer/GotchasTab.tsx +0 -89
- package/apps/harness-dashboard/components/drawer/HypothesisTab.tsx +0 -42
- package/apps/harness-dashboard/components/drawer/IncidentsTab.tsx +0 -50
- package/apps/harness-dashboard/components/drawer/MissionDocTab.tsx +0 -96
- package/apps/harness-dashboard/components/drawer/MissionFlowTab.tsx +0 -576
- package/apps/harness-dashboard/components/drawer/OwnerHistoryTab.tsx +0 -160
- package/apps/harness-dashboard/components/drawer/RoomMetricsTab.tsx +0 -90
- package/apps/harness-dashboard/components/drawer/TracksTab.tsx +0 -47
- package/apps/harness-dashboard/components/three/ArchiveBoxes.tsx +0 -95
- package/apps/harness-dashboard/components/three/DeptBoard.tsx +0 -175
- package/apps/harness-dashboard/components/three/Floor3D.tsx +0 -404
- package/apps/harness-dashboard/components/three/GoalCard3D.tsx +0 -123
- package/apps/harness-dashboard/components/three/HypothesisCards.tsx +0 -71
- package/apps/harness-dashboard/components/three/MeetingWhiteboard.tsx +0 -98
- package/apps/harness-dashboard/components/three/Minifig3D.tsx +0 -391
- package/apps/harness-dashboard/components/three/OpsSiren.tsx +0 -99
- package/apps/harness-dashboard/components/three/Stage3D.tsx +0 -104
- package/apps/harness-dashboard/components/three/TrackRibbons.tsx +0 -81
- package/apps/harness-dashboard/lib/__tests__/i18n.test.ts +0 -16
- package/apps/harness-dashboard/lib/__tests__/iso.test.ts +0 -42
- package/apps/harness-dashboard/lib/__tests__/state-mapping.test.ts +0 -183
- package/apps/harness-dashboard/lib/agent-roster.ts +0 -42
- package/apps/harness-dashboard/lib/furniture.ts +0 -165
- package/apps/harness-dashboard/lib/i18n.ts +0 -26
- package/apps/harness-dashboard/lib/iso.ts +0 -150
- package/apps/harness-dashboard/lib/markdown.tsx +0 -306
- package/apps/harness-dashboard/lib/path-planning.ts +0 -72
- package/apps/harness-dashboard/lib/state-mapping.ts +0 -146
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import type { GotchaEntry } from "@/lib/types";
|
|
4
|
-
import { MarkdownView } from "@/lib/markdown";
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
gotchas: GotchaEntry[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function GotchasTab({ gotchas }: Props) {
|
|
11
|
-
const [selected, setSelected] = useState<GotchaEntry | null>(null);
|
|
12
|
-
const [search, setSearch] = useState("");
|
|
13
|
-
|
|
14
|
-
if (selected) {
|
|
15
|
-
return (
|
|
16
|
-
<div className="space-y-3">
|
|
17
|
-
<button
|
|
18
|
-
type="button"
|
|
19
|
-
onClick={() => setSelected(null)}
|
|
20
|
-
className="flex items-center gap-1.5 font-mono text-[10px] text-cyan-400/70 hover:text-cyan-300 transition-colors"
|
|
21
|
-
>
|
|
22
|
-
← Back
|
|
23
|
-
</button>
|
|
24
|
-
<div className="font-mono text-[10px] text-gray-500">
|
|
25
|
-
.harness/gotchas/{selected.id}.md
|
|
26
|
-
</div>
|
|
27
|
-
<MarkdownView source={selected.content} />
|
|
28
|
-
</div>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const filtered = search.trim()
|
|
33
|
-
? gotchas.filter(
|
|
34
|
-
(g) =>
|
|
35
|
-
g.title.toLowerCase().includes(search.toLowerCase()) ||
|
|
36
|
-
g.id.toLowerCase().includes(search.toLowerCase()) ||
|
|
37
|
-
g.tags.some((t) => t.toLowerCase().includes(search.toLowerCase()))
|
|
38
|
-
)
|
|
39
|
-
: gotchas;
|
|
40
|
-
|
|
41
|
-
if (gotchas.length === 0) {
|
|
42
|
-
return <div className="text-gray-500 text-xs">No gotchas found in .harness/gotchas/</div>;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div className="space-y-2">
|
|
47
|
-
{/* Search */}
|
|
48
|
-
<input
|
|
49
|
-
type="text"
|
|
50
|
-
value={search}
|
|
51
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
52
|
-
placeholder="Search gotchas…"
|
|
53
|
-
className="w-full rounded border border-gray-700/60 bg-black/30 px-2.5 py-1.5 font-mono text-[11px] text-gray-300 placeholder-gray-600 focus:border-cyan-400/40 focus:outline-none"
|
|
54
|
-
/>
|
|
55
|
-
|
|
56
|
-
<div className="font-mono text-[9px] text-gray-600 px-0.5">
|
|
57
|
-
{filtered.length} / {gotchas.length} gotchas
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<div className="space-y-1.5">
|
|
61
|
-
{filtered.map((g) => (
|
|
62
|
-
<button
|
|
63
|
-
key={g.id}
|
|
64
|
-
type="button"
|
|
65
|
-
onClick={() => setSelected(g)}
|
|
66
|
-
className="w-full text-left rounded border border-gray-700/50 bg-black/20 px-3 py-2 hover:border-amber-400/30 hover:bg-amber-400/5 transition-colors group"
|
|
67
|
-
>
|
|
68
|
-
<div className="font-mono text-[11px] text-gray-200 group-hover:text-amber-200 leading-snug">
|
|
69
|
-
{g.title}
|
|
70
|
-
</div>
|
|
71
|
-
<div className="font-mono text-[9px] text-gray-600 mt-0.5">{g.id}</div>
|
|
72
|
-
{g.tags.length > 0 && (
|
|
73
|
-
<div className="flex flex-wrap gap-1 mt-1">
|
|
74
|
-
{g.tags.slice(0, 5).map((tag) => (
|
|
75
|
-
<span
|
|
76
|
-
key={tag}
|
|
77
|
-
className="rounded bg-gray-700/40 px-1.5 py-0.5 font-mono text-[8px] text-gray-500"
|
|
78
|
-
>
|
|
79
|
-
{tag}
|
|
80
|
-
</span>
|
|
81
|
-
))}
|
|
82
|
-
</div>
|
|
83
|
-
)}
|
|
84
|
-
</button>
|
|
85
|
-
))}
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import type { HypothesisEntry } from "@/lib/types";
|
|
3
|
-
|
|
4
|
-
const VERDICT_TONE: Record<string, string> = {
|
|
5
|
-
pending: "border-aura-talking/40 bg-aura-talking/10 text-aura-talking",
|
|
6
|
-
valid: "border-aura-typing/40 bg-aura-typing/10 text-aura-typing",
|
|
7
|
-
invalid: "border-aura-alert/40 bg-aura-alert/10 text-aura-alert",
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
interface HypothesisTabProps {
|
|
11
|
-
hypothesis: HypothesisEntry[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function HypothesisTab({ hypothesis }: HypothesisTabProps) {
|
|
15
|
-
if (hypothesis.length === 0) {
|
|
16
|
-
return (
|
|
17
|
-
<div className="text-gray-500" data-testid="hypothesis-empty">
|
|
18
|
-
No active hypothesis.
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
return (
|
|
23
|
-
<ul className="space-y-2" data-testid="hypothesis-list">
|
|
24
|
-
{hypothesis.map((h) => (
|
|
25
|
-
<li
|
|
26
|
-
key={h.id}
|
|
27
|
-
data-testid={`hypothesis-row-${h.id}`}
|
|
28
|
-
className={`rounded border px-2 py-1.5 ${
|
|
29
|
-
VERDICT_TONE[h.verdict] ?? VERDICT_TONE.pending
|
|
30
|
-
}`}
|
|
31
|
-
>
|
|
32
|
-
<div className="flex items-center justify-between text-[11px]">
|
|
33
|
-
<span className="font-semibold">{h.id}</span>
|
|
34
|
-
<span className="uppercase tracking-wider text-[9px]">{h.verdict}</span>
|
|
35
|
-
</div>
|
|
36
|
-
<div className="mt-1 text-[11px] text-gray-100">{h.brief}</div>
|
|
37
|
-
{h.ts && <div className="mt-0.5 text-[9px] text-gray-500">{h.ts}</div>}
|
|
38
|
-
</li>
|
|
39
|
-
))}
|
|
40
|
-
</ul>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import type { IncidentEntry } from "@/lib/types";
|
|
3
|
-
|
|
4
|
-
const SEVERITY_TONE: Record<string, string> = {
|
|
5
|
-
low: "border-aura-idle/40 bg-aura-idle/10 text-gray-300",
|
|
6
|
-
medium: "border-aura-talking/40 bg-aura-talking/10 text-aura-talking",
|
|
7
|
-
high: "border-aura-alert/40 bg-aura-alert/10 text-aura-alert",
|
|
8
|
-
critical: "border-aura-alert bg-aura-alert/30 text-aura-alert",
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
interface IncidentsTabProps {
|
|
12
|
-
incidents: IncidentEntry[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function IncidentsTab({ incidents }: IncidentsTabProps) {
|
|
16
|
-
if (incidents.length === 0) {
|
|
17
|
-
return (
|
|
18
|
-
<div className="text-gray-500" data-testid="incidents-empty">
|
|
19
|
-
No open incidents.
|
|
20
|
-
</div>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
return (
|
|
24
|
-
<ul className="space-y-2" data-testid="incidents-list">
|
|
25
|
-
{incidents.map((it) => (
|
|
26
|
-
<li
|
|
27
|
-
key={it.id}
|
|
28
|
-
data-testid={`incident-${it.id}`}
|
|
29
|
-
className={`rounded border px-2 py-1.5 ${
|
|
30
|
-
SEVERITY_TONE[it.severity] ?? SEVERITY_TONE.medium
|
|
31
|
-
}`}
|
|
32
|
-
>
|
|
33
|
-
<div className="flex items-center justify-between text-[11px]">
|
|
34
|
-
<span className="font-semibold">{it.id}</span>
|
|
35
|
-
<span className="uppercase tracking-wider text-[9px]">
|
|
36
|
-
{it.severity}
|
|
37
|
-
</span>
|
|
38
|
-
</div>
|
|
39
|
-
<div className="text-[10px] opacity-80">dept: {it.dept}</div>
|
|
40
|
-
{it.message && (
|
|
41
|
-
<div className="mt-1 text-[11px] text-gray-100">{it.message}</div>
|
|
42
|
-
)}
|
|
43
|
-
{it.ts && (
|
|
44
|
-
<div className="mt-0.5 text-[9px] text-gray-500">{it.ts}</div>
|
|
45
|
-
)}
|
|
46
|
-
</li>
|
|
47
|
-
))}
|
|
48
|
-
</ul>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
import type { MissionDoc } from "@/lib/types";
|
|
4
|
-
import { MarkdownView } from "@/lib/markdown";
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
missions: MissionDoc[];
|
|
8
|
-
role: "ceo" | "cto" | "cqo" | "coo" | "cdo" | "ops" | "worker";
|
|
9
|
-
workerName?: string;
|
|
10
|
-
fromLabel: string;
|
|
11
|
-
toLabel: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function MissionDocTab({ missions, role, workerName, fromLabel, toLabel }: Props) {
|
|
15
|
-
const [selectedIdx, setSelectedIdx] = useState(0);
|
|
16
|
-
const mission = missions[selectedIdx];
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
setSelectedIdx(0);
|
|
20
|
-
}, [role, workerName]);
|
|
21
|
-
|
|
22
|
-
if (!missions.length) {
|
|
23
|
-
return (
|
|
24
|
-
<div className="text-gray-500">
|
|
25
|
-
No mission documents found in .harness/documents/
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const getContent = (m: MissionDoc): string | null => {
|
|
31
|
-
if (role === "worker" && workerName) {
|
|
32
|
-
return m.workers.find((w) => w.name === workerName)?.content ?? null;
|
|
33
|
-
}
|
|
34
|
-
const cxxRole = role as Exclude<typeof role, "worker">;
|
|
35
|
-
return m[cxxRole] ?? null;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const content = getContent(mission);
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<div className="space-y-3">
|
|
42
|
-
{/* Routing breadcrumb */}
|
|
43
|
-
<div className="flex items-center gap-2 flex-wrap">
|
|
44
|
-
<span className="font-mono text-[9px] uppercase tracking-[0.2em] text-gray-500">flow</span>
|
|
45
|
-
<span className="rounded bg-amber-500/10 border border-amber-500/30 px-2 py-0.5 text-[10px] text-amber-300 font-mono">
|
|
46
|
-
{fromLabel}
|
|
47
|
-
</span>
|
|
48
|
-
<span className="text-gray-600">→</span>
|
|
49
|
-
<span className="rounded border border-cyan-400/30 bg-cyan-400/10 px-2 py-0.5 text-[10px] text-cyan-300 font-mono">
|
|
50
|
-
this
|
|
51
|
-
</span>
|
|
52
|
-
<span className="text-gray-600">→</span>
|
|
53
|
-
<span className="rounded border border-gray-600/40 bg-gray-800/30 px-2 py-0.5 text-[10px] text-gray-400 font-mono">
|
|
54
|
-
{toLabel}
|
|
55
|
-
</span>
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
{/* Mission selector */}
|
|
59
|
-
<div className="flex gap-1 flex-wrap">
|
|
60
|
-
{missions.slice(0, 6).map((m, i) => (
|
|
61
|
-
<button
|
|
62
|
-
key={m.missionId}
|
|
63
|
-
type="button"
|
|
64
|
-
onClick={() => setSelectedIdx(i)}
|
|
65
|
-
className={`rounded px-2 py-1 font-mono text-[9px] transition-colors ${
|
|
66
|
-
i === selectedIdx
|
|
67
|
-
? "bg-cyan-400/15 text-cyan-300 border border-cyan-400/30"
|
|
68
|
-
: "text-gray-500 hover:text-gray-300 border border-transparent"
|
|
69
|
-
}`}
|
|
70
|
-
>
|
|
71
|
-
{i === 0 ? "current" : m.missionId.slice(0, 16)}
|
|
72
|
-
</button>
|
|
73
|
-
))}
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
{/* Mission ID */}
|
|
77
|
-
<div className="font-mono text-[10px] text-gray-500">
|
|
78
|
-
{mission.missionId} · {new Date(mission.ts).toLocaleDateString()}
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
|
-
{/* Document content */}
|
|
82
|
-
{!content ? (
|
|
83
|
-
<div className="text-gray-500 text-[11px]">
|
|
84
|
-
No {role} document for this mission.
|
|
85
|
-
<div className="mt-1 text-[10px] text-gray-600">
|
|
86
|
-
Present: {mission.cxxPresent.join(", ") || "none"}
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
) : (
|
|
90
|
-
<div className="rounded border border-gray-700/60 bg-black/20 p-3 max-h-[60vh] overflow-y-auto">
|
|
91
|
-
<MarkdownView source={content} />
|
|
92
|
-
</div>
|
|
93
|
-
)}
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
}
|