@flue/client 0.0.1 → 0.0.2
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 +23 -0
- package/dist/index.d.mts +104 -0
- package/dist/index.mjs +316 -0
- package/package.json +27 -15
- package/src/errors.ts +0 -19
- package/src/flue.ts +0 -83
- package/src/index.ts +0 -9
- package/src/prompt.ts +0 -76
- package/src/result.ts +0 -106
- package/src/shell.ts +0 -28
- package/src/skill.ts +0 -167
- package/src/types.ts +0 -51
- package/tsconfig.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @flue/client
|
|
2
|
+
|
|
3
|
+
Container-side SDK for running Flue workflows.
|
|
4
|
+
|
|
5
|
+
## Support
|
|
6
|
+
|
|
7
|
+
- Bun
|
|
8
|
+
- Node: v23+ Supported. (v22 supported, but requires `--experimental-strip-types`)
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { Flue } from '@flue/client';
|
|
14
|
+
|
|
15
|
+
const flue = new Flue({
|
|
16
|
+
workdir: process.cwd(),
|
|
17
|
+
branch: 'flue/test',
|
|
18
|
+
args: { issueNumber: 123 },
|
|
19
|
+
secrets: { GITHUB_TOKEN: process.env.GITHUB_TOKEN ?? '' },
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Use flue.skill(), flue.prompt(), flue.shell()
|
|
23
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
|
|
3
|
+
//#region src/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Error thrown when skill result extraction or validation fails.
|
|
6
|
+
*/
|
|
7
|
+
declare class SkillOutputError extends Error {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
rawOutput: string;
|
|
10
|
+
validationErrors?: unknown;
|
|
11
|
+
constructor(message: string, opts: {
|
|
12
|
+
sessionId: string;
|
|
13
|
+
rawOutput: string;
|
|
14
|
+
validationErrors?: unknown;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/types.d.ts
|
|
19
|
+
interface FlueOptions {
|
|
20
|
+
/** OpenCode server URL (default: 'http://localhost:48765'). */
|
|
21
|
+
opencodeUrl?: string;
|
|
22
|
+
/** Working directory (the repo root inside the container). */
|
|
23
|
+
workdir: string;
|
|
24
|
+
/** Working branch for commits. */
|
|
25
|
+
branch?: string;
|
|
26
|
+
/** Workflow arguments. */
|
|
27
|
+
args?: Record<string, unknown>;
|
|
28
|
+
/** Scoped secrets. */
|
|
29
|
+
secrets?: Record<string, string>;
|
|
30
|
+
/** Default model for skill/prompt invocations. */
|
|
31
|
+
model?: {
|
|
32
|
+
providerID: string;
|
|
33
|
+
modelID: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
interface SkillOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
37
|
+
/** Key-value args serialized into the prompt. */
|
|
38
|
+
args?: Record<string, unknown>;
|
|
39
|
+
/** Valibot schema for structured result extraction. */
|
|
40
|
+
result?: S;
|
|
41
|
+
/** Override model for this skill. */
|
|
42
|
+
model?: {
|
|
43
|
+
providerID: string;
|
|
44
|
+
modelID: string;
|
|
45
|
+
};
|
|
46
|
+
/** Advanced: override the entire prompt. */
|
|
47
|
+
prompt?: string;
|
|
48
|
+
}
|
|
49
|
+
interface PromptOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
50
|
+
/** Valibot schema for structured result extraction. */
|
|
51
|
+
result?: S;
|
|
52
|
+
/** Override model for this prompt. */
|
|
53
|
+
model?: {
|
|
54
|
+
providerID: string;
|
|
55
|
+
modelID: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
interface ShellOptions {
|
|
59
|
+
/** Environment variables scoped to this subprocess only. */
|
|
60
|
+
env?: Record<string, string>;
|
|
61
|
+
/** Text to pipe to the command's stdin. */
|
|
62
|
+
stdin?: string;
|
|
63
|
+
/** Working directory (default: Flue's workdir). */
|
|
64
|
+
cwd?: string;
|
|
65
|
+
/** Timeout in milliseconds. */
|
|
66
|
+
timeout?: number;
|
|
67
|
+
}
|
|
68
|
+
interface ShellResult {
|
|
69
|
+
stdout: string;
|
|
70
|
+
stderr: string;
|
|
71
|
+
exitCode: number;
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/flue.d.ts
|
|
75
|
+
declare class Flue {
|
|
76
|
+
/** Working branch for commits. */
|
|
77
|
+
readonly branch: string;
|
|
78
|
+
/** Workflow arguments passed by the runner. */
|
|
79
|
+
readonly args: Record<string, unknown>;
|
|
80
|
+
/** Scoped secrets passed by the runner. */
|
|
81
|
+
readonly secrets: Record<string, string>;
|
|
82
|
+
private readonly workdir;
|
|
83
|
+
private readonly model?;
|
|
84
|
+
private readonly client;
|
|
85
|
+
constructor(options: FlueOptions);
|
|
86
|
+
/** Run a named skill with a result schema. */
|
|
87
|
+
skill<S extends v.GenericSchema>(name: string, options: SkillOptions<S> & {
|
|
88
|
+
result: S;
|
|
89
|
+
}): Promise<v.InferOutput<S>>;
|
|
90
|
+
/** Run a named skill without a result schema (fire-and-forget). */
|
|
91
|
+
skill(name: string, options?: SkillOptions): Promise<void>;
|
|
92
|
+
/** Run an inline prompt in a new OpenCode session. */
|
|
93
|
+
prompt<S extends v.GenericSchema>(promptText: string, options: PromptOptions<S> & {
|
|
94
|
+
result: S;
|
|
95
|
+
}): Promise<v.InferOutput<S>>;
|
|
96
|
+
/** Run an inline prompt without a result schema. */
|
|
97
|
+
prompt(promptText: string, options?: PromptOptions): Promise<void>;
|
|
98
|
+
/** Execute a shell command with scoped environment variables. */
|
|
99
|
+
shell(command: string, options?: ShellOptions): Promise<ShellResult>;
|
|
100
|
+
/** Close the OpenCode client connection. */
|
|
101
|
+
close(): Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { Flue, type FlueOptions, type PromptOptions, type ShellOptions, type ShellResult, type SkillOptions, SkillOutputError };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { createOpencodeClient } from "@opencode-ai/sdk";
|
|
2
|
+
import { exec } from "node:child_process";
|
|
3
|
+
import { toJsonSchema } from "@valibot/to-json-schema";
|
|
4
|
+
import * as v from "valibot";
|
|
5
|
+
|
|
6
|
+
//#region src/errors.ts
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when skill result extraction or validation fails.
|
|
9
|
+
*/
|
|
10
|
+
var SkillOutputError = class extends Error {
|
|
11
|
+
sessionId;
|
|
12
|
+
rawOutput;
|
|
13
|
+
validationErrors;
|
|
14
|
+
constructor(message, opts) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "SkillOutputError";
|
|
17
|
+
this.sessionId = opts.sessionId;
|
|
18
|
+
this.rawOutput = opts.rawOutput;
|
|
19
|
+
this.validationErrors = opts.validationErrors;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/shell.ts
|
|
25
|
+
async function runShell(command, options) {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
const child = exec(command, {
|
|
28
|
+
cwd: options?.cwd,
|
|
29
|
+
env: options?.env ? {
|
|
30
|
+
...process.env,
|
|
31
|
+
...options.env
|
|
32
|
+
} : process.env,
|
|
33
|
+
timeout: options?.timeout
|
|
34
|
+
}, (error, stdout, stderr) => {
|
|
35
|
+
const rawCode = error && typeof error.code === "number" ? error.code : 0;
|
|
36
|
+
resolve({
|
|
37
|
+
stdout: stdout ?? "",
|
|
38
|
+
stderr: stderr ?? "",
|
|
39
|
+
exitCode: error ? rawCode || 1 : 0
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
if (options?.stdin) {
|
|
43
|
+
child.stdin?.write(options.stdin);
|
|
44
|
+
child.stdin?.end();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/prompt.ts
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a Valibot schema represents a plain string type.
|
|
53
|
+
*/
|
|
54
|
+
function isStringSchema(schema) {
|
|
55
|
+
return schema.type === "string";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Checks if a skill name is a file path (contains '/' or ends with '.md').
|
|
59
|
+
*/
|
|
60
|
+
function isFilePath(name) {
|
|
61
|
+
return name.includes("/") || name.endsWith(".md");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the prompt text for a skill invocation.
|
|
65
|
+
*
|
|
66
|
+
* If `name` looks like a file path (contains '/' or ends with '.md'), the
|
|
67
|
+
* prompt instructs the agent to read and follow that file under
|
|
68
|
+
* `.opencode/skills/`. Otherwise, it instructs the agent to use the named
|
|
69
|
+
* skill.
|
|
70
|
+
*
|
|
71
|
+
* @param name - A skill name or a file path relative to .opencode/skills/.
|
|
72
|
+
* @param args - Key-value arguments to include in the prompt.
|
|
73
|
+
* @param schema - Optional Valibot schema for result extraction.
|
|
74
|
+
* @returns The complete prompt string.
|
|
75
|
+
*/
|
|
76
|
+
function buildSkillPrompt(name, args, schema) {
|
|
77
|
+
const parts = [
|
|
78
|
+
"You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input, never use the question tool. Make your best judgment and proceed independently.",
|
|
79
|
+
"",
|
|
80
|
+
isFilePath(name) ? `Read and use the .opencode/skills/${name} skill.` : `Use the ${name} skill.`
|
|
81
|
+
];
|
|
82
|
+
if (args && Object.keys(args).length > 0) parts.push(`\nArguments:\n${JSON.stringify(args, null, 2)}`);
|
|
83
|
+
if (schema) if (isStringSchema(schema)) parts.push("\nWhen complete, output your result between these exact delimiters (the result can contain any content including code blocks):", "---RESULT_START---", "Your text output here", "---RESULT_END---");
|
|
84
|
+
else {
|
|
85
|
+
const { $schema: _, ...schemaWithoutMeta } = toJsonSchema(schema, { errorMode: "ignore" });
|
|
86
|
+
parts.push("\nWhen complete, output your result between these exact delimiters as JSON conforming to this schema:", "```json", JSON.stringify(schemaWithoutMeta, null, 2), "```", "", "Format:", "---RESULT_START---", "{\"key\": \"value\"}", "---RESULT_END---");
|
|
87
|
+
}
|
|
88
|
+
return parts.join("\n");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/result.ts
|
|
93
|
+
/**
|
|
94
|
+
* Extracts and validates a structured result from OpenCode response parts.
|
|
95
|
+
*
|
|
96
|
+
* Scans TextParts for the last ---RESULT_START--- / ---RESULT_END--- block,
|
|
97
|
+
* parses the content, and validates it against the provided Valibot schema.
|
|
98
|
+
*
|
|
99
|
+
* @param parts - The response parts from OpenCode's session.prompt().
|
|
100
|
+
* @param schema - The Valibot schema to validate against.
|
|
101
|
+
* @param sessionId - The session ID (for error reporting).
|
|
102
|
+
* @returns The validated, typed result.
|
|
103
|
+
* @throws {SkillOutputError} If no result block is found or validation fails.
|
|
104
|
+
*/
|
|
105
|
+
function extractResult(parts, schema, sessionId) {
|
|
106
|
+
const allText = parts.filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
107
|
+
const resultBlock = extractLastResultBlock(allText);
|
|
108
|
+
if (resultBlock === null) {
|
|
109
|
+
console.error(`[flue] extractResult: no RESULT_START/RESULT_END block found (session: ${sessionId}, text length: ${allText.length} chars)`);
|
|
110
|
+
console.error(`[flue] extractResult: response tail (last 500 chars): ${allText.slice(-500)}`);
|
|
111
|
+
throw new SkillOutputError("No ---RESULT_START--- / ---RESULT_END--- block found in the assistant response.", {
|
|
112
|
+
sessionId,
|
|
113
|
+
rawOutput: allText
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
console.log(`[flue] extractResult: found result block (${resultBlock.length} chars, session: ${sessionId})`);
|
|
117
|
+
if (schema.type === "string") {
|
|
118
|
+
const parseResult = v.safeParse(schema, resultBlock);
|
|
119
|
+
if (!parseResult.success) {
|
|
120
|
+
console.error("[flue] extractResult: string validation failed", parseResult.issues);
|
|
121
|
+
throw new SkillOutputError("Result validation failed for string schema.", {
|
|
122
|
+
sessionId,
|
|
123
|
+
rawOutput: resultBlock,
|
|
124
|
+
validationErrors: parseResult.issues
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
console.log(`[flue] extractResult: validated string result (${resultBlock.length} chars)`);
|
|
128
|
+
return parseResult.output;
|
|
129
|
+
}
|
|
130
|
+
let parsed;
|
|
131
|
+
try {
|
|
132
|
+
parsed = JSON.parse(resultBlock);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.error(`[flue] extractResult: JSON parse failed for block: ${resultBlock.slice(0, 200)}`);
|
|
135
|
+
throw new SkillOutputError("Failed to parse result block as JSON.", {
|
|
136
|
+
sessionId,
|
|
137
|
+
rawOutput: resultBlock,
|
|
138
|
+
validationErrors: err
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const parseResult = v.safeParse(schema, parsed);
|
|
142
|
+
if (!parseResult.success) {
|
|
143
|
+
console.error("[flue] extractResult: schema validation failed", parseResult.issues);
|
|
144
|
+
console.error("[flue] extractResult: parsed value was:", JSON.stringify(parsed));
|
|
145
|
+
throw new SkillOutputError("Result does not match the expected schema.", {
|
|
146
|
+
sessionId,
|
|
147
|
+
rawOutput: resultBlock,
|
|
148
|
+
validationErrors: parseResult.issues
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
console.log("[flue] extractResult: validated result:", JSON.stringify(parseResult.output));
|
|
152
|
+
return parseResult.output;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Extracts the content of the last ---RESULT_START--- / ---RESULT_END--- block from text.
|
|
156
|
+
* Returns null if no result block is found.
|
|
157
|
+
*/
|
|
158
|
+
function extractLastResultBlock(text) {
|
|
159
|
+
const matches = text.matchAll(/---RESULT_START---\s*\n([\s\S]*?)---RESULT_END---/g);
|
|
160
|
+
let lastMatch = null;
|
|
161
|
+
for (const match of matches) lastMatch = match[1]?.trim() ?? null;
|
|
162
|
+
return lastMatch;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/skill.ts
|
|
167
|
+
/** How often to poll and log progress (ms). */
|
|
168
|
+
const POLL_INTERVAL = 5e3;
|
|
169
|
+
/** Max times we'll see 0 assistant messages before giving up. */
|
|
170
|
+
const MAX_EMPTY_POLLS = 3;
|
|
171
|
+
/** Max time to poll before timing out (ms) - 45 minutes. */
|
|
172
|
+
const MAX_POLL_TIME = 2700 * 1e3;
|
|
173
|
+
/**
|
|
174
|
+
* Run a named skill via the OpenCode client and optionally extract a typed result.
|
|
175
|
+
*/
|
|
176
|
+
async function runSkill(client, workdir, name, options) {
|
|
177
|
+
const { args, result: schema, model, prompt: promptOverride } = options ?? {};
|
|
178
|
+
const prompt = promptOverride ?? buildSkillPrompt(name, args, schema);
|
|
179
|
+
console.log(`[flue] skill("${name}"): starting`);
|
|
180
|
+
console.log(`[flue] skill("${name}"): creating session`);
|
|
181
|
+
const session = await client.session.create({
|
|
182
|
+
body: { title: name },
|
|
183
|
+
query: { directory: workdir }
|
|
184
|
+
});
|
|
185
|
+
console.log(`[flue] skill("${name}"): session created`, {
|
|
186
|
+
hasData: !!session.data,
|
|
187
|
+
sessionId: session.data?.id,
|
|
188
|
+
error: session.error
|
|
189
|
+
});
|
|
190
|
+
if (!session.data) throw new Error(`Failed to create OpenCode session for skill "${name}".`);
|
|
191
|
+
const sessionId = session.data.id;
|
|
192
|
+
const promptStart = Date.now();
|
|
193
|
+
console.log(`[flue] skill("${name}"): sending prompt async`);
|
|
194
|
+
const asyncResult = await client.session.promptAsync({
|
|
195
|
+
path: { id: sessionId },
|
|
196
|
+
query: { directory: workdir },
|
|
197
|
+
body: {
|
|
198
|
+
...model ? { model } : {},
|
|
199
|
+
parts: [{
|
|
200
|
+
type: "text",
|
|
201
|
+
text: prompt
|
|
202
|
+
}]
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
console.log(`[flue] skill("${name}"): prompt sent`, {
|
|
206
|
+
hasError: !!asyncResult.error,
|
|
207
|
+
error: asyncResult.error
|
|
208
|
+
});
|
|
209
|
+
if (asyncResult.error) throw new Error(`Failed to send prompt for skill "${name}" (session ${sessionId}): ${JSON.stringify(asyncResult.error)}`);
|
|
210
|
+
console.log(`[flue] skill("${name}"): starting polling`);
|
|
211
|
+
const parts = await pollUntilIdle(client, sessionId, workdir, name, promptStart);
|
|
212
|
+
const promptElapsed = ((Date.now() - promptStart) / 1e3).toFixed(1);
|
|
213
|
+
console.log(`[flue] skill("${name}"): completed (${promptElapsed}s)`);
|
|
214
|
+
if (!schema) return;
|
|
215
|
+
return extractResult(parts, schema, sessionId);
|
|
216
|
+
}
|
|
217
|
+
async function pollUntilIdle(client, sessionId, workdir, skillName, startTime) {
|
|
218
|
+
let emptyPolls = 0;
|
|
219
|
+
for (;;) {
|
|
220
|
+
await sleep(POLL_INTERVAL);
|
|
221
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(0);
|
|
222
|
+
if (Date.now() - startTime > MAX_POLL_TIME) throw new Error(`Skill "${skillName}" timed out after ${elapsed}s. Session never went idle. This may indicate a stuck session or OpenCode bug.`);
|
|
223
|
+
console.log(`[flue] skill("${skillName}"): calling session.status()`);
|
|
224
|
+
const statusResult = await client.session.status({ query: { directory: workdir } });
|
|
225
|
+
console.log(`[flue] skill("${skillName}"): status result: ${JSON.stringify({
|
|
226
|
+
hasData: !!statusResult.data,
|
|
227
|
+
sessionIds: statusResult.data ? Object.keys(statusResult.data) : [],
|
|
228
|
+
error: statusResult.error
|
|
229
|
+
})}`);
|
|
230
|
+
const sessionStatus = statusResult.data?.[sessionId];
|
|
231
|
+
console.log(`[flue] skill("${skillName}"): sessionStatus for ${sessionId}: ${JSON.stringify(sessionStatus)}`);
|
|
232
|
+
if (!sessionStatus || sessionStatus.type === "idle") {
|
|
233
|
+
const parts = await fetchAllAssistantParts(client, sessionId, workdir);
|
|
234
|
+
if (parts.length === 0) {
|
|
235
|
+
emptyPolls++;
|
|
236
|
+
if (emptyPolls >= MAX_EMPTY_POLLS) throw new Error(`Skill "${skillName}" produced no output after ${elapsed}s and ${emptyPolls} empty polls. The agent may have failed to start — check model ID and API key.`);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
return parts;
|
|
240
|
+
}
|
|
241
|
+
console.log(`[flue] skill("${skillName}"): running (${elapsed}s)`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Fetch ALL parts from every assistant message in the session.
|
|
246
|
+
*/
|
|
247
|
+
async function fetchAllAssistantParts(client, sessionId, workdir) {
|
|
248
|
+
const messagesResult = await client.session.messages({
|
|
249
|
+
path: { id: sessionId },
|
|
250
|
+
query: { directory: workdir }
|
|
251
|
+
});
|
|
252
|
+
if (!messagesResult.data) throw new Error(`Failed to fetch messages for session ${sessionId}.`);
|
|
253
|
+
const assistantMessages = messagesResult.data.filter((m) => m.info.role === "assistant");
|
|
254
|
+
const allParts = [];
|
|
255
|
+
for (const msg of assistantMessages) allParts.push(...msg.parts ?? []);
|
|
256
|
+
return allParts;
|
|
257
|
+
}
|
|
258
|
+
function sleep(ms) {
|
|
259
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
//#endregion
|
|
263
|
+
//#region src/flue.ts
|
|
264
|
+
var Flue = class {
|
|
265
|
+
/** Working branch for commits. */
|
|
266
|
+
branch;
|
|
267
|
+
/** Workflow arguments passed by the runner. */
|
|
268
|
+
args;
|
|
269
|
+
/** Scoped secrets passed by the runner. */
|
|
270
|
+
secrets;
|
|
271
|
+
workdir;
|
|
272
|
+
model;
|
|
273
|
+
client;
|
|
274
|
+
constructor(options) {
|
|
275
|
+
this.branch = options.branch ?? "main";
|
|
276
|
+
this.args = options.args ?? {};
|
|
277
|
+
this.secrets = options.secrets ?? {};
|
|
278
|
+
this.workdir = options.workdir;
|
|
279
|
+
this.model = options.model;
|
|
280
|
+
this.client = createOpencodeClient({
|
|
281
|
+
baseUrl: options.opencodeUrl ?? "http://localhost:48765",
|
|
282
|
+
directory: options.workdir
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
async skill(name, options) {
|
|
286
|
+
const mergedOptions = {
|
|
287
|
+
...options,
|
|
288
|
+
args: this.args || options?.args ? {
|
|
289
|
+
...this.args,
|
|
290
|
+
...options?.args
|
|
291
|
+
} : void 0,
|
|
292
|
+
model: options?.model ?? this.model
|
|
293
|
+
};
|
|
294
|
+
return runSkill(this.client, this.workdir, name, mergedOptions);
|
|
295
|
+
}
|
|
296
|
+
async prompt(promptText, options) {
|
|
297
|
+
const mergedOptions = {
|
|
298
|
+
result: options?.result,
|
|
299
|
+
model: options?.model ?? this.model,
|
|
300
|
+
prompt: promptText
|
|
301
|
+
};
|
|
302
|
+
return runSkill(this.client, this.workdir, "__inline__", mergedOptions);
|
|
303
|
+
}
|
|
304
|
+
/** Execute a shell command with scoped environment variables. */
|
|
305
|
+
async shell(command, options) {
|
|
306
|
+
return runShell(command, {
|
|
307
|
+
...options,
|
|
308
|
+
cwd: options?.cwd ?? this.workdir
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/** Close the OpenCode client connection. */
|
|
312
|
+
async close() {}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
//#endregion
|
|
316
|
+
export { Flue, SkillOutputError };
|
package/package.json
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
"name": "@flue/client",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.mts",
|
|
8
|
+
"import": "./dist/index.mjs"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsdown",
|
|
18
|
+
"check:types": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@opencode-ai/sdk": "latest",
|
|
22
|
+
"@valibot/to-json-schema": "^1.0.0",
|
|
23
|
+
"valibot": "^1.0.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"tsdown": "^0.20.3"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/errors.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error thrown when skill result extraction or validation fails.
|
|
3
|
-
*/
|
|
4
|
-
export class SkillOutputError extends Error {
|
|
5
|
-
sessionId: string;
|
|
6
|
-
rawOutput: string;
|
|
7
|
-
validationErrors?: unknown;
|
|
8
|
-
|
|
9
|
-
constructor(
|
|
10
|
-
message: string,
|
|
11
|
-
opts: { sessionId: string; rawOutput: string; validationErrors?: unknown },
|
|
12
|
-
) {
|
|
13
|
-
super(message);
|
|
14
|
-
this.name = 'SkillOutputError';
|
|
15
|
-
this.sessionId = opts.sessionId;
|
|
16
|
-
this.rawOutput = opts.rawOutput;
|
|
17
|
-
this.validationErrors = opts.validationErrors;
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/flue.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { createOpencodeClient, type OpencodeClient } from '@opencode-ai/sdk';
|
|
2
|
-
import type * as v from 'valibot';
|
|
3
|
-
import { runShell } from './shell.ts';
|
|
4
|
-
import { runSkill } from './skill.ts';
|
|
5
|
-
import type {
|
|
6
|
-
FlueOptions,
|
|
7
|
-
PromptOptions,
|
|
8
|
-
ShellOptions,
|
|
9
|
-
ShellResult,
|
|
10
|
-
SkillOptions,
|
|
11
|
-
} from './types.ts';
|
|
12
|
-
|
|
13
|
-
export class Flue {
|
|
14
|
-
/** Working branch for commits. */
|
|
15
|
-
readonly branch: string;
|
|
16
|
-
/** Workflow arguments passed by the runner. */
|
|
17
|
-
readonly args: Record<string, unknown>;
|
|
18
|
-
/** Scoped secrets passed by the runner. */
|
|
19
|
-
readonly secrets: Record<string, string>;
|
|
20
|
-
|
|
21
|
-
private readonly workdir: string;
|
|
22
|
-
private readonly model?: { providerID: string; modelID: string };
|
|
23
|
-
private readonly client: OpencodeClient;
|
|
24
|
-
|
|
25
|
-
constructor(options: FlueOptions) {
|
|
26
|
-
this.branch = options.branch ?? 'main';
|
|
27
|
-
this.args = options.args ?? {};
|
|
28
|
-
this.secrets = options.secrets ?? {};
|
|
29
|
-
this.workdir = options.workdir;
|
|
30
|
-
this.model = options.model;
|
|
31
|
-
this.client = createOpencodeClient({
|
|
32
|
-
baseUrl: options.opencodeUrl ?? 'http://localhost:48765',
|
|
33
|
-
directory: options.workdir,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Run a named skill with a result schema. */
|
|
38
|
-
async skill<S extends v.GenericSchema>(
|
|
39
|
-
name: string,
|
|
40
|
-
options: SkillOptions<S> & { result: S },
|
|
41
|
-
): Promise<v.InferOutput<S>>;
|
|
42
|
-
/** Run a named skill without a result schema (fire-and-forget). */
|
|
43
|
-
async skill(name: string, options?: SkillOptions): Promise<void>;
|
|
44
|
-
// biome-ignore lint/suspicious/noExplicitAny: runtime implementation of overloaded interface
|
|
45
|
-
async skill(name: string, options?: SkillOptions<v.GenericSchema | undefined>): Promise<any> {
|
|
46
|
-
const mergedOptions: SkillOptions<v.GenericSchema | undefined> = {
|
|
47
|
-
...options,
|
|
48
|
-
args: this.args || options?.args ? { ...this.args, ...options?.args } : undefined,
|
|
49
|
-
model: options?.model ?? this.model,
|
|
50
|
-
};
|
|
51
|
-
return runSkill(this.client, this.workdir, name, mergedOptions);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Run an inline prompt in a new OpenCode session. */
|
|
55
|
-
async prompt<S extends v.GenericSchema>(
|
|
56
|
-
promptText: string,
|
|
57
|
-
options: PromptOptions<S> & { result: S },
|
|
58
|
-
): Promise<v.InferOutput<S>>;
|
|
59
|
-
/** Run an inline prompt without a result schema. */
|
|
60
|
-
async prompt(promptText: string, options?: PromptOptions): Promise<void>;
|
|
61
|
-
// biome-ignore lint/suspicious/noExplicitAny: runtime implementation of overloaded interface
|
|
62
|
-
async prompt(
|
|
63
|
-
promptText: string,
|
|
64
|
-
options?: PromptOptions<v.GenericSchema | undefined>,
|
|
65
|
-
): Promise<any> {
|
|
66
|
-
const mergedOptions: SkillOptions<v.GenericSchema | undefined> = {
|
|
67
|
-
result: options?.result,
|
|
68
|
-
model: options?.model ?? this.model,
|
|
69
|
-
prompt: promptText,
|
|
70
|
-
};
|
|
71
|
-
return runSkill(this.client, this.workdir, '__inline__', mergedOptions);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Execute a shell command with scoped environment variables. */
|
|
75
|
-
async shell(command: string, options?: ShellOptions): Promise<ShellResult> {
|
|
76
|
-
return runShell(command, { ...options, cwd: options?.cwd ?? this.workdir });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Close the OpenCode client connection. */
|
|
80
|
-
async close(): Promise<void> {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}
|
package/src/index.ts
DELETED
package/src/prompt.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { toJsonSchema } from '@valibot/to-json-schema';
|
|
2
|
-
import type * as v from 'valibot';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Checks if a Valibot schema represents a plain string type.
|
|
6
|
-
*/
|
|
7
|
-
function isStringSchema(schema: v.GenericSchema): boolean {
|
|
8
|
-
return schema.type === 'string';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Checks if a skill name is a file path (contains '/' or ends with '.md').
|
|
13
|
-
*/
|
|
14
|
-
function isFilePath(name: string): boolean {
|
|
15
|
-
return name.includes('/') || name.endsWith('.md');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Build the prompt text for a skill invocation.
|
|
20
|
-
*
|
|
21
|
-
* If `name` looks like a file path (contains '/' or ends with '.md'), the
|
|
22
|
-
* prompt instructs the agent to read and follow that file under
|
|
23
|
-
* `.opencode/skills/`. Otherwise, it instructs the agent to use the named
|
|
24
|
-
* skill.
|
|
25
|
-
*
|
|
26
|
-
* @param name - A skill name or a file path relative to .opencode/skills/.
|
|
27
|
-
* @param args - Key-value arguments to include in the prompt.
|
|
28
|
-
* @param schema - Optional Valibot schema for result extraction.
|
|
29
|
-
* @returns The complete prompt string.
|
|
30
|
-
*/
|
|
31
|
-
export function buildSkillPrompt(
|
|
32
|
-
name: string,
|
|
33
|
-
args?: Record<string, unknown>,
|
|
34
|
-
schema?: v.GenericSchema,
|
|
35
|
-
): string {
|
|
36
|
-
const instruction = isFilePath(name)
|
|
37
|
-
? `Read and use the .opencode/skills/${name} skill.`
|
|
38
|
-
: `Use the ${name} skill.`;
|
|
39
|
-
const parts: string[] = [
|
|
40
|
-
'You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input, never use the question tool. Make your best judgment and proceed independently.',
|
|
41
|
-
'',
|
|
42
|
-
instruction,
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
if (args && Object.keys(args).length > 0) {
|
|
46
|
-
parts.push(`\nArguments:\n${JSON.stringify(args, null, 2)}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (schema) {
|
|
50
|
-
if (isStringSchema(schema)) {
|
|
51
|
-
parts.push(
|
|
52
|
-
'\nWhen complete, output your result between these exact delimiters (the result can contain any content including code blocks):',
|
|
53
|
-
'---RESULT_START---',
|
|
54
|
-
'Your text output here',
|
|
55
|
-
'---RESULT_END---',
|
|
56
|
-
);
|
|
57
|
-
} else {
|
|
58
|
-
const jsonSchema = toJsonSchema(schema, { errorMode: 'ignore' });
|
|
59
|
-
// Remove the $schema meta-property — it's noise in the prompt
|
|
60
|
-
const { $schema: _, ...schemaWithoutMeta } = jsonSchema;
|
|
61
|
-
parts.push(
|
|
62
|
-
'\nWhen complete, output your result between these exact delimiters as JSON conforming to this schema:',
|
|
63
|
-
'```json',
|
|
64
|
-
JSON.stringify(schemaWithoutMeta, null, 2),
|
|
65
|
-
'```',
|
|
66
|
-
'',
|
|
67
|
-
'Format:',
|
|
68
|
-
'---RESULT_START---',
|
|
69
|
-
'{"key": "value"}',
|
|
70
|
-
'---RESULT_END---',
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return parts.join('\n');
|
|
76
|
-
}
|
package/src/result.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import type { Part } from '@opencode-ai/sdk';
|
|
2
|
-
import * as v from 'valibot';
|
|
3
|
-
import { SkillOutputError } from './errors.ts';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Extracts and validates a structured result from OpenCode response parts.
|
|
7
|
-
*
|
|
8
|
-
* Scans TextParts for the last ---RESULT_START--- / ---RESULT_END--- block,
|
|
9
|
-
* parses the content, and validates it against the provided Valibot schema.
|
|
10
|
-
*
|
|
11
|
-
* @param parts - The response parts from OpenCode's session.prompt().
|
|
12
|
-
* @param schema - The Valibot schema to validate against.
|
|
13
|
-
* @param sessionId - The session ID (for error reporting).
|
|
14
|
-
* @returns The validated, typed result.
|
|
15
|
-
* @throws {SkillOutputError} If no result block is found or validation fails.
|
|
16
|
-
*/
|
|
17
|
-
export function extractResult<S extends v.GenericSchema>(
|
|
18
|
-
parts: Part[],
|
|
19
|
-
schema: S,
|
|
20
|
-
sessionId: string,
|
|
21
|
-
): v.InferOutput<S> {
|
|
22
|
-
// Collect all text content from TextParts
|
|
23
|
-
const textParts = parts.filter((p): p is Extract<Part, { type: 'text' }> => p.type === 'text');
|
|
24
|
-
|
|
25
|
-
// Find the last ---RESULT_START--- / ---RESULT_END--- block across all text parts
|
|
26
|
-
const allText = textParts.map((p) => p.text).join('\n');
|
|
27
|
-
const resultBlock = extractLastResultBlock(allText);
|
|
28
|
-
|
|
29
|
-
if (resultBlock === null) {
|
|
30
|
-
console.error(
|
|
31
|
-
`[flue] extractResult: no RESULT_START/RESULT_END block found (session: ${sessionId}, text length: ${allText.length} chars)`,
|
|
32
|
-
);
|
|
33
|
-
console.error(`[flue] extractResult: response tail (last 500 chars): ${allText.slice(-500)}`);
|
|
34
|
-
throw new SkillOutputError(
|
|
35
|
-
'No ---RESULT_START--- / ---RESULT_END--- block found in the assistant response.',
|
|
36
|
-
{
|
|
37
|
-
sessionId,
|
|
38
|
-
rawOutput: allText,
|
|
39
|
-
},
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log(
|
|
44
|
-
`[flue] extractResult: found result block (${resultBlock.length} chars, session: ${sessionId})`,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
// For string schemas, return the raw text content
|
|
48
|
-
if (schema.type === 'string') {
|
|
49
|
-
const parseResult = v.safeParse(schema, resultBlock);
|
|
50
|
-
if (!parseResult.success) {
|
|
51
|
-
console.error('[flue] extractResult: string validation failed', parseResult.issues);
|
|
52
|
-
throw new SkillOutputError('Result validation failed for string schema.', {
|
|
53
|
-
sessionId,
|
|
54
|
-
rawOutput: resultBlock,
|
|
55
|
-
validationErrors: parseResult.issues,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
console.log(`[flue] extractResult: validated string result (${resultBlock.length} chars)`);
|
|
59
|
-
return parseResult.output;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// For non-string schemas, parse as JSON
|
|
63
|
-
let parsed: unknown;
|
|
64
|
-
try {
|
|
65
|
-
parsed = JSON.parse(resultBlock);
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.error(
|
|
68
|
-
`[flue] extractResult: JSON parse failed for block: ${resultBlock.slice(0, 200)}`,
|
|
69
|
-
);
|
|
70
|
-
throw new SkillOutputError('Failed to parse result block as JSON.', {
|
|
71
|
-
sessionId,
|
|
72
|
-
rawOutput: resultBlock,
|
|
73
|
-
validationErrors: err,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const parseResult = v.safeParse(schema, parsed);
|
|
78
|
-
if (!parseResult.success) {
|
|
79
|
-
console.error('[flue] extractResult: schema validation failed', parseResult.issues);
|
|
80
|
-
console.error('[flue] extractResult: parsed value was:', JSON.stringify(parsed));
|
|
81
|
-
throw new SkillOutputError('Result does not match the expected schema.', {
|
|
82
|
-
sessionId,
|
|
83
|
-
rawOutput: resultBlock,
|
|
84
|
-
validationErrors: parseResult.issues,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log('[flue] extractResult: validated result:', JSON.stringify(parseResult.output));
|
|
89
|
-
return parseResult.output;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Extracts the content of the last ---RESULT_START--- / ---RESULT_END--- block from text.
|
|
94
|
-
* Returns null if no result block is found.
|
|
95
|
-
*/
|
|
96
|
-
function extractLastResultBlock(text: string): string | null {
|
|
97
|
-
const regex = /---RESULT_START---\s*\n([\s\S]*?)---RESULT_END---/g;
|
|
98
|
-
const matches = text.matchAll(regex);
|
|
99
|
-
let lastMatch: string | null = null;
|
|
100
|
-
|
|
101
|
-
for (const match of matches) {
|
|
102
|
-
lastMatch = match[1]?.trim() ?? null;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return lastMatch;
|
|
106
|
-
}
|
package/src/shell.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { exec } from 'node:child_process';
|
|
2
|
-
import type { ShellOptions, ShellResult } from './types.ts';
|
|
3
|
-
|
|
4
|
-
export async function runShell(command: string, options?: ShellOptions): Promise<ShellResult> {
|
|
5
|
-
return new Promise((resolve) => {
|
|
6
|
-
const child = exec(
|
|
7
|
-
command,
|
|
8
|
-
{
|
|
9
|
-
cwd: options?.cwd,
|
|
10
|
-
env: options?.env ? { ...process.env, ...options.env } : process.env,
|
|
11
|
-
timeout: options?.timeout,
|
|
12
|
-
},
|
|
13
|
-
(error, stdout, stderr) => {
|
|
14
|
-
const rawCode =
|
|
15
|
-
error && typeof (error as { code?: number }).code === 'number'
|
|
16
|
-
? (error as { code?: number }).code
|
|
17
|
-
: 0;
|
|
18
|
-
const exitCode = error ? rawCode || 1 : 0;
|
|
19
|
-
resolve({ stdout: stdout ?? '', stderr: stderr ?? '', exitCode });
|
|
20
|
-
},
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
if (options?.stdin) {
|
|
24
|
-
child.stdin?.write(options.stdin);
|
|
25
|
-
child.stdin?.end();
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
package/src/skill.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import type { OpencodeClient, Part } from '@opencode-ai/sdk';
|
|
2
|
-
import type * as v from 'valibot';
|
|
3
|
-
import { buildSkillPrompt } from './prompt.ts';
|
|
4
|
-
import { extractResult } from './result.ts';
|
|
5
|
-
import type { SkillOptions } from './types.ts';
|
|
6
|
-
|
|
7
|
-
/** How often to poll and log progress (ms). */
|
|
8
|
-
const POLL_INTERVAL = 5_000;
|
|
9
|
-
|
|
10
|
-
/** Max times we'll see 0 assistant messages before giving up. */
|
|
11
|
-
const MAX_EMPTY_POLLS = 3;
|
|
12
|
-
|
|
13
|
-
/** Max time to poll before timing out (ms) - 45 minutes. */
|
|
14
|
-
const MAX_POLL_TIME = 45 * 60 * 1000;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Run a named skill via the OpenCode client and optionally extract a typed result.
|
|
18
|
-
*/
|
|
19
|
-
export async function runSkill<S extends v.GenericSchema | undefined = undefined>(
|
|
20
|
-
client: OpencodeClient,
|
|
21
|
-
workdir: string,
|
|
22
|
-
name: string,
|
|
23
|
-
options?: SkillOptions<S>,
|
|
24
|
-
): Promise<S extends v.GenericSchema ? v.InferOutput<S> : void> {
|
|
25
|
-
const { args, result: schema, model, prompt: promptOverride } = options ?? {};
|
|
26
|
-
|
|
27
|
-
const prompt =
|
|
28
|
-
promptOverride ?? buildSkillPrompt(name, args, schema as v.GenericSchema | undefined);
|
|
29
|
-
|
|
30
|
-
console.log(`[flue] skill("${name}"): starting`);
|
|
31
|
-
|
|
32
|
-
console.log(`[flue] skill("${name}"): creating session`);
|
|
33
|
-
const session = await client.session.create({
|
|
34
|
-
body: { title: name },
|
|
35
|
-
query: { directory: workdir },
|
|
36
|
-
});
|
|
37
|
-
console.log(`[flue] skill("${name}"): session created`, {
|
|
38
|
-
hasData: !!session.data,
|
|
39
|
-
sessionId: session.data?.id,
|
|
40
|
-
error: session.error,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (!session.data) {
|
|
44
|
-
throw new Error(`Failed to create OpenCode session for skill "${name}".`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const sessionId = session.data.id;
|
|
48
|
-
const promptStart = Date.now();
|
|
49
|
-
|
|
50
|
-
console.log(`[flue] skill("${name}"): sending prompt async`);
|
|
51
|
-
const asyncResult = await client.session.promptAsync({
|
|
52
|
-
path: { id: sessionId },
|
|
53
|
-
query: { directory: workdir },
|
|
54
|
-
body: {
|
|
55
|
-
...(model ? { model } : {}),
|
|
56
|
-
parts: [{ type: 'text', text: prompt }],
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
console.log(`[flue] skill("${name}"): prompt sent`, {
|
|
61
|
-
hasError: !!asyncResult.error,
|
|
62
|
-
error: asyncResult.error,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
if (asyncResult.error) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`Failed to send prompt for skill "${name}" (session ${sessionId}): ${JSON.stringify(asyncResult.error)}`,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
console.log(`[flue] skill("${name}"): starting polling`);
|
|
72
|
-
const parts = await pollUntilIdle(client, sessionId, workdir, name, promptStart);
|
|
73
|
-
const promptElapsed = ((Date.now() - promptStart) / 1000).toFixed(1);
|
|
74
|
-
|
|
75
|
-
console.log(`[flue] skill("${name}"): completed (${promptElapsed}s)`);
|
|
76
|
-
|
|
77
|
-
if (!schema) {
|
|
78
|
-
return undefined as S extends v.GenericSchema ? v.InferOutput<S> : undefined;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return extractResult(parts, schema as v.GenericSchema, sessionId) as S extends v.GenericSchema
|
|
82
|
-
? v.InferOutput<S>
|
|
83
|
-
: undefined;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async function pollUntilIdle(
|
|
87
|
-
client: OpencodeClient,
|
|
88
|
-
sessionId: string,
|
|
89
|
-
workdir: string,
|
|
90
|
-
skillName: string,
|
|
91
|
-
startTime: number,
|
|
92
|
-
): Promise<Part[]> {
|
|
93
|
-
let emptyPolls = 0;
|
|
94
|
-
|
|
95
|
-
for (;;) {
|
|
96
|
-
await sleep(POLL_INTERVAL);
|
|
97
|
-
|
|
98
|
-
const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);
|
|
99
|
-
|
|
100
|
-
if (Date.now() - startTime > MAX_POLL_TIME) {
|
|
101
|
-
throw new Error(
|
|
102
|
-
`Skill "${skillName}" timed out after ${elapsed}s. Session never went idle. This may indicate a stuck session or OpenCode bug.`,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
console.log(`[flue] skill("${skillName}"): calling session.status()`);
|
|
107
|
-
const statusResult = await client.session.status({ query: { directory: workdir } });
|
|
108
|
-
console.log(
|
|
109
|
-
`[flue] skill("${skillName}"): status result: ${JSON.stringify({ hasData: !!statusResult.data, sessionIds: statusResult.data ? Object.keys(statusResult.data) : [], error: statusResult.error })}`,
|
|
110
|
-
);
|
|
111
|
-
const sessionStatus = statusResult.data?.[sessionId];
|
|
112
|
-
console.log(
|
|
113
|
-
`[flue] skill("${skillName}"): sessionStatus for ${sessionId}: ${JSON.stringify(sessionStatus)}`,
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
if (!sessionStatus || sessionStatus.type === 'idle') {
|
|
117
|
-
const parts = await fetchAllAssistantParts(client, sessionId, workdir);
|
|
118
|
-
|
|
119
|
-
if (parts.length === 0) {
|
|
120
|
-
emptyPolls++;
|
|
121
|
-
if (emptyPolls >= MAX_EMPTY_POLLS) {
|
|
122
|
-
throw new Error(
|
|
123
|
-
`Skill "${skillName}" produced no output after ${elapsed}s and ${emptyPolls} empty polls. ` +
|
|
124
|
-
`The agent may have failed to start — check model ID and API key.`,
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return parts;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log(`[flue] skill("${skillName}"): running (${elapsed}s)`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Fetch ALL parts from every assistant message in the session.
|
|
139
|
-
*/
|
|
140
|
-
async function fetchAllAssistantParts(
|
|
141
|
-
client: OpencodeClient,
|
|
142
|
-
sessionId: string,
|
|
143
|
-
workdir: string,
|
|
144
|
-
): Promise<Part[]> {
|
|
145
|
-
const messagesResult = await client.session.messages({
|
|
146
|
-
path: { id: sessionId },
|
|
147
|
-
query: { directory: workdir },
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
if (!messagesResult.data) {
|
|
151
|
-
throw new Error(`Failed to fetch messages for session ${sessionId}.`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const messages = messagesResult.data as Array<{ info: { role: string }; parts?: Part[] }>;
|
|
155
|
-
const assistantMessages = messages.filter((m) => m.info.role === 'assistant');
|
|
156
|
-
|
|
157
|
-
const allParts: Part[] = [];
|
|
158
|
-
for (const msg of assistantMessages) {
|
|
159
|
-
allParts.push(...(msg.parts ?? []));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return allParts;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function sleep(ms: number): Promise<void> {
|
|
166
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
167
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type * as v from 'valibot';
|
|
2
|
-
|
|
3
|
-
export interface FlueOptions {
|
|
4
|
-
/** OpenCode server URL (default: 'http://localhost:48765'). */
|
|
5
|
-
opencodeUrl?: string;
|
|
6
|
-
/** Working directory (the repo root inside the container). */
|
|
7
|
-
workdir: string;
|
|
8
|
-
/** Working branch for commits. */
|
|
9
|
-
branch?: string;
|
|
10
|
-
/** Workflow arguments. */
|
|
11
|
-
args?: Record<string, unknown>;
|
|
12
|
-
/** Scoped secrets. */
|
|
13
|
-
secrets?: Record<string, string>;
|
|
14
|
-
/** Default model for skill/prompt invocations. */
|
|
15
|
-
model?: { providerID: string; modelID: string };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface SkillOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
19
|
-
/** Key-value args serialized into the prompt. */
|
|
20
|
-
args?: Record<string, unknown>;
|
|
21
|
-
/** Valibot schema for structured result extraction. */
|
|
22
|
-
result?: S;
|
|
23
|
-
/** Override model for this skill. */
|
|
24
|
-
model?: { providerID: string; modelID: string };
|
|
25
|
-
/** Advanced: override the entire prompt. */
|
|
26
|
-
prompt?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface PromptOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
30
|
-
/** Valibot schema for structured result extraction. */
|
|
31
|
-
result?: S;
|
|
32
|
-
/** Override model for this prompt. */
|
|
33
|
-
model?: { providerID: string; modelID: string };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface ShellOptions {
|
|
37
|
-
/** Environment variables scoped to this subprocess only. */
|
|
38
|
-
env?: Record<string, string>;
|
|
39
|
-
/** Text to pipe to the command's stdin. */
|
|
40
|
-
stdin?: string;
|
|
41
|
-
/** Working directory (default: Flue's workdir). */
|
|
42
|
-
cwd?: string;
|
|
43
|
-
/** Timeout in milliseconds. */
|
|
44
|
-
timeout?: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface ShellResult {
|
|
48
|
-
stdout: string;
|
|
49
|
-
stderr: string;
|
|
50
|
-
exitCode: number;
|
|
51
|
-
}
|
package/tsconfig.json
DELETED
package/tsconfig.tsbuildinfo
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/errors.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/types.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/auth.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/pathserializer.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/bodyserializer.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/types.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/serversentevents.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/client/utils.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/client/types.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/core/params.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/client/client.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/client/index.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/gen/sdk.gen.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/client.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/server.d.ts","../../node_modules/.pnpm/@opencode-ai+sdk@1.1.55/node_modules/@opencode-ai/sdk/dist/index.d.ts","../../node_modules/.pnpm/valibot@1.2.0_typescript@5.9.3/node_modules/valibot/dist/index.d.mts","./src/types.ts","./src/shell.ts","../../node_modules/.pnpm/@valibot+to-json-schema@1.5.0_valibot@1.2.0_typescript@5.9.3_/node_modules/@valibot/to-json-schema/dist/index.d.mts","./src/prompt.ts","./src/result.ts","./src/skill.ts","./src/flue.ts","./src/index.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/compatibility/index.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/globals.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/events.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/header.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/readable.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/file.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/fetch.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/formdata.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/connector.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/client.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/errors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/dispatcher.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-origin.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool-stats.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/handlers.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/balanced-pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-client.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-pool.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-errors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/proxy-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-handler.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-agent.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/api.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/interceptors.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/util.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cookies.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/patch.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/websocket.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/eventsource.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/filereader.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/content-type.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cache.d.ts","../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/index.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/assert.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/assert/strict.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/async_hooks.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/buffer.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/child_process.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/cluster.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/console.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/constants.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/crypto.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/dgram.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/dns.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/dns/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/domain.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/events.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/fs.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/fs/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/http.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/http2.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/https.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/inspector.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/inspector.generated.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/module.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/net.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/os.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/path.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/perf_hooks.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/process.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/punycode.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/querystring.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/readline.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/readline/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/repl.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/sea.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/sqlite.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/stream.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/stream/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/stream/consumers.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/stream/web.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/string_decoder.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/test.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/timers.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/timers/promises.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/tls.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/trace_events.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/tty.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/url.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/util.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/v8.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/vm.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/wasi.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/worker_threads.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/zlib.d.ts","../../node_modules/.pnpm/@types+node@22.19.9/node_modules/@types/node/index.d.ts"],"fileIdsList":[[82,89,93,111,159,176,177],[89,111,159,176,177],[83,85,88,89,90,91,111,159,176,177],[83,86,87,88,111,159,176,177],[85,89,111,159,176,177],[111,159,176,177],[84,111,159,176,177],[86,111,159,176,177],[83,85,111,159,176,177],[82,87,89,92,111,159,176,177],[94,95,111,159,176,177],[82,111,159,176,177],[111,156,157,159,176,177],[111,158,159,176,177],[159,176,177],[111,159,164,176,177,194],[111,159,160,165,170,176,177,179,191,202],[111,159,160,161,170,176,177,179],[106,107,108,111,159,176,177],[111,159,162,176,177,203],[111,159,163,164,171,176,177,180],[111,159,164,176,177,191,199],[111,159,165,167,170,176,177,179],[111,158,159,166,176,177],[111,159,167,168,176,177],[111,159,169,170,176,177],[111,158,159,170,176,177],[111,159,170,171,172,176,177,191,202],[111,159,170,171,172,176,177,186,191,194],[111,152,159,167,170,173,176,177,179,191,202],[111,159,170,171,173,174,176,177,179,191,199,202],[111,159,173,175,176,177,191,199,202],[109,110,111,112,113,114,115,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208],[111,159,170,176,177],[111,159,176,177,178,202],[111,159,167,170,176,177,179,191],[111,159,176,177,180],[111,159,176,177,181],[111,158,159,176,177,182],[111,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208],[111,159,176,177,184],[111,159,176,177,185],[111,159,170,176,177,186,187],[111,159,176,177,186,188,203,205],[111,159,171,176,177],[111,159,170,176,177,191,192,194],[111,159,176,177,193,194],[111,159,176,177,191,192],[111,159,176,177,194],[111,159,176,177,195],[111,156,159,176,177,191,196],[111,159,170,176,177,197,198],[111,159,176,177,197,198],[111,159,164,176,177,179,191,199],[111,159,176,177,200],[111,159,176,177,179,201],[111,159,173,176,177,185,202],[111,159,164,176,177,203],[111,159,176,177,191,204],[111,159,176,177,178,205],[111,159,176,177,206],[111,152,159,176,177],[111,152,159,170,172,176,177,182,191,194,202,204,205,207],[111,159,176,177,191,208],[111,124,128,159,176,177,202],[111,124,159,176,177,191,202],[111,119,159,176,177],[111,121,124,159,176,177,199,202],[111,159,176,177,179,199],[111,159,176,177,209],[111,119,159,176,177,209],[111,121,124,159,176,177,179,202],[111,116,117,120,123,159,170,176,177,191,202],[111,124,131,159,176,177],[111,116,122,159,176,177],[111,124,145,146,159,176,177],[111,120,124,159,176,177,194,202,209],[111,145,159,176,177,209],[111,118,119,159,176,177,209],[111,124,159,176,177],[111,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,146,147,148,149,150,151,159,176,177],[111,124,139,159,176,177],[111,124,131,132,159,176,177],[111,122,124,132,133,159,176,177],[111,123,159,176,177],[111,116,119,124,159,176,177],[111,124,128,132,133,159,176,177],[111,128,159,176,177],[111,122,124,127,159,176,177,202],[111,116,121,124,131,159,176,177],[111,159,176,177,191],[111,119,124,145,159,176,177,207,209],[96,97,98,99,103,111,159,176,177],[81,98,104,111,159,176,177],[97,100,111,159,176,177],[81,96,97,111,159,176,177],[98,111,159,160,176,177],[96,97,98,101,102,111,159,176,177],[97,111,159,176,177]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},"a872780d14d3951905602af3d24b3e9473bc4943744ce7478fae868af3fa2d6e",{"version":"abd950a6eb114f55ae2210538340b4167a5d6e2f270864433417a9417c9c59b2","impliedFormat":99},{"version":"96135fbf1dab9f857c9df88a191fdc435517f7a5b021d09cad0c290a1dcec436","impliedFormat":99},{"version":"c36ce4ffa39eae9d8d5f3262bbff170f55b375156bc4eeadadfeede2820aa4c2","impliedFormat":99},{"version":"44fd7a3b2fac384971e638548c227835a2f8c3c2232edff7e0f951a0e136e562","impliedFormat":99},{"version":"80498d31235c22ee711a9fb6f0ca2bcb8fbf5c9a787f3d3a76962b440df70013","impliedFormat":99},{"version":"c41ccf7ec4fecea9d6e5b72ae7f20c91bbe85a8a82caada5ae8a3bc5a56c8926","impliedFormat":99},{"version":"77fed0312d2ec2b08afb890b7760b5f2328f6e09065ea05b5fc35d5294fbb434","impliedFormat":99},{"version":"11f6e61b31e0c89eae79ce790895bf85b918572c32c2de45998f7cbacbb3b963","impliedFormat":99},{"version":"d23fac93be3afb1c83269864f13b5e5fc246b05cb21b7e019e38403e4ef1aba5","impliedFormat":99},{"version":"358599da1d31542e1d3ebf35a4a98665395ea8eaf0063826b8838974f7e826e5","impliedFormat":99},{"version":"06240cf9eca32a7ea5436ee67c8420bc1ddacfaf0d28cd17d09dd56a65c8fb9a","impliedFormat":99},{"version":"5f71dae22207eb5119b2e005e046c0404a29454292e07c68668e39c9931414cd","impliedFormat":99},{"version":"84edb938f2b673df750cf83e9516218404e9df7e32e66f2f063c813d7f4d0e62","impliedFormat":99},{"version":"579f61b51c0e5dc0119ab49fc536130749280c7a23e489e753fcce08c229ce2c","impliedFormat":99},{"version":"2a7a35e3f1ead49569fe0423ae65055184f9384b97999cd90bb99878f727e585","impliedFormat":99},{"version":"1a86d5d23dfb656002bc90facad9d11ccc3310ec1c3df2ec236e7cf55d13cc8b","impliedFormat":99},"85c296b837a5b386e6a6c31972eeeb7cb26344303711f718922d04470d5225d8","7df3008db55a62e6dc68d055e79fb244457e75a8ab23f76f3ea651fe8e08595d",{"version":"b2d97c4c522dce41429a8515e1ee33d6bf686eb0057faa5848d93528017106dd","impliedFormat":99},"b608c3d4e979d29fdb7fc2ac83f369edd83c822439d1d02305aa9de22331cdd9","a204b98c206a79d73f543c5c6a6a4329dcd5a180507b847dec809f8983632304","610d549d511e1c5c604ae6247cbb2902edef78257ca61e56a22be6742091b7ea","3fe3fa0eba3bebc36bc472decdeb0598f1754f85173e390f40187944ca9a9409","722e88206499acc94b6407ca0097b642ce18d58845b9dc5fabea5bcd22cfc40f",{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"bb45cd435da536500f1d9692a9b49d0c570b763ccbf00473248b777f5c1f353b","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b039f55681caaf111d5eb84d292b9bee9e0131d0db1ad0871eef0964f533c73","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c959a391a75be9789b43c8468f71e3fa06488b4d691d5729dde1416dcd38225b","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1}],"root":[81,98,99,[101,105]],"options":{"allowImportingTsExtensions":true,"allowJs":true,"esModuleInterop":true,"module":99,"noUncheckedIndexedAccess":true,"skipLibCheck":true,"strict":true,"target":9,"verbatimModuleSyntax":true},"referencedMap":[[94,1],[91,2],[92,3],[89,4],[88,5],[83,6],[85,7],[90,6],[84,6],[87,8],[86,9],[93,10],[82,6],[96,11],[95,12],[156,13],[157,13],[158,14],[111,15],[159,16],[160,17],[161,18],[106,6],[109,19],[107,6],[108,6],[162,20],[163,21],[164,22],[165,23],[166,24],[167,25],[168,25],[169,26],[170,27],[171,28],[172,29],[112,6],[110,6],[173,30],[174,31],[175,32],[209,33],[176,34],[177,6],[178,35],[179,36],[180,37],[181,38],[182,39],[183,40],[184,41],[185,42],[186,43],[187,43],[188,44],[189,6],[190,45],[191,46],[193,47],[192,48],[194,49],[195,50],[196,51],[197,52],[198,53],[199,54],[200,55],[201,56],[202,57],[203,58],[204,59],[205,60],[206,61],[113,6],[114,6],[115,6],[153,62],[154,6],[155,6],[207,63],[208,64],[100,6],[79,6],[80,6],[14,6],[13,6],[2,6],[15,6],[16,6],[17,6],[18,6],[19,6],[20,6],[21,6],[22,6],[3,6],[23,6],[24,6],[4,6],[25,6],[29,6],[26,6],[27,6],[28,6],[30,6],[31,6],[32,6],[5,6],[33,6],[34,6],[35,6],[36,6],[6,6],[40,6],[37,6],[38,6],[39,6],[41,6],[7,6],[42,6],[47,6],[48,6],[43,6],[44,6],[45,6],[46,6],[8,6],[52,6],[49,6],[50,6],[51,6],[53,6],[9,6],[54,6],[55,6],[56,6],[58,6],[57,6],[59,6],[60,6],[10,6],[61,6],[62,6],[63,6],[11,6],[64,6],[65,6],[66,6],[67,6],[68,6],[1,6],[69,6],[70,6],[12,6],[74,6],[72,6],[77,6],[76,6],[71,6],[75,6],[73,6],[78,6],[131,65],[141,66],[130,65],[151,67],[122,68],[121,69],[150,70],[144,71],[149,72],[124,73],[138,74],[123,75],[147,76],[119,77],[118,70],[148,78],[120,79],[125,80],[126,6],[129,80],[116,6],[152,81],[142,82],[133,83],[134,84],[136,85],[132,86],[135,87],[145,70],[127,88],[128,89],[137,90],[117,91],[140,82],[139,80],[143,6],[146,92],[97,6],[81,6],[104,93],[105,94],[101,95],[102,96],[99,97],[103,98],[98,99]],"affectedFilesPendingEmit":[81,104,105,101,102,99,103,98],"version":"5.9.3"}
|