create-pmos 0.500.0 → 0.502.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-pmos",
3
- "version": "0.500.0",
3
+ "version": "0.502.0",
4
4
  "description": "Scaffold the PMOS portable kit — run the PMOS product-management workflow (initiative → lane-fit spec → contract → build → three gates, with work-type lanes for features, research, maintenance, incidents, and content) entirely inside your own repo, with all state as git-versioned files. Includes `workflow-sweep`, which audits the state every board derives from and separates real defects from work you simply have not done. `create-pmos workspace` also installs + launches the local Terminal Workspace GUI. No database, no network, no telemetry.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -32,6 +32,32 @@
32
32
  "audit"
33
33
  ],
34
34
  "pmosChanges": [
35
+ {
36
+ "v": "0.502.0",
37
+ "at": "2026-11-03T04:51:26.562Z",
38
+ "f": 3,
39
+ "prs": [
40
+ {
41
+ "n": 1185,
42
+ "t": "Full task names in the Timeline too",
43
+ "s": "Full task names in the Timeline too",
44
+ "k": "fix"
45
+ }
46
+ ]
47
+ },
48
+ {
49
+ "v": "0.501.0",
50
+ "at": "2026-11-03T04:44:45.129Z",
51
+ "f": 3,
52
+ "prs": [
53
+ {
54
+ "n": 1184,
55
+ "t": "Home's list toggle always opens and closes the list",
56
+ "s": "Home's list toggle always opens and closes the list",
57
+ "k": "fix"
58
+ }
59
+ ]
60
+ },
35
61
  {
36
62
  "v": "0.500.0",
37
63
  "at": "2026-11-03T04:17:03.191Z",
@@ -397,31 +423,6 @@
397
423
  "k": "new"
398
424
  }
399
425
  ]
400
- },
401
- {
402
- "v": "0.482.0",
403
- "at": "2026-11-01T23:25:19.509Z",
404
- "f": 3,
405
- "prs": [
406
- {
407
- "n": 1142,
408
- "t": "PDF takes the Viewer's whole width; a queued chat line leaves once read (batch 22 items 15, 16)",
409
- "s": "PDF takes the Viewer's whole width; a queued chat line leaves once read (batch 22 items 15, 16)",
410
- "k": "fix"
411
- }
412
- ]
413
- },
414
- {
415
- "v": "0.481.0",
416
- "at": "2026-11-01T15:21:25.176Z",
417
- "f": 3,
418
- "prs": [
419
- {
420
- "n": 1141,
421
- "t": "Batch 22: feedback fixes (held for one merge)",
422
- "s": "Batch 22: feedback fixes (held for one merge)"
423
- }
424
- ]
425
426
  }
426
427
  ]
427
428
  }
@@ -1,3 +1,3 @@
1
- kernel-source: pmos@74d94d5f
1
+ kernel-source: pmos@53b3f1f6
2
2
  assembled: 2026-11-03
3
3
  mode: vendor
@@ -2,7 +2,7 @@
2
2
  type: Reference
3
3
  title: "Eval calibration log"
4
4
  description: "Append-only record of every PM override of an evaluator verdict."
5
- generated: {by: process:create-pmos, at: "2026-11-03T04:17:00Z"}
5
+ generated: {by: process:create-pmos, at: "2026-11-03T04:51:22Z"}
6
6
  status: stable
7
7
  ---
8
8
 
@@ -2,7 +2,7 @@
2
2
  type: Reference
3
3
  title: "Health budgets"
4
4
  description: "Closed registry of health-budget anchors (D59), edited only by the PM."
5
- generated: {by: process:create-pmos, at: "2026-11-03T04:17:00Z"}
5
+ generated: {by: process:create-pmos, at: "2026-11-03T04:51:22Z"}
6
6
  status: stable
7
7
  ---
8
8
 
@@ -2,7 +2,7 @@
2
2
  type: Reference
3
3
  title: "Discoveries and friction log"
4
4
  description: "Append-only record of what runs discovered and where the process rubbed."
5
- generated: {by: process:create-pmos, at: "2026-11-03T04:17:00Z"}
5
+ generated: {by: process:create-pmos, at: "2026-11-03T04:51:22Z"}
6
6
  status: stable
7
7
  ---
8
8
 
