@harness-lab/cli 0.3.0 → 0.3.2
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/assets/workshop-bundle/SKILL.md +8 -0
- package/assets/workshop-bundle/bundle-manifest.json +19 -19
- package/assets/workshop-bundle/content/challenge-cards/deck.md +1 -1
- package/assets/workshop-bundle/content/challenge-cards/print-spec.md +1 -1
- package/assets/workshop-bundle/content/facilitation/master-guide.md +3 -4
- package/assets/workshop-bundle/content/project-briefs/code-review-helper.md +1 -1
- package/assets/workshop-bundle/content/project-briefs/doc-generator.md +2 -2
- package/assets/workshop-bundle/content/project-briefs/metrics-dashboard.md +1 -1
- package/assets/workshop-bundle/content/project-briefs/standup-bot.md +1 -1
- package/assets/workshop-bundle/content/talks/context-is-king.md +12 -4
- package/assets/workshop-bundle/materials/participant-resource-kit.md +1 -1
- package/assets/workshop-bundle/workshop-skill/closing-skill.md +2 -2
- package/assets/workshop-bundle/workshop-skill/commands.md +4 -0
- package/assets/workshop-bundle/workshop-skill/follow-up-package.md +1 -1
- package/assets/workshop-bundle/workshop-skill/locales/en/commands.md +4 -0
- package/assets/workshop-bundle/workshop-skill/locales/en/reference.md +1 -0
- package/assets/workshop-bundle/workshop-skill/recap.md +1 -1
- package/assets/workshop-bundle/workshop-skill/reference.md +9 -1
- package/package.json +1 -1
- package/src/run-cli.js +173 -23
|
@@ -326,6 +326,14 @@ Rules for rich scenes:
|
|
|
326
326
|
|
|
327
327
|
Archive the current workshop instance with optional notes.
|
|
328
328
|
|
|
329
|
+
### `workshop facilitator learnings`
|
|
330
|
+
|
|
331
|
+
Query the cross-cohort learnings log to review rotation signals from past and current workshops.
|
|
332
|
+
Prefer invoking `harness --json workshop learnings` for machine-readable output.
|
|
333
|
+
Supports flags: `--tag TAG`, `--instance ID`, `--cohort NAME`, `--limit N` (default 20).
|
|
334
|
+
When the facilitator asks for rotation signals, captured observations, or what happened during past handoffs, use this command.
|
|
335
|
+
If the learnings log is empty, say so and suggest capturing the first signal using the rotation capture panel in the facilitator dashboard.
|
|
336
|
+
|
|
329
337
|
### `workshop analyze`
|
|
330
338
|
|
|
331
339
|
Review the team's repo against the handoff criteria in `workshop-skill/analyze-checklist.md`.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifestVersion": 1,
|
|
3
3
|
"bundleName": "harness-lab-workshop",
|
|
4
|
-
"bundleVersion": "0.3.
|
|
5
|
-
"contentHash": "
|
|
4
|
+
"bundleVersion": "0.3.2",
|
|
5
|
+
"contentHash": "579eac8240790ff7974b9cfdfba7f4c2ae0c901fbf3bf312e1017ad258069174",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"path": "content/challenge-cards/.gitkeep",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": "content/challenge-cards/deck.md",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "d2523b1fbedd84faef5327affe5a698f44b8634c9eb0da8320dc8339bc5158fc"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "content/challenge-cards/locales/en/deck.md",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
"path": "content/challenge-cards/print-spec.md",
|
|
21
|
-
"sha256": "
|
|
21
|
+
"sha256": "0c6bc2953d6296b8901705d938a29c1ef859490e53cc265fe401bb9585611e16"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"path": "content/codex-craft.md",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"path": "content/facilitation/master-guide.md",
|
|
37
|
-
"sha256": "
|
|
37
|
+
"sha256": "c5f3df56380b3df498a92dc6de55e922b2c7722e53e4f6f2efbef9b76de1d163"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"path": "content/project-briefs/.gitkeep",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
"path": "content/project-briefs/code-review-helper.md",
|
|
45
|
-
"sha256": "
|
|
45
|
+
"sha256": "faf51210e1305683432f3e96eec1e18f91cdb2f1fd086ff73aeb70b6d17895a0"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"path": "content/project-briefs/devtoolbox-cli.md",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"path": "content/project-briefs/doc-generator.md",
|
|
53
|
-
"sha256": "
|
|
53
|
+
"sha256": "b4a3da683eba039f6009be61fe546ed1585341c82c3492f94add8363ad9496e3"
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"path": "content/project-briefs/locales/en/code-review-helper.md",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"path": "content/project-briefs/metrics-dashboard.md",
|
|
77
|
-
"sha256": "
|
|
77
|
+
"sha256": "926dd8ccedab65a30b862bf4dc481f2c8054778e5668d97f5c8cf46665c60860"
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"path": "content/project-briefs/standup-bot.md",
|
|
81
|
-
"sha256": "
|
|
81
|
+
"sha256": "c2f56513bf69dd92c95f3dbd68c5b0925d19faf17d9d42eb2ed40c7cc8e8839b"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"path": "content/talks/.gitkeep",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
"path": "content/talks/context-is-king.md",
|
|
93
|
-
"sha256": "
|
|
93
|
+
"sha256": "2f666585220c50901fe91443904a127e3357aa71a92e93b10eafa17100eb105c"
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
"path": "docs/harness-cli-foundation.md",
|
|
@@ -126,11 +126,11 @@
|
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"path": "materials/participant-resource-kit.md",
|
|
129
|
-
"sha256": "
|
|
129
|
+
"sha256": "c9c58ebf3e66a6f6823a06b5d938bc930eb3a768d3d23a2b4f18fe99b4b85a47"
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
"path": "SKILL.md",
|
|
133
|
-
"sha256": "
|
|
133
|
+
"sha256": "0188da9de8f517a09dc4d0e2eb14f395aa465048253bf0c719995e8a232a33e2"
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
"path": "workshop-blueprint/agenda.json",
|
|
@@ -166,11 +166,11 @@
|
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
168
|
"path": "workshop-skill/closing-skill.md",
|
|
169
|
-
"sha256": "
|
|
169
|
+
"sha256": "f0ce3f0f4a515dff14dab77fd31317a73a489ee24ba536eb7dd20f0b13cff4ec"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
"path": "workshop-skill/commands.md",
|
|
173
|
-
"sha256": "
|
|
173
|
+
"sha256": "d0af2bcc53c9752be3b013da002c22d4a8c7a09dea1995075b82550947141736"
|
|
174
174
|
},
|
|
175
175
|
{
|
|
176
176
|
"path": "workshop-skill/facilitator.md",
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
},
|
|
179
179
|
{
|
|
180
180
|
"path": "workshop-skill/follow-up-package.md",
|
|
181
|
-
"sha256": "
|
|
181
|
+
"sha256": "3299b0cf49e90f87ec3090ed934234d8c06e502fd3305c4e69c8aadfe1b42e7e"
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"path": "workshop-skill/install.md",
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
},
|
|
187
187
|
{
|
|
188
188
|
"path": "workshop-skill/locales/en/commands.md",
|
|
189
|
-
"sha256": "
|
|
189
|
+
"sha256": "596af69cff67b770c284b4485c94bc39b511a60f3ff1b2b34f91f2c58a9f8b03"
|
|
190
190
|
},
|
|
191
191
|
{
|
|
192
192
|
"path": "workshop-skill/locales/en/follow-up-package.md",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
"path": "workshop-skill/locales/en/reference.md",
|
|
201
|
-
"sha256": "
|
|
201
|
+
"sha256": "2e941f974ae86c79131770d40302eec0e7968e217f36d8ff166065c7819c47b3"
|
|
202
202
|
},
|
|
203
203
|
{
|
|
204
204
|
"path": "workshop-skill/locales/en/setup.md",
|
|
@@ -206,11 +206,11 @@
|
|
|
206
206
|
},
|
|
207
207
|
{
|
|
208
208
|
"path": "workshop-skill/recap.md",
|
|
209
|
-
"sha256": "
|
|
209
|
+
"sha256": "c479b255b4ebd35dde9a1afbf7a174e3aa8b348ebed8e07187f641f5dcb1b143"
|
|
210
210
|
},
|
|
211
211
|
{
|
|
212
212
|
"path": "workshop-skill/reference.md",
|
|
213
|
-
"sha256": "
|
|
213
|
+
"sha256": "438cfc517d5ff707ce737e81a7ec3f8098c08f8fd2589ac105aea968da39f9a6"
|
|
214
214
|
},
|
|
215
215
|
{
|
|
216
216
|
"path": "workshop-skill/setup.md",
|
|
@@ -15,7 +15,7 @@ Karty nejsou body navíc. Jsou to malé zásahy, které zlepšují způsob prác
|
|
|
15
15
|
- `Rozdělte práci do více vláken` — zkuste dvě nezávislé linie práce a jednoho člověka na integraci.
|
|
16
16
|
- `Delegujte úkol a vraťte se ke kontrole za 10 minut` — neskákejte agentovi do každého kroku, kontrolujte až výsledek.
|
|
17
17
|
- `Přidejte nejmenší užitečné ověření` — zapište done criteria jako spustitelný check (unit test, tracer bullet nebo jednoduchý browser check) dřív, než agent dostane víc autonomie.
|
|
18
|
-
- `Napište diagnózu po handoffu` — pojmenujte, co pomohlo, co chybělo a jaký je další
|
|
18
|
+
- `Napište diagnózu po handoffu` — pojmenujte, co pomohlo, co chybělo a jaký je další bezpečný krok.
|
|
19
19
|
- `Opravte jeden slabý signál v repu` — README, AGENTS.md, plán, runbook nebo check.
|
|
20
20
|
|
|
21
21
|
## Advanced
|
|
@@ -24,7 +24,7 @@ Spustit den jako společný start pro celý workshop, ne jako provozní brief k
|
|
|
24
24
|
2. proč na tom záleží právě teď
|
|
25
25
|
3. analogie typu Lego duck: stejné ingredience, různé použitelné výsledky
|
|
26
26
|
4. krátká pohybová aktivace podle zkušenosti s AI agenty
|
|
27
|
-
5. první pracovní kontrakt pro
|
|
27
|
+
5. první pracovní kontrakt pro build fázi 1
|
|
28
28
|
|
|
29
29
|
### Lego-duck analogie
|
|
30
30
|
|
|
@@ -78,7 +78,7 @@ Do oběda má být vidět:
|
|
|
78
78
|
|
|
79
79
|
### Cíl
|
|
80
80
|
|
|
81
|
-
Proměnit energii z openingu v přesnou tezi a čistý most do
|
|
81
|
+
Proměnit energii z openingu v přesnou tezi a čistý most do build fáze 1.
|
|
82
82
|
|
|
83
83
|
### Klíčová message
|
|
84
84
|
|
|
@@ -108,7 +108,7 @@ Pointa:
|
|
|
108
108
|
- přenos mantinelů
|
|
109
109
|
- přenos done criteria
|
|
110
110
|
|
|
111
|
-
###
|
|
111
|
+
### Co si odnesete do build fáze
|
|
112
112
|
|
|
113
113
|
Na konci talku má být jasné:
|
|
114
114
|
|
|
@@ -232,7 +232,6 @@ Vést ho jako krátký checkpoint, ze kterého si týmy odnesou jednu věc, kter
|
|
|
232
232
|
|
|
233
233
|
- Začněte `README`, `AGENTS.md` a planem.
|
|
234
234
|
- Needitujte hned první soubor, který otevřete.
|
|
235
|
-
- Nejprve si udělejte mapu: co funguje, co chybí, co je rizikové.
|
|
236
235
|
- Nejdřív napište vlastní diagnózu: co pomáhá, co chybí, co je rizikové a jaký je další bezpečný krok.
|
|
237
236
|
- Když tým neví, po čem sáhnout, vraťte ho k learner kitu: `template-agents`, `reference`, `analyze-checklist` a challenge cards.
|
|
238
237
|
|
|
@@ -24,7 +24,7 @@ Vaším úkolem je navrhnout nástroj, který z diffu nebo změny vytvoří pou
|
|
|
24
24
|
- Nástroj vytvoří review checklist ze seed diffu.
|
|
25
25
|
- Výstup odlišuje jistá zjištění od doporučení, hypotéz a bodů pro lidský úsudek.
|
|
26
26
|
- Je jasné, jak přidat nové pravidlo nebo heuristiku bez dlouhého onboardingu.
|
|
27
|
-
- Další tým může během
|
|
27
|
+
- Další tým může během 10 minut pokračovat v rozvoji bez chaosu.
|
|
28
28
|
|
|
29
29
|
## První krok pro agenta
|
|
30
30
|
|
|
@@ -9,7 +9,7 @@ Vaším úkolem je navrhnout nástroj, který z projektu vygeneruje základní
|
|
|
9
9
|
## User stories
|
|
10
10
|
|
|
11
11
|
- Jako vývojář chci z projektu rychle získat základní technickou dokumentaci bez ručního sepisování všeho od nuly.
|
|
12
|
-
- Jako reviewer chci během
|
|
12
|
+
- Jako reviewer chci během 5 minut pochopit strukturu modulů a hlavní vstupní body.
|
|
13
13
|
- Jako tým po rotaci chci objevit architekturu projektu bez dlouhého pátrání po souvislostech.
|
|
14
14
|
|
|
15
15
|
## Architektonické poznámky
|
|
@@ -26,7 +26,7 @@ Vaším úkolem je navrhnout nástroj, který z projektu vygeneruje základní
|
|
|
26
26
|
- Je jasné, jak se nástroj spouští lokálně a nad jakým vstupem.
|
|
27
27
|
- Výstup odděluje fakta od odhadů nebo heuristik.
|
|
28
28
|
- Další tým umí přidat nový typ výstupu bez chaosu v repu.
|
|
29
|
-
- Reviewer během
|
|
29
|
+
- Reviewer během 10 minut pozná, odkud které tvrzení pochází.
|
|
30
30
|
|
|
31
31
|
## První krok pro agenta
|
|
32
32
|
|
|
@@ -10,7 +10,7 @@ Vaším úkolem je navrhnout jednoduchý dashboard, který z několika metrik v
|
|
|
10
10
|
|
|
11
11
|
- Jako tým chci zobrazit několik metrik na jedné obrazovce tak, aby z nich šlo rychle vyčíst stav.
|
|
12
12
|
- Jako facilitátor chci snadno měnit seed data bez zásahu do UI logiky.
|
|
13
|
-
- Jako tým po rotaci chci během
|
|
13
|
+
- Jako tým po rotaci chci během 10 minut pochopit strukturu dat, komponent i obrazovek.
|
|
14
14
|
|
|
15
15
|
## Architektonické poznámky
|
|
16
16
|
|
|
@@ -25,7 +25,7 @@ Vaším úkolem je navrhnout nástroj, který ze standup vstupů vytvoří přeh
|
|
|
25
25
|
- Nástroj umí ingestovat seed data a vytvořit čitelný souhrn.
|
|
26
26
|
- Výstup zvýrazní blokery nebo položky, které potřebují pozornost.
|
|
27
27
|
- Repo obsahuje instrukce, jak řešení napojit na reálný chat nebo jiný vstupní kanál.
|
|
28
|
-
- Po rotaci
|
|
28
|
+
- Po rotaci může nový tým pokračovat v práci z README a `AGENTS.md` bez ústního handoffu.
|
|
29
29
|
- Je jasné, co je jisté shrnutí a co je jen heuristika nebo návrh.
|
|
30
30
|
|
|
31
31
|
## První krok pro agenta
|
|
@@ -43,15 +43,23 @@ Vezmeme stejný malý task ve dvou podmínkách. Jedna varianta bude prompt blob
|
|
|
43
43
|
|
|
44
44
|
## Hlavní teze
|
|
45
45
|
|
|
46
|
+
### Kontext je páka
|
|
47
|
+
|
|
46
48
|
- Kontext je páka, ne kosmetika.
|
|
47
49
|
- `AGENTS.md`, skills a runbooky jsou týmová infrastruktura.
|
|
48
50
|
- `AGENTS.md` nemá být encyklopedie. Má to být mapa, která ukáže, kam sáhnout dál.
|
|
49
|
-
- Co není v repu, neexistuje. Slack, ústní dovysvětlení a
|
|
51
|
+
- Co není v repu, neexistuje. Slack, ústní dovysvětlení a „to si pamatujeme" se rozpadne, jakmile práci někdo převezme.
|
|
52
|
+
|
|
53
|
+
### Ověření je hranice důvěry
|
|
54
|
+
|
|
50
55
|
- Testy jsou hranice důvěry. Když agent pracuje samostatněji, musíte mnohem líp ověřovat, že udělal právě to, co jste chtěli.
|
|
51
56
|
- Jednoduché mantinely zrychlují práci. Agentovi pomáhá jasný build/test flow, viditelné hranice a předvídatelná struktura.
|
|
52
57
|
- U UI práce je výchozí pattern: agent exploration, potom repeatable browser test, potom lidské review.
|
|
53
58
|
- „Nech model jezdit v mém běžném přihlášeném browseru“ není výchozí doporučení. Bezpečnější je izolované lokální prostředí a jasné mantinely.
|
|
54
|
-
- Ověření napsané dřív, než pustíte agenta do většího kusu práce, není test-first dogma.
|
|
59
|
+
- Ověření napsané dřív, než pustíte agenta do většího kusu práce, není test-first dogma. Znamená to zapsat done criteria v takové formě, aby je agent i další tým uměl zkontrolovat. Iteraci to zrychluje, protože agent dostane přesné mantinely, ne další prompt.
|
|
60
|
+
|
|
61
|
+
### Repo se udržuje, ne jen plní
|
|
62
|
+
|
|
55
63
|
- Úklid není bonus po workshopu. Když narazíte na opakující se chaos, je čas ho proměnit v lepší template, ověření nebo runbook.
|
|
56
64
|
- Odpolední návaznost prověří, jestli váš kontext funguje i bez vás.
|
|
57
65
|
|
|
@@ -62,14 +70,14 @@ Vezmeme stejný malý task ve dvou podmínkách. Jedna varianta bude prompt blob
|
|
|
62
70
|
- Když agent dělá víc, já musím lépe ověřovat.
|
|
63
71
|
- Handoff není závěr dne. Je to průběžná podmínka celé práce.
|
|
64
72
|
|
|
65
|
-
##
|
|
73
|
+
## Co si odnesete do build fáze
|
|
66
74
|
|
|
67
75
|
Po tomhle talku se tým nemá vracet k repu s pocitem, že potřebuje jen chytřejší prompt. Má se vracet s jedním jasným očekáváním:
|
|
68
76
|
|
|
69
77
|
- pokud ještě nemá workshop skill, teď je chvíle na `harness skill install`, pak `Codex: $workshop setup` nebo `pi: /skill:workshop`
|
|
70
78
|
- nejdřív krátká mapa v repu
|
|
71
79
|
- potom krátký plán kroků
|
|
72
|
-
- potom první explicitní
|
|
80
|
+
- potom první explicitní ověření, že agent dělá, co jste čekali
|
|
73
81
|
- teprve potom další feature motion
|
|
74
82
|
|
|
75
83
|
## Závěr
|
|
@@ -77,7 +77,7 @@ Poznámka:
|
|
|
77
77
|
Codex a další kódovací agenti se mění měsíčně. Tenhle kit není zmrazená reference — je to startovní harness pro vaši vlastní čtecí praxi.
|
|
78
78
|
|
|
79
79
|
- **Codex CLI release notes** — čtěte při každém vydání. Změny v approval módech a sandboxingu jsou ty nejdůležitější.
|
|
80
|
-
- **Simon Willison's blog** ([simonwillison.net](https://simonwillison.net/)) —
|
|
80
|
+
- **Simon Willison's blog** ([simonwillison.net](https://simonwillison.net/)) — praktický zdroj o Codexu, Claude Code a dalších agentech. Píše z vlastní každodenní praxe.
|
|
81
81
|
- **OpenAI Harness Engineering articles** — viz `docs/learner-reference-gallery.md` pro odkazy.
|
|
82
82
|
- **Anthropic engineering blog** — když pracujete s Claude Code, sledujte oficiální posts.
|
|
83
83
|
- **Vlastní `AGENTS.md` jako živý dokument** — každé čtvrtletí si je znovu přečtěte skeptickým okem. Smažte, co už není nosné. Jednoduchost je součást harnessu.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Úkol
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Po posledním bloku vytvoř krátké shrnutí workshopu, které je:
|
|
6
6
|
|
|
7
7
|
- konkrétní
|
|
8
8
|
- systémové, ne osobní
|
|
@@ -19,7 +19,7 @@ Na konci dne vytvoř krátké shrnutí workshopu, které je:
|
|
|
19
19
|
|
|
20
20
|
1. Co pomohlo týmům pokračovat po handoffu
|
|
21
21
|
2. Co opakovaně chybělo
|
|
22
|
-
3. Jaké 2
|
|
22
|
+
3. Jaké 2–3 principy si má místnost odnést do příštího týdne
|
|
23
23
|
4. Jedna závěrečná věta, která propojí workshop s reálnou prací v týmu
|
|
24
24
|
|
|
25
25
|
## Styl
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
- Když si nejste jistí workflow: `workshop commands`
|
|
40
40
|
- Když chcete materiály i po workshopu: `workshop resources`, `workshop follow-up`, `workshop gallery`
|
|
41
41
|
|
|
42
|
+
## Facilitátorské příkazy
|
|
43
|
+
|
|
44
|
+
- `workshop facilitator learnings` — dotaz do learnings logu: záznamy z rotace z minulých i aktuálních workshopů. Podporuje filtrování podle tagu, instance a cohortu.
|
|
45
|
+
|
|
42
46
|
## Důležitá poznámka
|
|
43
47
|
|
|
44
48
|
`workshop` skill je garantovaný výchozí nástroj workshopu. Další workflow skills a veřejné toolkity jsou doporučené rozšíření, ne podmínka účasti.
|
|
@@ -32,7 +32,7 @@ Krátký navazující dotaz:
|
|
|
32
32
|
|
|
33
33
|
- Vytvořili jste `AGENTS.md` v reálném projektu?
|
|
34
34
|
- Přidali jste build/test příkazy nebo sekci `Done When`?
|
|
35
|
-
- Přidali jste další
|
|
35
|
+
- Přidali jste další bezpečný krok nebo krátký handoff runbook?
|
|
36
36
|
- Co vám pomohlo a co vás zablokovalo?
|
|
37
37
|
|
|
38
38
|
## W³ připomínka
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
- If you are unsure about workflow: `workshop commands`
|
|
40
40
|
- If you want materials after the workshop too: `workshop resources`, `workshop follow-up`, `workshop gallery`
|
|
41
41
|
|
|
42
|
+
## Facilitator commands
|
|
43
|
+
|
|
44
|
+
- `workshop facilitator learnings` — query the cross-cohort learnings log: rotation signals from past and current workshops. Supports filtering by tag, instance, and cohort.
|
|
45
|
+
|
|
42
46
|
## Important note
|
|
43
47
|
|
|
44
48
|
The `workshop` skill is the guaranteed workshop default. Additional workflow skills and public toolkits are recommended accelerators, not a requirement for participation.
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
- `Codex: $workshop` for orientation during the day
|
|
60
60
|
- `Codex: $workshop template` when the repo is missing baseline context
|
|
61
61
|
- `Codex: $workshop analyze` before handoff or after rotation when you want to expose blind spots in the repo quickly
|
|
62
|
+
- `Codex: $workshop facilitator learnings` or `harness workshop learnings` to query the cross-cohort learnings log (rotation signals from past workshops). Prefers the CLI path for machine-readable output with filtering by tag, instance, or cohort.
|
|
62
63
|
|
|
63
64
|
## Recommended participant loop
|
|
64
65
|
|
|
@@ -26,4 +26,4 @@ Vraťte se ke sticky note z části `A teď?` a převeďte ji na první konkr
|
|
|
26
26
|
|
|
27
27
|
## Až si nebudete jistí
|
|
28
28
|
|
|
29
|
-
Začněte jednoduše: napište, co chcete udělat, kde je kontext, jaká jsou omezení, podle čeho poznáte hotovo a jaký je další
|
|
29
|
+
Začněte jednoduše: napište, co chcete udělat, kde je kontext, jaká jsou omezení, podle čeho poznáte hotovo a jaký je další bezpečný krok, když práce zůstane rozdělaná.
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
- V prvním buildu: `template-agents`, brief, plán a první ověření
|
|
37
37
|
- Před obědem: dopsat další bezpečný krok a použít `workshop analyze`, když si nejste jistí handoffem
|
|
38
38
|
- Po rotaci: `workshop analyze`, learner kit a challenge cards místo ústního rescue
|
|
39
|
-
-
|
|
39
|
+
- Po posledním bloku: `workshop recap` a `workshop follow-up`
|
|
40
40
|
|
|
41
41
|
## Doporučené příkazy
|
|
42
42
|
|
|
@@ -87,6 +87,14 @@
|
|
|
87
87
|
|
|
88
88
|
Dobrý prompt nestačí. Když má práce přežít handoff, musí být kontext uložený v repu, další bezpečný krok musí být dohledatelný a ověření musí zůstat čitelné i pro cizí tým.
|
|
89
89
|
|
|
90
|
+
## Learnings log — pro facilitátory
|
|
91
|
+
|
|
92
|
+
- Po rotaci můžete procházet zachycené signály přímo v CLI: `harness workshop learnings`
|
|
93
|
+
- Filtrujte podle tagu: `harness --json workshop learnings --tag missing_runbook`
|
|
94
|
+
- Filtrujte podle kohorty nebo instance: `--cohort 2026-Q2`, `--instance <id>`
|
|
95
|
+
- V dashboardu: rotační panel v detailu instance obsahuje capture formulář i přehled posledních záznamů
|
|
96
|
+
- Learnings log přežije smazání instance a postupně buduje evidenci pro vylepšení blueprintu
|
|
97
|
+
|
|
90
98
|
## Kam dál po workshopu
|
|
91
99
|
|
|
92
100
|
- Oficiální docs, OpenAI článek o Harness Engineering a ověřené veřejné skill repozitáře najdete v [`docs/learner-reference-gallery.md`](../docs/learner-reference-gallery.md).
|
package/package.json
CHANGED
package/src/run-cli.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { getDefaultDashboardUrl } from "./config.js";
|
|
2
4
|
import { createHarnessClient, HarnessApiError } from "./client.js";
|
|
3
5
|
import { createCliUi, prompt, writeLine } from "./io.js";
|
|
@@ -200,38 +202,87 @@ function resolveCurrentInstanceTarget(session, env) {
|
|
|
200
202
|
};
|
|
201
203
|
}
|
|
202
204
|
|
|
205
|
+
function helpLine(command, description) {
|
|
206
|
+
return description ? `${command.padEnd(48)} ${description}` : ` ${command}`;
|
|
207
|
+
}
|
|
208
|
+
|
|
203
209
|
function printUsage(io, ui) {
|
|
204
210
|
ui.heading("Harness CLI");
|
|
205
|
-
ui.paragraph(`Version ${version}
|
|
211
|
+
ui.paragraph(`Workshop toolkit for teams working with AI coding agents. Version ${version}.`);
|
|
206
212
|
ui.blank();
|
|
213
|
+
|
|
207
214
|
ui.section("Usage");
|
|
215
|
+
ui.commandList(["harness <command> [flags]"]);
|
|
216
|
+
ui.blank();
|
|
217
|
+
|
|
218
|
+
ui.section("Participant");
|
|
219
|
+
ui.commandList([
|
|
220
|
+
helpLine("skill install [--target PATH] [--force]", "Install the workshop skill into your repo"),
|
|
221
|
+
]);
|
|
222
|
+
ui.blank();
|
|
223
|
+
|
|
224
|
+
ui.section("Authentication");
|
|
208
225
|
ui.commandList([
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"harness version",
|
|
226
|
+
helpLine("auth login [--auth device|basic|neon]", "Authenticate as a facilitator"),
|
|
227
|
+
helpLine("auth logout", "End the current session"),
|
|
228
|
+
helpLine("auth status", "Check session status"),
|
|
213
229
|
]);
|
|
214
230
|
ui.blank();
|
|
215
|
-
|
|
231
|
+
|
|
232
|
+
ui.section("Workshop — inspect");
|
|
233
|
+
ui.commandList([
|
|
234
|
+
helpLine("workshop status", "Show current state and selected instance"),
|
|
235
|
+
helpLine("workshop current-instance", "Show the locally selected instance"),
|
|
236
|
+
helpLine("workshop select-instance <id> [--clear]", "Pin an instance for subsequent commands"),
|
|
237
|
+
helpLine("workshop list-instances", "List all facilitator-visible instances"),
|
|
238
|
+
helpLine("workshop show-instance <id>", "Inspect one instance in detail"),
|
|
239
|
+
]);
|
|
240
|
+
ui.blank();
|
|
241
|
+
|
|
242
|
+
ui.section("Workshop — lifecycle");
|
|
243
|
+
ui.commandList([
|
|
244
|
+
helpLine("workshop create-instance [<id>]", "Create a new workshop from a template"),
|
|
245
|
+
helpLine(" [--template-id ID] [--content-lang cs|en]", ""),
|
|
246
|
+
helpLine(" [--event-title TEXT] [--city CITY]", ""),
|
|
247
|
+
helpLine("workshop update-instance <id>", "Update event metadata for an instance"),
|
|
248
|
+
helpLine(" [--content-lang cs|en] [--event-title TEXT]", ""),
|
|
249
|
+
helpLine(" [--city CITY]", ""),
|
|
250
|
+
helpLine("workshop reset-instance <id> [--template-id ID]", "Reset an instance from the blueprint"),
|
|
251
|
+
helpLine("workshop prepare <id>", "Mark an instance as ready for participants"),
|
|
252
|
+
helpLine("workshop remove-instance <id>", "Soft-remove an instance from the list"),
|
|
253
|
+
helpLine("workshop archive [--notes TEXT]", "Snapshot runtime state before reset"),
|
|
254
|
+
]);
|
|
255
|
+
ui.blank();
|
|
256
|
+
|
|
257
|
+
ui.section("Workshop — live facilitation");
|
|
216
258
|
ui.commandList([
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"
|
|
220
|
-
"
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
-
"harness workshop status",
|
|
224
|
-
"harness workshop list-instances",
|
|
225
|
-
"harness workshop show-instance <instance-id>",
|
|
226
|
-
"harness workshop participant-access [<instance-id>] [--rotate] [--code VALUE]",
|
|
227
|
-
"harness workshop archive [--notes TEXT]",
|
|
228
|
-
"harness workshop create-instance [<instance-id>] [--template-id ID] [--content-lang cs|en] [--event-title TEXT] [--city CITY]",
|
|
229
|
-
"harness workshop update-instance <instance-id> [--content-lang cs|en] [--event-title TEXT] [--city CITY]",
|
|
230
|
-
"harness workshop reset-instance <instance-id> [--template-id ID]",
|
|
231
|
-
"harness workshop prepare <instance-id>",
|
|
232
|
-
"harness workshop remove-instance <instance-id>",
|
|
233
|
-
"harness workshop phase set <phase-id>",
|
|
259
|
+
helpLine("workshop phase set <phase-id>", "Advance the agenda to a phase"),
|
|
260
|
+
helpLine("workshop participant-access [<id>]", "Inspect or rotate the event code"),
|
|
261
|
+
helpLine(" [--rotate] [--code VALUE]", ""),
|
|
262
|
+
helpLine("workshop learnings", "Query the cross-cohort learnings log"),
|
|
263
|
+
helpLine(" [--tag TAG] [--instance ID]", ""),
|
|
264
|
+
helpLine(" [--cohort NAME] [--limit N]", ""),
|
|
234
265
|
]);
|
|
266
|
+
ui.blank();
|
|
267
|
+
|
|
268
|
+
ui.section("Global flags");
|
|
269
|
+
ui.commandList([
|
|
270
|
+
helpLine("--json", "Output machine-readable JSON"),
|
|
271
|
+
helpLine("--help", "Show this help"),
|
|
272
|
+
helpLine("--version", "Print version"),
|
|
273
|
+
]);
|
|
274
|
+
ui.blank();
|
|
275
|
+
|
|
276
|
+
ui.section("Examples");
|
|
277
|
+
ui.commandList([
|
|
278
|
+
helpLine("harness skill install", "Install workshop skill here"),
|
|
279
|
+
helpLine("harness auth login", "Start device-code login"),
|
|
280
|
+
helpLine("harness workshop status", "Check what instance you target"),
|
|
281
|
+
helpLine("harness workshop learnings --tag missing_runbook", "Search learnings by tag"),
|
|
282
|
+
]);
|
|
283
|
+
ui.blank();
|
|
284
|
+
|
|
285
|
+
ui.paragraph("Documentation: https://github.com/ondrej-svec/harness-lab");
|
|
235
286
|
}
|
|
236
287
|
|
|
237
288
|
function printVersion(io) {
|
|
@@ -1142,6 +1193,101 @@ async function handleWorkshopPhaseSet(io, ui, env, positionals, deps) {
|
|
|
1142
1193
|
}
|
|
1143
1194
|
}
|
|
1144
1195
|
|
|
1196
|
+
async function handleWorkshopLearningsQuery(io, ui, env, flags) {
|
|
1197
|
+
const dataDir = env.HARNESS_DATA_DIR ?? path.join(process.cwd(), "data");
|
|
1198
|
+
const logPath = env.HARNESS_LEARNINGS_LOG_PATH ?? path.join(dataDir, "learnings-log.jsonl");
|
|
1199
|
+
|
|
1200
|
+
let rawLines;
|
|
1201
|
+
try {
|
|
1202
|
+
const content = await fs.readFile(logPath, "utf8");
|
|
1203
|
+
rawLines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
1204
|
+
} catch (error) {
|
|
1205
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
1206
|
+
ui.json("Workshop Learnings", { ok: true, signals: [], totalMatched: 0, source: logPath });
|
|
1207
|
+
return 0;
|
|
1208
|
+
}
|
|
1209
|
+
ui.status("error", `Could not read learnings log at ${logPath}: ${error instanceof Error ? error.message : String(error)}`, { stream: "stderr" });
|
|
1210
|
+
return 1;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
let entries;
|
|
1214
|
+
try {
|
|
1215
|
+
entries = rawLines.map((line) => JSON.parse(line));
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
ui.status("error", `Learnings log has malformed JSON lines: ${error instanceof Error ? error.message : String(error)}`, { stream: "stderr" });
|
|
1218
|
+
return 1;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
const filterTag = readStringFlag(flags, "tag");
|
|
1222
|
+
const filterInstance = readStringFlag(flags, "instance");
|
|
1223
|
+
const filterCohort = readStringFlag(flags, "cohort");
|
|
1224
|
+
const limit = Number(readStringFlag(flags, "limit") ?? "20");
|
|
1225
|
+
|
|
1226
|
+
let matched = entries;
|
|
1227
|
+
if (filterTag) {
|
|
1228
|
+
matched = matched.filter((entry) =>
|
|
1229
|
+
Array.isArray(entry.signal?.tags) && entry.signal.tags.some((tag) => tag === filterTag),
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1232
|
+
if (filterInstance) {
|
|
1233
|
+
matched = matched.filter((entry) => entry.instanceId === filterInstance);
|
|
1234
|
+
}
|
|
1235
|
+
if (filterCohort) {
|
|
1236
|
+
matched = matched.filter((entry) => entry.cohort === filterCohort);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
const totalMatched = matched.length;
|
|
1240
|
+
const limited = Number.isFinite(limit) && limit > 0 ? matched.slice(-limit) : matched;
|
|
1241
|
+
|
|
1242
|
+
if (ui.jsonMode) {
|
|
1243
|
+
ui.json("Workshop Learnings", {
|
|
1244
|
+
ok: true,
|
|
1245
|
+
totalMatched,
|
|
1246
|
+
returned: limited.length,
|
|
1247
|
+
source: logPath,
|
|
1248
|
+
signals: limited.map((entry) => ({
|
|
1249
|
+
cohort: entry.cohort,
|
|
1250
|
+
instanceId: entry.instanceId,
|
|
1251
|
+
capturedAt: entry.signal?.capturedAt ?? entry.loggedAt,
|
|
1252
|
+
capturedBy: entry.signal?.capturedBy ?? "unknown",
|
|
1253
|
+
teamId: entry.signal?.teamId ?? null,
|
|
1254
|
+
tags: entry.signal?.tags ?? [],
|
|
1255
|
+
freeText: entry.signal?.freeText ?? "",
|
|
1256
|
+
})),
|
|
1257
|
+
});
|
|
1258
|
+
return 0;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
ui.heading("Workshop Learnings");
|
|
1262
|
+
if (limited.length === 0) {
|
|
1263
|
+
ui.paragraph(totalMatched === 0
|
|
1264
|
+
? "No signals captured yet. Use the rotation capture panel in the facilitator dashboard during the continuation shift."
|
|
1265
|
+
: `No signals matched the current filters (${totalMatched} total in log).`,
|
|
1266
|
+
);
|
|
1267
|
+
ui.blank();
|
|
1268
|
+
ui.keyValue("Source", logPath);
|
|
1269
|
+
return 0;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
ui.paragraph(`${totalMatched} signal${totalMatched === 1 ? "" : "s"} matched${totalMatched > limited.length ? ` (showing last ${limited.length})` : ""}`);
|
|
1273
|
+
ui.blank();
|
|
1274
|
+
|
|
1275
|
+
for (const entry of limited) {
|
|
1276
|
+
const signal = entry.signal ?? {};
|
|
1277
|
+
const capturedAt = signal.capturedAt ?? entry.loggedAt ?? "";
|
|
1278
|
+
const time = capturedAt ? new Date(capturedAt).toLocaleString("en-US", { dateStyle: "short", timeStyle: "short" }) : "";
|
|
1279
|
+
const team = signal.teamId ? ` [${signal.teamId}]` : "";
|
|
1280
|
+
const tags = Array.isArray(signal.tags) && signal.tags.length > 0 ? ` {${signal.tags.join(", ")}}` : "";
|
|
1281
|
+
|
|
1282
|
+
ui.section(`${entry.cohort ?? "?"} · ${time}${team}${tags}`);
|
|
1283
|
+
ui.paragraph(signal.freeText ?? "(no observation text)", { indent: " " });
|
|
1284
|
+
ui.blank();
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
ui.keyValue("Source", logPath);
|
|
1288
|
+
return 0;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1145
1291
|
export async function runCli(argv, io, deps = {}) {
|
|
1146
1292
|
const fetchFn = deps.fetchFn ?? globalThis.fetch;
|
|
1147
1293
|
const mergedDeps = { fetchFn, sleepFn: deps.sleepFn, openUrl: deps.openUrl, cwd: deps.cwd };
|
|
@@ -1241,6 +1387,10 @@ export async function runCli(argv, io, deps = {}) {
|
|
|
1241
1387
|
return handleWorkshopPhaseSet(io, ui, io.env, positionals, mergedDeps);
|
|
1242
1388
|
}
|
|
1243
1389
|
|
|
1390
|
+
if (scope === "workshop" && action === "learnings") {
|
|
1391
|
+
return handleWorkshopLearningsQuery(io, ui, io.env, flags);
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1244
1394
|
printUsage(io, ui);
|
|
1245
1395
|
return 1;
|
|
1246
1396
|
}
|