@cfbender/cesium 0.6.1 → 0.7.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.
- package/CHANGELOG.md +100 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/prompt/system-fragment.md +73 -8
- package/src/render/annotate-frozen.ts +90 -0
- package/src/render/blocks/render.ts +20 -0
- package/src/render/blocks/renderers/callout.ts +3 -2
- package/src/render/blocks/renderers/code.ts +17 -2
- package/src/render/blocks/renderers/compare-table.ts +3 -2
- package/src/render/blocks/renderers/diagram.ts +3 -2
- package/src/render/blocks/renderers/diff.ts +23 -9
- package/src/render/blocks/renderers/hero.ts +3 -2
- package/src/render/blocks/renderers/kv.ts +3 -2
- package/src/render/blocks/renderers/list.ts +5 -4
- package/src/render/blocks/renderers/pill-row.ts +3 -2
- package/src/render/blocks/renderers/prose.ts +8 -2
- package/src/render/blocks/renderers/raw-html.ts +8 -2
- package/src/render/blocks/renderers/risk-table.ts +3 -2
- package/src/render/blocks/renderers/section.ts +4 -2
- package/src/render/blocks/renderers/timeline.ts +3 -2
- package/src/render/blocks/renderers/tldr.ts +3 -2
- package/src/render/client-js.ts +804 -6
- package/src/render/critique.ts +5 -335
- package/src/render/theme.ts +431 -6
- package/src/render/validate.ts +353 -97
- package/src/render/wrap.ts +67 -9
- package/src/server/api.ts +162 -3
- package/src/storage/index-gen.ts +4 -2
- package/src/storage/mutate.ts +433 -27
- package/src/tools/annotate.ts +336 -0
- package/src/tools/ask.ts +2 -6
- package/src/tools/critique.ts +15 -45
- package/src/tools/publish.ts +16 -56
- package/src/tools/styleguide.ts +7 -1
- package/src/tools/wait.ts +77 -24
package/src/tools/wait.ts
CHANGED
|
@@ -6,7 +6,14 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
6
6
|
import type { PluginInput } from "@opencode-ai/plugin";
|
|
7
7
|
import { loadConfig, type CesiumConfig } from "../config.ts";
|
|
8
8
|
import { loadIndex } from "../storage/index-cache.ts";
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
AnswerValue,
|
|
11
|
+
Comment,
|
|
12
|
+
Verdict,
|
|
13
|
+
InteractiveAskData,
|
|
14
|
+
InteractiveAnnotateData,
|
|
15
|
+
} from "../render/validate.ts";
|
|
16
|
+
import { coerceInteractiveData } from "../render/validate.ts";
|
|
10
17
|
import { readEmbeddedMetadata } from "../storage/write.ts";
|
|
11
18
|
import { readFile } from "node:fs/promises";
|
|
12
19
|
|
|
@@ -16,17 +23,13 @@ export interface WaitToolOverrides {
|
|
|
16
23
|
|
|
17
24
|
export type WaitStatus = "complete" | "incomplete" | "expired" | "cancelled" | "not-found";
|
|
18
25
|
|
|
19
|
-
const TOOL_DESCRIPTION = `cesium_wait — Block until the user completes a cesium_ask interactive artifact, or
|
|
20
|
-
until timeout. Returns the user's answers as a map keyed by question id.
|
|
26
|
+
const TOOL_DESCRIPTION = `cesium_wait — Block until the user completes a cesium_ask or cesium_annotate interactive artifact, or until timeout.
|
|
21
27
|
|
|
22
|
-
Pass the id returned from cesium_ask. Default timeout is 10 minutes. Polls the
|
|
23
|
-
artifact file every 500ms (no server-side coordination needed — disk is the source
|
|
24
|
-
of truth).
|
|
28
|
+
Pass the id returned from cesium_ask or cesium_annotate. Default timeout is 10 minutes. Polls the artifact file every 500ms (no server-side coordination needed — disk is the source of truth).
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
with whatever they
|
|
29
|
-
publish a partial artifact).`;
|
|
30
|
+
For cesium_ask sessions, returns { status, answers, remaining } where answers is a map keyed by question id. For cesium_annotate sessions, additionally returns { status, comments, verdict, kind: "annotate" } where comments is an array of { id, anchor, selectedText, comment, createdAt } and verdict is { value: "approve" | "request_changes" | "comment", decidedAt } or null if the user hasn't decided yet.
|
|
31
|
+
|
|
32
|
+
Use this immediately after cesium_ask or cesium_annotate when you need the user's input to continue. If the user doesn't finish within the timeout, you'll get status: "incomplete" with whatever they've done so far — handle that case (re-prompt, give up, or publish a partial artifact).`;
|
|
30
33
|
|
|
31
34
|
export function createWaitTool(
|
|
32
35
|
_ctx: PluginInput,
|
|
@@ -105,8 +108,13 @@ async function resolveArtifactPath(stateDir: string, id: string): Promise<string
|
|
|
105
108
|
|
|
106
109
|
interface PollResult {
|
|
107
110
|
status: WaitStatus;
|
|
111
|
+
// Ask-mode fields (empty for annotate)
|
|
108
112
|
answers: Record<string, AnswerValue>;
|
|
109
113
|
remaining: string[];
|
|
114
|
+
// Annotate-mode fields (omitted/empty for ask)
|
|
115
|
+
comments?: Comment[];
|
|
116
|
+
verdict?: { value: Verdict; decidedAt: string } | null;
|
|
117
|
+
kind?: "ask" | "annotate";
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
async function pollLoop(
|
|
@@ -128,12 +136,26 @@ async function pollLoop(
|
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
const meta = readEmbeddedMetadata(html);
|
|
131
|
-
|
|
139
|
+
const interactive = coerceInteractiveData(meta === null ? null : meta["interactive"]);
|
|
140
|
+
if (interactive === null) {
|
|
132
141
|
return { status: "not-found", answers: {}, remaining: [] };
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
|
|
144
|
+
if (interactive.kind === "ask") {
|
|
145
|
+
return pollAsk(interactive, artifactPath, timeoutMs, pollIntervalMs, startTime);
|
|
146
|
+
}
|
|
136
147
|
|
|
148
|
+
// kind === "annotate"
|
|
149
|
+
return buildAnnotateResult(interactive, artifactPath, timeoutMs, pollIntervalMs, startTime);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function pollAsk(
|
|
153
|
+
interactive: InteractiveAskData,
|
|
154
|
+
artifactPath: string,
|
|
155
|
+
timeoutMs: number,
|
|
156
|
+
pollIntervalMs: number,
|
|
157
|
+
startTime: number,
|
|
158
|
+
): Promise<PollResult> {
|
|
137
159
|
const answers = extractAnswers(interactive);
|
|
138
160
|
const remaining = interactive.questions
|
|
139
161
|
.map((q) => q.id)
|
|
@@ -166,21 +188,52 @@ async function pollLoop(
|
|
|
166
188
|
return pollLoop(artifactPath, timeoutMs, pollIntervalMs, startTime);
|
|
167
189
|
}
|
|
168
190
|
|
|
169
|
-
|
|
191
|
+
async function buildAnnotateResult(
|
|
192
|
+
interactive: InteractiveAnnotateData,
|
|
193
|
+
artifactPath: string,
|
|
194
|
+
timeoutMs: number,
|
|
195
|
+
pollIntervalMs: number,
|
|
196
|
+
startTime: number,
|
|
197
|
+
): Promise<PollResult> {
|
|
198
|
+
const { comments, verdict } = interactive;
|
|
199
|
+
const base = {
|
|
200
|
+
answers: {} as Record<string, AnswerValue>,
|
|
201
|
+
remaining: [] as string[],
|
|
202
|
+
comments,
|
|
203
|
+
verdict,
|
|
204
|
+
kind: "annotate" as const,
|
|
205
|
+
};
|
|
170
206
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
207
|
+
switch (interactive.status) {
|
|
208
|
+
case "complete":
|
|
209
|
+
return { status: "complete", ...base };
|
|
210
|
+
case "expired":
|
|
211
|
+
return { status: "expired", ...base };
|
|
212
|
+
case "cancelled":
|
|
213
|
+
return { status: "cancelled", ...base };
|
|
214
|
+
case "open":
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check timeout
|
|
219
|
+
if (Date.now() - startTime >= timeoutMs) {
|
|
220
|
+
return { status: "incomplete", ...base };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Sleep then recurse
|
|
224
|
+
await sleep(pollIntervalMs);
|
|
225
|
+
|
|
226
|
+
// Check timeout again after sleep (in case sleep took longer)
|
|
227
|
+
if (Date.now() - startTime >= timeoutMs) {
|
|
228
|
+
return { status: "incomplete", ...base };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return pollLoop(artifactPath, timeoutMs, pollIntervalMs, startTime);
|
|
181
232
|
}
|
|
182
233
|
|
|
183
|
-
|
|
234
|
+
// ─── Helpers ───────────────────────────────────────────────────────────────────
|
|
235
|
+
|
|
236
|
+
function extractAnswers(interactive: InteractiveAskData): Record<string, AnswerValue> {
|
|
184
237
|
const answers: Record<string, AnswerValue> = {};
|
|
185
238
|
for (const [id, entry] of Object.entries(interactive.answers)) {
|
|
186
239
|
answers[id] = entry.value;
|