projectinator 0.3.1 → 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 (171) hide show
  1. package/README.md +7 -6
  2. package/bin/projectinator.mjs +22 -15
  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/cli.ts +0 -263
  125. package/src/cost.ts +0 -43
  126. package/src/council.ts +0 -175
  127. package/src/demo.ts +0 -106
  128. package/src/estimate.ts +0 -111
  129. package/src/executor.ts +0 -169
  130. package/src/git.ts +0 -72
  131. package/src/intake.ts +0 -125
  132. package/src/models.ts +0 -175
  133. package/src/narrate.ts +0 -87
  134. package/src/openrouter.ts +0 -119
  135. package/src/orchestrator.ts +0 -310
  136. package/src/pm.ts +0 -302
  137. package/src/preview.ts +0 -206
  138. package/src/registry-store.ts +0 -41
  139. package/src/registry.ts +0 -132
  140. package/src/research.ts +0 -123
  141. package/src/retro.ts +0 -99
  142. package/src/roles.ts +0 -401
  143. package/src/router.ts +0 -120
  144. package/src/run-bakeoff.ts +0 -77
  145. package/src/run-build.ts +0 -203
  146. package/src/run-web.ts +0 -87
  147. package/src/scout.ts +0 -121
  148. package/src/session-cost.ts +0 -17
  149. package/src/stack.ts +0 -46
  150. package/src/tui/App.tsx +0 -1760
  151. package/src/tui/BakeOff.tsx +0 -190
  152. package/src/tui/BoardEditor.tsx +0 -260
  153. package/src/tui/EditableBoard.tsx +0 -179
  154. package/src/tui/Frame.tsx +0 -142
  155. package/src/tui/Intake.tsx +0 -111
  156. package/src/tui/Kanban.tsx +0 -158
  157. package/src/tui/Settings.tsx +0 -513
  158. package/src/tui/StackPick.tsx +0 -79
  159. package/src/tui/WebAccounts.tsx +0 -197
  160. package/src/tui/components.tsx +0 -340
  161. package/src/tui/config.ts +0 -150
  162. package/src/tui/deploy.ts +0 -137
  163. package/src/tui/engine.ts +0 -749
  164. package/src/tui/notify.ts +0 -21
  165. package/src/tui/panels.tsx +0 -89
  166. package/src/tui/templates.ts +0 -119
  167. package/src/tui/theme.ts +0 -44
  168. package/src/tui/validate.ts +0 -53
  169. package/src/types.ts +0 -208
  170. package/src/web/oauth-anthropic.ts +0 -206
  171. 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"}