create-pmos 0.52.0 → 0.53.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 +2 -2
- package/payload/mods/pmos-cockpit/README.md +13 -0
- package/payload/mods/pmos-cockpit/hooks/lib/commands.mjs +2 -1
- package/payload/mods/pmos-cockpit/hooks/lib/grants.mjs +41 -11
- package/payload/mods/pmos-cockpit/hooks/lib/guard.mjs +228 -8
- package/payload/mods/pmos-cockpit/hooks/register.tsx +11 -3
- package/payload/planning/evals/eval-calibration.md +1 -1
- package/payload/planning/okrs/health-budgets.md +1 -1
- package/payload/scripts/plan-items-stage.js +271 -0
- package/payload/scripts/pmos-log.sh +18 -7
- package/payload/scripts/workflow-state.js +28 -2
- package/payload/state/discoveries.md +1 -1
- package/payload/state/log.md +1 -1
- package/workspace/bin/pmos.js +15 -1
- package/workspace/cut-stub.js +40 -0
- package/workspace/first-paint-audit.js +145 -0
- package/workspace/fixtures/capture/requirements/capture-2026-10-04-1.md +10 -0
- package/workspace/fixtures/initiatives-api/list.json +176 -0
- package/workspace/fixtures/initiatives-api/post-403.json +5 -0
- package/workspace/fixtures/initiatives-api/post-ok.json +10 -0
- package/workspace/fixtures/initiatives-api/roadmap.json +208 -0
- package/workspace/fixtures/initiatives-api/sheet.json +112 -0
- package/workspace/fixtures/report-api/draft.json +177 -0
- package/workspace/fixtures/reports-page/draft-biweekly-2026-10-16.md +97 -0
- package/workspace/fixtures/today-api/provider-rows.json +204 -0
- package/workspace/fixtures/today-api/seam-probe-kinds.json +5 -0
- package/workspace/guide/board.md +81 -0
- package/workspace/guide/breakdown.md +154 -0
- package/workspace/guide/command-palette.md +75 -0
- package/workspace/guide/index.md +27 -17
- package/workspace/guide/initiatives-roadmap.md +130 -0
- package/workspace/guide/initiatives-screen.md +89 -0
- package/workspace/guide/initiatives-timeline.md +57 -0
- package/workspace/guide/integrated-work.md +94 -0
- package/workspace/guide/knowledge-graph.md +3 -68
- package/workspace/guide/layout.md +98 -32
- package/workspace/guide/live-notes.md +3 -3
- package/workspace/guide/pm-only-acts.md +89 -0
- package/workspace/guide/pm-only-lines.md +61 -0
- package/workspace/guide/reports-page.md +80 -0
- package/workspace/guide/reports.md +73 -0
- package/workspace/guide/timeline.md +70 -0
- package/workspace/guide/today.md +85 -0
- package/workspace/guide/validate-with-typesafe.md +1 -1
- package/workspace/lib/actor.js +91 -0
- package/workspace/lib/board-cache.js +32 -2
- package/workspace/lib/board-cli.js +108 -0
- package/workspace/lib/board-fold.js +232 -0
- package/workspace/lib/breakdown-export.js +80 -0
- package/workspace/lib/capture.js +98 -0
- package/workspace/lib/engine/plan-items-stage.js +271 -0
- package/workspace/lib/engine/workflow-state.js +28 -2
- package/workspace/lib/factory-join.js +158 -0
- package/workspace/lib/grant-mint.js +113 -0
- package/workspace/lib/health-rules-factory.js +92 -0
- package/workspace/lib/health-rules-plan.js +164 -0
- package/workspace/lib/health.js +79 -0
- package/workspace/lib/initiative-cli.js +222 -0
- package/workspace/lib/initiative-display.js +183 -0
- package/workspace/lib/initiative-needs.js +127 -0
- package/workspace/lib/initiative-rows.js +206 -0
- package/workspace/lib/initiative-writer.js +141 -0
- package/workspace/lib/issues.js +206 -0
- package/workspace/lib/item-cli.js +195 -0
- package/workspace/lib/item-spans.js +137 -0
- package/workspace/lib/measure-cli.js +100 -0
- package/workspace/lib/measurements.js +189 -0
- package/workspace/lib/mobile-nav.js +57 -53
- package/workspace/lib/needs-providers.js +120 -0
- package/workspace/lib/placements.js +440 -0
- package/workspace/lib/plan-items.js +922 -0
- package/workspace/lib/plan-ledgers.js +85 -0
- package/workspace/lib/plan-rules.js +72 -0
- package/workspace/lib/plan-tree.js +367 -0
- package/workspace/lib/pm-guard.js +174 -0
- package/workspace/lib/pm-lines-needs.js +331 -0
- package/workspace/lib/pmos-verbs.js +66 -0
- package/workspace/lib/proactive.js +7 -4
- package/workspace/lib/report-cli.js +152 -0
- package/workspace/lib/report-draft.js +579 -0
- package/workspace/lib/report-needs.js +213 -0
- package/workspace/lib/route-modules.js +128 -0
- package/workspace/lib/routes-board.js +91 -0
- package/workspace/lib/routes-capture.js +52 -0
- package/workspace/lib/routes-initiatives.js +371 -0
- package/workspace/lib/routes-reports.js +163 -0
- package/workspace/lib/routes-timeline.js +197 -0
- package/workspace/lib/routes-today.js +32 -0
- package/workspace/lib/today-cli.js +99 -0
- package/workspace/lib/today.js +333 -0
- package/workspace/lib/triage.js +163 -0
- package/workspace/lib/verify-work-cli.js +81 -0
- package/workspace/lib/work-check-needs.js +99 -0
- package/workspace/package-lock.json +1 -1
- package/workspace/package.json +4 -5
- package/workspace/public/index.html +29 -19
- package/workspace/public/pm/app.js +299 -30
- package/workspace/public/pm/bd-board.js +113 -0
- package/workspace/public/pm/bd-drag.js +59 -0
- package/workspace/public/pm/bd-model.js +152 -0
- package/workspace/public/pm/bd-timeline.js +233 -0
- package/workspace/public/pm/bd-tree.js +244 -0
- package/workspace/public/pm/board-copy.js +57 -0
- package/workspace/public/pm/breakdown-api.js +58 -0
- package/workspace/public/pm/breakdown-copy.js +138 -0
- package/workspace/public/pm/components.css +3054 -0
- package/workspace/public/pm/cycle-review.js +125 -0
- package/workspace/public/pm/data.js +40 -187
- package/workspace/public/pm/dest-board.js +438 -0
- package/workspace/public/pm/dest-initiatives.js +134 -0
- package/workspace/public/pm/dest-reports.js +270 -0
- package/workspace/public/pm/dest-settings.js +217 -0
- package/workspace/public/pm/dest-today.js +176 -0
- package/workspace/public/pm/dialogs.js +88 -0
- package/workspace/public/pm/display-word.js +56 -0
- package/workspace/public/pm/dock.js +105 -0
- package/workspace/public/pm/fixture.js +8 -227
- package/workspace/public/pm/frame-copy.js +94 -0
- package/workspace/public/pm/handoff-box.js +82 -0
- package/workspace/public/pm/http.js +88 -0
- package/workspace/public/pm/icons.js +53 -0
- package/workspace/public/pm/initiative-list.js +218 -0
- package/workspace/public/pm/initiative-sheet.js +261 -0
- package/workspace/public/pm/initiatives-api.js +59 -0
- package/workspace/public/pm/initiatives-copy.js +215 -0
- package/workspace/public/pm/initiatives-timeline-copy.js +59 -0
- package/workspace/public/pm/initiatives-timeline.js +410 -0
- package/workspace/public/pm/initiatives-ui.js +123 -0
- package/workspace/public/pm/item-sheet.js +251 -0
- package/workspace/public/pm/keep-card.js +204 -0
- package/workspace/public/pm/lifecycle.js +7 -1
- package/workspace/public/pm/mobile.css +49 -20
- package/workspace/public/pm/mobile.js +157 -29
- package/workspace/public/pm/modes-live.js +7 -883
- package/workspace/public/pm/modes.js +32 -1024
- package/workspace/public/pm/new-initiative-sheet.js +74 -0
- package/workspace/public/pm/next-step-ui.js +3 -2
- package/workspace/public/pm/palette-copy.js +51 -0
- package/workspace/public/pm/palette.js +312 -0
- package/workspace/public/pm/panel-breakdown.js +702 -0
- package/workspace/public/pm/panel-cockpit.js +63 -295
- package/workspace/public/pm/panel-detail.js +25 -172
- package/workspace/public/pm/panel-initiatives.js +1 -19
- package/workspace/public/pm/panel-repos.js +31 -81
- package/workspace/public/pm/panel-tabs.js +197 -110
- package/workspace/public/pm/panel-trees.js +5 -2
- package/workspace/public/pm/portfolio-report.js +61 -0
- package/workspace/public/pm/primitives.js +656 -0
- package/workspace/public/pm/print.css +33 -0
- package/workspace/public/pm/provider-cards.js +136 -0
- package/workspace/public/pm/registry.js +194 -0
- package/workspace/public/pm/release-card.js +110 -0
- package/workspace/public/pm/report-view.js +309 -0
- package/workspace/public/pm/reports-copy.js +114 -0
- package/workspace/public/pm/roadmap.js +271 -0
- package/workspace/public/pm/sig-watch.js +41 -0
- package/workspace/public/pm/state.js +8 -4
- package/workspace/public/pm/status-banner.js +13 -5
- package/workspace/public/pm/tab-doc.js +2 -4
- package/workspace/public/pm/tab-term.js +12 -2
- package/workspace/public/pm/tab-web.js +3 -2
- package/workspace/public/pm/timeline-copy.js +48 -0
- package/workspace/public/pm/today-cards.js +244 -0
- package/workspace/public/pm/today-copy.js +97 -0
- package/workspace/public/pm/tokens.css +16 -18
- package/workspace/public/pm/topbar.js +102 -0
- package/workspace/public/pm/triage-card.js +60 -0
- package/workspace/public/pm/undo-hold.js +103 -0
- package/workspace/public/pm/view-addrepo.js +2 -1
- package/workspace/public/pm/view-livenotes.js +3 -1
- package/workspace/public/pm/view-today.js +7 -162
- package/workspace/public/vendor/Sortable.min.js +2 -0
- package/workspace/public/vendor/lucide-sprite.js +79 -0
- package/workspace/replaced-tests.json +2864 -0
- package/workspace/run-tests.js +56 -5
- package/workspace/server.js +312 -36
- package/workspace/sheet-answer.js +61 -0
- package/workspace/skills/measure.skill +41 -0
- package/workspace/skills/report-biweekly.skill +23 -25
- package/workspace/skills/tracker-refresh.skill +50 -0
- package/workspace/test-files.json +19 -3
- package/workspace/test-lists/base.json +6 -0
- package/workspace/test-lists/run2-a.json +6 -0
- package/workspace/test-lists/run2-b.json +13 -0
- package/workspace/test-lists/run2-c.json +19 -0
- package/workspace/test-lists/run2-d.json +22 -0
- package/workspace/test-lists/run3-0.json +5 -0
- package/workspace/test-lists/run3-a.json +5 -0
- package/workspace/test-lists/run3-b.json +6 -0
- package/workspace/test-lists/run3-c.json +15 -0
- package/workspace/test-lists/run3-d.json +6 -0
- package/workspace/test-lists/run4-a.json +8 -0
- package/workspace/test-lists/run4-b.json +6 -0
- package/workspace/test-lists/run4-c.json +13 -0
- package/workspace/test-lists/run4-d.json +9 -0
- package/workspace/test-lists/run5-a.json +6 -0
- package/workspace/test-lists/run5-b.json +6 -0
- package/workspace/test-lists/run5-c.json +15 -0
- package/workspace/test-run.js +27 -1
- package/workspace/third-party/README.md +44 -0
- package/workspace/third-party/lucide-static-1.52.0.LICENSE +43 -0
- package/workspace/third-party/sortablejs-1.15.7.LICENSE +21 -0
- package/workspace/design-parity.js +0 -673
- package/workspace/public/pm/tab-task.js +0 -86
- package/workspace/public/pm/view-guide.js +0 -141
- package/workspace/public/pm/view-knowledge.js +0 -225
- package/workspace/public/pm/view-memory.js +0 -122
- package/workspace/public/pm/view-portfolio.js +0 -153
- package/workspace/public/pm/view-reports.js +0 -190
- package/workspace/public/pm/view-scheduled.js +0 -161
- package/workspace/public/pm/view-skills.js +0 -216
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* pm/board-copy.js — every word the Board destination shows (pm-os-absorb Run 4, slice 4D).
|
|
2
|
+
*
|
|
3
|
+
* Pure data and pure functions. No DOM and no import, so glossary.test.js loads this file in Node and checks every string
|
|
4
|
+
* against the glossary. The four column names, the signals and the item sheet's words are the Breakdown's own
|
|
5
|
+
* (breakdown-copy.js): the Board reuses them, so a state has one name on every screen.
|
|
6
|
+
*
|
|
7
|
+
* The word Release is exempt from the glossary's `release` rule for this file only. On the Board it names the D65 gate that
|
|
8
|
+
* a person presses on a batch of work items, which is the one place the rule lets it stand.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const COPY = {
|
|
12
|
+
reading: 'Reading…',
|
|
13
|
+
readFailed: (why) => `Could not read the Board: ${why}`,
|
|
14
|
+
filter: 'Board filter',
|
|
15
|
+
filters: { active: 'Active', mine: 'Mine' },
|
|
16
|
+
initiative: 'Initiative',
|
|
17
|
+
anyInitiative: 'All initiatives',
|
|
18
|
+
addItem: 'Add item',
|
|
19
|
+
adding: {
|
|
20
|
+
title: 'Add item',
|
|
21
|
+
sub: 'The item goes to its initiative. Enter adds it.',
|
|
22
|
+
fieldTitle: 'Title',
|
|
23
|
+
fieldInitiative: 'Initiative',
|
|
24
|
+
fieldStage: 'Stage',
|
|
25
|
+
add: 'Add',
|
|
26
|
+
cancel: 'Cancel',
|
|
27
|
+
needTitle: 'Type a title first.',
|
|
28
|
+
needInitiative: 'No initiative can take an item yet.',
|
|
29
|
+
},
|
|
30
|
+
added: 'Item added.',
|
|
31
|
+
noItems: 'No item matches this filter. Choose another filter, or press Add item.',
|
|
32
|
+
noWorkspace: 'No repository is open. Open one to see its Board.',
|
|
33
|
+
noInitiatives: 'No initiative does work yet. A document initiative has no items.',
|
|
34
|
+
stageOf: (initiative, stage) => `${initiative} · ${stage}`,
|
|
35
|
+
notMerged: 'Done · your call · not merged',
|
|
36
|
+
summary: (n) => (n === 1 ? '1 item' : `${n} items`),
|
|
37
|
+
release: {
|
|
38
|
+
head: 'Release',
|
|
39
|
+
title: (initiative) => `Release · ${initiative}`,
|
|
40
|
+
batch: (id) => `Batch ${id}`,
|
|
41
|
+
items: (n) => (n === 1 ? '1 work item ready' : `${n} work items ready`),
|
|
42
|
+
press: 'Release',
|
|
43
|
+
pressLabel: (initiative, id) => `Release batch ${id} of ${initiative}`,
|
|
44
|
+
pressed: (n) => (n === 1 ? 'Release granted for 1 work item.' : `Release granted for ${n} work items.`),
|
|
45
|
+
waiting: 'Release arrives in Run 2.',
|
|
46
|
+
failed: (why) => `Release was not granted: ${why}`,
|
|
47
|
+
note: 'One press grants the whole batch. The factory opens pull requests only. It never merges.',
|
|
48
|
+
},
|
|
49
|
+
aria: {
|
|
50
|
+
open: (t) => `Open ${t}`,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const GLOSSARY = {
|
|
55
|
+
exempt: { release: 'On the Board, Release is the name of the D65 gate that a person presses on a batch of work items.' },
|
|
56
|
+
guide: 'board.md',
|
|
57
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* pm/breakdown-api.js — the four requests the Breakdown makes (pm-os-absorb Run 1), plus the needs read Today uses.
|
|
2
|
+
*
|
|
3
|
+
* Relative URLs only, to this server. Every POST goes through pm/http.js pressFetch, so it carries the
|
|
4
|
+
* per-launch nonce, and the browser adds the page's own Origin: the server's guard (lib/pm-guard.js) requires both before
|
|
5
|
+
* it records a write as the PM's (`pm:wawan`, via `ui`). Nothing here sends `by`, `via` or `at`; the writer sets them.
|
|
6
|
+
*
|
|
7
|
+
* Every function resolves to the server's JSON, or to `{ ok:false, error }` when the server could not be reached or did
|
|
8
|
+
* not answer JSON. None of them throws. In FIXTURE mode none of them makes a request.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { FIXTURE } from './state.js';
|
|
12
|
+
import { pressFetch } from './http.js';
|
|
13
|
+
|
|
14
|
+
const qs = (o) => Object.entries(o).filter(([, v]) => v !== null && v !== undefined && v !== '')
|
|
15
|
+
.map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)).join('&');
|
|
16
|
+
|
|
17
|
+
async function call(method, url, body, opts) {
|
|
18
|
+
if (FIXTURE) return { ok: false, error: 'fixture mode' };
|
|
19
|
+
let res;
|
|
20
|
+
try {
|
|
21
|
+
res = await (method === 'GET' ? fetch(url) : pressFetch(url, {
|
|
22
|
+
method, body: JSON.stringify(body), // pm/http.js: carries the per-launch nonce, and renews a stale one
|
|
23
|
+
keepalive: !!(opts && opts.keepalive),
|
|
24
|
+
}));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
return { ok: false, error: 'could not reach the workspace server — ' + ((e && e.message) || String(e)) };
|
|
27
|
+
}
|
|
28
|
+
let out;
|
|
29
|
+
try { out = await res.json(); } catch { return { ok: false, status: res.status, error: 'the server did not answer JSON (HTTP ' + res.status + ')' }; }
|
|
30
|
+
if (!res.ok && out && out.ok !== false) return { ok: false, status: res.status, error: 'HTTP ' + res.status };
|
|
31
|
+
if (out && typeof out === 'object' && !res.ok) out.status = res.status;
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** GET the Layout of one initiative. `ladder:false` is the fast path: no owed rows, used when only the items changed. */
|
|
36
|
+
export function getLayout(ws, id, { ladder = true } = {}) {
|
|
37
|
+
return call('GET', '/api/plan-items?' + qs({ ws, id, ladder: ladder ? null : '0' }));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** POST 1 to 50 events. `keepalive` lets a held write still reach the server while the page unloads. */
|
|
41
|
+
export function postEvents(ws, events, { keepalive = false } = {}) {
|
|
42
|
+
return call('POST', '/api/plan-items', { ws, events }, { keepalive });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Ask the server what Hand to agent would start. Starts nothing. */
|
|
46
|
+
export function prepareHandoff(ws, item) {
|
|
47
|
+
return call('POST', '/api/plan-items/handoff/prepare', { ws, item });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Start exactly what was prepared: the server refuses a prompt that changed since `sha`. */
|
|
51
|
+
export function goHandoff(ws, item, sha) {
|
|
52
|
+
return call('POST', '/api/plan-items/handoff/go', { ws, item, confirm: true, prompt_sha: sha });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The needs-you queue of one workspace (the existing route). Today reads its Keep, evidence and check rows. */
|
|
56
|
+
export function getNeeds(ws) {
|
|
57
|
+
return call('GET', '/api/needs?' + qs({ ws }));
|
|
58
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/* pm/breakdown-copy.js — every word the Breakdown shows (pm-os-absorb Run 1).
|
|
2
|
+
*
|
|
3
|
+
* Pure data and pure functions. No DOM and no import, so `glossary.test.js` can load this file in Node and check every
|
|
4
|
+
* string against the glossary rules. A string that a person reads on the Breakdown, in the item sheet, on a Keep card
|
|
5
|
+
* or in a toast is written here and nowhere else.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const MON = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
9
|
+
|
|
10
|
+
/** "2026-10-20" -> "20 Oct". A date-only value is read as a calendar day, never shifted by the time zone. */
|
|
11
|
+
export function shortDate(ymd) {
|
|
12
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(String(ymd || ''));
|
|
13
|
+
if (!m) return '';
|
|
14
|
+
return Number(m[3]) + ' ' + MON[Number(m[2]) - 1];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** An ISO timestamp -> "5 Oct", in the viewer's own calendar. */
|
|
18
|
+
export function dayOf(iso) {
|
|
19
|
+
const d = new Date(iso);
|
|
20
|
+
if (Number.isNaN(d.getTime())) return '';
|
|
21
|
+
return d.getDate() + ' ' + MON[d.getMonth()];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** An ISO timestamp -> "just now", "4 min ago", "3 h ago", "2 days ago", or the day for anything older than a week. */
|
|
25
|
+
export function ago(iso, now) {
|
|
26
|
+
const t = new Date(iso).getTime();
|
|
27
|
+
const n = Number.isFinite(now) ? now : Date.now();
|
|
28
|
+
if (!Number.isFinite(t)) return '';
|
|
29
|
+
const s = Math.max(0, Math.round((n - t) / 1000));
|
|
30
|
+
if (s < 60) return 'just now';
|
|
31
|
+
if (s < 3600) return Math.round(s / 60) + ' min ago';
|
|
32
|
+
if (s < 86400) return Math.round(s / 3600) + ' h ago';
|
|
33
|
+
const d = Math.round(s / 86400);
|
|
34
|
+
if (d < 8) return d === 1 ? '1 day ago' : d + ' days ago';
|
|
35
|
+
return dayOf(iso);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** 1 -> "1 item", 9 -> "9 items". */
|
|
39
|
+
export const items = (n) => (n === 1 ? '1 item' : `${n} items`);
|
|
40
|
+
|
|
41
|
+
/** "agent · sess-3" -> "Agent · sess-3": a label at the start of a sentence. */
|
|
42
|
+
const cap = (s) => String(s || '').charAt(0).toUpperCase() + String(s || '').slice(1);
|
|
43
|
+
|
|
44
|
+
export const STATES = ['todo', 'doing', 'review', 'done'];
|
|
45
|
+
|
|
46
|
+
export const COPY = {
|
|
47
|
+
breakdown: 'Breakdown',
|
|
48
|
+
noBreakdown: 'no breakdown',
|
|
49
|
+
proposedOnly: (n) => `no breakdown · ${n} proposed`,
|
|
50
|
+
progress: (d, t) => `${d} of ${t}`,
|
|
51
|
+
reading: 'Reading…',
|
|
52
|
+
readFailed: (why) => `Could not read the breakdown: ${why}`,
|
|
53
|
+
owedFailed: (why) => `Owed steps are not shown. The workflow could not be read: ${why}`,
|
|
54
|
+
flagsHead: (n) => (n === 1 ? 'plan-items.jsonl has 1 flagged line:' : `plan-items.jsonl has ${n} flagged lines:`),
|
|
55
|
+
flagsMore: (n) => `and ${n} more`,
|
|
56
|
+
tree: 'Tree',
|
|
57
|
+
board: 'Board',
|
|
58
|
+
views: 'Breakdown view',
|
|
59
|
+
states: { todo: 'Todo', doing: 'Doing', review: 'Review', done: 'Done' },
|
|
60
|
+
stateCount: (s, n) => `${s} ${n}`,
|
|
61
|
+
columns: 'Board column',
|
|
62
|
+
signals: { blocked: 'Blocked', noEvidence: 'no evidence', late: 'late', movedByYou: 'moved by you', proposed: 'Proposed' },
|
|
63
|
+
owed: (noun, actor) => `Owed: ${noun} · ${actor}`,
|
|
64
|
+
derived: 'derived',
|
|
65
|
+
current: 'current',
|
|
66
|
+
other: 'Other',
|
|
67
|
+
proposedCount: (n) => `${n} proposed`,
|
|
68
|
+
showDone: (n) => `Show ${n} done`,
|
|
69
|
+
hideDone: (n) => `Hide ${n} done`,
|
|
70
|
+
addItem: 'Add item',
|
|
71
|
+
newItem: 'New item',
|
|
72
|
+
newItemHint: 'Enter adds it. Paste a list to add one item per line.',
|
|
73
|
+
tooMany: (n) => `${n} lines is more than 50. Nothing was added.`,
|
|
74
|
+
due: (d) => `due ${d}`,
|
|
75
|
+
by: (who) => `by ${who}`,
|
|
76
|
+
owners: { you: 'You', agent: 'Agent', person: 'Person', tracker: 'Tracker' },
|
|
77
|
+
keepTree: (n, date, who) => `${who ? cap(who) : 'The agent'} proposed ${items(n)} on ${date}.`,
|
|
78
|
+
keepToday: (n, who) => (who ? `${items(n)} · ${who}` : items(n)),
|
|
79
|
+
proposedBy: (who, date) => `Proposed by ${who || 'the agent'}${date ? ' on ' + date : ''}. It does not count until you keep it.`,
|
|
80
|
+
keepAll: 'Keep all',
|
|
81
|
+
addEvidence: 'Add evidence',
|
|
82
|
+
evidenceHint: 'commit:<sha>, pr:<number>, file:<path> or note:<text>',
|
|
83
|
+
keep: 'Keep',
|
|
84
|
+
withdrawAll: 'Withdraw all',
|
|
85
|
+
kept: (n) => `Kept ${items(n)}.`,
|
|
86
|
+
handToAgent: 'Hand to agent',
|
|
87
|
+
agentWill: (first, where) => `Agent will: ${first} · ${where}`,
|
|
88
|
+
preparing: 'Preparing…',
|
|
89
|
+
go: 'Go',
|
|
90
|
+
details: 'Details',
|
|
91
|
+
cancel: 'Cancel',
|
|
92
|
+
branch: 'Branch',
|
|
93
|
+
folder: 'Folder',
|
|
94
|
+
busy: 'A session is already working on this item.',
|
|
95
|
+
openSession: 'Open session',
|
|
96
|
+
sessionStarted: (name) => `Session started: ${name}`,
|
|
97
|
+
undo: 'Undo',
|
|
98
|
+
markedDone: 'Marked done.',
|
|
99
|
+
withdrawn: 'Withdrawn.',
|
|
100
|
+
withdrewN: (n) => `Withdrew ${items(n)}.`,
|
|
101
|
+
olderInTree: (n) => `${n} older in the Tree`,
|
|
102
|
+
nothingHere: 'Nothing here.',
|
|
103
|
+
emptyColumn: (s) => `Nothing in ${s}.`,
|
|
104
|
+
labels: {
|
|
105
|
+
title: 'Title', owner: 'Owner', ownerName: 'Name', trackerRef: 'Reference', stage: 'Stage', after: 'After', start: 'Start',
|
|
106
|
+
due: 'Due', milestone: 'Milestone', blocked: 'Blocked', blockedBecause: 'Blocked because', note: 'Note', history: 'History',
|
|
107
|
+
close: 'Close', withdraw: 'Withdraw', state: 'State',
|
|
108
|
+
},
|
|
109
|
+
afterNone: 'Nothing. It can start any time.',
|
|
110
|
+
addPredecessor: 'Add predecessor',
|
|
111
|
+
otherItemId: 'Item id from another initiative',
|
|
112
|
+
add: 'Add',
|
|
113
|
+
aria: {
|
|
114
|
+
reorder: (t) => `Reorder ${t}`,
|
|
115
|
+
markDone: (t) => `Mark done: ${t}`,
|
|
116
|
+
markNotDone: (t) => `Mark not done: ${t}`,
|
|
117
|
+
more: (t) => `More for ${t}`,
|
|
118
|
+
collapse: (s) => `Collapse ${s}`,
|
|
119
|
+
expand: (s) => `Expand ${s}`,
|
|
120
|
+
remove: (t) => `Remove ${t}`,
|
|
121
|
+
open: (t) => `Open ${t}`,
|
|
122
|
+
},
|
|
123
|
+
menu: { open: 'Open', moveTo: (s) => `Move to ${s}`, moveUp: 'Move up', moveDown: 'Move down' },
|
|
124
|
+
needs: {
|
|
125
|
+
evidence: 'no evidence',
|
|
126
|
+
flag: 'check',
|
|
127
|
+
open: 'Open',
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/** The owner as a person reads it: `person:Mei` -> "Mei", `tracker:NW-430` -> "NW-430". */
|
|
132
|
+
export function ownerLabel(owner) {
|
|
133
|
+
const o = String(owner || 'you');
|
|
134
|
+
if (o === 'you') return COPY.owners.you;
|
|
135
|
+
if (o === 'agent') return COPY.owners.agent;
|
|
136
|
+
const i = o.indexOf(':');
|
|
137
|
+
return i > 0 ? o.slice(i + 1) : o;
|
|
138
|
+
}
|