@longtable/cli 0.1.57 → 0.1.59
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/dist/cli.js +365 -73
- package/dist/debate.js +19 -31
- package/dist/longtable-codex-native-hook.js +36 -8
- package/dist/panel-runtime.d.ts +1 -0
- package/dist/panel-runtime.js +447 -88
- package/dist/panel.d.ts +13 -1
- package/dist/panel.js +343 -31
- package/dist/project-session.d.ts +0 -1
- package/dist/project-session.js +75 -116
- package/package.json +7 -7
package/dist/debate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import { buildInvocationIntent, buildPanelPlan } from "./panel.js";
|
|
2
|
+
import { buildInvocationIntent, buildPanelDecisionContext, buildPanelPlan } from "./panel.js";
|
|
3
3
|
import { getPersonaDefinition, parsePersonaKey } from "./personas.js";
|
|
4
4
|
function nowIso() {
|
|
5
5
|
return new Date().toISOString();
|
|
@@ -167,6 +167,10 @@ function buildSynthesis(plan, artifactPath, kind) {
|
|
|
167
167
|
const labels = plan.members.map((member) => member.label);
|
|
168
168
|
const highSensitivity = plan.checkpointSensitivity === "high";
|
|
169
169
|
const runLabel = kind === "debate" ? "panel debate" : "panel review";
|
|
170
|
+
const decisionContext = buildPanelDecisionContext(plan.prompt);
|
|
171
|
+
const localizedRunLabel = decisionContext.language === "ko"
|
|
172
|
+
? (kind === "debate" ? "패널 토론" : "패널 리뷰")
|
|
173
|
+
: runLabel;
|
|
170
174
|
return {
|
|
171
175
|
artifactPath,
|
|
172
176
|
summary: `The ${runLabel} completed across ${labels.join(", ")}. It should slow closure by turning role disagreement into an explicit researcher decision.`,
|
|
@@ -187,13 +191,16 @@ function buildSynthesis(plan, artifactPath, kind) {
|
|
|
187
191
|
"Choose whether the debate should affect the current artifact, the research design, or only the decision log."
|
|
188
192
|
],
|
|
189
193
|
recommendedCheckpoint: highSensitivity
|
|
190
|
-
?
|
|
191
|
-
|
|
194
|
+
? (decisionContext.language === "ko"
|
|
195
|
+
? `${localizedRunLabel}에서 ${decisionContext.focus}에 대한 높은 민감도의 불일치가 드러났습니다. ${decisionContext.decisionQuestion}`
|
|
196
|
+
: `The ${runLabel} surfaced high-sensitivity disagreement about ${decisionContext.focus}. ${decisionContext.decisionQuestion}`)
|
|
197
|
+
: decisionContext.decisionQuestion
|
|
192
198
|
};
|
|
193
199
|
}
|
|
194
200
|
export function createTeamDebateQuestionRecord(run, provider) {
|
|
195
201
|
const createdAt = nowIso();
|
|
196
202
|
const isDebate = run.interactionDepth === "debated";
|
|
203
|
+
const decisionContext = buildPanelDecisionContext(run.prompt);
|
|
197
204
|
return {
|
|
198
205
|
id: createId("question_record"),
|
|
199
206
|
createdAt,
|
|
@@ -202,51 +209,32 @@ export function createTeamDebateQuestionRecord(run, provider) {
|
|
|
202
209
|
prompt: {
|
|
203
210
|
id: createId("question_prompt"),
|
|
204
211
|
checkpointKey: "panel_debate_next_decision",
|
|
205
|
-
title:
|
|
212
|
+
title: decisionContext.language === "ko"
|
|
213
|
+
? (isDebate ? "패널 토론 후속 결정" : "패널 리뷰 후속 결정")
|
|
214
|
+
: (isDebate ? "Panel debate follow-up decision" : "Panel review follow-up decision"),
|
|
206
215
|
question: run.synthesis.recommendedCheckpoint,
|
|
207
216
|
type: "single_choice",
|
|
208
|
-
options:
|
|
209
|
-
{
|
|
210
|
-
value: "revise",
|
|
211
|
-
label: "Revise before proceeding",
|
|
212
|
-
description: "Use the debate result to revise the claim, design, or draft first."
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
value: "evidence",
|
|
216
|
-
label: "Gather or verify evidence first",
|
|
217
|
-
description: "Check source, data, or local artifact support before proceeding."
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
value: "proceed",
|
|
221
|
-
label: "Proceed with current direction",
|
|
222
|
-
description: "Accept the risk profile and continue with the current direction."
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
value: "defer",
|
|
226
|
-
label: "Keep this open",
|
|
227
|
-
description: "Do not commit yet; keep the debate issue visible as an open tension."
|
|
228
|
-
}
|
|
229
|
-
],
|
|
217
|
+
options: decisionContext.options,
|
|
230
218
|
allowOther: true,
|
|
231
|
-
otherLabel:
|
|
219
|
+
otherLabel: decisionContext.otherLabel,
|
|
232
220
|
required: run.roles.some((member) => {
|
|
233
221
|
const key = parsePersonaKey(member.role);
|
|
234
222
|
return key ? getPersonaDefinition(key).checkpointSensitivity === "high" : false;
|
|
235
223
|
}),
|
|
236
224
|
source: "runtime_guidance",
|
|
237
|
-
displayReason:
|
|
238
|
-
? "Role rebuttals and convergence should connect to an explicit researcher decision."
|
|
239
|
-
: "Cross-review created role disagreement that should connect to an explicit researcher decision.",
|
|
225
|
+
displayReason: decisionContext.displayReason,
|
|
240
226
|
rationale: [
|
|
241
227
|
"LongTable panel orchestration is a research harness surface, not a substitute for researcher judgment.",
|
|
242
228
|
isDebate
|
|
243
229
|
? "The fixed debate rounds created disagreement that should connect to an explicit researcher decision."
|
|
244
230
|
: "The cross-review round created disagreement that should connect to an explicit researcher decision.",
|
|
231
|
+
`Panel decision focus: ${decisionContext.focus}.`,
|
|
232
|
+
"Panel follow-up choices are compact by default; unlisted decisions should use Other.",
|
|
245
233
|
`LongTable panel run: ${run.id}.`
|
|
246
234
|
],
|
|
247
235
|
preferredSurfaces: provider === "claude"
|
|
248
236
|
? ["native_structured", "numbered"]
|
|
249
|
-
: ["mcp_elicitation", "numbered"]
|
|
237
|
+
: ["tmux_popup", "mcp_elicitation", "numbered"]
|
|
250
238
|
}
|
|
251
239
|
};
|
|
252
240
|
}
|
|
@@ -57,12 +57,41 @@ function readCombinedOutput(payload) {
|
|
|
57
57
|
safeString(payload.output)
|
|
58
58
|
].filter(Boolean).join("\n").trim();
|
|
59
59
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
60
|
+
function questionUsesKorean(question) {
|
|
61
|
+
return /[가-힣]/.test([
|
|
62
|
+
question.prompt.title,
|
|
63
|
+
question.prompt.question,
|
|
64
|
+
question.prompt.displayReason ?? "",
|
|
65
|
+
...question.prompt.options.flatMap((option) => [option.label, option.description ?? ""]),
|
|
66
|
+
question.prompt.otherLabel ?? ""
|
|
67
|
+
].join("\n"));
|
|
68
|
+
}
|
|
69
|
+
function formatQuestionChoices(question) {
|
|
70
|
+
const korean = questionUsesKorean(question);
|
|
71
|
+
const options = question.prompt.options.flatMap((option, index) => {
|
|
72
|
+
const recommended = option.recommended ? (korean ? " (추천)" : " (recommended)") : "";
|
|
73
|
+
return [
|
|
74
|
+
`${index + 1}. ${option.label}${recommended}`,
|
|
75
|
+
...(option.description ? [` ${option.description}`] : []),
|
|
76
|
+
` ${korean ? "기록값" : "Record value"}: ${option.value}`
|
|
77
|
+
];
|
|
78
|
+
});
|
|
62
79
|
if (question.prompt.allowOther) {
|
|
63
|
-
options.push("
|
|
80
|
+
options.push(`${question.prompt.options.length + 1}. ${question.prompt.otherLabel ?? (korean ? "직접 입력" : "Other")}`);
|
|
81
|
+
options.push(` ${korean ? "기록값" : "Record value"}: other`);
|
|
64
82
|
}
|
|
65
|
-
return options.join("
|
|
83
|
+
return options.join("\n");
|
|
84
|
+
}
|
|
85
|
+
function buildQuestionDecisionCard(question) {
|
|
86
|
+
const korean = questionUsesKorean(question);
|
|
87
|
+
return [
|
|
88
|
+
korean ? "LongTable 결정 카드" : "LongTable Decision Card",
|
|
89
|
+
`${korean ? "체크포인트" : "Checkpoint"}: ${question.prompt.title}`,
|
|
90
|
+
`${korean ? "무엇이 걸렸나" : "What is blocked"}: ${question.prompt.displayReason ?? question.prompt.rationale[0] ?? question.prompt.title}`,
|
|
91
|
+
`${korean ? "지금 결정할 것" : "Decision needed"}: ${question.prompt.question}`,
|
|
92
|
+
korean ? "선택지:" : "Choices:",
|
|
93
|
+
formatQuestionChoices(question)
|
|
94
|
+
].join("\n");
|
|
66
95
|
}
|
|
67
96
|
function pendingRequiredQuestions(state) {
|
|
68
97
|
return (state.questionLog ?? []).filter((question) => question.status === "pending" && question.prompt.required);
|
|
@@ -271,8 +300,8 @@ function buildWorkspaceSummary(runtime, detail = "compact") {
|
|
|
271
300
|
}
|
|
272
301
|
function buildPendingQuestionContext(question) {
|
|
273
302
|
return [
|
|
274
|
-
|
|
275
|
-
|
|
303
|
+
"Required Researcher Checkpoint is still pending.",
|
|
304
|
+
buildQuestionDecisionCard(question),
|
|
276
305
|
`Record it with longtable decide --question ${question.id} --answer <value> if you are outside MCP elicitation.`,
|
|
277
306
|
"Do not choose or record an answer unless the researcher explicitly provides the selection."
|
|
278
307
|
].join("\n");
|
|
@@ -291,8 +320,7 @@ function buildGeneratedQuestionsContext(questions, created) {
|
|
|
291
320
|
: `LongTable found ${questions.length} pending Researcher Checkpoint${questions.length === 1 ? "" : "s"} for this prompt.`
|
|
292
321
|
];
|
|
293
322
|
for (const question of questions) {
|
|
294
|
-
lines.push(
|
|
295
|
-
lines.push(` Options: ${formatQuestionOptions(question)}`);
|
|
323
|
+
lines.push(buildQuestionDecisionCard(question));
|
|
296
324
|
lines.push(` Record it with longtable decide --question ${question.id} --answer <value> if you are outside MCP elicitation.`);
|
|
297
325
|
}
|
|
298
326
|
lines.push("Do not choose or record answers for these checkpoints unless the researcher explicitly provides the selections.");
|
package/dist/panel-runtime.d.ts
CHANGED
|
@@ -17,4 +17,5 @@ export declare function refreshPanelWorkerRun(run: PanelWorkerRun): Promise<{
|
|
|
17
17
|
}>;
|
|
18
18
|
export declare function requestPanelWorkerStop(run: PanelWorkerRun): Promise<PanelWorkerRun>;
|
|
19
19
|
export declare function resumePanelWorkerRun(run: PanelWorkerRun): Promise<PanelWorkerRun>;
|
|
20
|
+
export declare function shutdownPanelWorkerRun(run: PanelWorkerRun): Promise<PanelWorkerRun>;
|
|
20
21
|
export declare function waitForPanelWorkerRun(run: PanelWorkerRun, timeoutMs: number): Promise<PanelWorkerRun>;
|