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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-pm.js","sourceRoot":"","sources":["../src/run-pm.ts"],"names":[],"mappings":"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"}
@@ -8,67 +8,56 @@
8
8
  //
9
9
  // The report is any benchmark write-up — e.g. save the deep-research harness output to a
10
10
  // text file and point this at it.
11
-
12
11
  import { readFileSync, writeFileSync } from "node:fs";
13
12
  import { fileURLToPath } from "node:url";
14
13
  import { dirname, join } from "node:path";
15
- import type { Provider } from "./types.js";
16
14
  import { extractFindings, validateFindings, extractionPrompt } from "./research.js";
17
-
18
15
  const args = process.argv.slice(2);
19
16
  const live = args.includes("--live");
20
17
  const outIdx = args.indexOf("--out");
21
18
  const modelIdx = args.indexOf("--model");
22
19
  const modelArg = (modelIdx >= 0 ? args[modelIdx + 1] : undefined) ?? "anthropic/claude-sonnet-4-6";
23
20
  const outArg = outIdx >= 0 ? args[outIdx + 1] : undefined;
24
-
25
- const consumed = new Set(["--live", "--out", outArg, "--model", modelArg].filter(Boolean) as string[]);
21
+ const consumed = new Set(["--live", "--out", outArg, "--model", modelArg].filter(Boolean));
26
22
  const reportPath = args.filter((a) => !consumed.has(a))[0];
27
-
28
23
  if (!reportPath) {
29
- console.error("\n Usage: npm run research -- <report.txt> [--live] [--out findings.json] [--model provider/id]\n");
30
- process.exit(1);
24
+ console.error("\n Usage: npm run research -- <report.txt> [--live] [--out findings.json] [--model provider/id]\n");
25
+ process.exit(1);
31
26
  }
32
-
33
27
  const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)));
34
28
  const outPath = outArg ?? join(projectRoot, "findings.json");
35
29
  const [provider, ...rest] = modelArg.split("/");
36
- const modelSpec = { provider: provider as Provider, model: rest.join("/") };
37
-
30
+ const modelSpec = { provider: provider, model: rest.join("/") };
38
31
  const report = readFileSync(reportPath, "utf-8");
39
-
40
32
  console.log(`\n Projectinator — Research extractor [${live ? "LIVE" : "DRY"}]`);
41
33
  console.log(` Report: ${reportPath} (${report.length} chars)`);
42
34
  console.log(` Model: ${modelSpec.provider}/${modelSpec.model}`);
43
35
  console.log(` Output: ${outPath}\n`);
44
-
45
36
  if (!live) {
46
- console.log(" --- extraction prompt (not sent, report truncated) ---");
47
- console.log(extractionPrompt(report.slice(0, 400) + "\n...[truncated]").split("\n").map((l) => " | " + l).join("\n"));
48
- console.log("\n Dry run. Add --live (and an API key) to extract.\n");
49
- process.exit(0);
37
+ console.log(" --- extraction prompt (not sent, report truncated) ---");
38
+ console.log(extractionPrompt(report.slice(0, 400) + "\n...[truncated]").split("\n").map((l) => " | " + l).join("\n"));
39
+ console.log("\n Dry run. Add --live (and an API key) to extract.\n");
40
+ process.exit(0);
50
41
  }
