create-pmos 0.197.0 → 0.198.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-report-design-real-test.js +225 -0
- package/workspace/c3-report-design-test.js +403 -0
- package/workspace/c3-report-setup-test.js +3 -2
- package/workspace/c3-work-test.js +1 -1
- package/workspace/guide/index.md +1 -0
- package/workspace/guide/report-design.md +104 -0
- package/workspace/guide/report-slides.md +3 -1
- package/workspace/guide/reports-set-up.md +2 -1
- package/workspace/lib/headless.js +24 -6
- package/workspace/lib/report-design.js +741 -0
- package/workspace/lib/report-draft.js +8 -3
- package/workspace/lib/report-setups.js +1 -1
- package/workspace/lib/route-modules.js +1 -0
- package/workspace/lib/routes-doc-sheet.js +8 -1
- package/workspace/lib/routes-report-design.js +481 -0
- package/workspace/lib/routes-reports.js +2 -1
- package/workspace/package-lock.json +2 -2
- package/workspace/package.json +1 -1
- package/workspace/public/pm/c3-demo-rd.js +426 -0
- package/workspace/public/pm/c3-demo-rep2.js +2 -0
- package/workspace/public/pm/c3-demo-rs.js +5 -1
- package/workspace/public/pm/c3-design-studio.js +308 -0
- package/workspace/public/pm/c3-doc-formats.js +3 -2
- package/workspace/public/pm/c3-doc-sheet.js +30 -5
- package/workspace/public/pm/c3-initiatives.js +2 -1
- package/workspace/public/pm/c3-report-deck.css +139 -0
- package/workspace/public/pm/c3-report-deck.js +558 -0
- package/workspace/public/pm/c3-report-frame.css +20 -0
- package/workspace/public/pm/c3-report-setup.js +18 -6
- package/workspace/server.js +17 -5
- package/workspace/skills/report-design.skill +61 -0
- package/workspace/test-lists/report-design-backend.json +5 -0
- package/workspace/test-lists/report-design-studio-ui.json +5 -0
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* (initiative workspace-headless-jobs; PM decision 2026-10-11: keep Jev, no direct Claude API, background
|
|
4
4
|
* jobs that need no human run headless).
|
|
5
5
|
*
|
|
6
|
-
* kindFor({ agent, origin, skill, env }) → 'notes' | 'skill' | 'ask' | 'drive' | 'scan-web' | 'scan-repo' | 'scan-research-web' | 'scan-research-repo' | 'report-setup' | 'report-find' | 'core-doc' | null (null: open a pane, as before)
|
|
7
|
-
* argsFor(kind, { modelArgs, addDirs })
|
|
6
|
+
* kindFor({ agent, origin, skill, env }) → 'notes' | 'skill' | 'ask' | 'drive' | 'scan-web' | 'scan-repo' | 'scan-research-web' | 'scan-research-repo' | 'report-setup' | 'report-find' | 'core-doc' | 'report-design' | null (null: open a pane, as before)
|
|
7
|
+
* argsFor(kind, { modelArgs, addDirs, writePaths }) → the argv after `claude` (writePaths: the one render file a report-design job may write)
|
|
8
8
|
* parseResult(stdout) → { ok, text, isError, turns, durationMs, costUsd, denied[] }
|
|
9
9
|
* streamLines(line) → { log: [lines], result: object|null } one stream-json event, for the live log
|
|
10
10
|
* logLines(result, exitCode) → the lines the read-only log pane shows at the end
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
* The `core-doc` kind drafts ONE core document (initiative core-documents): origin `core-doc:<scope>:<key>`. It reads and searches the repository,
|
|
45
45
|
* and its only write is `pmos coredoc write`, which writes a draft and nothing else (the server pins the scope and key in the run's environment).
|
|
46
46
|
* No Write, no Edit, no web, nothing that sends. The draft waits for the PM, who issues it. It never runs in a pane.
|
|
47
|
+
* The `report-design` kind is the report design studio (initiative report-design-studio): origin `report-design:<cadence>`. It reads the report's folder
|
|
48
|
+
* (the cycle document, the samples, the earlier versions and the brief) and writes ONE file: the render at the pending path the server gives it, named in
|
|
49
|
+
* its tool list as `Write(//<path>)` and `Edit(//<path>)`. It has no web tool, no Bash and no connector tool, and nothing that sends. The server sanitizes
|
|
50
|
+
* the render before anything shows it. It never runs in a pane.
|
|
47
51
|
*/
|
|
48
52
|
|
|
49
53
|
// The skills whose every start runs headless: they read, file a result for PMOS, and send nothing out.
|
|
@@ -74,6 +78,9 @@ const REPORT_SETUP_ORIGINS = Object.freeze(['report-setup:']);
|
|
|
74
78
|
const REPORT_FIND_ORIGINS = Object.freeze(['report-find:']);
|
|
75
79
|
// core-documents: one run drafts one core document of a portfolio, a board or an initiative (origin `core-doc:<scope>:<key>`).
|
|
76
80
|
const CORE_DOC_ORIGINS = Object.freeze(['core-doc:']);
|
|
81
|
+
// report-design-studio: a studio turn, a cycle render or a re-render to match (origin `report-design:<cadence>`).
|
|
82
|
+
const REPORT_DESIGN_ORIGINS = Object.freeze(['report-design:']);
|
|
83
|
+
const WRITE_PATH_KINDS = Object.freeze(['report-design']); // kinds whose one writable file the caller names (argsFor writePaths)
|
|
77
84
|
|
|
78
85
|
// What each kind may use. Read-only search is always allowed. The notes passes write their JSON (and rename the .tmp
|
|
79
86
|
// file) in their notes folder, which --add-dir opens to them; the skills also run `pmos` verbs and repository scripts.
|
|
@@ -101,6 +108,8 @@ const TOOLS = Object.freeze({
|
|
|
101
108
|
'report-find': Object.freeze(['Read', 'Glob', 'Grep', 'Bash(pmos report propose *)']),
|
|
102
109
|
// The core-doc run: read and search, and the one verb that writes a draft. No Write, no Edit, no web, nothing that sends.
|
|
103
110
|
'core-doc': Object.freeze(['Read', 'Glob', 'Grep', 'Bash(pmos coredoc write *)']),
|
|
111
|
+
// The design run: read and search only. Its one write, the render file, is added per run by argsFor (writePaths). No Bash, no web, nothing that sends.
|
|
112
|
+
'report-design': Object.freeze(['Read', 'Glob', 'Grep']),
|
|
104
113
|
skill: Object.freeze(['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash(pmos *)', 'Bash(node *)',
|
|
105
114
|
'Bash(git log *)', 'Bash(git status *)', 'Bash(git diff *)', 'Bash(ls *)', 'Bash(date *)']),
|
|
106
115
|
});
|
|
@@ -124,13 +133,22 @@ function kindFor({ agent, origin, skill, env } = {}) {
|
|
|
124
133
|
if (REPORT_SETUP_ORIGINS.some((p) => o.startsWith(p))) return 'report-setup';
|
|
125
134
|
if (REPORT_FIND_ORIGINS.some((p) => o.startsWith(p))) return 'report-find';
|
|
126
135
|
if (CORE_DOC_ORIGINS.some((p) => o.startsWith(p))) return 'core-doc';
|
|
136
|
+
if (REPORT_DESIGN_ORIGINS.some((p) => o.startsWith(p))) return 'report-design';
|
|
127
137
|
if (skill && HEADLESS_SKILLS.includes(String(skill))) return 'skill';
|
|
128
138
|
return null;
|
|
129
139
|
}
|
|
130
140
|
|
|
131
|
-
function argsFor(kind, { modelArgs = [], addDirs = [] } = {}) {
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
function argsFor(kind, { modelArgs = [], addDirs = [], writePaths = [] } = {}) {
|
|
142
|
+
if (!TOOLS[kind]) throw new Error('unknown headless kind: ' + kind);
|
|
143
|
+
const tools = TOOLS[kind].slice();
|
|
144
|
+
// A report-design run may write its render file and nothing else: one absolute path, no wildcard, no comma.
|
|
145
|
+
if (WRITE_PATH_KINDS.includes(kind)) {
|
|
146
|
+
for (const p of Array.isArray(writePaths) ? writePaths : []) {
|
|
147
|
+
const s = String(p || '');
|
|
148
|
+
if (!s.startsWith('/') || /[\s,*?()\[\]{}]/.test(s) || s.includes('..')) continue;
|
|
149
|
+
tools.push(`Write(/${s})`, `Edit(/${s})`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
134
152
|
// stream-json needs --verbose in print mode; it adds the step events, and the last line is the same result object as `json`.
|
|
135
153
|
const argv = ['-p', '--output-format', 'stream-json', '--verbose', '--no-session-persistence', ...modelArgs, '--allowedTools', tools.join(',')];
|
|
136
154
|
// A web run gets no directory at all, whatever the caller passes: it must not be able to read the repository.
|
|
@@ -242,4 +260,4 @@ function logLines(r, exitCode) {
|
|
|
242
260
|
return out;
|
|
243
261
|
}
|
|
244
262
|
|
|
245
|
-
module.exports = { HEADLESS_SKILLS, HEADLESS_ORIGINS, ASK_ORIGINS, DRIVE_ORIGINS, SCAN_WEB_ORIGINS, SCAN_REPO_ORIGINS, SCAN_RESEARCH_WEB_ORIGINS, SCAN_RESEARCH_REPO_ORIGINS, WEB_KINDS, REPORT_SETUP_ORIGINS, REPORT_FIND_ORIGINS, CORE_DOC_ORIGINS, TOOLS, DEFAULT_TIMEOUT_MS, kindFor, argsFor, timeoutMs, parseResult, streamLines, outcomeOf, logLines, switchedOff };
|
|
263
|
+
module.exports = { HEADLESS_SKILLS, HEADLESS_ORIGINS, ASK_ORIGINS, DRIVE_ORIGINS, SCAN_WEB_ORIGINS, SCAN_REPO_ORIGINS, SCAN_RESEARCH_WEB_ORIGINS, SCAN_RESEARCH_REPO_ORIGINS, WEB_KINDS, REPORT_SETUP_ORIGINS, REPORT_FIND_ORIGINS, CORE_DOC_ORIGINS, REPORT_DESIGN_ORIGINS, TOOLS, DEFAULT_TIMEOUT_MS, kindFor, argsFor, timeoutMs, parseResult, streamLines, outcomeOf, logLines, switchedOff };
|