create-pmos 0.140.0 → 0.141.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.140.0",
3
+ "version": "0.141.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": {
@@ -1,3 +1,3 @@
1
- kernel-source: pmos@86ccd34
1
+ kernel-source: pmos@6f1e5e1
2
2
  assembled: 2026-10-12
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-10-12T01:22:45Z"}
5
+ generated: {by: process:create-pmos, at: "2026-10-12T01:30:00Z"}
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-10-12T01:22:45Z"}
5
+ generated: {by: process:create-pmos, at: "2026-10-12T01:30:00Z"}
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-10-12T01:22:45Z"}
5
+ generated: {by: process:create-pmos, at: "2026-10-12T01:30:00Z"}
6
6
  status: stable
7
7
  ---
8
8
 
@@ -114,6 +114,7 @@ const { harness } = require('./c3-ini-harness');
114
114
  ok('L8 Move lists the stages of the initiative\'s own workflow', opts === 'Discover,Plan,Build & Deliver,Monitor & Evaluate', opts);
115
115
  await page.click('[data-ini-moveto="Discover"]');
116
116
  await until(() => store(() => window.__c3boards.rows.find((r) => r.id === 'IDPF-07').stage === 'Discover'));
117
+ await until(async () => /IDPF-07 moved to Discover/.test(await toast()));
117
118
  ok('L9 a pick moves it and the toast confirms', /IDPF-07 moved to Discover/.test(await toast()), await toast());
118
119
  await H.finish();
119
120
  })();
@@ -84,6 +84,21 @@ const { harness } = require('./c3-ini-harness');
84
84
  const nb = await store(() => { const b = window.__c3boards.boards.find((x) => x.id === 'partner-portal'); return b && { build: b.build, defTpl: b.defTpl }; });
85
85
  ok('NB2 Create board adds the board (Build and deliver off, Simple by default) and opens its Triage', nb && nb.build === false && nb.defTpl === 'simple' && await st(() => document.querySelector('[data-ini-tab="triage"]').getAttribute('aria-pressed') === 'true'), JSON.stringify(nb));
86
86
 
87
+ /* ── a board whose open initiatives carry no work and none is featured still lists them at a glance ── */
88
+ await page.click('[data-ini-tab="initiatives"]');
89
+ await until(() => st(() => !!document.querySelector('[data-ini="new-initiative"]')));
90
+ await page.click('[data-ini="new-initiative"]');
91
+ await until(() => st(() => !!document.querySelector('[data-ini="new-ini-form"]')));
92
+ await page.fill('[data-ini="ni-title"]', 'Partner sign-up page');
93
+ await page.fill('[data-ini="ni-anchor"]', 'KR 2.1 Activation to 45%');
94
+ await page.click('[data-ini="ni-create"]');
95
+ await until(() => st(() => !!document.querySelector('[data-ini-crumb="board"]')));
96
+ await page.click('[data-ini-crumb="board"]');
97
+ await until(() => st(() => !!document.querySelector('[data-ini-tab="summary"]')));
98
+ await page.click('[data-ini-tab="summary"]');
99
+ const pg = await until(() => st(() => document.querySelector('[data-ini-panel="summary"] [data-ini-catgo]') && { rows: document.querySelectorAll('[data-ini="glance"] [data-ini-row]').length, empty: /No open initiatives yet/.test(document.querySelector('[data-ini-panel="summary"]').textContent) }));
100
+ ok('B9 Summary lists an open initiative at a glance even when it has no work and is not featured', pg && pg.rows === 1 && !pg.empty, JSON.stringify(pg));
101
+
87
102
  /* ── New initiative, with its own workflow ── */
88
103
  await open('board:idpf:initiatives');
89
104
  await page.click('[data-ini="new-initiative"]');
@@ -24,7 +24,7 @@ Under the rows are a timeline of all boards (board › initiative › epic) and
24
24
 
25
25
  The tabs are **Summary**, **Initiatives**, **Triage**, **Backlog**, **Board**, **Timeline**, **Releases**, **Docs** and **Sprints**. A board with Build and deliver off has no Releases and no Sprints tab.
26
26
 
27
- - **Summary** shows the initiatives at a glance and one bar per category. Press a bar to open the Initiatives tab with that category.
27
+ - **Summary** shows the initiatives at a glance and one bar per category. At a glance lists up to six open initiatives. Initiatives with work, and Now initiatives that are not on track, come first. The others follow by end date. Press a bar to open the Initiatives tab with that category.
28
28
  - **Initiatives** lists the initiatives of the board, 25 on each page. Use the saved views (Now and next, Mine, At risk, No owner, All), the filters and the sort. Press **Move** on a row to move the initiative to a stage of its own workflow.
29
29
  - **Triage** lists the new asks. Add an ask, then open it to see its draft. Press **Accept** to start an initiative. An initiative needs an anchor (a KR or a health budget). Press **Ask for more** to ask a question, or **Decline** and give a reason.
30
30
  - **Backlog**, **Board** and **Timeline** show the epics and items. Jira items and PMOS tasks are mixed. The **Initiative** and **Source** filters are the same on the three tabs.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pmos-workspace",
3
- "version": "0.140.0",
3
+ "version": "0.141.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pmos-workspace",
9
- "version": "0.140.0",
9
+ "version": "0.141.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@xterm/addon-fit": "^0.11.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmos-workspace",
3
- "version": "0.140.0",
3
+ "version": "0.141.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",
@@ -335,8 +335,9 @@ export function mountInitiatives(pane, opts) {
335
335
  const inis = r.initiatives; const work = r.items; const open = inis.filter((i) => i.status !== 'done');
336
336
  const risk = inis.filter((i) => ['at risk', 'late'].includes(i.status)).sort((x, y) => String(x.end || '9').localeCompare(String(y.end || '9')));
337
337
  const withWork = new Set(work.map((w) => w.ini));
338
- const glance = open.filter((i) => withWork.has(i.id) || i.featured || (i.horizon === 'now' && i.status !== 'on track'))
339
- .sort((x, y) => (withWork.has(y.id) - withWork.has(x.id)) || ((y.featured ? 1 : 0) - (x.featured ? 1 : 0)) || String(x.end || '9').localeCompare(String(y.end || '9'))).slice(0, 6);
338
+ /* up to six open initiatives: the ones with work, featured, or Now and not on track first, then the rest by end date */
339
+ const prio = (i) => withWork.has(i.id) || i.featured || (i.horizon === 'now' && i.status !== 'on track') ? 1 : 0;
340
+ const glance = [...open].sort((x, y) => (prio(y) - prio(x)) || (withWork.has(y.id) - withWork.has(x.id)) || ((y.featured ? 1 : 0) - (x.featured ? 1 : 0)) || String(x.end || '9').localeCompare(String(y.end || '9'))).slice(0, 6);
340
341
  const epicsOf = (id) => work.filter((w) => w.ini === id && w.kind === 'Epic').length;
341
342
  const iniGlance = (i) => nrow({ ic: i.status === 'late' || i.status === 'at risk' ? 'alert' : 'init', hot: i.status === 'late' || i.status === 'at risk', title: i.title, onOpen: () => ctx.openInitiative(i.id), openLabel: 'Open ' + i.id,
342
343
  chips: [chipMono(i.id), stepsMini(wfOf(i, b), i.stage, tplName(i, b)), statusChip(i.status), progChip(i.progress || 0, toneOf(i)), ownerChip(i.owner), dateChip(i.start, i.end, i.status !== 'done' && i.end && daysBetween(ctx.today, i.end) < 0), chip(icon('bolt', 'sm'), plural(epicsOf(i.id), 'epic'))],