51
-
52
- const envKey: Record<string, string[]> = {
53
- anthropic: ["ANTHROPIC_API_KEY"], openai: ["OPENAI_API_KEY"],
54
- google: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
42
+ const envKey = {
43
+ anthropic: ["ANTHROPIC_API_KEY"], openai: ["OPENAI_API_KEY"],
44
+ google: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
55
45
  };
56
46
  if (!(envKey[modelSpec.provider] ?? []).some((k) => process.env[k])) {
57
- console.error(` No API key for ${modelSpec.provider}. Set: ${(envKey[modelSpec.provider] ?? []).join(", ")}\n`);
58
- process.exit(1);
47
+ console.error(` No API key for ${modelSpec.provider}. Set: ${(envKey[modelSpec.provider] ?? []).join(", ")}\n`);
48
+ process.exit(1);
59
49
  }
60
-
61
50
  console.log(" Extracting...\n");
62
51
  const findings = await extractFindings(report, { model: modelSpec });
63
52
  const { ok, issues } = validateFindings(findings);
64
-
65
53
  console.log(` Extracted ${findings.length} findings:`);
66
- for (const f of findings) console.log(` ${f.capability}/${f.tier} [${f.backend}] -> ${f.provider}/${f.model}`);
67
-
54
+ for (const f of findings)
55
+ console.log(` ${f.capability}/${f.tier} [${f.backend}] -> ${f.provider}/${f.model}`);
68
56
  if (!ok) {
69
- console.log(`\n Validation issues (fix models.ts or the report before applying):`);
70
- for (const i of issues) console.log(` ! finding ${i.index} (${i.model}): ${i.problem}`);
57
+ console.log(`\n Validation issues (fix models.ts or the report before applying):`);
58
+ for (const i of issues)
59
+ console.log(` ! finding ${i.index} (${i.model}): ${i.problem}`);
71
60
  }
72
-
73
61
  writeFileSync(outPath, JSON.stringify({ findings }, null, 2) + "\n");
74
62
  console.log(`\n Wrote ${outPath}. Next: npm run scout -- --from ${outPath}\n`);
63
+ //# sourceMappingURL=run-research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-research.js","sourceRoot":"","sources":["../src/run-research.ts"],"names":[],"mappings":"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"}
@@ -7,62 +7,52 @@
7
7
  // Findings normally come from a research/benchmark pass (the deep-research harness
8
8
  // emits exactly this kind of verified model->role data). Semi-auto: you see the diff
9
9
  // before anything changes.
10
-
11
10
  import { readFileSync } from "node:fs";
12
11
  import { fileURLToPath } from "node:url";
13
12
  import { dirname, join } from "node:path";
14
13
  import { loadRegistry, saveOverrides, OVERRIDES_FILENAME } from "./registry-store.js";
15
- import { proposeUpdate, formatProposal, meaningfulChanges, type Finding } from "./scout.js";
14
+ import { proposeUpdate, formatProposal, meaningfulChanges } from "./scout.js";
16
15
  import { validateFindings } from "./research.js";
17
-
18
16
  const args = process.argv.slice(2);
19
17
  const apply = args.includes("--apply");
20
18
  const fromIdx = args.indexOf("--from");
21
19
  const fromFile = fromIdx >= 0 ? args[fromIdx + 1] : undefined;
22
-
23
20
  const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)));
24
21
  const overridesPath = join(projectRoot, OVERRIDES_FILENAME);
25
-
26
22
  // A stand-in for research output. Shows an update, a no-op, an add, and the
27
23
  // unknown-model guard. Replace via --from with real verified findings.
