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 +1 -1
- package/payload/KIT-VERSION +1 -1
- package/payload/planning/evals/eval-calibration.md +1 -1
- package/payload/planning/okrs/health-budgets.md +1 -1
- package/payload/state/discoveries.md +1 -1
- package/workspace/c3-ib-triage-backlog-test.js +1 -0
- package/workspace/c3-initiatives-test.js +15 -0
- package/workspace/guide/initiative-boards.md +1 -1
- package/workspace/package-lock.json +2 -2
- package/workspace/package.json +1 -1
- package/workspace/public/pm/c3-initiatives.js +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-pmos",
|
|
3
|
-
"version": "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": {
|
package/payload/KIT-VERSION
CHANGED
|
@@ -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:
|
|
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:
|
|
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:
|
|
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.
|
|
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.
|
|
9
|
+
"version": "0.141.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@xterm/addon-fit": "^0.11.0",
|
package/workspace/package.json
CHANGED
|
@@ -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
|
-
|
|
339
|
-
|
|
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'))],
|