@deskwork/studio 0.45.2 → 0.47.0

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.
Files changed (39) hide show
  1. package/dist/lib/entry-resolver.d.ts +12 -11
  2. package/dist/lib/entry-resolver.d.ts.map +1 -1
  3. package/dist/lib/entry-resolver.js +19 -30
  4. package/dist/lib/entry-resolver.js.map +1 -1
  5. package/dist/pages/dashboard/lane-data.d.ts.map +1 -1
  6. package/dist/pages/dashboard/lane-data.js +17 -8
  7. package/dist/pages/dashboard/lane-data.js.map +1 -1
  8. package/dist/pages/dashboard/lane-data.ts +17 -8
  9. package/dist/pages/entry-review/data.d.ts.map +1 -1
  10. package/dist/pages/entry-review/data.js +44 -3
  11. package/dist/pages/entry-review/data.js.map +1 -1
  12. package/dist/pages/help.d.ts.map +1 -1
  13. package/dist/pages/help.js +24 -3
  14. package/dist/pages/help.js.map +1 -1
  15. package/dist/pages/help.ts +23 -3
  16. package/dist/pages/lanes/data.d.ts +10 -1
  17. package/dist/pages/lanes/data.d.ts.map +1 -1
  18. package/dist/pages/lanes/data.js +19 -1
  19. package/dist/pages/lanes/data.js.map +1 -1
  20. package/dist/pages/lanes/data.ts +31 -2
  21. package/dist/pages/lanes/edit-form.d.ts +10 -5
  22. package/dist/pages/lanes/edit-form.d.ts.map +1 -1
  23. package/dist/pages/lanes/edit-form.js +30 -11
  24. package/dist/pages/lanes/edit-form.js.map +1 -1
  25. package/dist/pages/lanes/edit-form.ts +30 -11
  26. package/dist/pages/lanes/new-form.d.ts +10 -7
  27. package/dist/pages/lanes/new-form.d.ts.map +1 -1
  28. package/dist/pages/lanes/new-form.js +29 -14
  29. package/dist/pages/lanes/new-form.js.map +1 -1
  30. package/dist/pages/lanes/new-form.ts +29 -14
  31. package/dist/pages/lanes/table.d.ts +4 -2
  32. package/dist/pages/lanes/table.d.ts.map +1 -1
  33. package/dist/pages/lanes/table.js +20 -4
  34. package/dist/pages/lanes/table.js.map +1 -1
  35. package/dist/pages/lanes/table.ts +26 -4
  36. package/dist/server.d.ts.map +1 -1
  37. package/dist/server.js +7 -2
  38. package/dist/server.js.map +1 -1
  39. package/package.json +2 -2
