@harness-lab/cli 0.2.6 → 0.2.8

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.
@@ -215,6 +215,18 @@ This is a facilitator-only command — do not surface to participants.
215
215
  Show the current instance state, agenda phase, facilitator list, and team count.
216
216
  Requires active facilitator session.
217
217
 
218
+ ### `workshop facilitator list-instances`
219
+
220
+ List the facilitator-visible workshop instance registry.
221
+ Prefer invoking `harness workshop list-instances` over raw API scripts or local session-file inspection.
222
+ Use this when the facilitator needs to discover what currently exists on a shared dashboard before choosing an explicit instance for reset, update, or agenda work.
223
+
224
+ ### `workshop facilitator show-instance <instance-id>`
225
+
226
+ Inspect one explicit workshop instance.
227
+ Prefer invoking `harness workshop show-instance <instance-id>` over raw API scripts.
228
+ Use this when the facilitator needs the full record for one instance rather than the deployment-default runtime status returned by `workshop facilitator status`.
229
+
218
230
  ### `workshop facilitator grant <email> <role>`
219
231
 
220
232
  Grant a Neon Auth user access to the current workshop instance.
@@ -249,6 +261,16 @@ Prefer invoking `harness workshop update-instance` over raw API scripts.
249
261
  Use this when the facilitator wants to correct or refine date, venue, room, address, or event title without resetting the instance.
250
262
  Support `contentLang` changes explicitly so facilitators can choose workshop delivery language per instance without changing admin UI language.
251
263
 
264
+ Facilitator discovery rule:
265
+ - for routine discovery, use `harness workshop list-instances` and `harness workshop show-instance`
266
+ - do not read local CLI session files or improvise authenticated `node -e` fetch scripts unless you are diagnosing the CLI itself
267
+
268
+ ### `workshop facilitator reset-instance <instance-id>`
269
+
270
+ Reset one existing workshop instance from the selected blueprint template. Requires facilitator session.
271
+ Prefer invoking `harness workshop reset-instance` over raw API scripts.
272
+ Use this when the facilitator wants fresh canonical agenda, runner, and presenter content for a live instance and accepts that local runtime state will be reinitialized.
273
+
252
274
  ### `workshop facilitator remove-instance`
253
275
 
254
276
  Remove a workshop instance from the active list without deleting its archive history. Requires facilitator session.
@@ -267,6 +289,13 @@ Inspect and edit the local agenda copy for one workshop instance. Requires facil
267
289
 
268
290
  Inspect and edit presenter scenes for one workshop instance. This includes listing scenes for an agenda item, creating a new scene, editing content, changing default scene, reordering scenes, and enabling or hiding scenes. Requires facilitator session.
269
291
 
292
+ Rules for rich scenes:
293
+ - keep scenes agenda-linked and room-facing rather than inventing a freeform slide deck
294
+ - prefer one dominant voice per scene and one main idea per scene
295
+ - use reviewed local blueprint assets for reusable visuals instead of ad hoc remote image URLs
296
+ - treat runtime scene edits as instance-local until a maintainer deliberately publishes them back into the repo
297
+ - when richer scene authoring or promotion is involved, follow `docs/presenter-rich-scene-authoring.md`
298
+
270
299
  ### `workshop facilitator archive`
271
300
 
272
301
  Archive the current workshop instance with optional notes.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "manifestVersion": 1,
3
3
  "bundleName": "harness-lab-workshop",
