create-pmos 0.227.0 → 0.228.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/guide/notes.md +1 -1
- package/workspace/lib/calendar-events.js +7 -5
- package/workspace/lib/routes-calendar-views.js +6 -4
- package/workspace/package-lock.json +2 -2
- package/workspace/package.json +1 -1
- package/workspace/public/pm/view-notes.js +7 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-pmos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.228.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-14T07:
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-14T07:24:11Z"}
|
|
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-14T07:
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-14T07:24:11Z"}
|
|
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-14T07:
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-14T07:24:11Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
package/workspace/guide/notes.md
CHANGED
|
@@ -265,7 +265,7 @@ The task appears in your My Work view and on the initiative's board when the not
|
|
|
265
265
|
|
|
266
266
|
Under the title, a note shows two lines: **Meeting** and **Initiative**.
|
|
267
267
|
|
|
268
|
-
- **Meeting** is the calendar event the note was taken in, or **Not on the calendar** for a hallway chat or a call. Press **Change** to select an event of the note's day or the day before, or **Not on the calendar**.
|
|
268
|
+
- **Meeting** is the calendar event the note was taken in, or **Not on the calendar** for a hallway chat or a call. Press **Change** to select an event of the note's day or the day before, or **Not on the calendar**. The list has every meeting the Calendar shows on those days, including meetings imported in Settings › Import.
|
|
269
269
|
- **Initiative** is the initiative the meeting was about. It says how it was set: **from the calendar event**, **suggested from what was said**, or **chosen by you**. Press **Change** to open the list. The list shows the suggestion first, then the initiatives that are active now, then **None**. Initiatives planned for Next and Later are in the menu under them, each marked with its horizon. When more than one repository is open, a **Repository** menu at the top of the list changes which repository's initiatives you see. If the repository is still being read, the list says so and fills in by itself. Press the initiative's name to open it.
|
|
270
270
|
|
|
271
271
|
When a note has no initiative, the summary suggests one: the open initiative that shares 3 or more words with what was said, when no other initiative shares as many. A suggestion never replaces an initiative you chose.
|
|
@@ -72,10 +72,10 @@ function readAll(runtimeDir, { now = Date.now() } = {}) {
|
|
|
72
72
|
return out.sort((a, b) => (Date.parse(a.at) || 0) - (Date.parse(b.at) || 0));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
/**
|
|
76
|
-
* the local day
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
/** One day's meetings as the Record menu and a note's meeting picker read them (GET /api/calendar-today?date=): every event readAll
|
|
76
|
+
* joins, kept when its start falls on the local day `day` (YYYY-MM-DD), in the shape the menu and a note's meeting link use:
|
|
77
|
+
* { id, start, end, title, time, minutes, with, src, ... }. Pure. */
|
|
78
|
+
function eventsOn(events, day) {
|
|
79
79
|
const out = [];
|
|
80
80
|
for (const e of events || []) {
|
|
81
81
|
const s = Date.parse(e && e.at);
|
|
@@ -89,5 +89,7 @@ function todayOf(events, now = Date.now()) {
|
|
|
89
89
|
}
|
|
90
90
|
return out.sort((a, b) => Date.parse(a.start) - Date.parse(b.start));
|
|
91
91
|
}
|
|
92
|
+
/** Today's meetings (the Record menu): eventsOn the local day of `now`. */
|
|
93
|
+
const todayOf = (events, now = Date.now()) => eventsOn(events, localDate(now));
|
|
92
94
|
|
|
93
|
-
module.exports = { readAll, asEvent, localIso, todayOf };
|
|
95
|
+
module.exports = { readAll, asEvent, localIso, todayOf, eventsOn };
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* layers, layers_total, layers_note, free, context, context_total, (lib/calendar-layers.js)
|
|
6
6
|
* link_boards } every board a meeting can be linked to: [{ ws, id, name }]
|
|
7
7
|
* &only=gantt → { ok, view, range, gantt, no_plan, strategy, today } the rows with a plan date or a Jira read, and how many have neither
|
|
8
|
-
* GET /api/calendar-today → { ok, date, events }
|
|
8
|
+
* GET /api/calendar-today[?date=YYYY-MM-DD] → { ok, date, events } one day's meetings (default today) for the Record menu and a
|
|
9
|
+
* note's meeting picker (calendar-events.js eventsOn)
|
|
9
10
|
* POST /api/calendar-links → { ok, link } what a meeting is about (lib/calendar-links.js, below)
|
|
10
11
|
* tidy, tidy_total, tidy_note } (lib/calendar-tidy.js: suggestions in words, no write)
|
|
11
12
|
*
|
|
@@ -232,10 +233,11 @@ module.exports = {
|
|
|
232
233
|
if (url.pathname === '/api/calendar-today') {
|
|
233
234
|
if (req.method !== 'GET') { ctx.json(res, { ok: false, error: 'GET only' }, 405); return true; }
|
|
234
235
|
const cal = require('./calendar-events.js');
|
|
235
|
-
const
|
|
236
|
+
const date = url.searchParams.get('date') || today();
|
|
237
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) { ctx.json(res, { ok: false, error: 'date must be YYYY-MM-DD' }, 400); return true; }
|
|
236
238
|
let events = [];
|
|
237
|
-
try { events = cal.
|
|
238
|
-
ctx.json(res, { ok: true, date
|
|
239
|
+
try { events = cal.eventsOn(cal.readAll(ctx.runtimeDir, { now: Date.now() }), date); } catch { events = []; }
|
|
240
|
+
ctx.json(res, { ok: true, date, events });
|
|
239
241
|
return true;
|
|
240
242
|
}
|
|
241
243
|
if (url.pathname !== '/api/calendar-views') return false;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmos-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.228.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.228.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@xterm/addon-fit": "^0.11.0",
|
package/workspace/package.json
CHANGED
|
@@ -1191,18 +1191,15 @@ async function link(ctx, n, patch, said) {
|
|
|
1191
1191
|
} else banner = { tone: 'bad', text: (r && r.error) || 'the link was not changed' };
|
|
1192
1192
|
ctx.setState({});
|
|
1193
1193
|
}
|
|
1194
|
-
/** The events of the note's day and the day before, from the
|
|
1194
|
+
/** The events of the note's day and the day before, from the list the Calendar draws (GET /api/calendar-today?date=, lib/calendar-events.js
|
|
1195
|
+
* readAll). The Agenda's read held only the calendar memory and today's brief, so an imported meeting was on the Calendar and missing here. */
|
|
1195
1196
|
async function eventsNear(n) {
|
|
1196
1197
|
const at = n.created_at || new Date().toISOString();
|
|
1197
|
-
const
|
|
1198
|
-
const
|
|
1199
|
-
const reads = await Promise.all(months.map((m) => pmGet('/api/proactive/agenda?month=' + m)));
|
|
1198
|
+
const days = [dateOfIso(new Date(Date.parse(at) - 86400000).toISOString()), dateOfIso(at)];
|
|
1199
|
+
const reads = await Promise.all(days.map((d) => pmGet('/api/calendar-today?date=' + d)));
|
|
1200
1200
|
const out = []; const seen = new Set();
|
|
1201
|
-
for (const
|
|
1202
|
-
|
|
1203
|
-
for (const d of [before, day]) for (const e of ((r.days[d] && r.days[d].events) || [])) { const k = e.start + '|' + e.title; if (!seen.has(k)) { seen.add(k); out.push({ ...e, date: d }); } }
|
|
1204
|
-
}
|
|
1205
|
-
return out.sort((a, b) => String(a.start).localeCompare(String(b.start)));
|
|
1201
|
+
reads.forEach((r, i) => { for (const e of (r && r.events) || []) { const k = e.start + '|' + e.title; if (!seen.has(k)) { seen.add(k); out.push({ ...e, date: days[i] }); } } });
|
|
1202
|
+
return out.sort((a, b) => Date.parse(a.start) - Date.parse(b.start));
|
|
1206
1203
|
}
|
|
1207
1204
|
async function meetingSheet(ctx, n) {
|
|
1208
1205
|
const box = el('div', { class: 'nt-picks', role: 'radiogroup', 'aria-label': 'Meeting' }, el('p', { class: 'nt-hint' }, 'reading your calendar …'));
|
|
@@ -1227,7 +1224,7 @@ async function meetingSheet(ctx, n) {
|
|
|
1227
1224
|
if (on) pick = String(i);
|
|
1228
1225
|
const other = notesFor(e).some((x) => x.id !== n.id);
|
|
1229
1226
|
return opt(String(i), e.title, dayOf(e.start) + ', ' + e.time + (other ? ' · has a note' : ''), on);
|
|
1230
|
-
}), evs.length ?
|
|
1227
|
+
}), ...(evs.length ? [] : [el('p', { class: 'nt-hint' }, 'No calendar events on these days.')]),
|
|
1231
1228
|
opt('adhoc', 'Not on the calendar', 'a hallway chat, a call', pick === 'adhoc'));
|
|
1232
1229
|
}
|
|
1233
1230
|
const HORIZON_WORDS = { now: 'Now', next: 'Next', later: 'Later' };
|