projectinator 0.3.0 → 0.4.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 (170) hide show
  1. package/README.md +30 -11
  2. package/bin/projectinator.mjs +56 -11
  3. package/dist/bakeoff.js +163 -0
  4. package/dist/bakeoff.js.map +1 -0
  5. package/dist/build-state.js +26 -0
  6. package/dist/build-state.js.map +1 -0
  7. package/dist/burndown.js +19 -0
  8. package/dist/burndown.js.map +1 -0
  9. package/dist/calibration.js +86 -0
  10. package/dist/calibration.js.map +1 -0
  11. package/dist/cli.js +289 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/cost.js +35 -0
  14. package/dist/cost.js.map +1 -0
  15. package/dist/council.js +147 -0
  16. package/dist/council.js.map +1 -0
  17. package/dist/demo.js +93 -0
  18. package/dist/demo.js.map +1 -0
  19. package/dist/estimate.js +98 -0
  20. package/dist/estimate.js.map +1 -0
  21. package/dist/executor.js +118 -0
  22. package/dist/executor.js.map +1 -0
  23. package/dist/git.js +82 -0
  24. package/dist/git.js.map +1 -0
  25. package/dist/intake.js +98 -0
  26. package/dist/intake.js.map +1 -0
  27. package/dist/models.js +171 -0
  28. package/dist/models.js.map +1 -0
  29. package/dist/narrate.js +76 -0
  30. package/dist/narrate.js.map +1 -0
  31. package/dist/openrouter.js +112 -0
  32. package/dist/openrouter.js.map +1 -0
  33. package/dist/orchestrator.js +273 -0
  34. package/dist/orchestrator.js.map +1 -0
  35. package/dist/pm.js +245 -0
  36. package/dist/pm.js.map +1 -0
  37. package/dist/preview.js +194 -0
  38. package/dist/preview.js.map +1 -0
  39. package/dist/registry-store.js +38 -0
  40. package/dist/registry-store.js.map +1 -0
  41. package/dist/registry.js +115 -0
  42. package/dist/registry.js.map +1 -0
  43. package/dist/research.js +98 -0
  44. package/dist/research.js.map +1 -0
  45. package/dist/retro.js +83 -0
  46. package/dist/retro.js.map +1 -0
  47. package/dist/roles.js +357 -0
  48. package/dist/roles.js.map +1 -0
  49. package/dist/router.js +95 -0
  50. package/dist/router.js.map +1 -0
  51. package/dist/run-bakeoff.js +68 -0
  52. package/dist/run-bakeoff.js.map +1 -0
  53. package/dist/run-build.js +193 -0
  54. package/dist/run-build.js.map +1 -0
  55. package/{src/run-dev.ts → dist/run-dev.js} +23 -39
  56. package/dist/run-dev.js.map +1 -0
  57. package/{src/run-pm.ts → dist/run-pm.js} +34 -46
  58. package/dist/run-pm.js.map +1 -0
  59. package/{src/run-research.ts → dist/run-research.js} +19 -30
  60. package/dist/run-research.js.map +1 -0
  61. package/{src/run-scout.ts → dist/run-scout.js} +17 -27
  62. package/dist/run-scout.js.map +1 -0
  63. package/dist/run-web.js +93 -0
  64. package/dist/run-web.js.map +1 -0
  65. package/dist/scout.js +81 -0
  66. package/dist/scout.js.map +1 -0
  67. package/dist/session-cost.js +15 -0
  68. package/dist/session-cost.js.map +1 -0
  69. package/dist/stack.js +34 -0
  70. package/dist/stack.js.map +1 -0
  71. package/dist/stuck.js +21 -0
  72. package/dist/stuck.js.map +1 -0
  73. package/dist/tui/App.js +1269 -0
  74. package/dist/tui/App.js.map +1 -0
  75. package/dist/tui/BakeOff.js +95 -0
  76. package/dist/tui/BakeOff.js.map +1 -0
  77. package/dist/tui/BoardEditor.js +183 -0
  78. package/dist/tui/BoardEditor.js.map +1 -0
  79. package/dist/tui/EditableBoard.js +140 -0
  80. package/dist/tui/EditableBoard.js.map +1 -0
  81. package/dist/tui/Frame.js +78 -0
  82. package/dist/tui/Frame.js.map +1 -0
  83. package/dist/tui/Intake.js +59 -0
  84. package/dist/tui/Intake.js.map +1 -0
  85. package/dist/tui/Kanban.js +75 -0
  86. package/dist/tui/Kanban.js.map +1 -0
  87. package/dist/tui/Settings.js +299 -0
  88. package/dist/tui/Settings.js.map +1 -0
  89. package/dist/tui/StackPick.js +44 -0
  90. package/dist/tui/StackPick.js.map +1 -0
  91. package/dist/tui/WebAccounts.js +131 -0
  92. package/dist/tui/WebAccounts.js.map +1 -0
  93. package/dist/tui/components.js +178 -0
  94. package/dist/tui/components.js.map +1 -0
  95. package/dist/tui/config.js +129 -0
  96. package/dist/tui/config.js.map +1 -0
  97. package/dist/tui/deploy.js +114 -0
  98. package/dist/tui/deploy.js.map +1 -0
  99. package/dist/tui/engine.js +710 -0
  100. package/dist/tui/engine.js.map +1 -0
  101. package/dist/tui/notify.js +47 -0
  102. package/dist/tui/notify.js.map +1 -0
  103. package/dist/tui/panels.js +42 -0
  104. package/dist/tui/panels.js.map +1 -0
  105. package/dist/tui/templates.js +106 -0
  106. package/dist/tui/templates.js.map +1 -0
  107. package/dist/tui/theme.js +42 -0
  108. package/dist/tui/theme.js.map +1 -0
  109. package/dist/tui/validate.js +51 -0
  110. package/dist/tui/validate.js.map +1 -0
  111. package/{src/tui.tsx → dist/tui.js} +23 -33
  112. package/dist/tui.js.map +1 -0
  113. package/dist/types.js +19 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/web/oauth-anthropic.js +179 -0
  116. package/dist/web/oauth-anthropic.js.map +1 -0
  117. package/dist/web/session.js +274 -0
  118. package/dist/web/session.js.map +1 -0
  119. package/package.json +5 -4
  120. package/src/bakeoff.ts +0 -214
  121. package/src/build-state.ts +0 -47
  122. package/src/burndown.ts +0 -35
  123. package/src/calibration.ts +0 -88
  124. package/src/cost.ts +0 -43
  125. package/src/council.ts +0 -175
  126. package/src/demo.ts +0 -106
  127. package/src/estimate.ts +0 -111
  128. package/src/executor.ts +0 -169
  129. package/src/git.ts +0 -72
  130. package/src/intake.ts +0 -125
  131. package/src/models.ts +0 -175
  132. package/src/narrate.ts +0 -87
  133. package/src/openrouter.ts +0 -119
  134. package/src/orchestrator.ts +0 -310
  135. package/src/pm.ts +0 -302
  136. package/src/preview.ts +0 -206
  137. package/src/registry-store.ts +0 -41
  138. package/src/registry.ts +0 -132
  139. package/src/research.ts +0 -123
  140. package/src/retro.ts +0 -99
  141. package/src/roles.ts +0 -401
  142. package/src/router.ts +0 -120
  143. package/src/run-bakeoff.ts +0 -77
  144. package/src/run-build.ts +0 -203
  145. package/src/run-web.ts +0 -87
  146. package/src/scout.ts +0 -121
  147. package/src/session-cost.ts +0 -17
  148. package/src/stack.ts +0 -46
  149. package/src/tui/App.tsx +0 -1760
  150. package/src/tui/BakeOff.tsx +0 -190
  151. package/src/tui/BoardEditor.tsx +0 -260
  152. package/src/tui/EditableBoard.tsx +0 -179
  153. package/src/tui/Frame.tsx +0 -142
  154. package/src/tui/Intake.tsx +0 -111
  155. package/src/tui/Kanban.tsx +0 -158
  156. package/src/tui/Settings.tsx +0 -513
  157. package/src/tui/StackPick.tsx +0 -79
  158. package/src/tui/WebAccounts.tsx +0 -197
  159. package/src/tui/components.tsx +0 -340
  160. package/src/tui/config.ts +0 -150
  161. package/src/tui/deploy.ts +0 -137
  162. package/src/tui/engine.ts +0 -749
  163. package/src/tui/notify.ts +0 -21
  164. package/src/tui/panels.tsx +0 -89
  165. package/src/tui/templates.ts +0 -119
  166. package/src/tui/theme.ts +0 -44
  167. package/src/tui/validate.ts +0 -53
  168. package/src/types.ts +0 -208
  169. package/src/web/oauth-anthropic.ts +0 -206
  170. package/src/web/session.ts +0 -299