4
- "bundleVersion": "0.2.6",
5
- "contentHash": "9e7a3c6549f06cbe59278c731c73ae8c21f7e38cf82cbc533f1e708ccf47602c",
4
+ "bundleVersion": "0.2.8",
5
+ "contentHash": "6194a59089ff94131b647282c1b5e7574a6a9d112c48b4b9d58b600f5775736a",
6
6
  "files": [
7
7
  {
8
8
  "path": "content/challenge-cards/.gitkeep",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  {
36
36
  "path": "content/facilitation/master-guide.md",
37
- "sha256": "e22f4a811459be1fe23412e7d85c02fe20170e6e6c8534fc97c1616f65b2cfd8"
37
+ "sha256": "f0edc5eef8c7bc0efc67672e184edecce46fa5fd5e9820cfda0b28fbb8cb1a8f"
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": "0d70c455d000ec8bc01337db5feee2174be8359730b5c278cccee9c3e6b0f2f7"
45
+ "sha256": "3e174ff0d097fe132088774042f9db58c9c2494613d66950bdd423116bd7986d"
46
46
  },
47
47
  {
48
48
  "path": "content/project-briefs/devtoolbox-cli.md",
@@ -98,11 +98,11 @@
98
98
  },
99
99
  {
100
100
  "path": "content/talks/context-is-king.md",
101
- "sha256": "c380947051f4a66cdf47e846d5cc5d60ace0487f75dbc718b03fb7164cb94ef1"
101
+ "sha256": "4d0972fefac067de0b8803698b44bdf8ab0bee64b181d50d1ac5e26a92eb7089"
102
102
  },
103
103
  {
104
104
  "path": "docs/harness-cli-foundation.md",
105
- "sha256": "65b0b2cee7be792ad03f9be794230298d3efe8283e8e73acb033ef401d204e51"
105
+ "sha256": "f3b6125a4575c27dcb7b88474003f2a9b189a4b1b25bfaa462861571b69f7a51"
106
106
  },
107
107
  {
108
108
  "path": "docs/learner-reference-gallery.md",
@@ -134,11 +134,11 @@
134
134
  },
135
135
  {
136
136
  "path": "SKILL.md",
137
- "sha256": "107f2ba2574d358ed2ccd1c669a47008574517b811475c866247b0199836ae5b"
137
+ "sha256": "de24b73c431855143630f6d312d9bb2af0a16178c2c70f928c5c3a426e569777"
138
138
  },
139
139
  {
140
140
  "path": "workshop-blueprint/agenda.json",
141
- "sha256": "6b8e1925e20fabccfd3cd9e9d79839855f51b2b7fd449efbb336bf3edd4eadce"
141
+ "sha256": "91b4037578ce61d172e09941089b97180322552cb42bb52de87b3956e60b1ed0"
142
142
  },
143
143
  {
144
144
  "path": "workshop-blueprint/control-surfaces.md",
@@ -146,7 +146,7 @@
146
146
  },
147
147
  {
148
148
  "path": "workshop-blueprint/day-structure.md",
149
- "sha256": "2d2c7a43e959059fe5d3dbb2aae20e6828fee40c700729080677c2c7b6feb0dc"
149
+ "sha256": "ffecae258211cef2430112ca25e1ff59658cac729ea2a07b9cac48e9a2a6244e"
150
150
  },
151
151
  {
152
152
  "path": "workshop-blueprint/edit-boundaries.md",
@@ -158,7 +158,7 @@
158
158
  },
159
159
  {
160
160
  "path": "workshop-blueprint/README.md",
161
- "sha256": "ae809a473bbc88411891044de7609fa053e66e370a8d4063e5d7b9e68179a98c"
161
+ "sha256": "badb477ecfef7df163ec41c72c39e04bcde2a5a723c1b01bf2e91ed38924e903"
162
162
  },
163
163
  {
164
164
  "path": "workshop-blueprint/teaching-spine.md",
@@ -182,7 +182,7 @@
182
182
  },
183
183
  {
184
184
  "path": "workshop-skill/facilitator.md",
185
- "sha256": "22775cb783e825eeec83886932c801db1ff7e3617c170fee848b6071fa63d8a3"
185
+ "sha256": "f0e977df5979d0d218eabad026b66ecefa90802c71dc8a9468959334570f1c1c"
186
186
  },
187
187
  {
188
188
  "path": "workshop-skill/follow-up-package.md",
@@ -4,19 +4,55 @@
4
4
 
5
5
  ### Cíl
6
6
 
7
- Nastavit energii dne a jasně pojmenovat, o čem workshop je.
7
+ Spustit den jako room-facing launch pro celý workshop, ne jako provozní brief k dopoledni.
8
8
 
9
9
  ### Klíčová message
10
10
 
11
- > „Dnes nejde o to být nejrychlejší. Jde o to předat práci tak, aby ji cizí tým dokázal převzít a posunout dál.“
11
+ > „Dnes nejde o to být nejrychlejší. Jde o to postavit práci tak, aby ji cizí tým dokázal převzít a posunout dál.“
12
12
 
13
13
  ### Co potřebuje zaznít
14
14
 
15
- - Nejde o soutěž v promptování.
15
+ - Nezačínáme tool demo ani soutěž v promptování.
16
+ - Budeme se učit, stavět, předávat i přebírat. Ten oblouk dne je záměr workshopu.
16
17
  - Jde o práci s agentem tak, aby po vás zůstával použitelný kontext.
17
18
  - Odpolední část prověří, jestli repo opravdu unese převzetí dalším týmem.
18
19
  - Pokud nějaké důležité pravidlo žije jen v hovoru u stolu, ještě neexistuje.
19
20
 
21
+ ### Doporučený sled beatů
22
+
23
+ 1. day-opening promise
24
+ 2. proč na tom záleží právě teď
25
+ 3. analogie typu Lego duck: stejné ingredience, různé použitelné výsledky
26
+ 4. krátká pohybová aktivace podle zkušenosti s AI agenty
27
+ 5. první pracovní kontrakt pro Build fázi 1
28
+
29
+ ### Lego-duck analogie
30
+
31
+ Použijte ji krátce a věcně.
32
+
33
+ Pointa:
34
+
35
+ - stejný agent neznamená stejný výsledek
36
+ - kvalitu neurčuje samotný model
37
+ - kontext, mantinely a ověřování jsou součást výsledku
38
+
39
+ Nevést jako zábavnou odbočku. Vést jako vysvětlení, proč je harness engineering tvůrčí a inženýrská disciplína zároveň.
40
+
41
+ ### Pohybová aktivace
42
+
43
+ Použijte krátké rozdělení místnosti podle aktuální zkušenosti s AI agenty:
44
+
45
+ - používám skoro denně
46
+ - používám, ale opatrně
47
+ - jsem spíš na startu
48
+ - jsem skeptický, ale chci důkaz
49
+
50
+ Pravidla:
51
+
52
+ - ne dělat z toho networking kolo
53
+ - stačí přesun a 2 krátké hlasy
54
+ - pointa není seniorita, ale kalibrace místnosti a signál, že den je participativní
55
+
20
56
  ### Co má facilitátor průběžně vracet
21
57
 
22
58
  - „Kde by to našel další tým bez vás?“
@@ -24,6 +60,61 @@ Nastavit energii dne a jasně pojmenovat, o čem workshop je.
24
60
  - „Je `AGENTS.md` mapa, nebo už se z něj stává dump?“
25
61
  - „Jaký je další bezpečný krok pro cizího člověka nebo agenta?“
26
62
 
63
+ ### První pracovní kontrakt
64
+
65
+ Po launchi potřebuje místnost ještě jednu konkrétní věc:
66
+
67
+ - co má být po prvním build bloku opravdu vidět
68
+ - co nestačí jen slíbit
69
+
70
+ Do oběda má být vidět:
71
+
72
+ - repo a `README`, které dávají smysl cizímu člověku
73
+ - `AGENTS.md` jako krátká mapa
74
+ - plan nebo jasně vedená implementační stopa
75
+ - první explicitní check před dalším generováním
76
+
77
+ ## Context is King talk
78
+
79
+ ### Cíl
80
+
81
+ Proměnit energii z openingu v přesnou tezi a čistý most do Build fáze 1.
82
+
83
+ ### Klíčová message
84
+
85
+ > „Kontext je páka, ne kosmetika.“
86
+
87
+ ### Co potřebuje zaznít
88
+
89
+ - Neučíme se lépe promptovat. Učíme se postavit repo a workflow, ve kterém agent i cizí tým dokážou bezpečně pokračovat.
90
+ - `AGENTS.md`, skills, runbooky a checks jsou týmová infrastruktura, ne polish navíc.
91
+ - Team lead nestojí modelu za zády a nediktuje další větu každých třicet sekund.
92
+ - Po talku se tým vrací k repu s mapou, planem a prvním checkem, ne s lovem na chytřejší prompt.
93
+
94
+ ### Mikro-cvičení
95
+
96
+ Použijte stejný malý task ve dvou podmínkách:
97
+
98
+ 1. prompt blob
99
+ 2. krátké zadání s `Goal`, `Context`, `Constraints`, `Done When`
100
+
101
+ Nenechte to sklouznout do debaty o tom, který model je chytřejší.
102
+
103
+ Pointa:
104
+
105
+ - přenos záměru
106
+ - přenos mantinelů
107
+ - přenos done criteria
108
+
109
+ ### Most do Build fáze 1
110
+
111
+ Na konci talku má být jasné:
112
+
113
+ - teorie tím končí
114
+ - tým se vrací k repu
115
+ - nejdřív vzniká mapa a první explicitní check
116
+ - teprve potom dává smysl další feature motion
117
+
27
118
  ## Build fáze 1
28
119
 
29
120
  ### Viditelný milestone board
@@ -2,30 +2,30 @@
2
2
 
3
3
  ## Problém
4
4
 
5
- Code review bývá nevyrovnané. Některé změny projdou s dobrým checklistem a jasným popisem rizik, jiné bez společného rámce. Reviewer pak improvizuje, autor neví, co má ověřit předem, a tým ztrácí konzistenci.
5
+ Code review bývá nevyrovnané. Některé změny projdou s dobrým checklistem a jasným popisem rizik, jiné bez společného rámce. Reviewer pak improvizuje, autor neví, co má ověřit předem, a tým ztrácí konzistenci právě tam, kde by měl být nejpřesnější.
6
6
 
7
- Vaším úkolem je navrhnout nástroj, který z diffu nebo změny vytvoří použitelný review checklist.
7
+ Vaším úkolem je navrhnout nástroj, který z diffu nebo změny vytvoří použitelný review checklist a zároveň jasně oddělí jistotu, heuristiku a místa, kde je pořád potřeba lidský úsudek.
8
8
 
9
9
  ## User stories
10
10
 
11
- - Jako reviewer chci z diffu rychle získat checklist rizik, otázek a míst, na která se zaměřit.
12
- - Jako autor změny chci vědět, co mám zkontrolovat ještě před samotným review.
11
+ - Jako reviewer chci z diffu rychle získat checklist změněných hranic, rizik, otázek a míst, na která se zaměřit.
12
+ - Jako autor změny chci vědět, co mám ověřit ještě před samotným review.
13
13
  - Jako tým po rotaci chci navázat na heuristiky, které původní tým objevil, místo abych je znovu vymýšlel.
14
14
 
15
15
  ## Architektonické poznámky
16
16
 
17
- - Může jít o CLI, web nebo jednoduchý skript. Důležitý je jasný tok `diff → analýza → checklist`.
18
- - Musí být zřejmé, jaké vstupy nástroj očekává a co naopak neumí spolehlivě vyhodnotit.
19
- - Přidejte seed diff nebo `examples/`, aby šlo workflow lokálně ověřit.
20
- - Jasně oddělte heuristiku od jistoty. Nástroj má pomáhat reviewerovi, ne předstírat neomylnost.
17
+ - Může jít o CLI, web nebo jednoduchý skript. Důležitý je jasný tok `diff → rubric → checklist`.
18
+ - Musí být zřejmé, jaké vstupy nástroj očekává, co umí označit jistě a co naopak zůstává heuristické.
19
+ - Přidejte seed diff nebo `examples/`, aby šlo workflow lokálně ověřit a další tým rychle přidal nové pravidlo.
20
+ - Nástroj má pomáhat reviewerovi, ne předstírat neomylnost.
21
21
 
22
22
  ## Hotovo když
23
23
 
24
24
  - Nástroj vytvoří review checklist ze seed diffu.
25
- - Výstup odlišuje jistá zjištění od doporučení nebo hypotéz.
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
27
  - Další tým může během několika minut pokračovat v rozvoji bez chaosu.
28
28
 
29
29
  ## První krok pro agenta
30
30
 
31
- Nezačínej kódem. Nejdřív napiš pravidla review, tok vstupů a definici toho, co znamená dobrý checklist. Teprve potom navrhni první implementační slice.
31
+ Nezačínej kódem. Nejdřív napiš review rubric, tok vstupů a definici toho, co znamená dobrý checklist. Ukaž, kde je jistota, kde heuristika a co musí posoudit člověk. Teprve potom navrhni první implementační slice.
@@ -1,8 +1,14 @@
1
1
  # Context is King
2
2
 
3
- ## Otevírací moment
3
+ ## Otevírací modul
4
4
 
5
- Tento workshop skill i dashboard vznikly stejným způsobem, jakým dnes budeme pracovat my: s AI agentem, ale s důrazem na kontext. Nejde mi o prodej nástroje. Jde mi o to ukázat disciplínu, která z nástroje dělá použitelného spolupracovníka.
5
+ Tenhle workshop skill i dashboard vznikly stejným způsobem, jakým dnes budeme pracovat my: s AI agentem, ale s důrazem na kontext. Nejde mi o prodej nástroje. Jde mi o to ukázat disciplínu, která z nástroje dělá použitelného spolupracovníka.
6
+
7
+ Rámec pro room launch:
8
+
9
+ - dnes nezačínáme tool demo ani soutěž v promptování
10
+ - budeme se učit, stavět, předávat i přebírat
11
+ - odpoledne se ukáže, co z práce přežije bez nás
6
12
 
7
13
  ## Klíčová linka
8
14
 
@@ -12,9 +18,26 @@ Moje hlavní věta pro dnešek:
12
18
 
13
19
  > Neučíme se "lépe promptovat". Učíme se postavit repo a workflow, ve kterém agent i cizí tým dokážou bezpečně pokračovat.
14
20
 
21
+ ## Analogický beat
22
+
23
+ Když dáte lidem stejné kostky, nevznikne jedna správná kachna. Stejně tak ze stejného modelu nevzniká jedna správná práce. Rozdíl nedělá jen model. Rozdíl dělá kontext, mantinely, ověřování a představivost týmu.
24
+
25
+ Pointa analogie:
26
+
27
+ - stejný agent neznamená stejný výsledek
28
+ - kvalitu neurčuje samotný model
29
+ - pracovní systém kolem agenta je součást výsledku
30
+
15
31
  ## Mikro-cvičení
16
32
 
17
- Všichni dostanou stejný malý úkol. Jedna varianta bude prompt blob. Druhá varianta bude krátké zadání se 4 prvky a s odkazem na kontext zapsaný v repu. Pak porovnáme výsledky. Nehledáme „nejhezčí prompt“. Hledáme způsob práce, který přenese záměr, omezení a kritéria hotovo i do dalšího kroku.
33
+ Všichni dostanou stejný malý task. Jedna varianta bude prompt blob. Druhá varianta bude krátké zadání se 4 prvky a s odkazem na kontext zapsaný v repu. Pak porovnáme výsledky. Nehledáme „nejhezčí prompt“. Hledáme způsob práce, který přenese záměr, omezení a done criteria i do dalšího kroku.
34
+
35
+ 4 prvky pro druhou variantu:
36
+
37
+ - Goal
38
+ - Context
39
+ - Constraints
40
+ - Done When
18
41
 
19
42
  ## Hlavní teze
20
43
 
@@ -37,6 +60,15 @@ Všichni dostanou stejný malý úkol. Jedna varianta bude prompt blob. Druhá v
37
60
  - Když agent dělá víc, já musím lépe ověřovat.
38
61
  - Handoff není závěr dne. Je to průběžná podmínka celé práce.
39
62
 
63
+ ## Most do Build fáze 1
64
+
65
+ 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:
66
+
67
+ - nejdřív krátká mapa v repu
68
+ - potom plan
69
+ - potom první explicitní check
70
+ - teprve potom další feature motion
71
+
40
72
  ## Závěr
41
73
 
42
74
  Odpoledne nezažijete jen to, že „AI někdy funguje a někdy ne“. Zažijete, jak moc výsledek závisí na kvalitě pracovního systému, který kolem agenta postavíte.
@@ -8,7 +8,7 @@ Current implementation in this repo:
8
8
 
9
9
  - lives in the repository `harness-cli/` package and ships publicly as `@harness-lab/cli`
10
10
  - distributes a portable participant workshop skill bundle through `harness skill install`
11
- - covers `auth login/logout/status` plus `workshop status/create-instance/update-instance/prepare/remove-instance/archive/phase set`
11
+ - covers `auth login/logout/status` plus `workshop status/list-instances/show-instance/create-instance/update-instance/reset-instance/prepare/remove-instance/archive/phase set`
12
12
  - targets the existing shared dashboard facilitator APIs
13
13
  - is tested for browser/device auth, local-dev Basic Auth fallback, and cookie-backed Neon bootstrap fallback
14
14
  - stores sessions in a local file under `HARNESS_CLI_HOME` or `~/.harness` by default
@@ -39,8 +39,11 @@ Required commands:
39
39
  - `harness auth logout`
40
40
  - `harness auth status`
41
41
  - `harness workshop status`
42
+ - `harness workshop list-instances`
43
+ - `harness workshop show-instance <instance-id>`
42
44
  - `harness workshop create-instance`
43
45
  - `harness workshop update-instance`
46
+ - `harness workshop reset-instance <instance-id>`
44
47
  - `harness workshop archive`
45
48
  - `harness workshop prepare`
46
49
  - `harness workshop remove-instance`
@@ -88,8 +91,13 @@ Current target-selection order:
88
91
 
89
92
  Current command posture:
90
93
 
94
+ - explicit workspace-discovery commands:
95
+ - `harness workshop list-instances`
96
+ - explicit target required:
97
+ - `harness workshop show-instance <instance-id>`
91
98
  - explicit target required:
92
99
  - `harness workshop update-instance <instance-id>`
100
+ - `harness workshop reset-instance <instance-id>`
93
101
  - `harness workshop prepare <instance-id>`
94
102
  - `harness workshop remove-instance <instance-id>`
95
103
  - explicit target is the created resource:
@@ -103,6 +111,7 @@ Current discoverability path:
103
111
 
104
112
  - facilitators can inspect available workshop instances through the dashboard workspace view
105
113
  - the same platform-scoped list lives behind the authenticated instances API surface at `/api/workshop/instances`
114
+ - the CLI should expose that list directly so facilitator skills do not need session-file inspection or raw authenticated scripts for routine discovery
106
115
 
107
116
  For the current facilitator lifecycle slice:
108
117
 
@@ -115,6 +124,11 @@ Current step-up posture:
115
124
  - the existing CLI command set (`workshop status/archive/phase set`) may run on a valid brokered device session
116
125
  - future higher-risk commands such as facilitator grant/revoke or destructive instance mutations should require a fresh browser approval window rather than silently reusing an older CLI session
117
126
 
127
+ Content refresh posture:
128
+
129
+ - after changing authored participant-facing sources in `workshop-skill/`, `content/`, or `workshop-blueprint/`, refresh the portable bundle and verify it before shipping facilitator or participant guidance
130
+ - when those changes must land in already-created workshop instances, `workshop reset-instance` is the intended re-import path
131
+
118
132
  ## Session Storage Posture
119
133
 
120
134
  Default storage backend:
@@ -39,7 +39,7 @@ Do not use this folder for live event state. Real dates, rooms, rosters, checkpo
39
39
  ### Structured data
40
40
 
41
41
  - [`agenda.json`](agenda.json)
42
- Public-readable workshop agenda summary and workshop metadata.
42
+ Public-readable 10-phase mirror of the workshop day and workshop metadata.
43
43
 
44
44
  ## Related Runtime Documents
45
45
 
@@ -51,5 +51,6 @@ For maintainers working in the source repository, the runtime-facing structured
51
51
 
52
52
  - `docs/workshop-content-language-architecture.md`
53
53
  - `dashboard/lib/workshop-blueprint-agenda.json`
54
+ - `dashboard/lib/workshop-blueprint-localized-content.ts`
54
55
 
55
- Treat those as maintainer/source-repo references, not as portable participant-bundle docs.
56
+ Treat those as maintainer/source-repo references, not as portable participant-bundle docs. The public `agenda.json` file should stay aligned with the same phase structure, but it is not the runtime import source.
@@ -1,21 +1,23 @@
1
1
  {
2
- "version": 1,
2
+ "version": 2,
3
3
  "blueprintId": "harness-lab-core-day",
4
4
  "title": "Harness Lab",
5
- "subtitle": "Workshop operating system pro práci s AI agenty",
5
+ "subtitle": "Public-readable 10-phase mirror of the Harness Lab workshop day",
6
+ "presentationMode": "public-readable-mirror",
7
+ "sourceNote": "Runtime imports come from dashboard/lib/workshop-blueprint-agenda.json plus dashboard/lib/workshop-blueprint-localized-content.ts.",
6
8
  "principles": [
7
- "Mapa před pohybem",
8
- "Ověření je hranice důvěry",
9
- "Pište tak, aby další tým mohl pokračovat"
9
+ "Context before generation",
10
+ "Verification is the trust boundary",
11
+ "Work so another team can continue"
10
12
  ],
11
13
  "phases": [
12
14
  {
13
15
  "id": "opening",
14
16
  "order": 1,
15
- "label": "Úvod a naladění",
17
+ "label": "Opening and framing",
16
18
  "startTime": "09:10",
17
19
  "kind": "shared",
18
- "goal": "Rámec dne: nejde o promptování, ale o repo a workflow, které přežijí handoff."
20
+ "goal": "Shift the room from prompt-hackathon expectations to continuation-quality discipline."
19
21
  },
20
22
  {
21
23
  "id": "talk",
@@ -23,31 +25,71 @@
23
25
  "label": "Context is King",
24
26
  "startTime": "09:40",
25
27
  "kind": "shared",
26
- "goal": "Krátký talk a porovnání přístupů. Krátká mapa v repu je silnější než prompt blob."
28
+ "goal": "Turn context into a precise thesis: AGENTS.md, plans, and checks are working infrastructure, not polish."
27
29
  },
28
30
  {
29
- "id": "build-1",
31
+ "id": "demo",
30
32
  "order": 3,
33
+ "label": "Demo",
34
+ "startTime": "10:05",
35
+ "kind": "shared",
36
+ "goal": "Show one compact workflow story: context, planning, implementation, review, and safe fallback moves."
37
+ },
38
+ {
39
+ "id": "build-1",
40
+ "order": 4,
31
41
  "label": "Build Phase 1",
32
42
  "startTime": "10:30",
33
43
  "kind": "team",
34
- "goal": "Nejdřív udělejte z repa operating surface: krátké AGENTS.md, plán, build/test flow, první ověření a první reviewed output."
44
+ "goal": "Before lunch, get every team to a navigable repo, AGENTS.md, a plan, one explicit check, and a first reviewed slice."
45
+ },
46
+ {
47
+ "id": "intermezzo-1",
48
+ "order": 5,
49
+ "label": "Intermezzo 1",
50
+ "startTime": "11:40",
51
+ "kind": "shared",
52
+ "goal": "Surface one change, one proof, and one next move from the room before lunch momentum slips."
53
+ },
54
+ {
55
+ "id": "lunch-reset",
56
+ "order": 6,
57
+ "label": "Lunch Reset",
58
+ "startTime": "12:15",
59
+ "kind": "shared",
60
+ "goal": "Frame lunch as a handoff preparation point, not as a pause between unrelated workshop blocks."
35
61
  },
36
62
  {
37
63
  "id": "rotation",
38
- "order": 4,
39
- "label": "Rotace týmů",
64
+ "order": 7,
65
+ "label": "Continuation Shift",
40
66
  "startTime": "13:30",
41
67
  "kind": "team",
42
- "goal": "Plný přesun lidí mezi stoly. Nejdřív čtěte a napište diagnózu, pak měňte kód."
68
+ "goal": "Force silent repo reading, diagnosis, and explicit continuation before anyone edits code."
69
+ },
70
+ {
71
+ "id": "build-2",
72
+ "order": 8,
73
+ "label": "Build Phase 2",
74
+ "startTime": "14:05",
75
+ "kind": "team",
76
+ "goal": "Turn continuation friction into better repo guidance, stronger checks, and clearer next moves."
77
+ },
78
+ {
79
+ "id": "intermezzo-2",
80
+ "order": 9,
81
+ "label": "Intermezzo 2",
82
+ "startTime": "15:05",
83
+ "kind": "shared",
84
+ "goal": "Name which repo signals actually saved time during continuation and which failures repeated."
43
85
  },
44
86
  {
45
87
  "id": "reveal",
46
- "order": 5,
47
- "label": "Reveal a reflexe",
88
+ "order": 10,
89
+ "label": "Reveal and reflection",
48
90
  "startTime": "15:45",
49
91
  "kind": "shared",
50
- "goal": "Co pomohlo pokračovat, co chybělo, a kterou bolest teď proměníme v lepší harness."
92
+ "goal": "Turn the day into reusable practice: what helped continuation, what failed, and what should change next week."
51
93
  }
52
94
  ],
53
95
  "runtimeImport": {
@@ -103,6 +103,31 @@ Habit installed:
103
103
  - cleanup and codification are part of delivery
104
104
  - repeated pain should become a better template, check, or runbook
105
105
 
106
+ ## Narrative Spine
107
+
108
+ The day should not feel like separate agenda cards. Each phase should change what the room now understands and what it is ready to do next.
109
+
110
+ - `opening`:
111
+ Shift the room from "AI hackathon energy" to "continuation-quality discipline." The key belief is that handoff without verbal rescue is part of the assignment from the first hour.
112
+ - `talk`:
113
+ Shift the room from a vague sense that context matters to a precise thesis: harness engineering is team infrastructure, not prompt cosmetics.
114
+ - `demo`:
115
+ Shift the room from abstract agreement to an observable workflow. The room should see context, plan, implementation, and review as one repeatable system.
116
+ - `build-1`:
117
+ Shift teams from listening to evidence. Before lunch, the repo needs to show map, plan, one executable check, and one verified step.
118
+ - `intermezzo-1`:
119
+ Shift from isolated table work to shared learning. The room should hear concrete repo signals, not generic progress reporting.
120
+ - `lunch-reset`:
121
+ Shift from local progress to handoff readiness. Going to lunch without a readable next safe step should feel unfinished.
122
+ - `rotation`:
123
+ Shift from authorship to inheritance. The receiving team must read first, diagnose second, and edit only after it can explain the state.
124
+ - `build-2`:
125
+ Shift from frustration to codification. Weak continuation signals should turn into clearer repo guidance, stronger checks, and better runbooks.
126
+ - `intermezzo-2`:
127
+ Shift from anecdotes about the afternoon to concrete continuation evidence. The room should identify which repo signals actually saved time.
128
+ - `reveal`:
129
+ Shift from reflection to adoption. The close should turn signals from the day into next-week practice and into improvements to the reusable workshop blueprint.
130
+
106
131
  ## What Must Survive In The Repo
107
132
 
108
133
  - goal and constraints
@@ -122,8 +147,8 @@ Habit installed:
122
147
  - `AGENTS.md` as a table of contents that points to deeper sources of truth
123
148
  - small, continuous garbage collection before bad patterns spread
124
149
 
125
- ## Canonical Agenda Source
150
+ ## Agenda Mirror
126
151
 
127
- The reusable agenda lives in [`agenda.json`](agenda.json).
152
+ The public-readable 10-phase mirror lives in [`agenda.json`](agenda.json).
128
153
 
129
- Runtime workshop instances import from that blueprint and then track live phase position, reveal state, teams, and checkpoints locally in the private runtime layer.
154
+ Runtime workshop instances import from the maintained dashboard blueprint source pair and then track live phase position, reveal state, teams, and checkpoints locally in the private runtime layer.
@@ -65,6 +65,59 @@ Show:
65
65
  - facilitator list with roles
66
66
  - team count
67
67
 
68
+ Use this for the current default or selected workshop context.
69
+ If the facilitator needs the full workspace registry first, use `list-instances` instead of probing local session files or writing raw authenticated fetch scripts.
70
+
71
+ ### `/workshop facilitator list-instances`
72
+
73
+ Preferred path:
74
+
75
+ ```bash
76
+ harness workshop list-instances
77
+ ```
78
+
79
+ Show:
80
+ - facilitator-visible instance ids
81
+ - template id
82
+ - status
83
+ - content language
84
+ - event title and room metadata when present
85
+
86
+ Raw API reference:
87
+
88
+ ```http
89
+ GET {DASHBOARD_URL}/api/workshop/instances
90
+ ```
91
+
92
+ Rules:
93
+ - prefer this over inspecting local session files or composing one-off authenticated scripts
94
+ - use it when the facilitator needs to discover which live instances exist before reset, update, or scene work
95
+ - keep raw API usage as a diagnostic fallback, not the default operator workflow
96
+
97
+ ### `/workshop facilitator show-instance <instance-id>`
98
+
99
+ Preferred path:
100
+
101
+ ```bash
102
+ harness workshop show-instance sample-workshop-demo-orbit
103
+ ```
104
+
105
+ Show:
106
+ - one explicit instance record
107
+ - summary metadata for quick operator inspection
108
+ - the full instance payload when the facilitator needs exact values before a mutation
109
+
110
+ Raw API reference:
111
+
112
+ ```http
113
+ GET {DASHBOARD_URL}/api/workshop/instances/{instanceId}
114
+ ```
115
+
116
+ Rules:
117
+ - use this when the facilitator needs one specific instance, not the deployment-default `workshop status`
118
+ - if the route returns `404`, the instance does not exist or is not visible to the facilitator
119
+ - prefer this over ad hoc authenticated scripts for routine discovery
120
+
68
121
  ### `/workshop facilitator grant <email> <role>`
69
122
 
70
123
  Use the CLI-backed privileged request path. The skill should not handle auth bootstrap itself.
@@ -176,6 +229,33 @@ Rules:
176
229
  - send only the fields you want to change
177
230
  - do not use reset for an ordinary title, venue, or room correction
178
231
  - if the route returns `400`, the payload is wrong; if it returns `404`, the instance does not exist
232
+ - use `--content-lang cs|en` when the facilitator intends to change the workshop delivery language for that instance
233
+
234
+ ### `/workshop facilitator reset-instance <instance-id>`
235
+
236
+ Preferred path:
237
+
238
+ ```bash
239
+ harness workshop reset-instance sample-workshop-demo-orbit --template-id blueprint-default
240
+ ```
241
+
242
+ Raw API reference:
243
+
244
+ ```http
245
+ PATCH {DASHBOARD_URL}/api/workshop/instances/{instanceId}
246
+ Content-Type: application/json
247
+
248
+ {
249
+ "action": "reset",
250
+ "templateId": "blueprint-default"
251
+ }
252
+ ```
253
+
254
+ Rules:
255
+ - use this when the goal is to re-import fresh blueprint-owned workshop content into an existing instance
256
+ - warn that reset archives current runtime state first and then clears live runtime state for the instance
257
+ - prefer `update-instance` for ordinary metadata corrections; reset is the high-impact operation
258
+ - if the facilitator does not specify a template, keep the current template unless there is a clear reason to switch
179
259
 
180
260
  ### `/workshop facilitator prepare`
181
261
 
@@ -291,6 +371,14 @@ Presenter scenes are agenda-linked, room-facing outputs for the facilitator and
291
371
  - delete a local scene
292
372
  - read and optionally edit `facilitatorNotes`, `sourceRefs`, and `blocks`
293
373
 
374
+ Rich-scene rules:
375
+
376
+ - keep presenter scenes agenda-linked; do not invent a separate slide-deck source of truth
377
+ - prefer one dominant voice and one main idea per scene
378
+ - for reusable visuals, prefer reviewed local blueprint assets and metadata over ad hoc remote image URLs
379
+ - runtime edits remain instance-local until a maintainer deliberately publishes them back into the repo
380
+ - when working in the source repo, use the maintainer playbook in `docs/presenter-rich-scene-authoring.md` for drafting, refinement, and publish-back
381
+
294
382
  Per-instance route:
295
383
 
296
384
  ```http
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-lab/cli",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Participant-facing Harness Lab CLI for facilitator auth and workshop operations",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/client.js CHANGED
@@ -90,6 +90,12 @@ export function createHarnessClient({ fetchFn, session }) {
90
90
  getWorkshopStatus() {
91
91
  return request("/api/workshop");
92
92
  },
93
+ listWorkshopInstances() {
94
+ return request("/api/workshop/instances");
95
+ },
96
+ getWorkshopInstance(instanceId) {
97
+ return request(`/api/workshop/instances/${encodeURIComponent(instanceId)}`);
98
+ },
93
99
  getAgenda() {
94
100
  return request("/api/agenda");
95
101
  },
@@ -108,6 +114,15 @@ export function createHarnessClient({ fetchFn, session }) {
108
114
  body: { action: "update_metadata", ...input },
109
115
  });
110
116
  },
117
+ resetWorkshopInstance(instanceId, templateId) {
118
+ return request(`/api/workshop/instances/${encodeURIComponent(instanceId)}`, {
119
+ method: "PATCH",
120
+ body: {
121
+ action: "reset",
122
+ ...(templateId ? { templateId } : {}),
123
+ },
124
+ });
125
+ },
111
126
  prepareWorkshopInstance(instanceId) {
112
127
  return request("/api/workshop", {
113
128
  method: "POST",
package/src/run-cli.js CHANGED
@@ -103,6 +103,7 @@ async function readRequiredCommandValue(io, flags, keys, promptLabel, fallbackVa
103
103
 
104
104
  function buildWorkshopMetadataInput(flags) {
105
105
  const input = {
106
+ contentLang: readStringFlag(flags, "content-lang", "content-language"),
106
107
  eventTitle: readStringFlag(flags, "event-title", "title"),
107
108
  city: readStringFlag(flags, "city"),
108
109
  dateRange: readStringFlag(flags, "date-range", "date"),
@@ -122,6 +123,7 @@ function hasWorkshopMetadataInput(input) {
122
123
 
123
124
  async function promptWorkshopMetadataInput(io) {
124
125
  const prompts = [
126
+ ["contentLang", "Content language (cs/en, leave blank to skip): "],
125
127
  ["eventTitle", "Event title (leave blank to skip): "],
126
128
  ["city", "City (leave blank to skip): "],
127
129
  ["dateRange", "Date range (leave blank to skip): "],
@@ -148,7 +150,9 @@ function summarizeWorkshopInstance(instance) {
148
150
 
149
151
  return {
150
152
  instanceId: instance?.id ?? null,
153
+ templateId: instance?.templateId ?? null,
151
154
  status: instance?.status ?? null,
155
+ contentLang: workshopMeta.contentLang ?? null,
152
156
  eventTitle: workshopMeta.eventTitle ?? null,
153
157
  city: workshopMeta.city ?? null,
154
158
  dateRange: workshopMeta.dateRange ?? null,
@@ -175,9 +179,12 @@ function printUsage(io, ui) {
175
179
  "harness auth status",
176
180
  "harness skill install [--target PATH] [--force]",
177
181
  "harness workshop status",
182
+ "harness workshop list-instances",
183
+ "harness workshop show-instance <instance-id>",
178
184
  "harness workshop archive [--notes TEXT]",
179
- "harness workshop create-instance [<instance-id>] [--template-id ID] [--event-title TEXT] [--city CITY]",
180
- "harness workshop update-instance <instance-id> [--event-title TEXT] [--city CITY]",
185
+ "harness workshop create-instance [<instance-id>] [--template-id ID] [--content-lang cs|en] [--event-title TEXT] [--city CITY]",
186
+ "harness workshop update-instance <instance-id> [--content-lang cs|en] [--event-title TEXT] [--city CITY]",
187
+ "harness workshop reset-instance <instance-id> [--template-id ID]",
181
188
  "harness workshop prepare <instance-id>",
182
189
  "harness workshop remove-instance <instance-id>",
183
190
  "harness workshop phase set <phase-id>",
@@ -582,6 +589,67 @@ async function handleWorkshopStatus(io, ui, env, deps) {
582
589
  }
583
590
  }
584
591
 
592
+ async function handleWorkshopListInstances(io, ui, env, deps) {
593
+ const session = await requireSession(io, ui, env);
594
+ if (!session) {
595
+ return 1;
596
+ }
597
+
598
+ try {
599
+ const client = createHarnessClient({ fetchFn: deps.fetchFn, session });
600
+ const result = await client.listWorkshopInstances();
601
+ const items = Array.isArray(result?.items) ? result.items.map((instance) => summarizeWorkshopInstance(instance)) : [];
602
+ ui.json("Workshop Instances", {
603
+ ok: true,
604
+ count: items.length,
605
+ items,
606
+ });
607
+ return 0;
608
+ } catch (error) {
609
+ if (error instanceof HarnessApiError) {
610
+ ui.status("error", `List instances failed: ${error.message}`, { stream: "stderr" });
611
+ return 1;
612
+ }
613
+ throw error;
614
+ }
615
+ }
616
+
617
+ async function handleWorkshopShowInstance(io, ui, env, positionals, flags, deps) {
618
+ const session = await requireSession(io, ui, env);
619
+ if (!session) {
620
+ return 1;
621
+ }
622
+
623
+ const instanceId = await readRequiredCommandValue(
624
+ io,
625
+ flags,
626
+ ["id", "instance-id"],
627
+ "Instance id: ",
628
+ readOptionalPositional(positionals, 2),
629
+ );
630
+ if (!instanceId) {
631
+ ui.status("error", "Instance id is required.", { stream: "stderr" });
632
+ return 1;
633
+ }
634
+
635
+ try {
636
+ const client = createHarnessClient({ fetchFn: deps.fetchFn, session });
637
+ const result = await client.getWorkshopInstance(instanceId);
638
+ ui.json("Workshop Instance", {
639
+ ok: true,
640
+ ...summarizeWorkshopInstance(result.instance),
641
+ instance: result.instance,
642
+ });
643
+ return 0;
644
+ } catch (error) {
645
+ if (error instanceof HarnessApiError) {
646
+ ui.status("error", `Show instance failed: ${error.message}`, { stream: "stderr" });
647
+ return 1;
648
+ }
649
+ throw error;
650
+ }
651
+ }
652
+
585
653
  async function handleWorkshopArchive(io, ui, env, flags, deps) {
586
654
  const session = await requireSession(io, ui, env);
587
655
  if (!session) {
@@ -731,6 +799,41 @@ async function handleWorkshopPrepare(io, ui, env, positionals, flags, deps) {
731
799
  }
732
800
  }
733
801
 
802
+ async function handleWorkshopResetInstance(io, ui, env, positionals, flags, deps) {
803
+ const session = await requireSession(io, ui, env);
804
+ if (!session) {
805
+ return 1;
806
+ }
807
+
808
+ const instanceId = await readRequiredCommandValue(
809
+ io,
810
+ flags,
811
+ ["id", "instance-id"],
812
+ "Instance id: ",
813
+ readOptionalPositional(positionals, 2),
814
+ );
815
+ if (!instanceId) {
816
+ ui.status("error", "Instance id is required.", { stream: "stderr" });
817
+ return 1;
818
+ }
819
+
820
+ try {
821
+ const client = createHarnessClient({ fetchFn: deps.fetchFn, session });
822
+ const result = await client.resetWorkshopInstance(
823
+ instanceId,
824
+ readStringFlag(flags, "template-id", "template"),
825
+ );
826
+ ui.json("Workshop Reset Instance", result);
827
+ return 0;
828
+ } catch (error) {
829
+ if (error instanceof HarnessApiError) {
830
+ ui.status("error", `Reset instance failed: ${error.message}`, { stream: "stderr" });
831
+ return 1;
832
+ }
833
+ throw error;
834
+ }
835
+ }
836
+
734
837
  async function handleWorkshopRemoveInstance(io, ui, env, positionals, flags, deps) {
735
838
  const session = await requireSession(io, ui, env);
736
839
  if (!session) {
@@ -844,6 +947,14 @@ export async function runCli(argv, io, deps = {}) {
844
947
  return handleWorkshopStatus(io, ui, io.env, mergedDeps);
845
948
  }
846
949
 
950
+ if (scope === "workshop" && action === "list-instances") {
951
+ return handleWorkshopListInstances(io, ui, io.env, mergedDeps);
952
+ }
953
+
954
+ if (scope === "workshop" && action === "show-instance") {
955
+ return handleWorkshopShowInstance(io, ui, io.env, positionals, flags, mergedDeps);
956
+ }
957
+
847
958
  if (scope === "workshop" && action === "archive") {
848
959
  return handleWorkshopArchive(io, ui, io.env, flags, mergedDeps);
849
960
  }
@@ -856,6 +967,10 @@ export async function runCli(argv, io, deps = {}) {
856
967
  return handleWorkshopUpdateInstance(io, ui, io.env, positionals, flags, mergedDeps);
857
968
  }
858
969
 
970
+ if (scope === "workshop" && action === "reset-instance") {
971
+ return handleWorkshopResetInstance(io, ui, io.env, positionals, flags, mergedDeps);
972
+ }
973
+
859
974
  if (scope === "workshop" && action === "prepare") {
860
975
  return handleWorkshopPrepare(io, ui, io.env, positionals, flags, mergedDeps);
861
976
  }