@longtable/cli 0.1.4 → 0.1.5

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.
package/README.md CHANGED
@@ -53,6 +53,7 @@ longtable start
53
53
  - 프로젝트 디렉토리 생성
54
54
  - `.longtable/` 메모리 파일 생성
55
55
  - 프로젝트용 `AGENTS.md` 생성
56
+ - `START-HERE.md` 생성
56
57
 
57
58
  을 수행합니다.
58
59
 
package/dist/cli.js CHANGED
@@ -27,6 +27,24 @@ const VALID_STAGES = new Set([
27
27
  "writing",
28
28
  "submission"
29
29
  ]);
30
+ const ANSI = {
31
+ reset: "\u001B[0m",
32
+ bold: "\u001B[1m",
33
+ dim: "\u001B[2m",
34
+ cyan: "\u001B[36m",
35
+ green: "\u001B[32m"
36
+ };
37
+ function style(text, prefix) {
38
+ return `${prefix}${text}${ANSI.reset}`;
39
+ }
40
+ function renderSectionCard(title, body) {
41
+ return [
42
+ "┌──────────────────────────────────────────────┐",
43
+ `│ ${title.padEnd(44, " ")}│`,
44
+ "└──────────────────────────────────────────────┘",
45
+ ...body
46
+ ].join("\n");
47
+ }
30
48
  function usage() {
31
49
  return [
32
50
  "Usage:",
@@ -122,15 +140,10 @@ function renderSetupHeader(flow) {
122
140
  const subtitle = flow === "interview"
123
141
  ? "We will ask about your research persona, challenge preferences, and authorship defaults."
124
142
  : "We will capture the minimum profile needed to start using Long Table.";
125
- return [
126
- "┌──────────────────────────────────────────────┐",
127
- `│ ${title.padEnd(44, " ")}│`,
128
- "└──────────────────────────────────────────────┘",
129
- subtitle
130
- ].join("\n");
143
+ return renderSectionCard(title, [subtitle]);
131
144
  }
132
145
  function renderQuestionHeader(index, total, section, prompt) {
133
- return [``, `[${index}/${total}] ${section}`, prompt].join("\n");
146
+ return [``, style(`[${index}/${total}] ${section}`, `${ANSI.bold}${ANSI.cyan}`), prompt].join("\n");
134
147
  }
135
148
  function questionSection(questionId) {
136
149
  if (questionId === "field" || questionId === "careerStage" || questionId === "experienceLevel") {
@@ -154,9 +167,9 @@ function clearLine() {
154
167
  return "\u001B[2K\r";
155
168
  }
156
169
  function renderArrowMenu(prompt, choices, selectedIndex) {
157
- const lines = [prompt, "Use ↑/↓ and Enter."];
170
+ const lines = [style(prompt, ANSI.bold), style("Use ↑/↓ and Enter.", ANSI.dim)];
158
171
  for (let index = 0; index < choices.length; index += 1) {
159
- const prefix = index === selectedIndex ? ">" : " ";
172
+ const prefix = index === selectedIndex ? style(">", `${ANSI.bold}${ANSI.green}`) : " ";
160
173
  lines.push(`${prefix} ${choices[index].label} - ${choices[index].description}`);
161
174
  }
162
175
  return lines.join("\n");
@@ -450,10 +463,10 @@ async function collectProjectInterview(setup, args) {
450
463
  try {
451
464
  if (needsInteractivePrompts) {
452
465
  console.log("");
453
- console.log("┌──────────────────────────────────────────────┐");
454
- console.log(" Long Table Project Start │");
455
- console.log("└──────────────────────────────────────────────┘");
456
- console.log("We will create a project workspace and a session memory seed for today's work.");
466
+ console.log(renderSectionCard("Long Table Project Start", [
467
+ "We will create a project workspace and a session memory seed for today's work.",
468
+ "At the end, Long Table will tell you exactly which directory to open in Codex."
469
+ ]));
457
470
  console.log("");
458
471
  }
459
472
  const projectName = (typeof args.name === "string" && args.name.trim()) ||
@@ -855,11 +868,15 @@ async function runStart(args) {
855
868
  }
856
869
  console.log(renderProjectWorkspaceSummary(context));
857
870
  console.log("");
858
- console.log("Next step:");
859
- console.log(`- cd "${context.project.projectPath}"`);
860
- console.log("- start Codex in that directory if you want a plain Codex session that inherits Long Table project instructions");
861
- console.log(`- or run: longtable ask --cwd "${context.project.projectPath}" --prompt "${context.session.currentGoal.replaceAll("\"", "\\\"")}"`);
862
- console.log("- the workspace now includes `.longtable/` memory files and a project-scoped `AGENTS.md`");
871
+ console.log(renderSectionCard("Next Step", [
872
+ `1. cd "${context.project.projectPath}"`,
873
+ "2. run `codex` in that directory",
874
+ "3. begin with your current goal in natural language",
875
+ "",
876
+ `Suggested first message: ${context.session.currentBlocker ? `"I want to work on ${context.session.currentGoal}. My current blocker is ${context.session.currentBlocker}."` : `"I want to work on ${context.session.currentGoal}."`}`,
877
+ "",
878
+ `Optional CLI path: longtable ask --cwd "${context.project.projectPath}" --prompt "${context.session.currentGoal.replaceAll("\"", "\\\"")}"`
879
+ ]));
863
880
  }
864
881
  async function runCodexSubcommand(subcommand, args) {
865
882
  const customDir = typeof args.dir === "string" ? args.dir : undefined;
@@ -42,6 +42,37 @@ function buildWorkspaceGuide(project, session) {
42
42
  ];
43
43
  return lines.join("\n");
44
44
  }
45
+ function buildStartHereGuide(project, session) {
46
+ const lines = [
47
+ "# Start Here",
48
+ "",
49
+ `Project: ${project.projectName}`,
50
+ "",
51
+ "This workspace was created by Long Table for a single research project.",
52
+ "",
53
+ "## What to do now",
54
+ "1. Open Codex in this directory.",
55
+ "2. Start with your current goal, not a shell command.",
56
+ "3. Let Long Table keep disagreement visible when it matters.",
57
+ "",
58
+ "## Suggested first message",
59
+ session.currentBlocker
60
+ ? `"I want to work on ${session.currentGoal}. My current blocker is: ${session.currentBlocker}."`
61
+ : `"I want to work on ${session.currentGoal}."`,
62
+ "",
63
+ "## What Long Table already knows in this directory",
64
+ `- Current goal: ${session.currentGoal}`,
65
+ ...(session.currentBlocker ? [`- Current blocker: ${session.currentBlocker}`] : []),
66
+ `- Requested perspectives: ${session.requestedPerspectives.length > 0 ? session.requestedPerspectives.join(", ") : "auto"}`,
67
+ `- Disagreement visibility: ${session.disagreementPreference}`,
68
+ "",
69
+ "## Files",
70
+ "- `AGENTS.md` tells Codex how to behave in this workspace.",
71
+ "- `.longtable/current-session.json` stores the current session goal and blocker.",
72
+ "- `.longtable/project.json` stores the project-level record."
73
+ ];
74
+ return lines.join("\n");
75
+ }
45
76
  function buildProjectAgentsMd(project, session) {
46
77
  return [
47
78
  "# AGENTS.md",
@@ -60,6 +91,9 @@ function buildProjectAgentsMd(project, session) {
60
91
  "- Begin exploratory work with clarifying or tension questions before recommending a direction.",
61
92
  "- If you foreground role perspectives, disclose them with `Long Table consulted: ...`.",
62
93
  "- Keep one accountable synthesis, but do not hide meaningful disagreement.",
94
+ ...(session.disagreementPreference === "always_visible"
95
+ ? ["- In this workspace, panel disagreement should be visible by default rather than hidden behind a single synthesis."]
96
+ : []),
63
97
  "- Do not expose internal tool logs, file-search traces, or process commentary in the researcher-facing answer.",
64
98
  "",
65
99
  "## Session memory",
@@ -161,6 +195,7 @@ export async function createOrUpdateProjectWorkspace(options) {
161
195
  await writeFile(join(sessionsDir, `${sessionId}.json`), JSON.stringify(session, null, 2), "utf8");
162
196
  await writeFile(join(metaDir, "state.json"), buildStateSeed(project, session, options.setup), "utf8");
163
197
  await writeFile(join(projectPath, "LONGTABLE.md"), buildWorkspaceGuide(project, session), "utf8");
198
+ await writeFile(join(projectPath, "START-HERE.md"), buildStartHereGuide(project, session), "utf8");
164
199
  await writeFile(join(projectPath, "AGENTS.md"), buildProjectAgentsMd(project, session), "utf8");
165
200
  return {
166
201
  project,
@@ -194,14 +229,20 @@ export async function loadProjectContextFromDirectory(startPath) {
194
229
  }
195
230
  export function renderProjectWorkspaceSummary(context) {
196
231
  return [
197
- "Long Table project workspace",
198
- `project: ${context.project.projectName}`,
199
- `path: ${context.project.projectPath}`,
200
- `goal: ${context.session.currentGoal}`,
201
- ...(context.session.currentBlocker ? [`blocker: ${context.session.currentBlocker}`] : []),
202
- `perspectives: ${context.session.requestedPerspectives.length > 0 ? context.session.requestedPerspectives.join(", ") : "auto"}`,
203
- `disagreement: ${context.session.disagreementPreference}`,
204
- `project file: ${context.projectFilePath}`,
205
- `session file: ${context.sessionFilePath}`
232
+ "┌──────────────────────────────────────────────┐",
233
+ "│ Long Table Project Workspace │",
234
+ "└──────────────────────────────────────────────┘",
235
+ `Project: ${context.project.projectName}`,
236
+ `Path: ${context.project.projectPath}`,
237
+ `Goal: ${context.session.currentGoal}`,
238
+ ...(context.session.currentBlocker ? [`Blocker: ${context.session.currentBlocker}`] : []),
239
+ `Perspectives: ${context.session.requestedPerspectives.length > 0 ? context.session.requestedPerspectives.join(", ") : "auto"}`,
240
+ `Disagreement: ${context.session.disagreementPreference}`,
241
+ "",
242
+ "Created files:",
243
+ `- ${context.projectFilePath}`,
244
+ `- ${context.sessionFilePath}`,
245
+ `- ${join(context.project.projectPath, "START-HERE.md")}`,
246
+ `- ${join(context.project.projectPath, "AGENTS.md")}`
206
247
  ].join("\n");
207
248
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longtable/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "description": "Researcher-facing Long Table CLI on top of the legacy Diverga package surface",
6
6
  "type": "module",