linersh 0.5.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 (95) hide show
  1. package/README.md +168 -0
  2. package/bin/liner.js +126 -0
  3. package/dist/App.js +195 -0
  4. package/dist/App.js.map +1 -0
  5. package/dist/agents/detect.js +102 -0
  6. package/dist/agents/detect.js.map +1 -0
  7. package/dist/agents/events.js +8 -0
  8. package/dist/agents/events.js.map +1 -0
  9. package/dist/agents/jtbd-clarify.js +144 -0
  10. package/dist/agents/jtbd-clarify.js.map +1 -0
  11. package/dist/agents/parsers.js +316 -0
  12. package/dist/agents/parsers.js.map +1 -0
  13. package/dist/agents/prompts.js +301 -0
  14. package/dist/agents/prompts.js.map +1 -0
  15. package/dist/agents/run-log.js +71 -0
  16. package/dist/agents/run-log.js.map +1 -0
  17. package/dist/agents/runner.js +180 -0
  18. package/dist/agents/runner.js.map +1 -0
  19. package/dist/agents/types.js +2 -0
  20. package/dist/agents/types.js.map +1 -0
  21. package/dist/bin-resolver.js +92 -0
  22. package/dist/bin-resolver.js.map +1 -0
  23. package/dist/browser-support.js +62 -0
  24. package/dist/browser-support.js.map +1 -0
  25. package/dist/colors.js +105 -0
  26. package/dist/colors.js.map +1 -0
  27. package/dist/components/Header.js +17 -0
  28. package/dist/components/Header.js.map +1 -0
  29. package/dist/components/KeyHints.js +10 -0
  30. package/dist/components/KeyHints.js.map +1 -0
  31. package/dist/components/LabeledBox.js +53 -0
  32. package/dist/components/LabeledBox.js.map +1 -0
  33. package/dist/components/NextSteps.js +18 -0
  34. package/dist/components/NextSteps.js.map +1 -0
  35. package/dist/config.js +88 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/editor.js +40 -0
  38. package/dist/editor.js.map +1 -0
  39. package/dist/gates.js +121 -0
  40. package/dist/gates.js.map +1 -0
  41. package/dist/index.js +17 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/ipc.js +136 -0
  44. package/dist/ipc.js.map +1 -0
  45. package/dist/phases.js +348 -0
  46. package/dist/phases.js.map +1 -0
  47. package/dist/progress.js +185 -0
  48. package/dist/progress.js.map +1 -0
  49. package/dist/screens/AgentSetup.js +217 -0
  50. package/dist/screens/AgentSetup.js.map +1 -0
  51. package/dist/screens/BootSplash.js +159 -0
  52. package/dist/screens/BootSplash.js.map +1 -0
  53. package/dist/screens/BrowserSetup.js +181 -0
  54. package/dist/screens/BrowserSetup.js.map +1 -0
  55. package/dist/screens/CompileView.js +297 -0
  56. package/dist/screens/CompileView.js.map +1 -0
  57. package/dist/screens/FramingConfirmReview.js +193 -0
  58. package/dist/screens/FramingConfirmReview.js.map +1 -0
  59. package/dist/screens/Gate1Review.js +143 -0
  60. package/dist/screens/Gate1Review.js.map +1 -0
  61. package/dist/screens/Gate2Review.js +158 -0
  62. package/dist/screens/Gate2Review.js.map +1 -0
  63. package/dist/screens/ImportPrompt.js +65 -0
  64. package/dist/screens/ImportPrompt.js.map +1 -0
  65. package/dist/screens/LocalFilePicker.js +139 -0
  66. package/dist/screens/LocalFilePicker.js.map +1 -0
  67. package/dist/screens/NewMixtapeWizard.js +662 -0
  68. package/dist/screens/NewMixtapeWizard.js.map +1 -0
  69. package/dist/screens/NewProjectPrompt.js +66 -0
  70. package/dist/screens/NewProjectPrompt.js.map +1 -0
  71. package/dist/screens/PhaseRunner.js +1119 -0
  72. package/dist/screens/PhaseRunner.js.map +1 -0
  73. package/dist/screens/ProcessManifest.js +158 -0
  74. package/dist/screens/ProcessManifest.js.map +1 -0
  75. package/dist/screens/ProjectHub.js +546 -0
  76. package/dist/screens/ProjectHub.js.map +1 -0
  77. package/dist/screens/Settings.js +72 -0
  78. package/dist/screens/Settings.js.map +1 -0
  79. package/dist/screens/SourceModal.js +269 -0
  80. package/dist/screens/SourceModal.js.map +1 -0
  81. package/dist/screens/TapeBrowser.js +277 -0
  82. package/dist/screens/TapeBrowser.js.map +1 -0
  83. package/dist/screens/TapeDraftReview.js +440 -0
  84. package/dist/screens/TapeDraftReview.js.map +1 -0
  85. package/dist/screens/TapeEditor.js +310 -0
  86. package/dist/screens/TapeEditor.js.map +1 -0
  87. package/dist/screens/cassette-art.js +72 -0
  88. package/dist/screens/cassette-art.js.map +1 -0
  89. package/dist/store.js +10 -0
  90. package/dist/store.js.map +1 -0
  91. package/dist/types.js +3 -0
  92. package/dist/types.js.map +1 -0
  93. package/dist/yaml-io.js +345 -0
  94. package/dist/yaml-io.js.map +1 -0
  95. package/package.json +54 -0