@@ -56,7 +56,16 @@ export interface LaneRow {
56
56
  readonly id: string;
57
57
  readonly name: string;
58
58
  readonly pipelineTemplate: string;
59
- readonly contentDir: string;
59
+ /**
60
+ * Add-time scaffold directories keyed by artifact kind. Per Phase 39
61
+ * (sites→lanes retirement) a lane carries no `contentDir`; this is the
62
+ * lane's only location-adjacent metadata and is an add-time
63
+ * convenience only — never identity, never resolution. Empty object
64
+ * when the lane defines no scaffold defaults.
65
+ */
66
+ readonly scaffoldDefaults: Readonly<Record<string, string>>;
67
+ /** Website host — present only when the lane publishes a site. */
68
+ readonly host: string | null;
60
69
  readonly archived: boolean;
61
70
  readonly archivedAt: string | null;
62
71
  readonly entryCount: number;
@@ -133,6 +142,22 @@ export interface LanesPageData {
133
142
  readonly availableTemplates: readonly string[];
134
143
  }
135
144
 
145
+ /**
146
+ * Normalize a lane's optional `scaffoldDefaults` (a partial map that may
147
+ * carry `undefined` values) into a plain `Record<string, string>`
148
+ * dropping any undefined entries — the renderer-facing shape.
149
+ */
150
+ function normalizeScaffoldDefaults(
151
+ scaffoldDefaults: LaneConfig['scaffoldDefaults'],
152
+ ): Record<string, string> {
153
+ const out: Record<string, string> = {};
154
+ if (scaffoldDefaults === undefined) return out;
155
+ for (const [kind, dir] of Object.entries(scaffoldDefaults)) {
156
+ if (typeof dir === 'string' && dir.length > 0) out[kind] = dir;
157
+ }
158
+ return out;
159
+ }
160
+
136
161
  function laneRowFromConfig(
137
162
  id: string,
138
163
  config: LaneConfig,
@@ -146,7 +171,11 @@ function laneRowFromConfig(
146
171
  id,
147
172
  name: config.name,
148
173
  pipelineTemplate: config.pipelineTemplate,
149
- contentDir: config.contentDir,
174
+ scaffoldDefaults: normalizeScaffoldDefaults(config.scaffoldDefaults),
175
+ host:
176
+ typeof config.host === 'string' && config.host.length > 0
177
+ ? config.host
178
+ : null,
150
179
  archived: archivedAt !== null,
151
180
  archivedAt,
152
181
  entryCount,
@@ -9,11 +9,16 @@
9
9
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2
10
10
  * the studio never mutates state — the form's copy button produces
11
11
  * `/deskwork:lane update <id> [--name <label>] [--template <id>]
12
- * [--content-dir <path>]` with ONLY the fields that differ from
13
- * the current lane config. The client controller in `lanes-page.ts`
14
- * compares the form's live values against `data-current-*`
15
- * attributes on each field and rebuilds the slash command on
16
- * every change event.
12
+ * [--scaffold-default markdown=<dir>] [--host <h>]` with ONLY the
13
+ * fields that differ from the current lane config. The client
14
+ * controller in `lanes-page.ts` compares the form's live values
15
+ * against `data-current-*` attributes on each field and rebuilds the
16
+ * slash command on every change event.
17
+ *
18
+ * Per Phase 39 (sites→lanes retirement) a lane carries no `contentDir`;
19
+ * the former content-dir input becomes the lane's add-time
20
+ * `scaffoldDefaults.markdown` directory (the editorial pipeline's
21
+ * artifact kind) plus an optional `host` input.
17
22
  *
18
23
  * The lane's `id` is immutable (per Task 6.1's CLI contract); the
19
24
  * form does not present an id field.
@@ -1 +1 @@
1
- {"version":3,"file":"edit-form.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/edit-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,kBAAkB,EAAE,SAAS,MAAM,EAAE,GACpC,OAAO,CAsFT"}
1
+ {"version":3,"file":"edit-form.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/edit-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,kBAAkB,EAAE,SAAS,MAAM,EAAE,GACpC,OAAO,CAoGT"}
@@ -9,11 +9,16 @@
9
9
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2
10
10
  * the studio never mutates state — the form's copy button produces
11
11
  * `/deskwork:lane update <id> [--name <label>] [--template <id>]
12
- * [--content-dir <path>]` with ONLY the fields that differ from
13
- * the current lane config. The client controller in `lanes-page.ts`
14
- * compares the form's live values against `data-current-*`
15
- * attributes on each field and rebuilds the slash command on
16
- * every change event.
12
+ * [--scaffold-default markdown=<dir>] [--host <h>]` with ONLY the
13
+ * fields that differ from the current lane config. The client
14
+ * controller in `lanes-page.ts` compares the form's live values
15
+ * against `data-current-*` attributes on each field and rebuilds the
16
+ * slash command on every change event.
17
+ *
18
+ * Per Phase 39 (sites→lanes retirement) a lane carries no `contentDir`;
19
+ * the former content-dir input becomes the lane's add-time
20
+ * `scaffoldDefaults.markdown` directory (the editorial pipeline's
21
+ * artifact kind) plus an optional `host` input.
17
22
  *
18
23
  * The lane's `id` is immutable (per Task 6.1's CLI contract); the
19
24
  * form does not present an id field.
@@ -34,7 +39,8 @@ export function renderEditForm(row, availableTemplates) {
34
39
  Edit <code>${row.id}</code>
35
40
  </h3>
36
41
  <p class="lanes-form-desc">
37
- Mutate <code>name</code> / <code>template</code> / <code>contentDir</code>.
42
+ Mutate <code>name</code> / <code>template</code> /
43
+ <code>scaffoldDefaults.markdown</code> / <code>host</code>.
38
44
  The slash command below carries only the fields that changed.
39
45
  </p>
40
46
  </header>
@@ -63,14 +69,27 @@ export function renderEditForm(row, availableTemplates) {
63
69
  </select>
64
70
  </label>
65
71
  <label class="lanes-field">
66
- <span class="lanes-field-label">Content dir</span>
72
+ <span class="lanes-field-label">Scaffold default (markdown)</span>
73
+ <input
74
+ class="lanes-input"
75
+ type="text"
76
+ name="scaffoldMarkdown"
77
+ data-lanes-field="scaffoldMarkdown"
78
+ data-current="${row.scaffoldDefaults['markdown'] ?? ''}"
79
+ value="${row.scaffoldDefaults['markdown'] ?? ''}"
80
+ autocomplete="off"
81
+ spellcheck="false"
82
+ >
83
+ </label>
84
+ <label class="lanes-field">
85
+ <span class="lanes-field-label">Host (optional)</span>
67
86
  <input
68
87
  class="lanes-input"
69
88
  type="text"
70
- name="contentDir"
71
- data-lanes-field="contentDir"
72
- data-current="${row.contentDir}"
73
- value="${row.contentDir}"
89
+ name="host"
90
+ data-lanes-field="host"
91
+ data-current="${row.host ?? ''}"
92
+ value="${row.host ?? ''}"
74
93
  autocomplete="off"
75
94
  spellcheck="false"
76
95
  >
@@ -1 +1 @@
1
- {"version":3,"file":"edit-form.js","sourceRoot":"","sources":["../../../src/pages/lanes/edit-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAGxD,MAAM,UAAU,cAAc,CAC5B,GAAY,EACZ,kBAAqC;IAErC,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAC5C,CAAC,EAAE,EAAE,EAAE,CACL,MAAM,CACJ,IAAI,CAAA,kBAAkB,EAAE,IAAI,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,CACpG,CACJ,CAAC;IAEF,OAAO,MAAM,CAAC,IAAI,CAAA;;;4BAGQ,GAAG,CAAC,EAAE;;sBAEZ,GAAG,CAAC,EAAE;iDACqB,GAAG,CAAC,EAAE;;;qEAGc,GAAG,CAAC,EAAE;uBACpD,GAAG,CAAC,EAAE;;;;;;;;;;;;;;;4BAeD,GAAG,CAAC,IAAI;qBACf,GAAG,CAAC,IAAI;;;;;;;;;;4BAUD,GAAG,CAAC,gBAAgB;;cAElC,eAAe;;;;;;;;;;4BAUD,GAAG,CAAC,UAAU;qBACrB,GAAG,CAAC,UAAU;;;;;;;;;;;0BAWT,GAAG,CAAC,EAAE;iCACC,GAAG,CAAC,EAAE;;;;;;;0BAOb,GAAG,CAAC,EAAE;;;;;;0BAMN,GAAG,CAAC,EAAE;;;eAGjB,CAAC,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"edit-form.js","sourceRoot":"","sources":["../../../src/pages/lanes/edit-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAGxD,MAAM,UAAU,cAAc,CAC5B,GAAY,EACZ,kBAAqC;IAErC,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAC5C,CAAC,EAAE,EAAE,EAAE,CACL,MAAM,CACJ,IAAI,CAAA,kBAAkB,EAAE,IAAI,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,CACpG,CACJ,CAAC;IAEF,OAAO,MAAM,CAAC,IAAI,CAAA;;;4BAGQ,GAAG,CAAC,EAAE;;sBAEZ,GAAG,CAAC,EAAE;iDACqB,GAAG,CAAC,EAAE;;;qEAGc,GAAG,CAAC,EAAE;uBACpD,GAAG,CAAC,EAAE;;;;;;;;;;;;;;;;4BAgBD,GAAG,CAAC,IAAI;qBACf,GAAG,CAAC,IAAI;;;;;;;;;;4BAUD,GAAG,CAAC,gBAAgB;;cAElC,eAAe;;;;;;;;;;4BAUD,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE;qBAC7C,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE;;;;;;;;;;;;4BAY/B,GAAG,CAAC,IAAI,IAAI,EAAE;qBACrB,GAAG,CAAC,IAAI,IAAI,EAAE;;;;;;;;;;;0BAWT,GAAG,CAAC,EAAE;iCACC,GAAG,CAAC,EAAE;;;;;;;0BAOb,GAAG,CAAC,EAAE;;;;;;0BAMN,GAAG,CAAC,EAAE;;;eAGjB,CAAC,CAAC;AACjB,CAAC"}
@@ -9,11 +9,16 @@
9
9
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2
10
10
  * the studio never mutates state — the form's copy button produces
11
11
  * `/deskwork:lane update <id> [--name <label>] [--template <id>]
12
- * [--content-dir <path>]` with ONLY the fields that differ from
13
- * the current lane config. The client controller in `lanes-page.ts`
14
- * compares the form's live values against `data-current-*`
15
- * attributes on each field and rebuilds the slash command on
16
- * every change event.
12
+ * [--scaffold-default markdown=<dir>] [--host <h>]` with ONLY the
13
+ * fields that differ from the current lane config. The client
14
+ * controller in `lanes-page.ts` compares the form's live values
15
+ * against `data-current-*` attributes on each field and rebuilds the
16
+ * slash command on every change event.
17
+ *
18
+ * Per Phase 39 (sites→lanes retirement) a lane carries no `contentDir`;
19
+ * the former content-dir input becomes the lane's add-time
20
+ * `scaffoldDefaults.markdown` directory (the editorial pipeline's
21
+ * artifact kind) plus an optional `host` input.
17
22
  *
18
23
  * The lane's `id` is immutable (per Task 6.1's CLI contract); the
19
24
  * form does not present an id field.
@@ -46,7 +51,8 @@ export function renderEditForm(
46
51
  Edit <code>${row.id}</code>
47
52
  </h3>
48
53
  <p class="lanes-form-desc">
49
- Mutate <code>name</code> / <code>template</code> / <code>contentDir</code>.
54
+ Mutate <code>name</code> / <code>template</code> /
55
+ <code>scaffoldDefaults.markdown</code> / <code>host</code>.
50
56
  The slash command below carries only the fields that changed.
51
57
  </p>
52
58
  </header>
@@ -75,14 +81,27 @@ export function renderEditForm(
75
81
  </select>
76
82
  </label>
77
83
  <label class="lanes-field">
78
- <span class="lanes-field-label">Content dir</span>
84
+ <span class="lanes-field-label">Scaffold default (markdown)</span>
85
+ <input
86
+ class="lanes-input"
87
+ type="text"
88
+ name="scaffoldMarkdown"
89
+ data-lanes-field="scaffoldMarkdown"
90
+ data-current="${row.scaffoldDefaults['markdown'] ?? ''}"
91
+ value="${row.scaffoldDefaults['markdown'] ?? ''}"
92
+ autocomplete="off"
93
+ spellcheck="false"
94
+ >
95
+ </label>
96
+ <label class="lanes-field">
97
+ <span class="lanes-field-label">Host (optional)</span>
79
98
  <input
80
99
  class="lanes-input"
81
100
  type="text"
82
- name="contentDir"
83
- data-lanes-field="contentDir"
84
- data-current="${row.contentDir}"
85
- value="${row.contentDir}"
101
+ name="host"
102
+ data-lanes-field="host"
103
+ data-current="${row.host ?? ''}"
104
+ value="${row.host ?? ''}"
86
105
  autocomplete="off"
87
106
  spellcheck="false"
88
107
  >
@@ -4,18 +4,21 @@
4
4
  *
5
5
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2,
6
6
  * the studio never mutates state — the form's submit button copies
7
- * the equivalent `/deskwork:lane create <id> --template <id> --content-
8
- * dir <path> [--name <label>]` slash command to the clipboard. The
9
- * operator then pastes the command into Claude Code; the agent runs
10
- * the CLI; the CLI writes the lane config.
7
+ * the equivalent `/deskwork:lane create <id> --template <id>
8
+ * [--scaffold-default markdown=<dir>] [--host <h>] [--name <label>]`
9
+ * slash command to the clipboard. The operator then pastes the command
10
+ * into Claude Code; the agent runs the CLI; the CLI writes the lane
11
+ * config.
11
12
  *
12
13
  * The form has a live preview <code> element showing the slash
13
14
  * command as the operator types. The client controller in
14
15
  * `lanes-page.ts` rebuilds the preview on every change event.
15
16
  *
16
- * Required fields: id, template, contentDir. Name is optional and
17
- * defaults to the id on the CLI side; the preview omits `--name`
18
- * when name is empty.
17
+ * Required fields: id, template. Per Phase 39 (sites→lanes retirement)
18
+ * a lane carries no `contentDir`; the scaffold default (markdown) and
19
+ * host fields are OPTIONAL — a lane is fully valid with neither. Name
20
+ * is optional and defaults to the id on the CLI side; the preview omits
21
+ * each optional flag when its field is empty.
19
22
  */
20
23
  import { type RawHtml } from '../html.ts';
21
24
  interface NewFormInput {
@@ -1 +1 @@
1
- {"version":3,"file":"new-form.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/new-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD,UAAU,YAAY;IACpB,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAqF9D"}
1
+ {"version":3,"file":"new-form.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/new-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD,UAAU,YAAY;IACpB,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAiG9D"}
@@ -4,18 +4,21 @@
4
4
  *
5
5
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2,
6
6
  * the studio never mutates state — the form's submit button copies
7
- * the equivalent `/deskwork:lane create <id> --template <id> --content-
8
- * dir <path> [--name <label>]` slash command to the clipboard. The
9
- * operator then pastes the command into Claude Code; the agent runs
10
- * the CLI; the CLI writes the lane config.
7
+ * the equivalent `/deskwork:lane create <id> --template <id>
8
+ * [--scaffold-default markdown=<dir>] [--host <h>] [--name <label>]`
9
+ * slash command to the clipboard. The operator then pastes the command
10
+ * into Claude Code; the agent runs the CLI; the CLI writes the lane
11
+ * config.
11
12
  *
12
13
  * The form has a live preview <code> element showing the slash
13
14
  * command as the operator types. The client controller in
14
15
  * `lanes-page.ts` rebuilds the preview on every change event.
15
16
  *
16
- * Required fields: id, template, contentDir. Name is optional and
17
- * defaults to the id on the CLI side; the preview omits `--name`
18
- * when name is empty.
17
+ * Required fields: id, template. Per Phase 39 (sites→lanes retirement)
18
+ * a lane carries no `contentDir`; the scaffold default (markdown) and
19
+ * host fields are OPTIONAL — a lane is fully valid with neither. Name
20
+ * is optional and defaults to the id on the CLI side; the preview omits
21
+ * each optional flag when its field is empty.
19
22
  */
20
23
  import { html, unsafe } from "../html.js";
21
24
  export function renderNewLaneForm(input) {
@@ -72,23 +75,35 @@ export function renderNewLaneForm(input) {
72
75
  <span class="lanes-field-hint">union of plugin presets and project overrides</span>
73
76
  </label>
74
77
  <label class="lanes-field">
75
- <span class="lanes-field-label">Content dir</span>
78
+ <span class="lanes-field-label">Scaffold default (markdown, optional)</span>
76
79
  <input
77
80
  class="lanes-input"
78
81
  type="text"
79
- name="contentDir"
80
- data-lanes-field="contentDir"
81
- placeholder="e.g. mockups"
82
- required
82
+ name="scaffoldMarkdown"
83
+ data-lanes-field="scaffoldMarkdown"
84
+ placeholder="e.g. src/content/blog"
85
+ autocomplete="off"
86
+ spellcheck="false"
87
+ >
88
+ <span class="lanes-field-hint">where /deskwork:add drops a NEW markdown file; never resolution</span>
89
+ </label>
90
+ <label class="lanes-field">
91
+ <span class="lanes-field-label">Host (optional)</span>
92
+ <input
93
+ class="lanes-input"
94
+ type="text"
95
+ name="host"
96
+ data-lanes-field="host"
97
+ placeholder="e.g. example.com"
83
98
  autocomplete="off"
84
99
  spellcheck="false"
85
100
  >
86
- <span class="lanes-field-hint">relative to the project root</span>
101
+ <span class="lanes-field-hint">present only when this lane publishes a website</span>
87
102
  </label>
88
103
  </div>
89
104
  <div class="lanes-form-preview">
90
105
  <span class="lanes-form-preview-label">Command preview</span>
91
- <code class="lanes-form-preview-cmd" data-lanes-preview>/deskwork:lane create &lt;id&gt; --template &lt;template&gt; --content-dir &lt;path&gt;</code>
106
+ <code class="lanes-form-preview-cmd" data-lanes-preview>/deskwork:lane create &lt;id&gt; --template &lt;template&gt;</code>
92
107
  </div>
93
108
  <div class="lanes-form-actions">
94
109
  <button
@@ -1 +1 @@
1
- {"version":3,"file":"new-form.js","sourceRoot":"","sources":["../../../src/pages/lanes/new-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAMxD,MAAM,UAAU,iBAAiB,CAAC,KAAmB;IACnD,MAAM,eAAe,GAAG,KAAK,CAAC,kBAAkB;SAC7C,GAAG,CACF,CAAC,EAAE,EAAE,EAAE,CACL,MAAM,CAAC,IAAI,CAAA,kBAAkB,EAAE,KAAK,EAAE,WAAW,CAAC,CACrD,CAAC;IAEJ,OAAO,MAAM,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CN,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA+Bd,CAAC,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"new-form.js","sourceRoot":"","sources":["../../../src/pages/lanes/new-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAMxD,MAAM,UAAU,iBAAiB,CAAC,KAAmB;IACnD,MAAM,eAAe,GAAG,KAAK,CAAC,kBAAkB;SAC7C,GAAG,CACF,CAAC,EAAE,EAAE,EAAE,CACL,MAAM,CAAC,IAAI,CAAA,kBAAkB,EAAE,KAAK,EAAE,WAAW,CAAC,CACrD,CAAC;IAEJ,OAAO,MAAM,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CN,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA2Cd,CAAC,CAAC;AACjB,CAAC"}
@@ -4,18 +4,21 @@
4
4
  *
5
5
  * The form is a CLIENT-SIDE copy-builder. Per THESIS Consequence 2,
6
6
  * the studio never mutates state — the form's submit button copies
7
- * the equivalent `/deskwork:lane create <id> --template <id> --content-
8
- * dir <path> [--name <label>]` slash command to the clipboard. The
9
- * operator then pastes the command into Claude Code; the agent runs
10
- * the CLI; the CLI writes the lane config.
7
+ * the equivalent `/deskwork:lane create <id> --template <id>
8
+ * [--scaffold-default markdown=<dir>] [--host <h>] [--name <label>]`
9
+ * slash command to the clipboard. The operator then pastes the command
10
+ * into Claude Code; the agent runs the CLI; the CLI writes the lane
11
+ * config.
11
12
  *
12
13
  * The form has a live preview <code> element showing the slash
13
14
  * command as the operator types. The client controller in
14
15
  * `lanes-page.ts` rebuilds the preview on every change event.
15
16
  *
16
- * Required fields: id, template, contentDir. Name is optional and
17
- * defaults to the id on the CLI side; the preview omits `--name`
18
- * when name is empty.
17
+ * Required fields: id, template. Per Phase 39 (sites→lanes retirement)
18
+ * a lane carries no `contentDir`; the scaffold default (markdown) and
19
+ * host fields are OPTIONAL — a lane is fully valid with neither. Name
20
+ * is optional and defaults to the id on the CLI side; the preview omits
21
+ * each optional flag when its field is empty.
19
22
  */
20
23
 
21
24
  import { html, unsafe, type RawHtml } from '../html.ts';
@@ -82,23 +85,35 @@ export function renderNewLaneForm(input: NewFormInput): RawHtml {
82
85
  <span class="lanes-field-hint">union of plugin presets and project overrides</span>
83
86
  </label>
84
87
  <label class="lanes-field">
85
- <span class="lanes-field-label">Content dir</span>
88
+ <span class="lanes-field-label">Scaffold default (markdown, optional)</span>
86
89
  <input
87
90
  class="lanes-input"
88
91
  type="text"
89
- name="contentDir"
90
- data-lanes-field="contentDir"
91
- placeholder="e.g. mockups"
92
- required
92
+ name="scaffoldMarkdown"
93
+ data-lanes-field="scaffoldMarkdown"
94
+ placeholder="e.g. src/content/blog"
95
+ autocomplete="off"
96
+ spellcheck="false"
97
+ >
98
+ <span class="lanes-field-hint">where /deskwork:add drops a NEW markdown file; never resolution</span>
99
+ </label>
100
+ <label class="lanes-field">
101
+ <span class="lanes-field-label">Host (optional)</span>
102
+ <input
103
+ class="lanes-input"
104
+ type="text"
105
+ name="host"
106
+ data-lanes-field="host"
107
+ placeholder="e.g. example.com"
93
108
  autocomplete="off"
94
109
  spellcheck="false"
95
110
  >
96
- <span class="lanes-field-hint">relative to the project root</span>
111
+ <span class="lanes-field-hint">present only when this lane publishes a website</span>
97
112
  </label>
98
113
  </div>
99
114
  <div class="lanes-form-preview">
100
115
  <span class="lanes-form-preview-label">Command preview</span>
101
- <code class="lanes-form-preview-cmd" data-lanes-preview>/deskwork:lane create &lt;id&gt; --template &lt;template&gt; --content-dir &lt;path&gt;</code>
116
+ <code class="lanes-form-preview-cmd" data-lanes-preview>/deskwork:lane create &lt;id&gt; --template &lt;template&gt;</code>
102
117
  </div>
103
118
  <div class="lanes-form-actions">
104
119
  <button
@@ -2,8 +2,10 @@
2
2
  * Lane-table renderer for `/dev/lanes` (Phase 6 Task 6.3).
3
3
  *
4
4
  * Renders the active-lane table: one row per lane with id, name,
5
- * bound pipeline template, contentDir, entry count, plus per-row
6
- * Edit / Archive buttons and a reorder handle.
5
+ * bound pipeline template, scaffold defaults, entry count, plus
6
+ * per-row Edit / Archive buttons and a reorder handle. Per Phase 39
7
+ * (sites→lanes retirement) a lane carries no `contentDir`; the column
8
+ * surfaces the lane's add-time `scaffoldDefaults` instead.
7
9
  *
8
10
  * Per `.claude/rules/affordance-placement.md`, the row's controls
9
11
  * live ON the row (component-attached, not toolbar-attached) —
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAqB,MAAM,WAAW,CAAC;AAQ1E,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AA8JD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CA6BpE"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/pages/lanes/table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAqB,MAAM,WAAW,CAAC;AAQ1E,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAkLD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CA6BpE"}
@@ -2,8 +2,10 @@
2
2
  * Lane-table renderer for `/dev/lanes` (Phase 6 Task 6.3).
3
3
  *
4
4
  * Renders the active-lane table: one row per lane with id, name,
5
- * bound pipeline template, contentDir, entry count, plus per-row
6
- * Edit / Archive buttons and a reorder handle.
5
+ * bound pipeline template, scaffold defaults, entry count, plus
6
+ * per-row Edit / Archive buttons and a reorder handle. Per Phase 39
7
+ * (sites→lanes retirement) a lane carries no `contentDir`; the column
8
+ * surfaces the lane's add-time `scaffoldDefaults` instead.
7
9
  *
8
10
  * Per `.claude/rules/affordance-placement.md`, the row's controls
9
11
  * live ON the row (component-attached, not toolbar-attached) —
@@ -72,7 +74,7 @@ function renderTableRow(row, availableTemplates) {
72
74
  <td class="lanes-cell lanes-cell--id"><code>${row.id}</code></td>
73
75
  <td class="lanes-cell lanes-cell--name">${row.name}</td>
74
76
  <td class="lanes-cell lanes-cell--template"><code>${row.pipelineTemplate}</code></td>
75
- <td class="lanes-cell lanes-cell--content-dir"><code>${row.contentDir}</code></td>
77
+ <td class="lanes-cell lanes-cell--scaffold-defaults">${renderScaffoldDefaults(row.scaffoldDefaults)}</td>
76
78
  <td class="lanes-cell lanes-cell--count">${row.entryCount}</td>
77
79
  <td class="lanes-cell lanes-cell--visibility">
78
80
  <span
@@ -100,6 +102,20 @@ function renderTableRow(row, availableTemplates) {
100
102
  </td>
101
103
  </tr>`);
102
104
  }
105
+ /**
106
+ * Render a lane's add-time `scaffoldDefaults` as a compact list of
107
+ * `<kind> → <dir>` pairs. Empty map renders an em-dash so the column
108
+ * still communicates "no scaffold defaults configured" rather than a
109
+ * blank cell. Per Phase 39 this replaces the former content-dir cell.
110
+ */
111
+ function renderScaffoldDefaults(scaffoldDefaults) {
112
+ const entries = Object.entries(scaffoldDefaults);
113
+ if (entries.length === 0) {
114
+ return unsafe(html `<span class="lanes-scaffold-empty" aria-label="No scaffold defaults">—</span>`);
115
+ }
116
+ const items = entries.map(([kind, dir]) => unsafe(html `<li class="lanes-scaffold-item"><code class="lanes-scaffold-kind">${kind}</code> → <code class="lanes-scaffold-dir">${dir}</code></li>`));
117
+ return unsafe(html `<ul class="lanes-scaffold-list">${items}</ul>`);
118
+ }
103
119
  function renderCopyButton(input) {
104
120
  return unsafe(html `
105
121
  <button
@@ -220,7 +236,7 @@ function renderHeadRow() {
220
236
  <th class="lanes-th lanes-th--id" scope="col">ID</th>
221
237
  <th class="lanes-th lanes-th--name" scope="col">Name</th>
222
238
  <th class="lanes-th lanes-th--template" scope="col">Template</th>
223
- <th class="lanes-th lanes-th--content-dir" scope="col">Content dir</th>
239
+ <th class="lanes-th lanes-th--scaffold-defaults" scope="col">Scaffold defaults</th>
224
240
  <th class="lanes-th lanes-th--count" scope="col">Entries</th>
225
241
  <th class="lanes-th lanes-th--visibility" scope="col">State</th>
226
242
  <th class="lanes-th lanes-th--actions" scope="col">Actions</th>
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../src/pages/lanes/table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../src/pages/lanes/table.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,10 @@
2
2
  * Lane-table renderer for `/dev/lanes` (Phase 6 Task 6.3).
3
3
  *
4
4
  * Renders the active-lane table: one row per lane with id, name,
5
- * bound pipeline template, contentDir, entry count, plus per-row
6
- * Edit / Archive buttons and a reorder handle.
5
+ * bound pipeline template, scaffold defaults, entry count, plus
6
+ * per-row Edit / Archive buttons and a reorder handle. Per Phase 39
7
+ * (sites→lanes retirement) a lane carries no `contentDir`; the column
8
+ * surfaces the lane's add-time `scaffoldDefaults` instead.
7
9
  *
8
10
  * Per `.claude/rules/affordance-placement.md`, the row's controls
9
11
  * live ON the row (component-attached, not toolbar-attached) —
@@ -98,7 +100,7 @@ function renderTableRow(
98
100
  <td class="lanes-cell lanes-cell--id"><code>${row.id}</code></td>
99
101
  <td class="lanes-cell lanes-cell--name">${row.name}</td>
100
102
  <td class="lanes-cell lanes-cell--template"><code>${row.pipelineTemplate}</code></td>
101
- <td class="lanes-cell lanes-cell--content-dir"><code>${row.contentDir}</code></td>
103
+ <td class="lanes-cell lanes-cell--scaffold-defaults">${renderScaffoldDefaults(row.scaffoldDefaults)}</td>
102
104
  <td class="lanes-cell lanes-cell--count">${row.entryCount}</td>
103
105
  <td class="lanes-cell lanes-cell--visibility">
104
106
  <span
@@ -127,6 +129,26 @@ function renderTableRow(
127
129
  </tr>`);
128
130
  }
129
131
 
132
+ /**
133
+ * Render a lane's add-time `scaffoldDefaults` as a compact list of
134
+ * `<kind> → <dir>` pairs. Empty map renders an em-dash so the column
135
+ * still communicates "no scaffold defaults configured" rather than a
136
+ * blank cell. Per Phase 39 this replaces the former content-dir cell.
137
+ */
138
+ function renderScaffoldDefaults(
139
+ scaffoldDefaults: Readonly<Record<string, string>>,
140
+ ): RawHtml {
141
+ const entries = Object.entries(scaffoldDefaults);
142
+ if (entries.length === 0) {
143
+ return unsafe(html`<span class="lanes-scaffold-empty" aria-label="No scaffold defaults">—</span>`);
144
+ }
145
+ const items = entries.map(
146
+ ([kind, dir]) =>
147
+ unsafe(html`<li class="lanes-scaffold-item"><code class="lanes-scaffold-kind">${kind}</code> → <code class="lanes-scaffold-dir">${dir}</code></li>`),
148
+ );
149
+ return unsafe(html`<ul class="lanes-scaffold-list">${items}</ul>`);
150
+ }
151
+
130
152
  interface CopyButtonInput {
131
153
  readonly label: string;
132
154
  readonly copy: string;
@@ -258,7 +280,7 @@ function renderHeadRow(): RawHtml {
258
280
  <th class="lanes-th lanes-th--id" scope="col">ID</th>
259
281
  <th class="lanes-th lanes-th--name" scope="col">Name</th>
260
282
  <th class="lanes-th lanes-th--template" scope="col">Template</th>
261
- <th class="lanes-th lanes-th--content-dir" scope="col">Content dir</th>
283
+ <th class="lanes-th lanes-th--scaffold-defaults" scope="col">Scaffold defaults</th>
262
284
  <th class="lanes-th lanes-th--count" scope="col">Entries</th>
263
285
  <th class="lanes-th lanes-th--visibility" scope="col">State</th>
264
286
  <th class="lanes-th lanes-th--actions" scope="col">Actions</th>
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0BtE,UAAU,OAAO;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CA6FpF;AAoFD,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA6QlD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0BtE,UAAU,OAAO;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CA6FpF;AAoFD,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA6QlD"}
package/dist/server.js CHANGED
@@ -33,6 +33,7 @@ import { existsSync, realpathSync } from 'node:fs';
33
33
  import { dirname, isAbsolute, resolve } from 'node:path';
34
34
  import { fileURLToPath } from 'node:url';
35
35
  import { readConfig } from '@deskwork/core/config';
36
+ import { listLaneConfigs } from '@deskwork/core/lanes';
36
37
  import { readWorkflow } from '@deskwork/core/review/pipeline';
37
38
  import { createApiRouter } from "./routes/api.js";
38
39
  import { serveScrapbookFile } from "./routes/scrapbook-file.js";
@@ -626,7 +627,11 @@ async function main() {
626
627
  printBanner({
627
628
  urls: reachableUrls,
628
629
  projectRoot,
629
- siteSlugs: Object.keys(config.sites),
630
+ // Phase 39c (sites→lanes retirement): the boot banner reports the
631
+ // project's LANES (the unit deskwork operates on), not the retired
632
+ // `config.sites` keyspace. `config` is unused for the banner now but
633
+ // is still read above for the studio context.
634
+ laneIds: listLaneConfigs(projectRoot),
630
635
  tailscale,
631
636
  port: result.port,
632
637
  override: hostOverride,
@@ -642,7 +647,7 @@ function printBanner(b) {
642
647
  process.stdout.write(` http://${b.tailscale.magicDnsName}:${b.port}/ (Tailscale magic-DNS)\n`);
643
648
  }
644
649
  process.stdout.write(` project: ${b.projectRoot}\n`);
645
- process.stdout.write(` sites: ${b.siteSlugs.join(', ')}\n`);
650
+ process.stdout.write(` lanes: ${b.laneIds.join(', ') || '(none yet)'}\n`);
646
651
  if (b.autoIncrementedFrom !== null) {
647
652
  // Issue #43: surface the auto-increment so the operator isn't
648
653
  // confused when the URL doesn't match the documented default.