28
- const SAMPLE_FINDINGS: Finding[] = [
29
- { capability: "code", tier: "high", backend: "api", provider: "anthropic", model: "claude-fable-5", evidence: "SWE-bench Verified: Fable 5 95% now the API pick over Opus 4.8 88.6%", date: "2026-07-15" },
30
- { capability: "test", tier: "fast", backend: "api", provider: "google", model: "gemini-3-flash-preview", evidence: "Still cheapest high-volume reviewer" },
31
- { capability: "plan", tier: "high", backend: "api", provider: "openai", model: "gpt-5.6-sol", evidence: "New plan/high tier for hard planning tasks" },
24
+ const SAMPLE_FINDINGS = [
25
+ { capability: "code", tier: "high", backend: "api", provider: "anthropic", model: "claude-fable-5", evidence: "SWE-bench Verified: Fable 5 95% now the API pick over Opus 4.8 88.6%", date: "2026-07-15" },
26
+ { capability: "test", tier: "fast", backend: "api", provider: "google", model: "gemini-3-flash-preview", evidence: "Still cheapest high-volume reviewer" },
27
+ { capability: "plan", tier: "high", backend: "api", provider: "openai", model: "gpt-5.6-sol", evidence: "New plan/high tier for hard planning tasks" },
32
28
  ];
33
-
34
- const findings: Finding[] = fromFile
35
- ? (JSON.parse(readFileSync(fromFile, "utf-8")) as { findings: Finding[] }).findings
36
- : SAMPLE_FINDINGS;
37
-
29
+ const findings = fromFile
30
+ ? JSON.parse(readFileSync(fromFile, "utf-8")).findings
31
+ : SAMPLE_FINDINGS;
38
32
  // Guard against findings that reference models we don't know about.
39
33
  const validation = validateFindings(findings);
40
34
  if (!validation.ok) {
41
- console.log("\n Findings reference unknown/mismatched models:");
42
- for (const i of validation.issues) console.log(` ! finding ${i.index} (${i.model}): ${i.problem}`);
43
- console.log(" (These will surface as 'unknown-model' below and block --apply.)");
35
+ console.log("\n Findings reference unknown/mismatched models:");
36
+ for (const i of validation.issues)
37
+ console.log(` ! finding ${i.index} (${i.model}): ${i.problem}`);
38
+ console.log(" (These will surface as 'unknown-model' below and block --apply.)");
44
39
  }
45
-
46
40
  const current = loadRegistry(overridesPath);
47
41
  const proposal = proposeUpdate(current, findings);
48
-
49
42
  console.log(`\n Projectinator — Scout [${apply ? "APPLY" : "DRY"}]`);
50
43
  console.log(` Findings: ${findings.length}${fromFile ? ` (from ${fromFile})` : " (sample)"}\n`);
51
44
  console.log(" Proposed registry changes:");
52
45
  console.log(formatProposal(proposal.changes));
53
-
54
46
  const real = meaningfulChanges(proposal.changes);
55
47
  const unknown = real.filter((c) => c.kind === "unknown-model");
56
-
57
48
  if (!apply) {
58
- console.log(`\n ${real.length} change(s). Re-run with --apply to write ${OVERRIDES_FILENAME}.\n`);
59
- process.exit(0);
49
+ console.log(`\n ${real.length} change(s). Re-run with --apply to write ${OVERRIDES_FILENAME}.\n`);
50
+ process.exit(0);
60
51
  }
61
-
62
52
  if (unknown.length) {
63
- console.error(`\n Refusing to apply: ${unknown.length} finding(s) reference a model not in models.ts. Add it first.\n`);
64
- process.exit(1);
53
+ console.error(`\n Refusing to apply: ${unknown.length} finding(s) reference a model not in models.ts. Add it first.\n`);
54
+ process.exit(1);
65
55
  }
66
-
67
56
  saveOverrides(proposal.updated, overridesPath);
68
57
  console.log(`\n Applied. Wrote ${OVERRIDES_FILENAME}. Routing now uses the updated registry.\n`);
58
+ //# sourceMappingURL=run-scout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-scout.js","sourceRoot":"","sources":["../src/run-scout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ // EXPERIMENTAL web-login CLI.
2
+ //
3
+ // npm run web -- login claude open a browser, log in once (session saved)
4
+ // npm run web -- ask claude "2+2? one word" send a prompt via your web session
5
+ //
6
+ // This is the standalone proof-of-concept. Wiring it into the full build pipeline
7
+ // (parsing tasks/verdicts/code from text) is a separate step.
8
+ import { spawn } from "node:child_process";
9
+ import { createInterface } from "node:readline";
10
+ import { webLogin, webComplete, webDump, closeWebSessions, isWebProvider, PROVIDERS } from "./web/session.js";
11
+ import { buildAuthorizeUrl, exchangeCode, oauthTest } from "./web/oauth-anthropic.js";
12
+ const [cmd, provider, ...rest] = process.argv.slice(2);
13
+ function usage() {
14
+ console.log("\n Usage:");
15
+ console.log(" npm run web -- login <provider>");
16
+ console.log(' npm run web -- ask <provider> "your prompt"');
17
+ console.log(" npm run web -- oauth # Claude: OAuth connect (subscription)");
18
+ console.log(" npm run web -- oauth-test # Claude: probe if the token still works");
19
+ console.log(`\n Providers: ${Object.keys(PROVIDERS).join(", ")}\n`);
20
+ process.exit(1);
21
+ }
22
+ function ask(q) {
23
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
24
+ return new Promise((resolve) => rl.question(q, (a) => { rl.close(); resolve(a); }));
25
+ }
26
+ // ---- Claude OAuth (subscription) — the enforcement experiment ----
27
+ if (cmd === "oauth") {
28
+ const pending = buildAuthorizeUrl();
29
+ console.log("\n Opening your browser to approve Claude access…");
30
+ console.log(" If it doesn't open, paste this URL manually:\n");
31
+ console.log(" " + pending.url + "\n");
32
+ try {
33
+ spawn("open", [pending.url], { stdio: "ignore", detached: true }).unref();
34
+ }
35
+ catch { /* print-only */ }
36
+ const code = await ask(" After approving, copy the code shown on the page and paste it here:\n code> ");
37
+ try {
38
+ await exchangeCode(code, pending);
39
+ console.log("\n Token stored. Testing whether it survives enforcement…\n");
40
+ const reply = await oauthTest();
41
+ console.log(` ✅ Works. Reply: ${reply}\n`);
42
+ }
43
+ catch (e) {
44
+ console.error(`\n ❌ ${e instanceof Error ? e.message : e}\n`);
45
+ process.exit(1);
46
+ }
47
+ process.exit(0);
48
+ }
49
+ else if (cmd === "oauth-test") {
50
+ try {
51
+ const reply = await oauthTest();
52
+ console.log(`\n ✅ Works. Reply: ${reply}\n`);
53
+ }
54
+ catch (e) {
55
+ console.error(`\n ❌ ${e instanceof Error ? e.message : e}\n`);
56
+ process.exit(1);
57
+ }
58
+ process.exit(0);
59
+ }
60
+ if (!cmd || !provider || !isWebProvider(provider))
61
+ usage();
62
+ if (cmd === "login") {
63
+ await webLogin(provider);
64
+ console.log(` Logged in to ${PROVIDERS[provider].label}. Try: npm run web -- ask ${provider} "hello"\n`);
65
+ }
66
+ else if (cmd === "ask") {
67
+ const prompt = rest.join(" ").trim();
68
+ if (!prompt)
69
+ usage();
70
+ console.log(` Asking ${PROVIDERS[provider].label} via your web session…\n`);
71
+ try {
72
+ const reply = await webComplete(provider, prompt);
73
+ console.log(" --- reply ---");
74
+ console.log(reply.split("\n").map((l) => " " + l).join("\n"));
75
+ console.log("");
76
+ }
77
+ catch (e) {
78
+ console.error(` Failed: ${e instanceof Error ? e.message : e}`);
79
+ console.error(` If selectors are stale, edit src/web/session.ts. If not logged in, run: npm run web -- login ${provider}\n`);
80
+ await closeWebSessions();
81
+ process.exit(1);
82
+ }
83
+ await closeWebSessions(); // one-shot CLI: shut the background browser down
84
+ }
85
+ else if (cmd === "dump") {
86
+ const prompt = rest.join(" ").trim() || "say hello in one word";
87
+ console.log(` Diagnosing ${PROVIDERS[provider].label} DOM…\n`);
88
+ await webDump(provider, prompt);
89
+ }
90
+ else {
91
+ usage();
92
+ }
93
+ //# sourceMappingURL=run-web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-web.js","sourceRoot":"","sources":["../src/run-web.ts"],"names":[],"mappings":"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"}
package/dist/scout.js ADDED
@@ -0,0 +1,81 @@
1
+ // The Scout — keeps the registry current.
2
+ //
3
+ // Input: findings (best model per capability+tier, from a research/benchmark pass —
4
+ // the same kind of verified output the deep-research harness produces).
5
+ // Output: a proposed registry + a human-readable diff. SEMI-AUTO by design: the Scout
6
+ // proposes, you approve, then apply. Nothing changes routing without a look.
7
+ //
8
+ // Pure + testable: no network. Feed it findings; it computes the delta.
9
+ import { MODELS } from "./models.js";
10
+ const keyOf = (c, t) => `${c}/${t}`;
11
+ /** Compute a proposed registry from the current one + findings. Pure. */
12
+ export function proposeUpdate(current, findings) {
13
+ // Clone entries so we don't mutate the input.
14
+ const map = new Map(current.map((e) => [keyOf(e.capability, e.tier), cloneEntry(e)]));
15
+ const changes = [];
16
+ for (const f of findings) {
17
+ const k = keyOf(f.capability, f.tier);
18
+ const known = !!MODELS[f.model];
19
+ const existing = map.get(k);
20
+ if (!existing) {
21
+ // New capability/tier slot — seed both backends with the finding, mark others later.
22
+ map.set(k, {
23
+ capability: f.capability,
24
+ tier: f.tier,
25
+ byBackend: {
26
+ web: { provider: f.provider, model: f.model },
27
+ api: { provider: f.provider, model: f.model },
28
+ },
29
+ evidence: f.evidence,
30
+ updated: f.date ?? "scout",
31
+ });
32
+ changes.push({
33
+ kind: known ? "add" : "unknown-model",
34
+ capability: f.capability, tier: f.tier, backend: f.backend,
35
+ to: f.model, evidence: f.evidence,
36
+ });
37
+ continue;
38
+ }
39
+ const cur = existing.byBackend[f.backend];
40
+ if (cur.model === f.model && cur.provider === f.provider) {
41
+ changes.push({
42
+ kind: "noop", capability: f.capability, tier: f.tier, backend: f.backend,
43
+ from: cur.model, to: f.model, evidence: f.evidence,
44
+ });
45
+ continue;
46
+ }
47
+ existing.byBackend[f.backend] = { provider: f.provider, model: f.model };
48
+ existing.evidence = f.evidence;
49
+ existing.updated = f.date ?? "scout";
50
+ changes.push({
51
+ kind: known ? "update" : "unknown-model",
52
+ capability: f.capability, tier: f.tier, backend: f.backend,
53
+ from: cur.model, to: f.model, evidence: f.evidence,
54
+ });
55
+ }
56
+ return { updated: [...map.values()], changes };
57
+ }
58
+ /** Only the changes that actually alter routing (drops noops). */
59
+ export function meaningfulChanges(changes) {
60
+ return changes.filter((c) => c.kind !== "noop");
61
+ }
62
+ export function formatProposal(changes) {
63
+ const real = meaningfulChanges(changes);
64
+ if (!real.length)
65
+ return " No changes — registry already matches the findings.";
66
+ const icon = { add: "+", update: "~", noop: " ", "unknown-model": "!" };
67
+ return real
68
+ .map((c) => {
69
+ const arrow = c.from ? `${c.from} -> ${c.to}` : c.to;
70
+ const warn = c.kind === "unknown-model" ? " [!] model not in models.ts — add it before applying" : "";
71
+ return ` ${icon[c.kind]} ${c.capability}/${c.tier} [${c.backend}] ${arrow}\n ${c.evidence}${warn}`;
72
+ })
73
+ .join("\n");
74
+ }
75
+ function cloneEntry(e) {
76
+ return {
77
+ ...e,
78
+ byBackend: { web: { ...e.byBackend.web }, api: { ...e.byBackend.api } },
79
+ };
80
+ }
81
+ //# sourceMappingURL=scout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scout.js","sourceRoot":"","sources":["../src/scout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ // Running total of money spent in THIS process (session). Every Pi session adds its
2
+ // own cost here after it finishes, so it captures builds, planning, breakdowns — all of it.
3
+ // Resets on process restart (module-level state).
4
+ let total = 0;
5
+ export function addSessionCost(n) {
6
+ if (Number.isFinite(n) && n > 0)
7
+ total += n;
8
+ }
9
+ export function sessionCost() {
10
+ return Math.round(total * 100) / 100;
11
+ }
12
+ export function resetSessionCost() {
13
+ total = 0;
14
+ }
15
+ //# sourceMappingURL=session-cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-cost.js","sourceRoot":"","sources":["../src/session-cost.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,4FAA4F;AAC5F,kDAAkD;AAElD,IAAI,KAAK,GAAG,CAAC,CAAC;AAEd,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,KAAK,GAAG,CAAC,CAAC;AACZ,CAAC"}
package/dist/stack.js ADDED
@@ -0,0 +1,34 @@
1
+ // Target stack — the platform + framework a build should target. The choice is
2
+ // turned into a short instruction appended to the brief, so the PM and dev build
3
+ // the right thing. Kept build-free on purpose (CDN React, no Vite/npm) so the
4
+ // existing static test/preview/deploy pipeline works unchanged.
5
+ export const WEB_FRAMEWORKS = [
6
+ { id: "vanilla", label: "Vanilla HTML / CSS / JS (no framework)" },
7
+ { id: "react", label: "React (via CDN, no build step)" },
8
+ { id: "ai", label: "Let the AI decide" },
9
+ ];
10
+ const WEB_DESC = {
11
+ vanilla: "vanilla HTML, CSS, and JavaScript — no framework, no build step",
12
+ react: "React loaded from a CDN (no build step): a single index.html that imports React and ReactDOM " +
13
+ "from https://esm.sh/react and https://esm.sh/react-dom/client as ES modules, uses function " +
14
+ "components and hooks, and mounts into a <div id=\"root\">. Put styles in styles.css. Do NOT use " +
15
+ "Vite, JSX files, npm, or any build tooling — everything must run by opening index.html.",
16
+ };
17
+ /** The instruction appended to the brief for the chosen stack (empty = AI decides). */
18
+ export function stackInstruction(choice) {
19
+ const { platform, framework } = choice;
20
+ if (platform !== "web") {
21
+ return `\n\nTarget platform: ${platform}. Native ${platform} toolchains aren't wired up yet — build a responsive web app (single index.html) styled to feel like a ${platform} app.`;
22
+ }
23
+ if (!framework || framework === "ai")
24
+ return ""; // let the PM pick a web approach
25
+ const desc = WEB_DESC[framework] ?? `the ${framework} stack (no build step; must run by opening index.html)`;
26
+ return `\n\nTarget stack: ${desc}.`;
27
+ }
28
+ /** Human label for a stored choice, for display. */
29
+ export function stackLabel(choice) {
30
+ if (choice.platform !== "web")
31
+ return `${choice.platform} (as web)`;
32
+ return WEB_FRAMEWORKS.find((f) => f.id === choice.framework)?.label ?? String(choice.framework);
33
+ }
34
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../src/stack.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,gEAAgE;AAYhE,MAAM,CAAC,MAAM,cAAc,GAAuC;IAChE,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,wCAAwC,EAAE;IAClE,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,gCAAgC,EAAE;IACxD,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE;CACzC,CAAC;AAEF,MAAM,QAAQ,GAA2B;IACvC,OAAO,EAAE,iEAAiE;IAC1E,KAAK,EACH,+FAA+F;QAC/F,6FAA6F;QAC7F,kGAAkG;QAClG,yFAAyF;CAC5F,CAAC;AAEF,uFAAuF;AACvF,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACvC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,wBAAwB,QAAQ,YAAY,QAAQ,0GAA0G,QAAQ,OAAO,CAAC;IACvL,CAAC;IACD,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC,CAAC,iCAAiC;IAClF,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,SAAS,wDAAwD,CAAC;IAC7G,OAAO,qBAAqB,IAAI,GAAG,CAAC;AACtC,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK;QAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,WAAW,CAAC;IACpE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClG,CAAC"}
package/dist/stuck.js ADDED
@@ -0,0 +1,21 @@
1
+ // "Is this task taking too long?" — pure, so the rule is testable and the UI just asks.
2
+ //
3
+ // A task is flagged once it has run for longer than BOTH a floor (nobody wants a "slow"
4
+ // badge at 20 s) and the larger of: 2x the typical duration of its bucket/model (from
5
+ // calibration, when known) or half its timeout. With no history and no timeout it never
6
+ // flags — we have nothing to compare against.
7
+ import { expectedDurationMs } from "./calibration.js";
8
+ const FLOOR_MS = 60_000;
9
+ export function stuckThresholdMs(capability, difficulty, modelId, timeoutMs) {
10
+ const typical = expectedDurationMs(capability, difficulty, modelId);
11
+ const fromHistory = typical ? typical * 2 : undefined;
12
+ const fromTimeout = timeoutMs > 0 ? timeoutMs / 2 : undefined;
13
+ if (fromHistory === undefined && fromTimeout === undefined)
14
+ return undefined;
15
+ return Math.max(FLOOR_MS, fromHistory ?? 0, fromTimeout ?? 0);
16
+ }
17
+ export function isStuck(elapsedMs, capability, difficulty, modelId, timeoutMs) {
18
+ const t = stuckThresholdMs(capability, difficulty, modelId, timeoutMs);
19
+ return t !== undefined && elapsedMs > t;
20
+ }
21
+ //# sourceMappingURL=stuck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stuck.js","sourceRoot":"","sources":["../src/stuck.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,EAAE;AACF,wFAAwF;AACxF,sFAAsF;AACtF,wFAAwF;AACxF,8CAA8C;AAG9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,QAAQ,GAAG,MAAM,CAAC;AAExB,MAAM,UAAU,gBAAgB,CAAC,UAAsB,EAAE,UAAsB,EAAE,OAA2B,EAAE,SAAiB;IAC7H,MAAM,OAAO,GAAG,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACpE,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7E,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,IAAI,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,UAAsB,EAAE,UAAsB,EAAE,OAA2B,EAAE,SAAiB;IACvI,MAAM,CAAC,GAAG,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,CAAC;AAC1C,CAAC"}