@@ -1,4 +1,30 @@
1
1
  [
2
+ {
3
+ "v": "0.502.0",
4
+ "at": "2026-11-03T04:51:26.562Z",
5
+ "f": 3,
6
+ "prs": [
7
+ {
8
+ "n": 1185,
9
+ "t": "Full task names in the Timeline too",
10
+ "s": "Full task names in the Timeline too",
11
+ "k": "fix"
12
+ }
13
+ ]
14
+ },
15
+ {
16
+ "v": "0.501.0",
17
+ "at": "2026-11-03T04:44:45.129Z",
18
+ "f": 3,
19
+ "prs": [
20
+ {
21
+ "n": 1184,
22
+ "t": "Home's list toggle always opens and closes the list",
23
+ "s": "Home's list toggle always opens and closes the list",
24
+ "k": "fix"
25
+ }
26
+ ]
27
+ },
2
28
  {
3
29
  "v": "0.500.0",
4
30
  "at": "2026-11-03T04:17:03.191Z",
@@ -103,12 +103,20 @@ Press an initiative's name in the list, or open `?ini=<id>`. The list stays as i
103
103
  - **Set a Jira ticket's dates.** Press the dates of a Jira ticket in the List, or drag its bar on the Timeline, as you do for a task. PMOS keeps the start and due days and shows them in place of the sprint end. Jira does not change. The status and the name stay Jira's.
104
104
  - **Tasks** show one row (one group) for each stage of the workflow, in order. Finished stages and later stages are never merged into one row; they start folded, and the current stage and any stage with a late task start open.
105
105
  - **Change a task where it is.** In the List, press a task's name. The row opens in place: change the name (Enter saves), the status, and the dates. Only one row is open at a time. Esc closes it. The ⋯ after the dates has **Milestone** (or **Make it a plain task**), **Move to a stage**, **Open the task card** and **Delete task**. A milestone has one date: its due day. Each change shows **Undo**.
106
- - In the List, a task's full name always shows: a long name wraps onto more lines. A short prefix such as "Bus shelter:" stays in the name, in grey. The dates show at the right. In a narrow panel or on a phone, the dates show under the name. A task with no dates shows no date; open the row to set them.
106
+ - In the List, a task's full name always shows: a long name wraps onto more lines. A short prefix such as "Bus shelter:" stays in the name, in grey. The dates show at the right. In a narrow panel or on a phone, the dates show under the name. On a computer, the Timeline's name column wraps a long name too, and its row grows; on a phone, each title stays on one line above its bar. A task with no dates shows no date; open the row to set them.
107
107
  - **Add a task to a stage.** Press **+** on an open stage. The field opens at the top of that stage, with one row of chips under it. **Stage** is the stage you pressed + on; press it to pick another stage of the workflow. **Task** can change to **Milestone**: the box becomes ◇ and **Date** takes one day. **Dates** and **Owner** are optional; with no owner, the task is yours. Enter adds the task and keeps the field open for the next one. Esc closes the field.
108
108
  - **Move a task between stages.** On a computer, drag the grip at the left of a row. On a phone, press and hold the task's name, then drag. Drop it on a stage name to put it last in that stage, or between two rows to put it there. The status and the dates do not change. The message shows **Undo**.
109
109
  - A linked Jira ticket opens in place too. Its name and status stay Jira's ("In Progress in Jira · read 4 min ago"). Its dates can change, and it can be a milestone. It has no **Delete**.
110
110
  - **Delete a task.** Press the caret under a task's box (on a phone, press and hold the box) and press the trash at the end of the status picker. The task goes at once and the message shows **Undo**. In the Task Viewer, the trash is the last icon of the Status row, and **Delete** is the last entry of its ⋯ menu. You can delete every PMOS task, also a task that Claude planned in the breakdown and a task that a stage's To finish list made. A deleted To finish task does not come back when the stage is read again or when the initiative moves back to that stage. A Jira ticket has no Delete: change it in Jira. A task deleted in a draft leaves only the draft.
111
111
 
112
+ ## Show or hide the list
113
+
114
+ The button with the panel icon shows or hides the list on the left. It works in every layout: with a Viewer open beside the chat, with a Viewer on the full screen, with two Viewers, and in a narrow window.
115
+
116
+ - When a Viewer takes the full screen, the list starts as a narrow column of group icons. Press the panel icon at its top to show the full list. The Viewer stays open and becomes narrower.
117
+ - Press the panel icon in the list's header to hide the list again.
118
+ - PMOS keeps your choice on this computer. After you show or hide the list one time, a Viewer on the full screen does not change it.
119
+
112
120
  ## Back and forward
113
121
 
114
122
  The Viewer keeps one trail on Home, the Board and Insights.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pmos-workspace",
3
- "version": "0.500.0",
3
+ "version": "0.502.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pmos-workspace",
9
- "version": "0.500.0",
9
+ "version": "0.502.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@anthropic-ai/sdk": "^1.3.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmos-workspace",
3
- "version": "0.500.0",
3
+ "version": "0.502.0",
4
4
  "private": true,
5
5
  "description": "PMOS Terminal Workspace — local companion hosting real PTYs beside the library and gates (D62)",
6
6
  "license": "MIT",
@@ -148,8 +148,11 @@ function layout() {
148
148
  if (man && !phone && !S.page) {
149
149
  const room = S.desk.clientWidth - 64 - (S.row.length - 1) * 22; // the desk less its padding and the gaps
150
150
  const list = document.getElementById('hmList'), lw = list ? list.offsetWidth || 316 : 0;
151
- const own = P.owned ? P.owned() : null; // Home owns its list's fold (batch 20 item 6): only full screen takes its room, and it comes back as it was
152
- const fold = own !== null ? own || (S.row.length === 1 && S.row[0] !== C) : !S.keepList && (!S.row.includes(C) || room - lw < S.row.length * PANEL);
151
+ // Home owns its list's fold (batch 20 item 6). A full Viewer folds it only as a starting default: never once the PM has pressed the fold or
152
+ // unfold (remembered), and not after the rail's "Show the list" in this layout (batch 25 item 12: the PM can always open or close it)
153
+ const own = P.owned ? P.owned() : null;
154
+ const startFold = !S.keepList && !(P.chosen && P.chosen()) && S.row.length === 1 && S.row[0] !== C;
155
+ const fold = own !== null ? own || startFold : !S.keepList && (!S.row.includes(C) || room - lw < S.row.length * PANEL);
153
156
  if (fold !== P.railOn()) P.rail(fold);
154
157
  }
155
158
  if (back) P.rest(); else P.relayout();
@@ -122,6 +122,8 @@ const G = { subs: [], card: null, railKey: null, rail: false, lw: 0, hold: 0, ti
122
122
  * a Viewer's width, its reset, open wide and its close never do. null: the Viewer folds the list to a rail as it needs (a page without one). */
123
123
  export function listFold(o) { G.own = o && typeof o.folded === 'function' ? o : null; }
124
124
  const owned = () => (G.own ? !!G.own.folded() : null);
125
+ /** true: the PM has pressed the list's fold or unfold, so a full Viewer keeps the list as the PM left it (no starting fold). */
126
+ const chosen = () => !!(G.own && typeof G.own.chosen === 'function' && G.own.chosen());
125
127
  const mk = (i) => ({ i, el: null, cur: null, back: null, stack: [], fwd: [], wide: false, w: 0, drill: false, over: false, used: 0, ph: false, via: '' });
126
128
  let V = mk(0);
127
129
  const ALL = [V];
@@ -279,7 +281,7 @@ function setRail(on) {
279
281
  bar.innerHTML = `<button type="button" class="cz-vw-ib" data-cz-vw-rail="show" aria-label="Show the list" title="Show the list">${svg(P.list, 18)}</button><div class="cz-vw-railtiles"></div>`;
280
282
  bar.addEventListener('click', (e) => {
281
283
  const b = e.target.closest('[data-cz-vw-rail]'); if (!b) return;
282
- if (b.dataset.czVwRail === 'show' && G.own) { if (G.own.show) G.own.show(); return; } // the page unfolds its own list
284
+ if (b.dataset.czVwRail === 'show' && G.own) { if (G.own.show) G.own.show(); if (G.rail) setRail(false); return; } // the page unfolds its own list; a layout that folded it never holds it folded
283
285
  if (b.dataset.czVwRail === 'show' && G.managed && ALL.some((x) => shown(x) && G.managed('v' + x.i))) { setRail(false); return; } // cozy-panels.js lays it out
284
286
  if (b.dataset.czVwRail === 'show') { V.wide = false; apply(Math.min(V.w, sideMax())); redraw(); return; }
285
287
  // a group's tile: the page's card of that group's rows, beside the tile (batch 18 item 14, FlA1); the rail and the Viewer stay
@@ -785,6 +787,6 @@ export const panels = {
785
787
  relayout() { ALL.filter(shown).forEach((x) => on(x, () => { apply(V.wide ? room().wideMax : V.w || room().def); redraw(); })); },
786
788
  /** Back beside the chat after the engine laid it out: the width its kind keeps, else the default. */
787
789
  rest() { ALL.filter(shown).forEach((x) => on(x, () => { const k = widthOf(V.cur.kind); V.wide = false; apply(k || room().def); redraw(); })); },
788
- rail(v) { setRail(!!v); }, railOn: () => G.rail, owned,
790
+ rail(v) { setRail(!!v); }, railOn: () => G.rail, owned, chosen,
789
791
  };
790
792
  if (typeof window !== 'undefined') window.czViewer = { open, close, back, forward, trail, replaceUrl, drill, setPresses, setChip, setCheck, isOpen, current, body, onChange, placeholder, retitle, czSummary, czSections, widthOf, setWidth, wide, railOn, railCard, railSync, keepWide, ICONS };
@@ -636,8 +636,12 @@ function drawList() {
636
636
  }
637
637
  /** The list's own fold (batch 20 item 6): kept on this computer, the one thing that folds or unfolds the list. With a Viewer open it is the rail. */
638
638
  function setFold(on) {
639
- S.folded = !!on; store.set('pmos.home.fold', on ? '1' : null); drawList();
640
- if (VW.isOpen() && VW.panels) VW.panels.relayout();
639
+ S.folded = !!on; store.set('pmos.home.fold', on ? '1' : '0'); drawList(); // '0': the PM opened it, and a full Viewer keeps it open from now on
640
+ if (VW.isOpen() && VW.panels) {
641
+ VW.panels.relayout();
642
+ // a Viewer the panels lay out (full, two side by side) does not ask the page again: the press folds or unfolds the list now, in every layout
643
+ if (VW.panels.railOn() !== (S.folded && !isPhone())) VW.panels.rail(S.folded && !isPhone());
644
+ }
641
645
  }
642
646
  /* ── the folded rail's card (batch 18 item 14, FlA1–FlA5) ──
643
647
  * With the Viewer wide, Home's list folds to a rail of group tiles (cozy-viewer.js). A tile's press opens a card beside it with that group's
@@ -1907,7 +1911,7 @@ async function todayPress(k, b) {
1907
1911
  }
1908
1912
  $('#hmDesk').insertAdjacentHTML('afterbegin', `<button type="button" class="hm-unfold" id="hmUnfold" aria-label="Show the list" title="Show the list">${SVG(I.fold, 16)}</button>`);
1909
1913
  $('#hmUnfold').onclick = () => setFold(false);
1910
- VW.listFold({ folded: () => S.folded && !isPhone(), show: () => setFold(false) });
1914
+ VW.listFold({ folded: () => S.folded && !isPhone(), chosen: () => store.get('pmos.home.fold') !== null, show: () => setFold(false) });
1911
1915
  function cta() {
1912
1916
  if (S.ini === 'product') { const C = H.productCard(S.D); if (C.sent) openUpdateViewer(); else { select('n:update'); } return; }
1913
1917
  const h = S.H || {};
@@ -290,6 +290,15 @@ button.iv-bxw.jr:hover .iv-cb { box-shadow: 0 0 0 3px var(--cz-well); }
290
290
  .ivt-n { position: sticky; left: 0; z-index: 3; width: var(--nw); flex: none; background: var(--cz-card); display: flex; align-items: center; gap: 10px; padding: 0 10px 0 14px; min-width: 0; }
291
291
  .ivt-r.k .ivt-n { padding-left: 34px; }
292
292
  .ivt-n .iv-tt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; font-size: var(--fs-2); }
293
+ /* batch 25 item 4 (TaskNamesWrap, agreed A): on a desktop a task's name is never cut in the Timeline either. It wraps in the name column;
294
+ * the row grows and its bar stays in the middle. (A phone keeps each title on one line above its bar.) */
295
+ @container (min-width: 521px) {
296
+ .ivt-r.k .ivt-n { padding-top: 7px; padding-bottom: 7px; }
297
+ .ivt-r.k .ivt-n .iv-tt { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: break-word; line-height: 1.35; flex: 1 1 0; }
298
+ /* the days of a hidden Start or Due column sit under the name, not beside it (the name keeps the width) */
299
+ .ivt-r.k .ivt-t { flex-wrap: wrap; row-gap: 2px; }
300
+ .ivt-r.k .ivt-wn { flex-basis: 100%; padding-left: 28px; flex-wrap: wrap; white-space: nowrap; }
301
+ }
293
302
  .ivt-r.x .iv-tt { color: var(--cz-ink3); font-weight: 600; }
294
303
  .ivt-n .iv-bxw { align-self: center; }
295
304
  .ivt-n .iv-cb { margin-top: 0 !important; }
@@ -826,6 +835,7 @@ button.lk-mt:hover { color: var(--cz-ink) !important; }
826
835
  .iva-r.k .iva-n { padding-left: 14px; }
827
836
  .iva-r.k .iva-l { padding-left: 14px; }
828
837
  .iva-r.k .iva-l .iv-tt { font-size: var(--fs-2); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
838
+ @container (min-width: 521px) { .iva-r.k .iva-l { padding-top: 7px; padding-bottom: 7px; } .iva-r.k .iva-l .iv-tt { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: break-word; line-height: 1.35; } } /* the full name, as in the Timeline (batch 25 item 4) */
829
839
  .iva-r.x .iva-l .iv-tt { color: var(--cz-ink3); font-weight: 600; }
830
840
  .iva-nt { font-size: 11px; font-weight: 800; white-space: nowrap; flex: none; }
831
841
  .iva-nt.lt { color: var(--cz-late); }