package/dist/gates.js ADDED
@@ -0,0 +1,121 @@
1
+ // Permissive parsers for the Gate 1 / Gate 2 review screens.
2
+ //
3
+ // These read working/* artifacts produced by the agent (or the curator by hand)
4
+ // and produce structured data the TUI can render. They are deliberately lenient
5
+ // — the artifacts are markdown/yaml meant for human eyes, not a strict schema.
6
+ import { readFileSync, existsSync } from "node:fs";
7
+ import * as YAML from "yaml";
8
+ /** Parse a candidate long-list markdown file produced in Phase 2. */
9
+ export function parseLonglist(path) {
10
+ if (!existsSync(path))
11
+ return [];
12
+ const text = readFileSync(path, "utf8");
13
+ const sections = [];
14
+ let current = null;
15
+ for (const rawLine of text.split("\n")) {
16
+ const line = rawLine.replace(/\r$/, "");
17
+ // Section header (## ...)
18
+ const headingMatch = line.match(/^##\s+(.+?)\s*$/);
19
+ if (headingMatch) {
20
+ // Drop the literal "Section:" prefix the template uses, so the displayed
21
+ // header reads as just the section name.
22
+ const title = (headingMatch[1] ?? "").replace(/^Section:\s*/i, "");
23
+ current = { title, candidates: [] };
24
+ sections.push(current);
25
+ continue;
26
+ }
27
+ if (!current)
28
+ continue;
29
+ // Bullet (- or *) followed by an optional checkbox.
30
+ const bulletMatch = line.match(/^\s*[-*]\s+(.*)$/);
31
+ if (!bulletMatch)
32
+ continue;
33
+ let rest = (bulletMatch[1] ?? "").trim();
34
+ rest = rest.replace(/^\[[ xX]\]\s*/, "");
35
+ const urlMatch = rest.match(/https?:\/\/\S+/);
36
+ const url = urlMatch ? urlMatch[0].replace(/[.,;)\]]+$/, "") : "";
37
+ const label = url ? rest.replace(url, "").replace(/\s+/g, " ").trim() : rest;
38
+ current.candidates.push({ url, label });
39
+ }
40
+ // Filter out empty sections (e.g. the intro paragraph before any heading).
41
+ return sections.filter((s) => s.candidates.length > 0);
42
+ }
43
+ export function parseEvaluation(path) {
44
+ if (!existsSync(path))
45
+ return [];
46
+ let parsed;
47
+ try {
48
+ parsed = YAML.parse(readFileSync(path, "utf8"));
49
+ }
50
+ catch {
51
+ return [];
52
+ }
53
+ if (!parsed || typeof parsed !== "object")
54
+ return [];
55
+ const raw = parsed["candidates"];
56
+ if (!Array.isArray(raw))
57
+ return [];
58
+ return raw.map((entry) => {
59
+ const o = (entry ?? {});
60
+ return {
61
+ url: String(o["url"] ?? ""),
62
+ title: String(o["title"] ?? ""),
63
+ decision: String(o["decision"] ?? ""),
64
+ rating: typeof o["rating"] === "number" ? o["rating"] : null,
65
+ section: String(o["section"] ?? ""),
66
+ rationale: String(o["rationale"] ?? ""),
67
+ note: String(o["note"] ?? ""),
68
+ };
69
+ });
70
+ }
71
+ export function parseQualityChecks(path) {
72
+ if (!existsSync(path))
73
+ return [];
74
+ const text = readFileSync(path, "utf8");
75
+ const checks = [];
76
+ let currentTest = null;
77
+ let buffer = [];
78
+ function flush() {
79
+ if (currentTest) {
80
+ checks.push({ test: currentTest, finding: buffer.join("\n").trim() });
81
+ }
82
+ buffer = [];
83
+ }
84
+ for (const rawLine of text.split("\n")) {
85
+ const line = rawLine.replace(/\r$/, "");
86
+ // ## Redundancy test → testName = "Redundancy"
87
+ const heading = line.match(/^##\s+(.+?)\s+test\s*$/i);
88
+ if (heading) {
89
+ flush();
90
+ currentTest = (heading[1] ?? "").trim();
91
+ continue;
92
+ }
93
+ if (currentTest)
94
+ buffer.push(line);
95
+ }
96
+ flush();
97
+ return checks.filter((c) => c.finding.length > 0);
98
+ }
99
+ export function groupEvaluation(items) {
100
+ const kept = [];
101
+ const trimmed = [];
102
+ const dropped = [];
103
+ for (const c of items) {
104
+ const d = String(c.decision || "").toLowerCase();
105
+ if (d === "kept" || d === "keep")
106
+ kept.push(c);
107
+ else if (d === "trim" || d === "trimmed")
108
+ trimmed.push(c);
109
+ else
110
+ dropped.push(c);
111
+ }
112
+ // Sort kept by descending rating so the strongest reads first.
113
+ kept.sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0));
114
+ trimmed.sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0));
115
+ return [
116
+ { decision: "kept", candidates: kept },
117
+ { decision: "trimmed", candidates: trimmed },
118
+ { decision: "dropped", candidates: dropped },
119
+ ];
120
+ }
121
+ //# sourceMappingURL=gates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { render } from "ink";
3
+ import { App } from "./App.js";
4
+ // Clear the terminal (screen + scrollback) before Ink mounts so the TUI
5
+ // starts at the top of a blank canvas — no `npm run dev` lines visible above
6
+ // the splash. `\x1B[2J` = erase visible viewport, `\x1B[3J` = erase scrollback,
7
+ // `\x1B[H` = home cursor.
8
+ if (process.stdout.isTTY) {
9
+ process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
10
+ }
11
+ const { waitUntilExit } = render(React.createElement(App, null));
12
+ waitUntilExit().catch((e) => {
13
+ // eslint-disable-next-line no-console
14
+ console.error(e);
15
+ process.exit(1);
16
+ });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,wEAAwE;AACxE,6EAA6E;AAC7E,gFAAgF;AAChF,0BAA0B;AAC1B,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,oBAAC,GAAG,OAAG,CAAC,CAAC;AAC1C,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;IACnC,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/ipc.js ADDED
@@ -0,0 +1,136 @@
1
+ // Subprocess spawning + NDJSON event stream parsing.
2
+ import { spawn } from "node:child_process";
3
+ import { createInterface } from "node:readline";
4
+ import { resolveBinary } from "./bin-resolver.js";
5
+ /** Spawn `liner compile --emit-events` and call `onEvent` for each NDJSON line. */
6
+ export function streamCompile(opts, onEvent) {
7
+ const bin = resolveBinary();
8
+ const args = [...bin.args, "compile", opts.folder, "--emit-events"];
9
+ if (opts.cookies)
10
+ args.push("--cookies", opts.cookies);
11
+ if (opts.noCache)
12
+ args.push("--no-cache");
13
+ if (opts.skipOptional)
14
+ args.push("--skip-optional");
15
+ if (opts.maxTranscriptLength != null) {
16
+ args.push("--max-transcript-length", String(opts.maxTranscriptLength));
17
+ }
18
+ if (opts.includeSections && opts.includeSections.length > 0) {
19
+ args.push("--include-sections", opts.includeSections.join(","));
20
+ }
21
+ if (opts.excludeSections && opts.excludeSections.length > 0) {
22
+ args.push("--exclude-sections", opts.excludeSections.join(","));
23
+ }
24
+ const child = spawn(bin.command, args, {
25
+ stdio: ["ignore", "pipe", "pipe"],
26
+ env: { ...process.env, PYTHONUNBUFFERED: "1" },
27
+ });
28
+ if (child.stdout) {
29
+ const rl = createInterface({ input: child.stdout });
30
+ rl.on("line", (line) => {
31
+ const trimmed = line.trim();
32
+ if (!trimmed)
33
+ return;
34
+ try {
35
+ const event = JSON.parse(trimmed);
36
+ onEvent(event);
37
+ }
38
+ catch {
39
+ // ignore non-JSON noise; surface via stderr collector
40
+ }
41
+ });
42
+ }
43
+ let stderr = "";
44
+ if (child.stderr) {
45
+ child.stderr.on("data", (chunk) => {
46
+ stderr += chunk.toString("utf8");
47
+ });
48
+ }
49
+ const done = new Promise((resolve) => {
50
+ child.on("close", (code) => resolve({ code, stderr }));
51
+ });
52
+ return {
53
+ child,
54
+ cancel: () => {
55
+ if (!child.killed)
56
+ child.kill("SIGTERM");
57
+ },
58
+ done,
59
+ };
60
+ }
61
+ /** Run `liner list --json --dir <dir>` and return project folder records. */
62
+ export async function listProjects(dir, recursive = false) {
63
+ const bin = resolveBinary();
64
+ const args = [...bin.args, "list", "--json", "--dir", dir];
65
+ if (recursive)
66
+ args.push("--recursive");
67
+ const result = await runCapture(bin.command, args);
68
+ if (result.code !== 0) {
69
+ throw new Error(`liner list failed (${result.code}): ${result.stderr}`);
70
+ }
71
+ if (!result.stdout.trim())
72
+ return [];
73
+ return JSON.parse(result.stdout);
74
+ }
75
+ /** Run `liner init <folder>` to scaffold a project folder. */
76
+ export async function runInit(folder, opts = {}) {
77
+ const bin = resolveBinary();
78
+ const args = [...bin.args, "init", folder];
79
+ if (opts.force)
80
+ args.push("--force");
81
+ const result = await runCapture(bin.command, args);
82
+ if (result.code !== 0) {
83
+ throw new Error(result.stderr.trim() || `liner init failed with code ${result.code}`);
84
+ }
85
+ }
86
+ /** Run `liner share <folder>` and return the archive path. */
87
+ export async function runShare(folder, opts = {}) {
88
+ const bin = resolveBinary();
89
+ const args = [...bin.args, "share", folder];
90
+ if (opts.noWorkingNotes)
91
+ args.push("--no-working-notes");
92
+ if (opts.noSourceContent)
93
+ args.push("--no-source-content");
94
+ if (opts.noPersonal)
95
+ args.push("--no-personal");
96
+ if (opts.minimal)
97
+ args.push("--minimal");
98
+ if (opts.out)
99
+ args.push("--out", opts.out);
100
+ const result = await runCapture(bin.command, args);
101
+ if (result.code !== 0) {
102
+ throw new Error(result.stderr.trim() || `liner share failed with code ${result.code}`);
103
+ }
104
+ // CLI prints "Wrote <path> (N entries)" to stderr (Rich console -> stderr).
105
+ const match = (result.stderr + result.stdout).match(/Wrote\s+(\S+)/);
106
+ if (match && match[1])
107
+ return match[1];
108
+ if (opts.out)
109
+ return opts.out;
110
+ // Fallback: derive default location.
111
+ return folder.replace(/\/+$/, "") + ".mixtape";
112
+ }
113
+ /** Run `liner import <archive> <dest>`. */
114
+ export async function runImport(archive, destination, opts = {}) {
115
+ const bin = resolveBinary();
116
+ const args = [...bin.args, "import", archive, destination];
117
+ if (opts.noRefetch)
118
+ args.push("--no-refetch");
119
+ if (opts.cookies)
120
+ args.push("--cookies", opts.cookies);
121
+ const result = await runCapture(bin.command, args);
122
+ if (result.code !== 0) {
123
+ throw new Error(result.stderr.trim() || `liner import failed with code ${result.code}`);
124
+ }
125
+ }
126
+ function runCapture(command, args) {
127
+ return new Promise((resolve) => {
128
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
129
+ let stdout = "";
130
+ let stderr = "";
131
+ child.stdout?.on("data", (c) => (stdout += c.toString("utf8")));
132
+ child.stderr?.on("data", (c) => (stderr += c.toString("utf8")));
133
+ child.on("close", (code) => resolve({ code, stdout, stderr }));
134
+ });
135
+ }
136
+ //# sourceMappingURL=ipc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"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"}
package/dist/phases.js ADDED
@@ -0,0 +1,348 @@
1
+ // Phase model for the curating-mixtapes methodology.
2
+ //
3
+ // Status is driven by a single progress cursor (see progress.ts), not by
4
+ // per-artifact filesystem checks. Detail strings still pull from the
5
+ // filesystem for context (source counts, character counts, etc.) but they
6
+ // no longer drive the ✓ / ◐ / ○ badge — the cursor does. This eliminates
7
+ // the swiss-cheese view where a later phase showed complete while earlier
8
+ // ones were empty just because some artifact happened to be on disk.
9
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { PHASE_ORDER, TOTAL_STEPS } from "./progress.js";
12
+ const GATE_FILE = ".liner-gates.json";
13
+ export function readGateState(folder) {
14
+ const path = join(folder.path, GATE_FILE);
15
+ if (!existsSync(path)) {
16
+ return { gate0Accepted: false, gate1Accepted: false, gate2Accepted: false };
17
+ }
18
+ try {
19
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
20
+ return {
21
+ gate0Accepted: Boolean(parsed.gate0Accepted),
22
+ gate1Accepted: Boolean(parsed.gate1Accepted),
23
+ gate2Accepted: Boolean(parsed.gate2Accepted),
24
+ };
25
+ }
26
+ catch {
27
+ return { gate0Accepted: false, gate1Accepted: false, gate2Accepted: false };
28
+ }
29
+ }
30
+ export function writeGateState(folder, state) {
31
+ const path = join(folder.path, GATE_FILE);
32
+ writeFileSync(path, JSON.stringify(state, null, 2), "utf8");
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Phase list construction
36
+ // ---------------------------------------------------------------------------
37
+ // Phase `number` is the user-visible step indicator in the TUI. We renumber
38
+ // the methodology's 1-8 (with Phase 3 = Fetching) into sequential 1-7 for
39
+ // the curator — fetching happens implicitly at compile time, so the user
40
+ // shouldn't see a "Phase 4 — Evaluation" come right after "Phase 2 — Candidate
41
+ // discovery" and wonder where Phase 3 went. The methodology numbering is
42
+ // still preserved in the artifact filenames (working/01-, 02-, 03-, 04-, 05-)
43
+ // — those follow the spec's canonical naming.
44
+ const PHASE_TEMPLATES = {
45
+ framing: {
46
+ id: "framing",
47
+ number: "1",
48
+ label: "Framing",
49
+ summary: "Define the JTBD and sketch a knowledge map.",
50
+ artifact: "working/01-jtbd-and-knowledge-map.md",
51
+ },
52
+ gate0: {
53
+ id: "gate0",
54
+ number: "↳",
55
+ label: "Confirm framing",
56
+ summary: "Review the knowledge map before any candidate search.",
57
+ artifact: null,
58
+ },
59
+ candidates: {
60
+ id: "candidates",
61
+ number: "2",
62
+ label: "Candidate discovery",
63
+ summary: "Long-list of candidate sources (URLs only — no fetching).",
64
+ artifact: "working/02-candidate-longlist.md",
65
+ },
66
+ gate1: {
67
+ id: "gate1",
68
+ number: "↳",
69
+ label: "Confirm candidates",
70
+ summary: "Review the long-list before any fetching.",
71
+ artifact: null,
72
+ },
73
+ evaluation: {
74
+ id: "evaluation",
75
+ number: "3",
76
+ label: "Evaluation",
77
+ summary: "Keep / trim / drop with curator notes.",
78
+ artifact: "working/03-evaluation.yaml",
79
+ },
80
+ quality: {
81
+ id: "quality",
82
+ number: "4",
83
+ label: "Quality checks",
84
+ summary: "Redundancy, coverage, disagreement, framing-gap tests.",
85
+ artifact: "working/04-quality-checks.md",
86
+ },
87
+ gate2: {
88
+ id: "gate2",
89
+ number: "↳",
90
+ label: "Confirm evaluation",
91
+ summary: "Review keep-list and findings before synthesis.",
92
+ artifact: null,
93
+ },
94
+ synthesis: {
95
+ id: "synthesis",
96
+ number: "5",
97
+ label: "Synthesis",
98
+ summary: "Curator's distilled understanding (800–2000 words).",
99
+ artifact: "synthesis.md",
100
+ },
101
+ assembly: {
102
+ id: "assembly",
103
+ number: "6",
104
+ label: "Assembly",
105
+ summary: "Write tape.yaml — sources with curator notes, sections, order.",
106
+ artifact: "tape.yaml",
107
+ },
108
+ compile: {
109
+ id: "compile",
110
+ number: "→",
111
+ label: "Compile",
112
+ summary: "Run `liner compile` to produce MIXTAPE.md and sources/.",
113
+ artifact: null,
114
+ },
115
+ empirical: {
116
+ id: "empirical",
117
+ number: "7",
118
+ label: "Empirical test (optional)",
119
+ summary: "Compare AI output with vs. without the mixtape.",
120
+ artifact: "working/05-empirical-test.md",
121
+ },
122
+ };
123
+ /**
124
+ * Compute the phase list for display. Status comes from `progress.step`;
125
+ * detail strings are informational and pull from the filesystem for context.
126
+ */
127
+ export function computePhases(folder, tape, progress) {
128
+ return PHASE_ORDER.map((phaseId, index) => {
129
+ const template = PHASE_TEMPLATES[phaseId];
130
+ const status = statusForIndex(index, progress.step);
131
+ const detail = detailFor(phaseId, status, folder, tape);
132
+ const subSteps = subStepsFor(phaseId, status, folder, tape);
133
+ return subSteps
134
+ ? { ...template, status, detail, subSteps }
135
+ : { ...template, status, detail };
136
+ });
137
+ }
138
+ /**
139
+ * Build the optional sub-step checklist for a phase. Returns undefined for
140
+ * phases that have one unit of work (most of them). Currently only Framing
141
+ * uses this — the wizard supplies the JTBD up front, but the knowledge map
142
+ * is the agent's job, so we want both shown so the curator knows the JTBD
143
+ * has registered even though the phase isn't done yet.
144
+ */
145
+ function subStepsFor(phaseId, status, folder, tape) {
146
+ if (phaseId !== "framing")
147
+ return undefined;
148
+ const jtbdSet = Boolean(tape.jtbd?.trim());
149
+ const clarsCount = tape.jtbd_clarifications?.length ?? 0;
150
+ const chars = readChars(join(folder.path, "working/01-jtbd-and-knowledge-map.md"));
151
+ // Knowledge map is "drafted" once the placeholder sentinel is gone AND
152
+ // the file has substantial content. We approximate via the
153
+ // artifact-has-real-content rule the progress migration uses.
154
+ const mapDrafted = status === "complete";
155
+ const steps = [];
156
+ steps.push({
157
+ done: jtbdSet,
158
+ text: "JTBD set",
159
+ hint: jtbdSet ? undefined : "wizard or hand-edit working/01",
160
+ });
161
+ if (clarsCount > 0) {
162
+ steps.push({
163
+ done: true,
164
+ text: "Clarifications captured",
165
+ hint: `${clarsCount} answered`,
166
+ });
167
+ }
168
+ steps.push({
169
+ done: mapDrafted,
170
+ text: "Knowledge map drafted",
171
+ hint: mapDrafted
172
+ ? `${chars.toLocaleString()} chars`
173
+ : status === "in_progress"
174
+ ? "press enter to draft"
175
+ : undefined,
176
+ });
177
+ return steps;
178
+ }
179
+ function statusForIndex(index, step) {
180
+ if (index < step)
181
+ return "complete";
182
+ if (index === step)
183
+ return "in_progress";
184
+ return "not_started";
185
+ }
186
+ function detailFor(phaseId, status, folder, tape) {
187
+ switch (phaseId) {
188
+ case "framing": {
189
+ const jtbdSet = Boolean(tape.jtbd?.trim());
190
+ const chars = readChars(join(folder.path, "working/01-jtbd-and-knowledge-map.md"));
191
+ if (status === "complete") {
192
+ return `JTBD set · knowledge map drafted (${chars.toLocaleString()} chars)`;
193
+ }
194
+ if (status === "in_progress") {
195
+ return jtbdSet
196
+ ? `JTBD set — press enter to draft the knowledge map`
197
+ : `no JTBD yet — press enter to set one`;
198
+ }
199
+ return "not yet";
200
+ }
201
+ case "gate0": {
202
+ if (status === "complete")
203
+ return "accepted";
204
+ if (status === "in_progress")
205
+ return tape.mode === "methodology"
206
+ ? "press enter to review the knowledge map"
207
+ : "auto-accept on advance (quick mode)";
208
+ return "not yet";
209
+ }
210
+ case "candidates": {
211
+ const chars = readChars(join(folder.path, "working/02-candidate-longlist.md"));
212
+ if (status === "complete")
213
+ return `${chars.toLocaleString()} chars in long-list`;
214
+ if (status === "in_progress")
215
+ return "press enter to start researching candidate sources";
216
+ return "not yet";
217
+ }
218
+ case "gate1": {
219
+ if (status === "complete")
220
+ return "accepted";
221
+ if (status === "in_progress")
222
+ return tape.mode === "methodology"
223
+ ? "press enter to review and accept"
224
+ : "auto-accept on advance (quick mode)";
225
+ return "not yet";
226
+ }
227
+ case "evaluation": {
228
+ const chars = readChars(join(folder.path, "working/03-evaluation.yaml"));
229
+ if (status === "complete")
230
+ return `${chars.toLocaleString()} chars · keep/trim/drop set`;
231
+ if (status === "in_progress")
232
+ return "press enter to run evaluation";
233
+ return "not yet";
234
+ }
235
+ case "quality": {
236
+ const chars = readChars(join(folder.path, "working/04-quality-checks.md"));
237
+ if (status === "complete")
238
+ return `${chars.toLocaleString()} chars in findings`;
239
+ if (status === "in_progress")
240
+ return "press enter to run the four quality tests";
241
+ return "not yet";
242
+ }
243
+ case "gate2": {
244
+ if (status === "complete")
245
+ return "accepted";
246
+ if (status === "in_progress")
247
+ return tape.mode === "methodology"
248
+ ? "press enter to review and accept"
249
+ : "auto-accept on advance (quick mode)";
250
+ return "not yet";
251
+ }
252
+ case "synthesis": {
253
+ const chars = readChars(folder.synthesisPath);
254
+ if (status === "complete")
255
+ return `synthesis written (${chars.toLocaleString()} chars)`;
256
+ if (status === "in_progress")
257
+ return "press enter to draft the synthesis";
258
+ return "not yet";
259
+ }
260
+ case "assembly": {
261
+ const n = tape.sources.length;
262
+ if (status === "complete")
263
+ return `${n} source${n === 1 ? "" : "s"} on tape`;
264
+ if (status === "in_progress")
265
+ return "press enter — agent proposes a draft to review";
266
+ return "not yet";
267
+ }
268
+ case "compile": {
269
+ if (status === "complete")
270
+ return "MIXTAPE.md on disk";
271
+ if (status === "in_progress")
272
+ return "press enter — fetches sources and builds MIXTAPE.md (auto-starts)";
273
+ return "not yet";
274
+ }
275
+ case "empirical": {
276
+ const chars = readChars(join(folder.path, "working/05-empirical-test.md"));
277
+ if (status === "complete")
278
+ return `${chars.toLocaleString()} chars`;
279
+ if (status === "in_progress")
280
+ return "optional — press enter to run the empirical test";
281
+ return "optional";
282
+ }
283
+ }
284
+ }
285
+ function readChars(path) {
286
+ if (!existsSync(path))
287
+ return 0;
288
+ try {
289
+ return readFileSync(path, "utf8").trim().length;
290
+ }
291
+ catch {
292
+ return 0;
293
+ }
294
+ }
295
+ // ---------------------------------------------------------------------------
296
+ // Status display helpers (used by all hub UI bits)
297
+ // ---------------------------------------------------------------------------
298
+ export function statusGlyph(status) {
299
+ switch (status) {
300
+ case "complete":
301
+ return "✓";
302
+ case "in_progress":
303
+ return "▶";
304
+ case "needs_review":
305
+ return "⚠";
306
+ case "blocked":
307
+ return "·";
308
+ case "not_started":
309
+ return "○";
310
+ }
311
+ }
312
+ export function statusColor(status) {
313
+ switch (status) {
314
+ case "complete":
315
+ return "green";
316
+ case "in_progress":
317
+ return "cyan";
318
+ case "needs_review":
319
+ return "magenta";
320
+ case "blocked":
321
+ return undefined;
322
+ case "not_started":
323
+ return undefined;
324
+ }
325
+ }
326
+ export function statusLabel(status) {
327
+ switch (status) {
328
+ case "complete":
329
+ return "complete";
330
+ case "in_progress":
331
+ return "current";
332
+ case "needs_review":
333
+ return "needs review";
334
+ case "blocked":
335
+ return "blocked";
336
+ case "not_started":
337
+ return "not started";
338
+ }
339
+ }
340
+ /** True when every phase including the optional empirical test is complete. */
341
+ export function everythingComplete(progress) {
342
+ return progress.step >= TOTAL_STEPS;
343
+ }
344
+ /** True when the core methodology (Phases 1-7 + Compile) is done. Phase 8 may or may not be. */
345
+ export function coreMethodologyComplete(progress) {
346
+ return progress.step >= TOTAL_STEPS - 1;
347
+ }
348
+ //# sourceMappingURL=phases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phases.js","sourceRoot":"","sources":["../src/phases.ts"],"names":[],"mappings":"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"}