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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/payload/KIT-VERSION +1 -1
  3. package/payload/planning/evals/eval-calibration.md +1 -1
  4. package/payload/planning/okrs/health-budgets.md +1 -1
  5. package/payload/state/discoveries.md +1 -1
  6. package/workspace/c3-report-design-real-test.js +225 -0
  7. package/workspace/c3-report-design-test.js +403 -0
  8. package/workspace/c3-report-setup-test.js +3 -2
  9. package/workspace/c3-work-test.js +1 -1
  10. package/workspace/guide/index.md +1 -0
  11. package/workspace/guide/report-design.md +104 -0
  12. package/workspace/guide/report-slides.md +3 -1
  13. package/workspace/guide/reports-set-up.md +2 -1
  14. package/workspace/lib/headless.js +24 -6
  15. package/workspace/lib/report-design.js +741 -0
  16. package/workspace/lib/report-draft.js +8 -3
  17. package/workspace/lib/report-setups.js +1 -1
  18. package/workspace/lib/route-modules.js +1 -0
  19. package/workspace/lib/routes-doc-sheet.js +8 -1
  20. package/workspace/lib/routes-report-design.js +481 -0
  21. package/workspace/lib/routes-reports.js +2 -1
  22. package/workspace/package-lock.json +2 -2
  23. package/workspace/package.json +1 -1
  24. package/workspace/public/pm/c3-demo-rd.js +426 -0
  25. package/workspace/public/pm/c3-demo-rep2.js +2 -0
  26. package/workspace/public/pm/c3-demo-rs.js +5 -1
  27. package/workspace/public/pm/c3-design-studio.js +308 -0
  28. package/workspace/public/pm/c3-doc-formats.js +3 -2
  29. package/workspace/public/pm/c3-doc-sheet.js +30 -5
  30. package/workspace/public/pm/c3-initiatives.js +2 -1
  31. package/workspace/public/pm/c3-report-deck.css +139 -0
  32. package/workspace/public/pm/c3-report-deck.js +558 -0
  33. package/workspace/public/pm/c3-report-frame.css +20 -0
  34. package/workspace/public/pm/c3-report-setup.js +18 -6
  35. package/workspace/server.js +17 -5
  36. package/workspace/skills/report-design.skill +61 -0
  37. package/workspace/test-lists/report-design-backend.json +5 -0
  38. 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 }) → the argv after `claude`
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
- const tools = TOOLS[kind];
133
- if (!tools) throw new Error('unknown headless kind: ' + kind);
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 };