package/dist/cli.js ADDED
@@ -0,0 +1,289 @@
1
+ // Headless CLI — `projectinator <command>`. Same engine as the cockpit (engine.ts),
2
+ // same workspace root, so builds started here show up in the TUI's project list.
3
+ //
4
+ // doctor check Node, keys, Chromium, Pi catalog, git
5
+ // build "<idea>" [...] plan + build without the TUI
6
+ // projects list past builds
7
+ // models the roster as it will actually run, with prices
8
+ //
9
+ // The launcher (bin/projectinator.mjs) handles --version/--help itself and only
10
+ // spawns this file for a real command, so those stay instant.
11
+ import { createInterface } from "node:readline";
12
+ import { spawnSync } from "node:child_process";
13
+ import { accessSync, constants, mkdirSync } from "node:fs";
14
+ import { homedir } from "node:os";
15
+ import { join } from "node:path";
16
+ import { MODELS, getModel } from "./models.js";
17
+ import { REGISTRY } from "./registry.js";
18
+ import { piRuntime, resolvePiModel } from "./executor.js";
19
+ import { chromiumAvailable, CHROMIUM_INSTALL_HINT } from "./preview.js";
20
+ import { applyKeysToEnv, getPrefs, getWebhookUrl, loadConfig, ENV_VAR } from "./tui/config.js";
21
+ import { postWebhook } from "./tui/notify.js";
22
+ import { availableProviders, effectiveRoster, listProjects, planBuild, startBuild, PROVIDER_LABEL, } from "./tui/engine.js";
23
+ const NODE_MIN = "22.19.0";
24
+ // `projectinator projects | head` closes our stdout early; that's not an error.
25
+ process.stdout.on("error", (e) => { if (e.code === "EPIPE")
26
+ process.exit(0); throw e; });
27
+ const money = (n) => `$${n.toFixed(2)}`;
28
+ export function parseArgv(args) {
29
+ const out = { positional: [], flags: {} };
30
+ for (let i = 0; i < args.length; i++) {
31
+ const a = args[i];
32
+ if (!a.startsWith("--")) {
33
+ out.positional.push(a);
34
+ continue;
35
+ }
36
+ const eq = a.indexOf("=");
37
+ if (eq > 0) {
38
+ out.flags[a.slice(2, eq)] = a.slice(eq + 1);
39
+ continue;
40
+ }
41
+ const next = args[i + 1];
42
+ if (next !== undefined && !next.startsWith("--")) {
43
+ out.flags[a.slice(2)] = next;
44
+ i++;
45
+ }
46
+ else
47
+ out.flags[a.slice(2)] = true;
48
+ }
49
+ return out;
50
+ }
51
+ function num(v, fallback) {
52
+ if (v === undefined || v === true)
53
+ return fallback;
54
+ const n = parseFloat(v);
55
+ return Number.isFinite(n) ? n : fallback;
56
+ }
57
+ export function semverGte(a, b) {
58
+ const pa = a.split(".").map(Number);
59
+ const pb = b.split(".").map(Number);
60
+ for (let i = 0; i < 3; i++) {
61
+ if ((pa[i] ?? 0) > (pb[i] ?? 0))
62
+ return true;
63
+ if ((pa[i] ?? 0) < (pb[i] ?? 0))
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ async function doctor() {
69
+ const checks = [];
70
+ const node = process.versions.node;
71
+ checks.push({ label: "Node", ok: semverGte(node, NODE_MIN), detail: `v${node} (need ≥ ${NODE_MIN})`, fatal: true });
72
+ const cfg = loadConfig();
73
+ const providers = availableProviders();
74
+ for (const p of Object.keys(ENV_VAR)) {
75
+ const has = providers.includes(p);
76
+ const src = cfg.keys[p] ? "~/.projectinator/config.json" : has ? "env" : "";
77
+ checks.push({ label: `Key: ${PROVIDER_LABEL[p]}`, ok: has, detail: has ? `set (${src})` : `not set — Settings → API keys, or export ${ENV_VAR[p]}` });
78
+ }
79
+ if (providers.length === 0)
80
+ checks.push({ label: "Any provider key", ok: false, detail: "no keys at all — nothing can run", fatal: true });
81
+ try {
82
+ const runtime = await piRuntime();
83
+ const bad = [];
84
+ for (const e of REGISTRY)
85
+ for (const b of ["api", "web"]) {
86
+ try {
87
+ resolvePiModel(runtime, e.byBackend[b].provider, e.byBackend[b].model);
88
+ }
89
+ catch {
90
+ bad.push(`${e.capability}/${e.tier}/${b}`);
91
+ }
92
+ }
93
+ checks.push({ label: "Pi model catalog", ok: bad.length === 0, detail: bad.length ? `unresolved: ${bad.join(", ")}` : `${Object.keys(MODELS).length} models priced, every registry pick resolves`, fatal: true });
94
+ }
95
+ catch (e) {
96
+ checks.push({ label: "Pi model catalog", ok: false, detail: e instanceof Error ? e.message : String(e), fatal: true });
97
+ }
98
+ const chromium = await chromiumAvailable();
99
+ checks.push({ label: "Headless Chromium", ok: chromium, detail: chromium ? "installed — tester runs the app" : `missing — tests will be code-reading only (PASS*); ${CHROMIUM_INSTALL_HINT}` });
100
+ const git = spawnSync("git", ["--version"], { encoding: "utf8" });
101
+ checks.push({ label: "git", ok: git.status === 0, detail: git.status === 0 ? git.stdout.trim() : "not found — builds won't be versioned (undo/history disabled)" });
102
+ const home = join(homedir(), ".projectinator");
103
+ try {
104
+ mkdirSync(home, { recursive: true });
105
+ accessSync(home, constants.W_OK);
106
+ checks.push({ label: "Data dir", ok: true, detail: home });
107
+ }
108
+ catch {
109
+ checks.push({ label: "Data dir", ok: false, detail: `${home} not writable`, fatal: true });
110
+ }
111
+ const prefs = getPrefs();
112
+ checks.push({ label: "Prefs", ok: true, detail: `budget cap ${money(prefs.budgetCapUSD)} · ${prefs.concurrency} at once · task limits ${prefs.taskTimeoutMin || "∞"} min / ${prefs.taskCostCapUSD ? money(prefs.taskCostCapUSD) : "∞"}` });
113
+ console.log("\n projectinator doctor\n");
114
+ for (const c of checks)
115
+ console.log(` ${c.ok ? "✓" : c.fatal ? "✗" : "!"} ${c.label.padEnd(22)} ${c.detail}`);
116
+ const fatal = checks.filter((c) => !c.ok && c.fatal);
117
+ const warn = checks.filter((c) => !c.ok && !c.fatal);
118
+ console.log(`\n ${fatal.length ? `${fatal.length} blocking problem${fatal.length === 1 ? "" : "s"}` : "Ready"}${warn.length ? ` · ${warn.length} warning${warn.length === 1 ? "" : "s"}` : ""}\n`);
119
+ return fatal.length ? 1 : 0;
120
+ }
121
+ // ---- projects ----
122
+ function projects() {
123
+ const list = listProjects();
124
+ if (!list.length) {
125
+ console.log("\n No projects yet. Run `projectinator` or `projectinator build \"an idea\"`.\n");
126
+ return 0;
127
+ }
128
+ console.log("");
129
+ for (const p of list) {
130
+ const done = p.state.outcomes.filter((o) => !o.error).length;
131
+ const mark = p.status === "complete" ? "✓" : p.status === "halted" ? "⚠" : "…";
132
+ console.log(` ${mark} ${p.slug.padEnd(40)} ${p.status.padEnd(9)} ${money(p.totalCost).padStart(8)} ${done}/${p.taskCount} tasks`);
133
+ console.log(` ${p.idea.slice(0, 90)}${p.idea.length > 90 ? "…" : ""}`);
134
+ }
135
+ console.log(`\n ${list.length} project${list.length === 1 ? "" : "s"} · ${money(list.reduce((a, p) => a + p.totalCost, 0))} all time · ${join(homedir(), "…")}\n`);
136
+ return 0;
137
+ }
138
+ // ---- models ----
139
+ function models() {
140
+ const providers = availableProviders();
141
+ console.log(`\n Roster as it will run now${providers.length ? ` (keys: ${providers.join(", ")})` : " (no keys — best-of-breed picks shown)"}\n`);
142
+ for (const r of effectiveRoster()) {
143
+ const m = r.model ? getModel(r.model) : undefined;
144
+ const price = m ? `$${m.cost.input}/$${m.cost.output} per 1M` : "";
145
+ console.log(` ${r.label.padEnd(18)} ${(r.model ?? "—").padEnd(28)} ${(r.provider ?? "").padEnd(11)} ${price}`);
146
+ }
147
+ console.log("\n Change in the app: Settings → Models. Prices are from Pi's catalog; actual cost is measured per run.\n");
148
+ return 0;
149
+ }
150
+ // ---- build ----
151
+ function ask(question) {
152
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
153
+ const { promise, resolve } = Promise.withResolvers();
154
+ rl.question(question, (a) => { rl.close(); resolve(a.trim()); });
155
+ return promise;
156
+ }
157
+ async function build(argv) {
158
+ const idea = argv.positional.join(" ").trim();
159
+ const json = argv.flags.json === true;
160
+ const yes = json || argv.flags.yes === true || argv.flags.y === true;
161
+ const dry = argv.flags["dry-run"] === true;
162
+ const emit = (o) => { if (json)
163
+ process.stdout.write(JSON.stringify(o) + "\n"); };
164
+ const say = (s) => { if (!json)
165
+ console.log(s); };
166
+ if (!idea) {
167
+ console.error(" build: give an idea, e.g. projectinator build \"a tip calculator\"");
168
+ return 2;
169
+ }
170
+ let providers = availableProviders();
171
+ const lock = argv.flags.provider;
172
+ if (typeof lock === "string") {
173
+ if (!(lock in PROVIDER_LABEL)) {
174
+ console.error(` build: unknown provider "${lock}" (anthropic | openai | google | openrouter)`);
175
+ return 2;
176
+ }
177
+ if (!providers.includes(lock)) {
178
+ console.error(` build: no key for ${lock} — export ${ENV_VAR[lock]} or set it in the app`);
179
+ return 1;
180
+ }
181
+ providers = [lock];
182
+ }
183
+ if (!providers.length) {
184
+ console.error(" build: no API key found. Run `projectinator doctor`.");
185
+ return 1;
186
+ }
187
+ const prefs = getPrefs();
188
+ const budget = num(argv.flags.budget, prefs.budgetCapUSD);
189
+ const concurrency = Math.max(1, Math.floor(num(argv.flags.concurrency, prefs.concurrency)));
190
+ const taskLimits = {
191
+ timeoutMs: num(argv.flags["task-timeout"], prefs.taskTimeoutMin) * 60_000,
192
+ costCapUSD: num(argv.flags["task-cap"], prefs.taskCostCapUSD),
193
+ };
194
+ say(`\n Planning with the PM (${providers.join("/")})…`);
195
+ const plan = await planBuild(idea, providers);
196
+ emit({ event: "plan", provider: plan.provider, modelId: plan.modelId, estCost: plan.estCost, tasks: plan.tasks });
197
+ say(`\n ${plan.tasks.length} tasks · estimated ${money(plan.estCost)} · cap ${money(budget)}${plan.lock ? ` · locked to ${plan.lock}` : ""}\n`);
198
+ for (const t of plan.tasks) {
199
+ const dep = t.dependsOn?.length ? ` ← ${t.dependsOn.join(", ")}` : "";
200
+ say(` ${t.id.padEnd(6)} ${t.capability.padEnd(7)} ${t.difficulty.padEnd(8)} ${t.title}${dep}`);
201
+ }
202
+ if (plan.estCost > budget)
203
+ say(`\n ⚠ Estimate exceeds the cap — the build may halt partway.`);
204
+ if (dry) {
205
+ say("\n Dry run — nothing built (the PM call above was the only spend).\n");
206
+ return 0;
207
+ }
208
+ if (!yes) {
209
+ const a = await ask(`\n Build it for ~${money(plan.estCost)}? [y/N] `);
210
+ if (!/^y(es)?$/i.test(a)) {
211
+ say(" Cancelled.\n");
212
+ return 0;
213
+ }
214
+ }
215
+ const onEvent = (e) => {
216
+ emit({ event: e.type, ...e });
217
+ if (json)
218
+ return;
219
+ if (e.type === "task_start")
220
+ console.log(` ▶ ${e.task.id} [${e.task.capability}] → ${e.provider}/${e.modelId}${e.round ? ` (round ${e.round})` : ""}`);
221
+ else if (e.type === "task_done")
222
+ console.log(` ✓ ${e.outcome.taskId} ${money(e.outcome.cost)} running ${money(e.runningTotal)}${e.outcome.verdict ? ` ${e.outcome.verdict.passed ? (e.outcome.verdict.runtimeChecked || e.outcome.capability !== "test" ? "PASS" : "PASS* (app not executed)") : "FAIL"}` : ""}`);
223
+ else if (e.type === "task_failed")
224
+ console.log(` ⛔ ${e.outcome.taskId} aborted: ${e.outcome.error} — billed ${money(e.outcome.cost)}`);
225
+ else if (e.type === "task_skipped")
226
+ console.log(` · ${e.taskId} skipped`);
227
+ else if (e.type === "test_failed")
228
+ console.log(` ✗ ${e.taskId} failed (${e.bugs} bugs) — round ${e.round}`);
229
+ else if (e.type === "retry_dev")
230
+ console.log(` ↻ re-running ${e.taskId} to fix ${e.forTest}`);
231
+ else if (e.type === "budget_halt")
232
+ console.log(` ⚠ budget halt at ${money(e.runningTotal)} (cap ${money(e.cap)})`);
233
+ else if (e.type === "cycle_or_error")
234
+ console.log(` ✗ ${e.message}`);
235
+ };
236
+ say(`\n Building…\n`);
237
+ const handle = startBuild(idea, plan, { concurrency, budgetCapUSD: budget, taskLimits, onEvent, mode: "auto" });
238
+ const r = await handle.promise;
239
+ emit({ event: "done", halted: r.halted, haltReason: r.haltReason, totalCost: r.totalCost, files: r.files, workspace: handle.workspace });
240
+ const hook = getWebhookUrl();
241
+ if (hook) {
242
+ const ok = await postWebhook(hook, { event: "build.finished", status: r.halted ? "halted" : "complete", haltReason: r.haltReason, idea, totalCost: r.totalCost, files: r.files, workspace: handle.workspace, at: new Date().toISOString() });
243
+ emit({ event: "webhook", url: hook, ok });
244
+ if (!ok)
245
+ say(` (webhook ${hook} did not accept the summary)`);
246
+ }
247
+ say(`\n ${r.halted ? `⚠ Halted (${r.haltReason ?? "?"})` : "✓ Complete"} · ${money(r.totalCost)} · ${r.files.length} file${r.files.length === 1 ? "" : "s"}`);
248
+ say(` ${handle.workspace}\n`);
249
+ return r.halted ? 3 : 0;
250
+ }
251
+ // ---- main ----
252
+ const USAGE = `Usage: projectinator <command> [options]
253
+
254
+ doctor check Node, API keys, Chromium, Pi catalog, git
255
+ build "<idea>" [options] plan + build headless (same workspace as the app)
256
+ --dry-run plan and estimate only (spends one PM call)
257
+ --yes, -y don't ask before building
258
+ --json NDJSON events on stdout (implies --yes)
259
+ --budget <usd> cap for this build (default: your prefs)
260
+ --provider <name> anthropic|openai|google|openrouter (default: prefs / keys)
261
+ --concurrency <n> tasks at once (default: your prefs)
262
+ --task-cap <usd> per-task cost ceiling (default: your prefs; 0 = off)
263
+ --task-timeout <min> per-task timeout (default: your prefs; 0 = off)
264
+ projects list past builds with status and cost
265
+ models the roster as it will run, with prices
266
+
267
+ Exit codes: 0 ok · 1 environment problem · 2 bad usage · 3 build halted`;
268
+ export async function main(args) {
269
+ applyKeysToEnv();
270
+ const argv = parseArgv(args);
271
+ const cmd = argv.positional.shift();
272
+ switch (cmd) {
273
+ case "doctor": return doctor();
274
+ case "projects": return projects();
275
+ case "models": return models();
276
+ case "build": return build(argv);
277
+ case undefined:
278
+ case "help":
279
+ console.log(USAGE);
280
+ return cmd ? 0 : 2;
281
+ default:
282
+ console.error(`projectinator: unknown command "${cmd}".\n\n${USAGE}`);
283
+ return 2;
284
+ }
285
+ }
286
+ if (process.argv[1] && import.meta.url === new URL(process.argv[1], "file://").href) {
287
+ process.exitCode = await main(process.argv.slice(2));
288
+ }
289
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/cost.js ADDED
@@ -0,0 +1,35 @@
1
+ // Cost estimation. Pure math over a token estimate + a model's price block.
2
+ const PER_MILLION = 1_000_000;
3
+ /** Resolve the applicable input/output/cache rates, honoring volume tiers.
4
+ * Highest matching `inputTokensAbove` threshold wins (Pi semantics). */
5
+ function ratesFor(model, inputTokens) {
6
+ const base = model.cost;
7
+ let rate = { input: base.input, output: base.output, cacheRead: base.cacheRead ?? base.input };
8
+ for (const tier of base.tiers ?? []) {
9
+ if (inputTokens > tier.inputTokensAbove) {
10
+ rate = {
11
+ input: tier.input,
12
+ output: tier.output,
13
+ cacheRead: tier.cacheRead ?? tier.input,
14
+ };
15
+ }
16
+ }
17
+ return rate;
18
+ }
19
+ /** Estimate USD cost for one task on a given model.
20
+ * A fraction of input can be served from cache at the cheaper cacheRead rate.
21
+ * Kept to 4 decimals, not cents: a backlog of sub-cent tasks would otherwise
22
+ * estimate to $0.00 and under-reserve budget in the parallel scheduler. */
23
+ export function estimateCost(est, model) {
24
+ const cachedFraction = clamp01(est.cachedInputFraction ?? 0);
25
+ const rate = ratesFor(model, est.input);
26
+ const freshInput = est.input * (1 - cachedFraction);
27
+ const cachedInput = est.input * cachedFraction;
28
+ const inputCost = (freshInput / PER_MILLION) * rate.input + (cachedInput / PER_MILLION) * rate.cacheRead;
29
+ const outputCost = (est.output / PER_MILLION) * rate.output;
30
+ return Math.round((inputCost + outputCost) * 10_000) / 10_000;
31
+ }
32
+ function clamp01(n) {
33
+ return Math.max(0, Math.min(1, n));
34
+ }
35
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAI5E,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B;yEACyE;AACzE,SAAS,QAAQ,CAAC,KAAY,EAAE,WAAmB;IACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,IAAI,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;IAC/F,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACpC,IAAI,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,GAAG;gBACL,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK;aACxC,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;4EAG4E;AAC5E,MAAM,UAAU,YAAY,CAAC,GAAkB,EAAE,KAAY;IAC3D,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAExC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,GAAG,cAAc,CAAC;IAE/C,MAAM,SAAS,GAAG,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACzG,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAE5D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC;AAChE,CAAC;AAED,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,147 @@
1
+ // Council planning (opt-in "deep plan"). Three perspectives propose epics from
2
+ // different lenses in parallel, then a synthesizer merges them into one ordered
3
+ // epic list. The user approves the epics; expansion into tasks happens after,
4
+ // via the normal decomposer seeded with these epics.
5
+ import { createAgentSession, defineTool, } from "@earendil-works/pi-coding-agent";
6
+ import { Type } from "typebox";
7
+ import { findEntry } from "./registry.js";
8
+ import { piRuntime, resolvePiModel } from "./executor.js";
9
+ import { addSessionCost } from "./session-cost.js";
10
+ const EpicsSchema = Type.Object({
11
+ epics: Type.Array(Type.Object({ name: Type.String(), rationale: Type.String({ description: "one line: why this epic exists" }) }, { additionalProperties: true })),
12
+ }, { additionalProperties: true });
13
+ function buildEpicsTool(toolName) {
14
+ let captured;
15
+ const tool = defineTool({
16
+ name: toolName,
17
+ label: "Submit Epics",
18
+ description: "Submit the epic list. Call exactly once.",
19
+ parameters: EpicsSchema,
20
+ execute: async (_id, params) => {
21
+ captured = params;
22
+ return { content: [{ type: "text", text: `Got ${params.epics.length} epics.` }], details: {} };
23
+ },
24
+ });
25
+ return { tool, get: () => captured };
26
+ }
27
+ function lastAssistantText(session) {
28
+ const msgs = session.messages;
29
+ for (let i = msgs.length - 1; i >= 0; i--) {
30
+ const m = msgs[i];
31
+ if (m?.role !== "assistant")
32
+ continue;
33
+ const c = m.content;
34
+ if (typeof c === "string")
35
+ return c;
36
+ if (Array.isArray(c))
37
+ return c.map((p) => (p && typeof p === "object" && "text" in p ? String(p.text) : "")).join("");
38
+ }
39
+ return "";
40
+ }
41
+ async function runEpicAgent(idea, system, toolName, ctx) {
42
+ const runtime = await piRuntime();
43
+ const { entry } = findEntry("plan", "mid");
44
+ const pick = ctx.modelOverride ?? entry.byBackend[ctx.backend];
45
+ try {
46
+ const model = resolvePiModel(runtime, pick.provider, pick.model);
47
+ const { tool, get } = buildEpicsTool(toolName);
48
+ const { session } = await createAgentSession({
49
+ model,
50
+ modelRuntime: runtime,
51
+ thinkingLevel: "low",
52
+ noTools: "all",
53
+ customTools: [tool],
54
+ tools: [toolName],
55
+ });
56
+ try {
57
+ await session.prompt(`${system}\n\n--- REQUEST ---\n${idea}`);
58
+ let raw = get();
59
+ if (!raw) {
60
+ await session.prompt(`Call ${toolName} now.`);
61
+ raw = get();
62
+ }
63
+ addSessionCost(session.getSessionStats().cost);
64
+ return (raw?.epics ?? [])
65
+ .map((e) => ({ name: String(e.name ?? "").trim(), rationale: String(e.rationale ?? "").trim() }))
66
+ .filter((e) => e.name);
67
+ }
68
+ finally {
69
+ session.dispose();
70
+ }
71
+ }
72
+ catch {
73
+ return [];
74
+ }
75
+ }
76
+ const LENSES = [
77
+ {
78
+ key: "architect",
79
+ system: "You are the ARCHITECT on a planning council. Propose the EPICS (big areas of work) for this build " +
80
+ "from a TECHNICAL structure lens — components, data, integration, scaffolding. 3-6 epics, each a short " +
81
+ "name + one-line rationale. Call submit_epics_architect once.",
82
+ },
83
+ {
84
+ key: "product",
85
+ system: "You are the PRODUCT lead on a planning council. Propose the EPICS from a USER-VALUE lens — the features " +
86
+ "and flows a user needs, in priority order. 3-6 epics, each a short name + one-line rationale. Call " +
87
+ "submit_epics_product once.",
88
+ },
89
+ {
90
+ key: "risk",
91
+ system: "You are the RISK/QA lead on a planning council. Propose the EPICS from a WHAT-COULD-GO-WRONG lens — " +
92
+ "validation, edge cases, error/empty states, testing, and anything easy to forget. 3-6 epics, each a " +
93
+ "short name + one-line rationale. Call submit_epics_risk once.",
94
+ },
95
+ ];
96
+ const SYNTH_SYSTEM = [
97
+ "You are the PROJECT MANAGER chairing a planning council. Three leads proposed epics from different lenses",
98
+ "(architect, product, risk). Merge them into ONE clean, ordered epic list for the build: dedupe overlaps,",
99
+ "keep what matters, drop noise, and order them the way the work should proceed. Aim for 3-7 epics. Each epic:",
100
+ "a short name + a one-line rationale that folds in the strongest point(s) from the leads. Call submit_epics once.",
101
+ ].join("\n");
102
+ /** Run the council: 3 lenses in parallel, then synthesize. Falls back to a single
103
+ * lens's epics if synthesis fails; empty only if everything fails. */
104
+ export async function councilEpics(idea, ctx) {
105
+ const proposalsRaw = await Promise.all(LENSES.map((l) => runEpicAgent(idea, l.system, `submit_epics_${l.key}`, ctx).then((epics) => ({ lens: l.key, epics }))));
106
+ const proposals = proposalsRaw.filter((p) => p.epics.length);
107
+ if (!proposals.length)
108
+ return { epics: [], proposals: [] };
109
+ // Synthesize.
110
+ const runtime = await piRuntime();
111
+ const { entry } = findEntry("plan", "mid");
112
+ const pick = ctx.modelOverride ?? entry.byBackend[ctx.backend];
113
+ try {
114
+ const model = resolvePiModel(runtime, pick.provider, pick.model);
115
+ const { tool, get } = buildEpicsTool("submit_epics");
116
+ const { session } = await createAgentSession({
117
+ model, modelRuntime: runtime, thinkingLevel: "low",
118
+ noTools: "all", customTools: [tool], tools: ["submit_epics"],
119
+ });
120
+ try {
121
+ const block = proposals
122
+ .map((p) => `### ${p.lens}\n${p.epics.map((e) => `- ${e.name}: ${e.rationale}`).join("\n")}`)
123
+ .join("\n\n");
124
+ await session.prompt(`${SYNTH_SYSTEM}\n\n--- REQUEST ---\n${idea}\n\n--- LEAD PROPOSALS ---\n${block}`);
125
+ let raw = get();
126
+ if (!raw) {
127
+ await session.prompt("Call submit_epics now.");
128
+ raw = get();
129
+ }
130
+ addSessionCost(session.getSessionStats().cost);
131
+ const epics = (raw?.epics ?? [])
132
+ .map((e) => ({ name: String(e.name ?? "").trim(), rationale: String(e.rationale ?? "").trim() }))
133
+ .filter((e) => e.name);
134
+ // Fall back to the largest single proposal if synthesis produced nothing.
135
+ const best = proposals.slice().sort((a, b) => b.epics.length - a.epics.length)[0].epics;
136
+ return { epics: epics.length ? epics : best, proposals };
137
+ }
138
+ finally {
139
+ session.dispose();
140
+ }
141
+ }
142
+ catch {
143
+ const best = proposals.slice().sort((a, b) => b.epics.length - a.epics.length)[0].epics;
144
+ return { epics: best, proposals };
145
+ }
146
+ }
147
+ //# sourceMappingURL=council.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"council.js","sourceRoot":"","sources":["../src/council.ts"],"names":[],"mappings":"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"}
package/dist/demo.js ADDED
@@ -0,0 +1,93 @@
1
+ // Phase 1 demo — proves the brain before wiring any agents.
2
+ // Feeds a fake "landing page + contact form" backlog through the router and prints
3
+ // backend, model, and estimated cost per task, plus the total.
4
+ //
5
+ // Run: npm run demo (cost-first / web backend)
6
+ // npm run demo -- api (force API backend)
7
+ // npm run demo -- ask (interactive-style; here stubbed to demonstrate)
8
+ import { fileURLToPath } from "node:url";
9
+ import { dirname, join } from "node:path";
10
+ import { DEFAULT_POLICY, routeBacklog } from "./router.js";
11
+ import { loadRegistry, OVERRIDES_FILENAME } from "./registry-store.js";
12
+ const BACKLOG = [
13
+ {
14
+ id: "T-01", epic: "E-1", story: "S-1", title: "Break brief into backlog",
15
+ capability: "plan", difficulty: "medium",
16
+ estTokens: { input: 10_000, output: 5_000 },
17
+ },
18
+ {
19
+ id: "T-02", epic: "E-1", story: "S-2", title: "Design hero + layout system",
20
+ capability: "design", difficulty: "high",
21
+ estTokens: { input: 20_000, output: 15_000 },
22
+ },
23
+ {
24
+ id: "T-03", epic: "E-2", story: "S-3", title: "Build page + contact form",
25
+ capability: "code", difficulty: "high", dependsOn: ["T-02"],
26
+ estTokens: { input: 400_000, output: 60_000, cachedInputFraction: 0.6 },
27
+ },
28
+ {
29
+ id: "T-04", epic: "E-2", story: "S-4", title: "Wire form handler",
30
+ capability: "code", difficulty: "low", dependsOn: ["T-03"],
31
+ estTokens: { input: 30_000, output: 8_000, cachedInputFraction: 0.5 },
32
+ },
33
+ {
34
+ id: "T-05", epic: "E-3", story: "S-5", title: "Review + test the build",
35
+ capability: "test", difficulty: "trivial", dependsOn: ["T-03", "T-04"],
36
+ estTokens: { input: 80_000, output: 15_000 },
37
+ },
38
+ {
39
+ id: "T-06", epic: "E-3", story: "S-6", title: "Run it, drive the CI/preview",
40
+ capability: "ops", difficulty: "high", dependsOn: ["T-04"],
41
+ estTokens: { input: 100_000, output: 20_000, cachedInputFraction: 0.4 },
42
+ },
43
+ ];
44
+ const arg = process.argv[2];
45
+ const policy = { ...DEFAULT_POLICY };
46
+ if (arg === "api")
47
+ policy.backendMode = "api";
48
+ if (arg === "web")
49
+ policy.backendMode = "web";
50
+ // For "ask" mode we'd wire real prompts; here we stub a chooser so the demo runs headless.
51
+ const prompts = arg === "ask"
52
+ ? {
53
+ chooseBackend: () => "api",
54
+ chooseModel: (_t, _e, _b) => undefined, // accept defaults
55
+ }
56
+ : undefined;
57
+ if (arg === "ask")
58
+ policy.backendMode = "ask";
59
+ // Load the effective registry (seed + any Scout overrides), so applied Scout
60
+ // changes are reflected here.
61
+ const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)));
62
+ const registry = loadRegistry(join(projectRoot, OVERRIDES_FILENAME));
63
+ const decisions = routeBacklog(BACKLOG, { policy, registry, prompts });
64
+ const pad = (s, n) => s.padEnd(n);
65
+ const money = (n) => `$${n.toFixed(2)}`;
66
+ console.log(`\n Projectinator — routing plan [backendMode=${policy.backendMode}, cap=${money(policy.budgetCapUSD)}]\n`);
67
+ console.log(" " +
68
+ pad("TASK", 7) + pad("CAPABILITY", 11) + pad("DIFF", 9) +
69
+ pad("BACKEND", 9) + pad("MODEL", 20) + pad("TIER", 6) + pad("COST", 9) + "RUNNING");
70
+ console.log(" " + "-".repeat(78));
71
+ for (const d of decisions) {
72
+ const task = BACKLOG.find((t) => t.id === d.taskId);
73
+ const flag = d.overCap ? " ⚠ OVER CAP" : "";
74
+ console.log(" " +
75
+ pad(d.taskId, 7) +
76
+ pad(task.capability, 11) +
77
+ pad(task.difficulty, 9) +
78
+ pad(d.backend, 9) +
79
+ pad(d.model.name, 20) +
80
+ pad(d.tier, 6) +
81
+ pad(money(d.cost), 9) +
82
+ money(d.runningTotal) +
83
+ flag);
84
+ }
85
+ const total = decisions.at(-1)?.runningTotal ?? 0;
86
+ console.log(" " + "-".repeat(78));
87
+ console.log(` TOTAL ESTIMATED: ${money(total)}\n`);
88
+ console.log(" Decision trail for T-03 (the developer task):");
89
+ for (const r of decisions.find((d) => d.taskId === "T-03").reasons) {
90
+ console.log(" · " + r);
91
+ }
92
+ console.log("");
93
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"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"}