@clicksmith/daemon 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-D5ABXTTD.js → chunk-QYIV67WH.js} +55 -19
- package/dist/chunk-QYIV67WH.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-D5ABXTTD.js.map +0 -1
|
@@ -89,7 +89,7 @@ async function enrichBundle(bundle, provider) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// src/run-manager.ts
|
|
92
|
-
import { mkdir } from "fs/promises";
|
|
92
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
93
93
|
import { join } from "path";
|
|
94
94
|
import {
|
|
95
95
|
configToAdapter,
|
|
@@ -114,6 +114,7 @@ var RunManager = class {
|
|
|
114
114
|
}
|
|
115
115
|
deps;
|
|
116
116
|
availabilityCache = /* @__PURE__ */ new Map();
|
|
117
|
+
_instructionFile = null;
|
|
117
118
|
/**
|
|
118
119
|
* Prepare a sandbox and start an agent run. The sandbox is prepared
|
|
119
120
|
* synchronously so a dirty-tree refusal surfaces as an error to the caller;
|
|
@@ -156,7 +157,10 @@ var RunManager = class {
|
|
|
156
157
|
logger
|
|
157
158
|
);
|
|
158
159
|
}
|
|
159
|
-
const enriched = await
|
|
160
|
+
const enriched = await Promise.race([
|
|
161
|
+
enrichBundle(input, this.deps.enrichment),
|
|
162
|
+
new Promise((resolve) => setTimeout(() => resolve(input), 300))
|
|
163
|
+
]);
|
|
160
164
|
await store.saveBundle(runId, enriched);
|
|
161
165
|
const run = {
|
|
162
166
|
runId,
|
|
@@ -242,7 +246,7 @@ var RunManager = class {
|
|
|
242
246
|
...rawSpec.env ?? {}
|
|
243
247
|
}
|
|
244
248
|
};
|
|
245
|
-
logger.
|
|
249
|
+
logger.debug(`run ${run.runId}: ${spec.command} ${spec.args.slice(0, 2).join(" ")}`);
|
|
246
250
|
const logBuffer = createLogBuffer(
|
|
247
251
|
(chunk) => store.appendLog(run.runId, chunk),
|
|
248
252
|
(err) => logger.warn(`run ${run.runId}: failed to persist agent log`, err)
|
|
@@ -286,7 +290,7 @@ var RunManager = class {
|
|
|
286
290
|
});
|
|
287
291
|
bus.emit({ type: "agent-done", runId: run.runId, exitCode: result.exitCode });
|
|
288
292
|
if (bundle.execution.autoApply) {
|
|
289
|
-
logger.
|
|
293
|
+
logger.debug(`run ${run.runId}: autoApply`);
|
|
290
294
|
await this.apply(run.runId);
|
|
291
295
|
}
|
|
292
296
|
}
|
|
@@ -385,14 +389,17 @@ var RunManager = class {
|
|
|
385
389
|
}
|
|
386
390
|
}
|
|
387
391
|
/**
|
|
388
|
-
* Resolve the instruction file passed to the agent.
|
|
389
|
-
*
|
|
390
|
-
* corpus before the targeted UI lookup has even started.
|
|
392
|
+
* Resolve the instruction file passed to the agent. Generated once per daemon
|
|
393
|
+
* session (content only varies by port) and reused across all runs.
|
|
391
394
|
*/
|
|
392
|
-
async resolveInstructionFile(
|
|
395
|
+
async resolveInstructionFile(_run) {
|
|
396
|
+
if (this._instructionFile) return this._instructionFile;
|
|
393
397
|
const { config, store } = this.deps;
|
|
394
398
|
const body = renderInstructionBody({ daemonPort: config.port });
|
|
395
|
-
|
|
399
|
+
const path = join(store.paths.root, "AGENT_INSTRUCTIONS.md");
|
|
400
|
+
await writeFile(path, body, "utf-8");
|
|
401
|
+
this._instructionFile = path;
|
|
402
|
+
return path;
|
|
396
403
|
}
|
|
397
404
|
};
|
|
398
405
|
async function safe(fn) {
|
|
@@ -455,21 +462,20 @@ function buildAgentPrompt(input) {
|
|
|
455
462
|
`Request: ${truncateLine(bundle.prompt, 300)}`,
|
|
456
463
|
`Route: ${truncateLine(bundle.app.route, 160)}`,
|
|
457
464
|
`Cwd: ${run.sandbox?.path ?? run.repoRoot ?? "(none)"}`,
|
|
458
|
-
`Isolation: ${run.isolation}`,
|
|
459
465
|
"",
|
|
460
466
|
"Targets:",
|
|
461
467
|
targets,
|
|
462
468
|
"",
|
|
463
|
-
"
|
|
469
|
+
"Immediate actions (run ONLY these; do NOT read project docs or explore files first):",
|
|
464
470
|
...firstActions,
|
|
465
471
|
"",
|
|
466
|
-
"
|
|
467
|
-
"-
|
|
468
|
-
"- If
|
|
469
|
-
"-
|
|
470
|
-
"-
|
|
471
|
-
`-
|
|
472
|
-
"- Keep final output brief: changed files
|
|
472
|
+
"Rules:",
|
|
473
|
+
"- If a source file:line is listed above, open only that file at that line. No grep needed.",
|
|
474
|
+
"- If only grep commands are listed, run them (max two), then edit the matching file.",
|
|
475
|
+
"- If a grep result is only a shared sprite/icon definition, grep further to find the component usage.",
|
|
476
|
+
"- Do NOT read AGENTS.md, CLAUDE.md, .cursor/rules, guidelines, or any other docs.",
|
|
477
|
+
`- Read the bundle only as a last resort if the target is still ambiguous: ${bundlePath}`,
|
|
478
|
+
"- Keep final output brief: changed files only.",
|
|
473
479
|
"",
|
|
474
480
|
modeLine
|
|
475
481
|
].join("\n");
|
|
@@ -687,6 +693,24 @@ var DaemonService = class {
|
|
|
687
693
|
const { run } = await this.runs.createRun(bundle);
|
|
688
694
|
return { runId: run.runId, bundle };
|
|
689
695
|
}
|
|
696
|
+
/** Fast path: create a run directly from elements + prompt, no prior session needed. */
|
|
697
|
+
async run(req) {
|
|
698
|
+
const now = /* @__PURE__ */ new Date();
|
|
699
|
+
const execution = ExecutionOptionsSchema.parse(req.execution ?? {});
|
|
700
|
+
let session = createSession({ app: req.app, now, ttlMs: this.config.ttlMs });
|
|
701
|
+
for (const elementInput of req.elements) {
|
|
702
|
+
const { session: next } = appendElement(session, elementInput, now);
|
|
703
|
+
session = next;
|
|
704
|
+
}
|
|
705
|
+
await this.store.saveSession({ ...session, status: "submitted", prompt: req.prompt });
|
|
706
|
+
const bundle = finalizeSession(session, {
|
|
707
|
+
prompt: req.prompt,
|
|
708
|
+
execution,
|
|
709
|
+
...req.enrichment ? { enrichment: req.enrichment } : {}
|
|
710
|
+
});
|
|
711
|
+
const { run } = await this.runs.createRun(bundle);
|
|
712
|
+
return { runId: run.runId, sessionId: session.id, bundle };
|
|
713
|
+
}
|
|
690
714
|
async apply(runId) {
|
|
691
715
|
return this.runs.apply(runId);
|
|
692
716
|
}
|
|
@@ -713,6 +737,7 @@ import Fastify from "fastify";
|
|
|
713
737
|
import websocket from "@fastify/websocket";
|
|
714
738
|
import {
|
|
715
739
|
CaptureRequestSchema,
|
|
740
|
+
RunRequestSchema,
|
|
716
741
|
SubmitRequestSchema
|
|
717
742
|
} from "@clicksmith/core";
|
|
718
743
|
async function buildServer(service) {
|
|
@@ -732,6 +757,17 @@ async function buildServer(service) {
|
|
|
732
757
|
if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });
|
|
733
758
|
return service.capture(parsed.data);
|
|
734
759
|
});
|
|
760
|
+
app.post("/run", async (req, reply) => {
|
|
761
|
+
const parsed = RunRequestSchema.safeParse(req.body);
|
|
762
|
+
if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });
|
|
763
|
+
try {
|
|
764
|
+
return await service.run(parsed.data);
|
|
765
|
+
} catch (err) {
|
|
766
|
+
if (err instanceof RefusalError)
|
|
767
|
+
return reply.code(409).send({ error: err.message, code: err.code });
|
|
768
|
+
throw err;
|
|
769
|
+
}
|
|
770
|
+
});
|
|
735
771
|
app.post("/submit", async (req, reply) => {
|
|
736
772
|
const parsed = SubmitRequestSchema.safeParse(req.body);
|
|
737
773
|
if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });
|
|
@@ -799,4 +835,4 @@ export {
|
|
|
799
835
|
NotFoundError,
|
|
800
836
|
buildServer
|
|
801
837
|
};
|
|
802
|
-
//# sourceMappingURL=chunk-
|
|
838
|
+
//# sourceMappingURL=chunk-QYIV67WH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/events.ts","../src/launcher.ts","../src/enrichment.ts","../src/run-manager.ts","../src/daemon-service.ts","../src/server.ts"],"sourcesContent":["import type { ServerEvent } from '@clicksmith/core';\n\ntype Listener = (event: ServerEvent) => void;\ninterface ReplayFilter {\n runId?: string;\n sessionId?: string;\n}\n\n/**\n * A tiny synchronous pub/sub for {@link ServerEvent}s. The Fastify WebSocket\n * layer subscribes to fan events out to connected extension clients; the run\n * manager publishes. Kept dependency-free and ordered (listeners fire in\n * registration order, events in emit order).\n */\nexport class EventBus {\n private readonly listeners = new Set<Listener>();\n private readonly history: ServerEvent[] = [];\n private readonly maxHistory: number;\n\n constructor(maxHistory = 500) {\n this.maxHistory = maxHistory;\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ServerEvent): void {\n this.history.push(event);\n if (this.history.length > this.maxHistory) this.history.shift();\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // A misbehaving listener must never break the emit loop.\n }\n }\n }\n\n /** Replay buffered events, scoped to a run or session to avoid noisy reconnects. */\n replay(filter: ReplayFilter = {}): ServerEvent[] {\n if (!filter.runId && !filter.sessionId) return [];\n return this.history.filter((event) => {\n if (filter.runId && 'runId' in event && event.runId === filter.runId) return true;\n if (filter.sessionId && 'sessionId' in event && event.sessionId === filter.sessionId) {\n return true;\n }\n return false;\n });\n }\n}\n","import { execa } from 'execa';\nimport type { CommandSpec } from '@clicksmith/agent-config';\n\nexport interface LaunchHandlers {\n onLog: (stream: 'stdout' | 'stderr', chunk: string) => void;\n signal?: AbortSignal;\n}\n\nexport interface LaunchResult {\n exitCode: number;\n stdout: string;\n canceled: boolean;\n}\n\n/**\n * Spawn a resolved {@link CommandSpec} with execa, streaming stdout/stderr to\n * the caller as they arrive. Never rejects on non-zero exit — the run manager\n * decides what a non-zero code means.\n */\nexport async function launchAgent(\n spec: CommandSpec,\n handlers: LaunchHandlers,\n): Promise<LaunchResult> {\n const subprocess = execa(spec.command, spec.args, {\n cwd: spec.cwd,\n env: { ...process.env, ...spec.env },\n stdin: 'ignore',\n reject: false,\n all: false,\n cancelSignal: handlers.signal,\n });\n\n let stdout = '';\n subprocess.stdout?.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdout += chunk;\n handlers.onLog('stdout', chunk);\n });\n subprocess.stderr?.on('data', (data: Buffer) => {\n handlers.onLog('stderr', data.toString());\n });\n\n const result = await subprocess;\n return {\n exitCode: result.exitCode ?? (result.isCanceled ? 130 : 0),\n stdout,\n canceled: Boolean(result.isCanceled),\n };\n}\n","import type { CaptureBundle, Enrichment } from '@clicksmith/core';\n\n/**\n * Pluggable, best-effort enrichment. When configured (e.g. backed by the\n * code-review-graph MCP), it resolves source locators to attach review context\n * and impact radius per element. Failures must be **non-blocking**: the run\n * manager catches errors and records them as warnings on the bundle.\n */\nexport interface EnrichmentProvider {\n id: string;\n enrich(bundle: CaptureBundle): Promise<Enrichment | null>;\n}\n\n/**\n * Apply an enrichment provider to a bundle, swallowing failures into warnings.\n * Returns a (possibly) new bundle; never throws.\n */\nexport async function enrichBundle(\n bundle: CaptureBundle,\n provider: EnrichmentProvider | undefined,\n): Promise<CaptureBundle> {\n if (!provider) return bundle;\n try {\n const enrichment = await provider.enrich(bundle);\n if (!enrichment) return bundle;\n return { ...bundle, enrichment };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n ...bundle,\n enrichment: {\n source: 'code-review-graph',\n perElement: bundle.enrichment?.perElement ?? [],\n warnings: [...(bundle.enrichment?.warnings ?? []), `enrichment failed: ${message}`],\n },\n };\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n configToAdapter,\n defaultBinExists,\n renderInstructionBody,\n resolveAgent,\n type AgentAdapter,\n type AgentConfig,\n type AgentLaunchContext,\n} from '@clicksmith/agent-config';\nimport {\n newRunId,\n type ApplyResponse,\n type CaptureBundle,\n type CapturedElement,\n type SandboxInfo,\n} from '@clicksmith/core';\nimport { describeSandbox, Git } from './git.js';\nimport { launchAgent } from './launcher.js';\nimport { enrichBundle, type EnrichmentProvider } from './enrichment.js';\nimport type { EventBus } from './events.js';\nimport type { FileStore } from './store.js';\nimport type { Logger } from './logger.js';\nimport type { DaemonConfig } from './config.js';\nimport type { RunRecord } from './types.js';\n\n/** Raised when a non-inplace run is requested against a dirty working tree. */\nexport class RefusalError extends Error {\n readonly code = 'DIRTY_TREE';\n}\n\nexport interface RunManagerDeps {\n store: FileStore;\n config: DaemonConfig;\n bus: EventBus;\n logger: Logger;\n enrichment?: EnrichmentProvider;\n /** Override PATH probing (tests inject a fake). */\n binExists?: (bin: string) => Promise<boolean>;\n}\n\nconst COMMIT_PREFIX = 'ClickSmith';\nconst POSITIVE_AVAILABILITY_CACHE_MS = 60_000;\nconst NEGATIVE_AVAILABILITY_CACHE_MS = 5_000;\nconst LOG_FLUSH_MS = 75;\nconst LOG_FLUSH_BYTES = 16 * 1024;\n\ninterface AvailabilityCacheEntry {\n ok: boolean;\n expiresAt: number;\n}\n\nexport class RunManager {\n private readonly availabilityCache = new Map<string, AvailabilityCacheEntry>();\n private _instructionFile: string | null = null;\n\n constructor(private readonly deps: RunManagerDeps) {}\n\n /**\n * Prepare a sandbox and start an agent run. The sandbox is prepared\n * synchronously so a dirty-tree refusal surfaces as an error to the caller;\n * the agent itself runs in the background, emitting WebSocket events.\n */\n async createRun(input: CaptureBundle): Promise<{ run: RunRecord }> {\n const { store, config, bus, logger } = this.deps;\n const agentConfig = resolveAgent(config.agents, input.execution.agentId);\n if (!agentConfig) {\n throw new RefusalError(\n `No agent configured (requested: ${input.execution.agentId ?? 'default'}).`,\n );\n }\n\n const runId = newRunId();\n const now = new Date();\n const repoRoot = config.repoRoot;\n const isolation = repoRoot ? input.execution.isolation : 'inplace';\n\n let sandbox: SandboxInfo | null = null;\n let baseCommit: string | null = null;\n let baseBranch: string | null = null;\n\n if (repoRoot) {\n const git = new Git(repoRoot);\n [baseCommit, baseBranch] = await Promise.all([\n git.headCommit(),\n safe(() => git.currentBranch()),\n ]);\n const baseRef = input.execution.baseRef ?? baseCommit;\n\n if (\n isolation !== 'inplace' &&\n (await git.isDirty({ exclude: ['.clicksmith/', '.clicksmith'] }))\n ) {\n throw new RefusalError(\n `Refusing to run in ${isolation} isolation: the working tree has uncommitted changes. ` +\n `Commit or stash them, or use inplace isolation explicitly.`,\n );\n }\n sandbox = await this.prepareSandbox(\n git,\n runId,\n isolation,\n baseRef,\n repoRoot,\n baseCommit,\n logger,\n );\n }\n\n const enriched = await Promise.race([\n enrichBundle(input, this.deps.enrichment),\n new Promise<CaptureBundle>((resolve) => setTimeout(() => resolve(input), 300)),\n ]);\n await store.saveBundle(runId, enriched);\n\n const run: RunRecord = {\n runId,\n sessionId: enriched.sessionId,\n agentId: agentConfig.id,\n status: 'running',\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n mode: enriched.execution.mode,\n isolation,\n prompt: enriched.prompt,\n repoRoot,\n baseCommit,\n baseBranch,\n sandbox,\n revert: null,\n };\n await store.saveRun(run);\n\n bus.emit({\n type: 'agent-started',\n runId,\n sessionId: run.sessionId,\n agentId: run.agentId,\n sandbox,\n });\n\n // Fire-and-forget the actual agent execution.\n void this.execute(run, enriched, agentConfig).catch((err) => {\n logger.error(`run ${runId} crashed`, err);\n });\n\n return { run };\n }\n\n private async prepareSandbox(\n git: Git,\n runId: string,\n isolation: SandboxInfo['isolation'],\n baseRef: string,\n repoRoot: string,\n baseCommit: string,\n logger: Logger,\n ): Promise<SandboxInfo> {\n const branch = `clicksmith/${runId}`;\n if (isolation === 'inplace') {\n return describeSandbox('inplace', repoRoot, null, baseCommit);\n }\n if (isolation === 'worktree') {\n if (await git.supportsWorktree()) {\n const path = this.deps.store.paths.sandboxDir(runId);\n await mkdir(join(path, '..'), { recursive: true });\n await git.createWorktree(path, branch, baseRef);\n return describeSandbox('worktree', path, branch, baseCommit);\n }\n logger.warn('git worktrees unavailable; falling back to a dedicated branch');\n }\n // branch isolation (explicit or worktree fallback)\n await git.createBranch(branch, baseRef);\n return describeSandbox('branch', repoRoot, branch, baseCommit);\n }\n\n private async execute(\n run: RunRecord,\n bundle: CaptureBundle,\n agentConfig: AgentConfig,\n ): Promise<void> {\n const { store, config, bus, logger } = this.deps;\n const sandboxPath = run.sandbox?.path ?? config.cwd;\n\n const instructionFile = await this.resolveInstructionFile(run);\n const agentPrompt = buildAgentPrompt({\n bundle,\n bundlePath: store.bundlePath(run.runId),\n run,\n });\n const ctx: AgentLaunchContext = {\n bundlePath: store.bundlePath(run.runId),\n prompt: bundle.prompt,\n agentPrompt,\n instructionFile,\n mode: bundle.execution.mode,\n mcpServer: 'clicksmith',\n cwd: sandboxPath,\n isolation: run.isolation,\n agentId: agentConfig.id,\n binExists: this.deps.binExists ?? defaultBinExists,\n };\n\n const adapter = configToAdapter(agentConfig);\n if (!(await this.isAgentAvailable(agentConfig, adapter, ctx))) {\n await this.fail(run, unavailableMessage(agentConfig));\n return;\n }\n\n const rawSpec = adapter.buildCommand(ctx);\n const spec = {\n ...rawSpec,\n env: {\n CLICKSMITH_BUNDLE_PATH: ctx.bundlePath,\n CLICKSMITH_INSTRUCTION_FILE: ctx.instructionFile,\n CLICKSMITH_MODE: ctx.mode,\n CLICKSMITH_ISOLATION: ctx.isolation,\n CLICKSMITH_RUN_ID: run.runId,\n ...(rawSpec.env ?? {}),\n },\n };\n logger.debug(`run ${run.runId}: ${spec.command} ${spec.args.slice(0, 2).join(' ')}`);\n\n const logBuffer = createLogBuffer(\n (chunk) => store.appendLog(run.runId, chunk),\n (err) => logger.warn(`run ${run.runId}: failed to persist agent log`, err),\n );\n\n let result;\n try {\n result = await launchAgent(spec, {\n onLog: (stream, chunk) => {\n logBuffer.append(chunk);\n bus.emit({ type: 'agent-log', runId: run.runId, stream, chunk });\n },\n });\n } catch (err) {\n await logBuffer.flush();\n await this.fail(run, err instanceof Error ? err.message : String(err));\n return;\n }\n await logBuffer.flush();\n\n // Capture artifacts from isolated sandboxes. Inplace runs edit the current\n // tree directly, so the extension does not need a daemon-generated patch.\n const plan = result.stdout.trim();\n let diff = '';\n if (run.sandbox && run.repoRoot && run.sandbox.isolation !== 'inplace') {\n diff = await Git.captureDiff(run.sandbox.path);\n }\n if (plan) await store.writeArtifact(run.runId, 'plan.md', plan);\n if (diff) await store.writeArtifact(run.runId, 'diff.patch', diff);\n\n run.exitCode = result.exitCode;\n run.hasPlan = plan.length > 0;\n run.hasDiff = diff.length > 0;\n\n if (result.exitCode !== 0) {\n await this.fail(run, `Agent exited with code ${result.exitCode}.`);\n return;\n }\n\n run.status = 'plan-ready';\n run.updatedAt = new Date().toISOString();\n await store.saveRun(run);\n bus.emit({\n type: 'plan-ready',\n runId: run.runId,\n ...(plan ? { plan } : {}),\n ...(diff ? { diff } : {}),\n });\n bus.emit({ type: 'agent-done', runId: run.runId, exitCode: result.exitCode });\n\n if (bundle.execution.autoApply) {\n logger.debug(`run ${run.runId}: autoApply`);\n await this.apply(run.runId);\n }\n }\n\n private async fail(run: RunRecord, message: string): Promise<void> {\n run.status = 'error';\n run.error = message;\n run.updatedAt = new Date().toISOString();\n await this.deps.store.saveRun(run);\n this.deps.bus.emit({ type: 'agent-error', runId: run.runId, message });\n }\n\n private async isAgentAvailable(\n agentConfig: AgentConfig,\n adapter: AgentAdapter,\n ctx: AgentLaunchContext,\n ): Promise<boolean> {\n const key = availabilityCacheKey(agentConfig);\n const now = Date.now();\n const cached = this.availabilityCache.get(key);\n if (cached && cached.expiresAt > now) return cached.ok;\n\n const ok = await adapter.isAvailable(ctx);\n this.availabilityCache.set(key, {\n ok,\n expiresAt: now + (ok ? POSITIVE_AVAILABILITY_CACHE_MS : NEGATIVE_AVAILABILITY_CACHE_MS),\n });\n return ok;\n }\n\n /**\n * Merge a finished run's sandbox changes back into the working tree. Reports\n * conflicts, commits on success, records revert metadata, and cleans up the\n * sandbox.\n */\n async apply(runId: string): Promise<ApplyResponse> {\n const { store, bus, logger } = this.deps;\n const run = await store.getRun(runId);\n if (!run) throw new Error(`Unknown run: ${runId}`);\n if (!run.repoRoot || !run.sandbox) {\n throw new Error(`Run ${runId} has no git sandbox to apply.`);\n }\n\n bus.emit({ type: 'apply-started', runId });\n const git = new Git(run.repoRoot);\n const previousHead = await git.headCommit();\n const message = `${COMMIT_PREFIX} run ${runId}: ${truncate(run.prompt, 72)}`;\n\n try {\n let commit: string | undefined;\n\n if (run.sandbox.isolation === 'worktree') {\n const diff = (await store.readArtifact(runId, 'diff.patch')) ?? '';\n const applied = await git.applyPatch(diff);\n if (!applied.ok) return await this.applyConflict(run, applied.conflicts);\n commit = diff.trim() ? await git.commit(message) : previousHead;\n await this.cleanupSandbox(run);\n } else if (run.sandbox.isolation === 'branch') {\n // Changes are already staged in the repo on the clicksmith branch.\n if (await git.hasChanges()) await git.commit(message);\n if (run.baseBranch) await git.switchTo(run.baseBranch);\n const merged = await git.merge(run.sandbox.branch!, message);\n if (!merged.ok) return await this.applyConflict(run, merged.conflicts);\n commit = await git.headCommit();\n await git.deleteBranch(run.sandbox.branch!);\n } else {\n // inplace: commit whatever the agent changed in the working tree.\n commit = (await git.hasChanges()) ? await git.commit(message) : previousHead;\n }\n\n run.status = 'applied';\n run.applied = { ...(commit ? { commit } : {}), at: new Date().toISOString() };\n run.revert = {\n previousHead,\n ...(commit && commit !== previousHead ? { appliedCommit: commit } : {}),\n instructions:\n commit && commit !== previousHead\n ? `git revert ${commit} # or: git reset --hard ${previousHead}`\n : 'No commit was created; nothing to revert.',\n };\n run.updatedAt = new Date().toISOString();\n await store.saveRun(run);\n\n bus.emit({ type: 'apply-done', runId, ...(commit ? { commit } : {}) });\n return { applied: true, ...(commit ? { commit } : {}) };\n } catch (err) {\n const messageText = err instanceof Error ? err.message : String(err);\n logger.error(`apply ${runId} failed`, messageText);\n run.status = 'apply-error';\n run.error = messageText;\n await store.saveRun(run);\n bus.emit({ type: 'apply-error', runId, message: messageText });\n return { applied: false };\n }\n }\n\n private async applyConflict(run: RunRecord, conflicts: string[]): Promise<ApplyResponse> {\n run.status = 'apply-error';\n run.error = `Apply conflicts in: ${conflicts.join(', ') || 'unknown files'}`;\n run.updatedAt = new Date().toISOString();\n await this.deps.store.saveRun(run);\n this.deps.bus.emit({\n type: 'apply-error',\n runId: run.runId,\n message: run.error,\n conflicts,\n });\n return { applied: false, conflicts };\n }\n\n private async cleanupSandbox(run: RunRecord): Promise<void> {\n if (!run.repoRoot || !run.sandbox) return;\n if (run.sandbox.isolation === 'worktree') {\n const git = new Git(run.repoRoot);\n await git.removeWorktree(run.sandbox.path, run.sandbox.branch ?? undefined);\n }\n }\n\n /**\n * Resolve the instruction file passed to the agent. Generated once per daemon\n * session (content only varies by port) and reused across all runs.\n */\n private async resolveInstructionFile(_run: RunRecord): Promise<string> {\n if (this._instructionFile) return this._instructionFile;\n const { config, store } = this.deps;\n const body = renderInstructionBody({ daemonPort: config.port });\n const path = join(store.paths.root, 'AGENT_INSTRUCTIONS.md');\n await writeFile(path, body, 'utf-8');\n this._instructionFile = path;\n return path;\n }\n}\n\nasync function safe<T>(fn: () => Promise<T>): Promise<T | null> {\n try {\n return await fn();\n } catch {\n return null;\n }\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length <= n ? s : `${s.slice(0, n - 1)}…`;\n}\n\nfunction unavailableMessage(agentConfig: AgentConfig): string {\n const checked = agentConfig.detect?.anyOf ?? [agentConfig.command];\n return (\n `Agent \"${agentConfig.id}\" is not available to the ClickSmith daemon. ` +\n `Checked: ${checked.join(', ')}. ` +\n `Install the agent CLI so it is on the daemon PATH, or set command/detect to an absolute path in .clicksmith/agents.config.json.`\n );\n}\n\nfunction availabilityCacheKey(agentConfig: AgentConfig): string {\n return [\n agentConfig.id,\n agentConfig.command,\n ...(agentConfig.detect?.anyOf ?? [agentConfig.command]),\n ].join('\\0');\n}\n\nfunction createLogBuffer(\n write: (chunk: string) => Promise<void>,\n onError: (err: unknown) => void,\n): { append: (chunk: string) => void; flush: () => Promise<void> } {\n let buffer = '';\n let timer: ReturnType<typeof setTimeout> | null = null;\n let flushChain = Promise.resolve();\n\n async function flush(): Promise<void> {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n if (!buffer) return flushChain;\n\n const chunk = buffer;\n buffer = '';\n flushChain = flushChain.then(() => write(chunk)).catch(onError);\n await flushChain;\n }\n\n return {\n append(chunk) {\n buffer += chunk;\n if (buffer.length >= LOG_FLUSH_BYTES) {\n void flush();\n } else if (!timer) {\n timer = setTimeout(() => void flush(), LOG_FLUSH_MS);\n }\n },\n flush,\n };\n}\n\nfunction buildAgentPrompt(input: {\n bundle: CaptureBundle;\n bundlePath: string;\n run: RunRecord;\n}): string {\n const { bundle, bundlePath, run } = input;\n const targets = bundle.elements.map(formatTargetSummary).join('\\n');\n const firstActions = buildFirstActions(bundle, bundlePath).map((action, index) => {\n return `${index + 1}. ${action}`;\n });\n const modeLine =\n bundle.execution.mode === 'edit'\n ? 'Mode: edit. Make the smallest working-tree change; do not ask for confirmation.'\n : 'Mode: plan. Inspect only and return a concise plan.';\n\n return [\n 'ClickSmith fast UI edit.',\n `Request: ${truncateLine(bundle.prompt, 300)}`,\n `Route: ${truncateLine(bundle.app.route, 160)}`,\n `Cwd: ${run.sandbox?.path ?? run.repoRoot ?? '(none)'}`,\n '',\n 'Targets:',\n targets,\n '',\n 'Immediate actions (run ONLY these; do NOT read project docs or explore files first):',\n ...firstActions,\n '',\n 'Rules:',\n '- If a source file:line is listed above, open only that file at that line. No grep needed.',\n '- If only grep commands are listed, run them (max two), then edit the matching file.',\n '- If a grep result is only a shared sprite/icon definition, grep further to find the component usage.',\n '- Do NOT read AGENTS.md, CLAUDE.md, .cursor/rules, guidelines, or any other docs.',\n `- Read the bundle only as a last resort if the target is still ambiguous: ${bundlePath}`,\n '- Keep final output brief: changed files only.',\n '',\n modeLine,\n ].join('\\n');\n}\n\nfunction formatTargetSummary(element: CapturedElement): string {\n const label = element.el.text || element.el.label || element.el.role || element.el.tag;\n const attrs = formatAttrs(element.el.attrs);\n const locator = formatLocator(element);\n const near = formatNear(element);\n const tokens = collectElementSearchTokens(element).slice(0, 5);\n return [\n `#${element.id} <${element.el.tag}> ${quoteText(label)}`,\n `locator=${locator}`,\n attrs ? `attrs=${attrs}` : '',\n near ? `near=${near}` : '',\n tokens.length ? `tokens=${tokens.map(quoteText).join(', ')}` : '',\n ]\n .filter(Boolean)\n .join(' | ');\n}\n\nfunction formatLocator(element: CapturedElement): string {\n const { locator } = element;\n if (locator.kind === 'source') {\n return `source:${locator.file}:${locator.line}${locator.column != null ? `:${locator.column}` : ''}`;\n }\n if (locator.kind === 'attr') {\n return `attr:${locator.attr}=${quoteText(locator.value)}`;\n }\n if (locator.kind === 'behavioral') {\n return `behavioral:${locator.role} ${quoteText(locator.name)}`;\n }\n return `dom:${truncateLine(locator.selector, 120)}`;\n}\n\nfunction formatAttrs(attrs: Record<string, string>): string {\n return Object.entries(attrs)\n .slice(0, 5)\n .map(([key, value]) => `${key}=${quoteText(value)}`)\n .join(' ');\n}\n\nfunction formatNear(element: CapturedElement): string {\n return [\n ...(element.near.labels ?? []).slice(0, 1).map((label) => `label=${quoteText(label)}`),\n ...(element.near.headings ?? []).slice(0, 1).map((heading) => `heading=${quoteText(heading)}`),\n ...(element.near.landmarks ?? []).slice(0, 1).map((landmark) => `landmark=${quoteText(landmark)}`),\n ].join(' ');\n}\n\nfunction buildFirstActions(bundle: CaptureBundle, bundlePath: string): string[] {\n const sourceActions = bundle.elements\n .filter((element) => element.locator.kind === 'source')\n .map((element) => {\n if (element.locator.kind !== 'source') return '';\n const start = Math.max(1, element.locator.line - 30);\n const end = element.locator.line + 30;\n return `Open #${element.id} source ${element.locator.file}:${element.locator.line} (for example: sed -n '${start},${end}p' ${shellQuote(element.locator.file)}).`;\n })\n .filter(Boolean);\n if (sourceActions.length) return sourceActions.slice(0, 2);\n\n const tokens = collectBundleSearchTokens(bundle);\n const actions: string[] = [];\n if (tokens.length) {\n actions.push(`git grep -n ${tokens.slice(0, 2).map((token) => `-e ${shellQuote(token)}`).join(' ')} -- . 2>/dev/null || true`);\n }\n if (tokens.length > 2) {\n actions.push(`git grep -n ${tokens.slice(2, 4).map((token) => `-e ${shellQuote(token)}`).join(' ')} -- . 2>/dev/null || true`);\n }\n if (actions.length) return actions;\n\n return [`No exact token captured. Read the fallback bundle once: ${bundlePath}`];\n}\n\nfunction collectBundleSearchTokens(bundle: CaptureBundle): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n const add = (token: string) => {\n const key = token.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(token);\n };\n\n for (const element of bundle.elements) {\n for (const token of collectElementSearchTokens(element)) add(token);\n }\n return out.slice(0, 8);\n}\n\nfunction collectElementSearchTokens(element: CapturedElement): string[] {\n const tokens: string[] = [];\n const add = (value: string | undefined) => {\n for (const token of searchTokenVariants(value)) {\n if (!tokens.some((existing) => existing.toLowerCase() === token.toLowerCase())) {\n tokens.push(token);\n }\n }\n };\n\n if (element.locator.kind === 'attr') add(element.locator.value);\n if (element.locator.kind === 'behavioral') add(element.locator.name);\n for (const token of clicksmithHintTokens(element)) add(token);\n for (const value of Object.values(element.el.attrs)) add(value);\n for (const token of element.el.iconHints ?? []) add(token);\n add(element.el.label);\n add(element.el.text);\n for (const label of element.near.labels ?? []) add(label);\n for (const heading of element.near.headings ?? []) add(heading);\n add(element.near.parentText);\n\n return tokens.slice(0, 10);\n}\n\nfunction clicksmithHintTokens(element: CapturedElement): string[] {\n const raw = element.frameworkHints?.clicksmith;\n if (!isRecord(raw)) return [];\n const tokens = raw.searchTokens;\n return Array.isArray(tokens) ? tokens.filter((token): token is string => typeof token === 'string') : [];\n}\n\nfunction searchTokenVariants(value: string | undefined): string[] {\n if (!value) return [];\n const normalized = value.trim().replace(/\\s+/g, ' ');\n if (!normalized || normalized.length > 120) return [];\n const variants = [normalized];\n if (normalized.startsWith('#') && normalized.length > 1) variants.unshift(normalized.slice(1));\n if (normalized.includes('/') && !normalized.includes(' ')) {\n variants.push(normalized.split('/').filter(Boolean).at(-1) ?? '');\n }\n return variants\n .map((token) => token.trim().replace(/^[\"'`#]+|[\"'`]+$/g, ''))\n .filter((token) => token.length >= 3 && token.length <= 80)\n .filter((token) => !COMMON_SEARCH_TOKENS.has(token.toLowerCase()));\n}\n\nfunction quoteText(value: string): string {\n return JSON.stringify(truncateLine(value, 120));\n}\n\nfunction truncateLine(value: string, max: number): string {\n const oneLine = value.replace(/\\s+/g, ' ').trim();\n return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 3)}...`;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nconst COMMON_SEARCH_TOKENS = new Set([\n 'button',\n 'click',\n 'div',\n 'false',\n 'icon',\n 'input',\n 'label',\n 'link',\n 'main',\n 'section',\n 'span',\n 'svg',\n 'true',\n 'use',\n]);\n","import {\n appendElement,\n createSession,\n ExecutionOptionsSchema,\n finalizeSession,\n removeElement,\n touchSession,\n type ApplyResponse,\n type CaptureRequest,\n type CaptureResponse,\n type HealthResponse,\n type RemoveElementResponse,\n type RunRequest,\n type RunResponse,\n type Session,\n type SubmitRequest,\n type SubmitResponse,\n} from '@clicksmith/core';\nimport { EventBus } from './events.js';\nimport { FileStore } from './store.js';\nimport { RunManager, type RunManagerDeps } from './run-manager.js';\nimport type { DaemonConfig } from './config.js';\nimport type { EnrichmentProvider } from './enrichment.js';\nimport { version as DAEMON_VERSION } from './version.js';\n\nexport interface DaemonServiceOptions {\n config: DaemonConfig;\n enrichment?: EnrichmentProvider;\n binExists?: RunManagerDeps['binExists'];\n}\n\n/**\n * The framework-agnostic core of the daemon. The HTTP/WS server and tests both\n * drive this; it owns sessions, runs, the event bus, and persistence.\n */\nexport class DaemonService {\n readonly config: DaemonConfig;\n readonly store: FileStore;\n readonly bus: EventBus;\n readonly runs: RunManager;\n\n constructor(opts: DaemonServiceOptions) {\n this.config = opts.config;\n this.store = new FileStore(opts.config.storageRoot);\n this.bus = new EventBus();\n this.runs = new RunManager({\n store: this.store,\n config: opts.config,\n bus: this.bus,\n logger: opts.config.logger,\n ...(opts.enrichment ? { enrichment: opts.enrichment } : {}),\n ...(opts.binExists ? { binExists: opts.binExists } : {}),\n });\n }\n\n async init(): Promise<void> {\n await this.store.init();\n await this.store.cleanupExpired();\n }\n\n /* ------------------------------- capture ------------------------------ */\n\n /** Create or append to the active session for an app/route. */\n async capture(req: CaptureRequest): Promise<CaptureResponse> {\n const now = new Date();\n let session = req.sessionId ? await this.store.getSession(req.sessionId) : undefined;\n if (!session) {\n session = createSession({ app: req.app, now, ttlMs: this.config.ttlMs });\n } else {\n session = touchSession(session, now, this.config.ttlMs);\n }\n\n const { session: next, element } = appendElement(session, req.element, now);\n await this.store.saveSession(next);\n\n this.bus.emit({ type: 'capture-ack', sessionId: next.id, element });\n return { sessionId: next.id, element };\n }\n\n async removeElement(sessionId: string, elementId: number): Promise<RemoveElementResponse> {\n const session = await this.store.getSession(sessionId);\n if (!session) return { removed: false };\n const { session: next, removed } = removeElement(session, elementId);\n if (removed) {\n await this.store.saveSession(next);\n this.bus.emit({ type: 'element-removed', sessionId, elementId });\n }\n return { removed };\n }\n\n async getSession(id: string): Promise<Session | undefined> {\n return this.store.getSession(id);\n }\n\n /* ------------------------------- submit ------------------------------- */\n\n /** Finalize a session into a bundle and start a run. */\n async submit(req: SubmitRequest): Promise<SubmitResponse> {\n const session = await this.store.getSession(req.sessionId);\n if (!session) throw new NotFoundError(`Unknown session: ${req.sessionId}`);\n\n const execution = ExecutionOptionsSchema.parse(req.execution ?? {});\n const bundle = finalizeSession(session, {\n prompt: req.prompt,\n execution,\n ...(req.enrichment ? { enrichment: req.enrichment } : {}),\n });\n\n const submitted: Session = { ...session, status: 'submitted', prompt: req.prompt };\n await this.store.saveSession(submitted);\n\n const { run } = await this.runs.createRun(bundle);\n return { runId: run.runId, bundle };\n }\n\n /** Fast path: create a run directly from elements + prompt, no prior session needed. */\n async run(req: RunRequest): Promise<RunResponse> {\n const now = new Date();\n const execution = ExecutionOptionsSchema.parse(req.execution ?? {});\n\n let session = createSession({ app: req.app, now, ttlMs: this.config.ttlMs });\n for (const elementInput of req.elements) {\n const { session: next } = appendElement(session, elementInput, now);\n session = next;\n }\n await this.store.saveSession({ ...session, status: 'submitted', prompt: req.prompt });\n\n const bundle = finalizeSession(session, {\n prompt: req.prompt,\n execution,\n ...(req.enrichment ? { enrichment: req.enrichment } : {}),\n });\n\n const { run } = await this.runs.createRun(bundle);\n return { runId: run.runId, sessionId: session.id, bundle };\n }\n\n async apply(runId: string): Promise<ApplyResponse> {\n return this.runs.apply(runId);\n }\n\n /* ------------------------------- health ------------------------------- */\n\n async health(): Promise<HealthResponse> {\n const sessions = await this.store.listSessions();\n return {\n ok: true,\n name: 'clicksmith-daemon',\n version: DAEMON_VERSION,\n host: this.config.host,\n port: this.config.port,\n repoRoot: this.config.repoRoot,\n activeSessions: sessions.filter((s) => s.status === 'active').length,\n };\n }\n}\n\nexport class NotFoundError extends Error {\n readonly code = 'NOT_FOUND';\n}\n","import Fastify, { type FastifyInstance } from 'fastify';\nimport websocket from '@fastify/websocket';\nimport {\n CaptureRequestSchema,\n RunRequestSchema,\n SubmitRequestSchema,\n type ClientMessage,\n type ServerEvent,\n} from '@clicksmith/core';\nimport { type DaemonService, NotFoundError } from './daemon-service.js';\nimport { RefusalError } from './run-manager.js';\n\ntype SubscribeMessage = Extract<ClientMessage, { type: 'subscribe' }> & { runId?: string };\n\n/**\n * Build the Fastify app exposing ClickSmith's HTTP + WebSocket surface on top\n * of a {@link DaemonService}. Binds loopback only; CORS is opened for localhost\n * so the browser extension can talk to it.\n */\nexport async function buildServer(service: DaemonService): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n\n // Minimal CORS for the extension (loopback only).\n app.addHook('onRequest', async (req, reply) => {\n reply.header('Access-Control-Allow-Origin', '*');\n reply.header('Access-Control-Allow-Methods', 'GET,POST,DELETE,OPTIONS');\n reply.header('Access-Control-Allow-Headers', 'content-type');\n if (req.method === 'OPTIONS') {\n reply.code(204).send();\n }\n });\n\n await app.register(websocket);\n\n /* ------------------------------- HTTP -------------------------------- */\n\n app.get('/health', async () => service.health());\n\n app.post('/capture', async (req, reply) => {\n const parsed = CaptureRequestSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });\n return service.capture(parsed.data);\n });\n\n app.post('/run', async (req, reply) => {\n const parsed = RunRequestSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });\n try {\n return await service.run(parsed.data);\n } catch (err) {\n if (err instanceof RefusalError)\n return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n app.post('/submit', async (req, reply) => {\n const parsed = SubmitRequestSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });\n try {\n return await service.submit(parsed.data);\n } catch (err) {\n if (err instanceof NotFoundError) return reply.code(404).send({ error: err.message });\n if (err instanceof RefusalError)\n return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n app.post<{ Params: { runId: string } }>('/apply/:runId', async (req, reply) => {\n try {\n return await service.apply(req.params.runId);\n } catch (err) {\n return reply.code(404).send({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.get<{ Params: { id: string } }>('/session/:id', async (req, reply) => {\n const session = await service.getSession(req.params.id);\n if (!session) return reply.code(404).send({ error: `Unknown session: ${req.params.id}` });\n return session;\n });\n\n app.delete<{ Params: { sessionId: string; elementId: string } }>(\n '/element/:sessionId/:elementId',\n async (req) => {\n const elementId = Number.parseInt(req.params.elementId, 10);\n return service.removeElement(req.params.sessionId, elementId);\n },\n );\n\n /* ----------------------------- WebSocket ----------------------------- */\n\n app.get('/ws', { websocket: true }, (socket) => {\n const send = (event: ServerEvent) => {\n if (socket.readyState === socket.OPEN) socket.send(JSON.stringify(event));\n };\n const unsubscribe = service.bus.subscribe(send);\n\n socket.on('message', (raw: Buffer) => {\n let msg: ClientMessage;\n try {\n msg = JSON.parse(raw.toString()) as ClientMessage;\n } catch {\n return;\n }\n if (msg.type === 'ping') socket.send(JSON.stringify({ type: 'pong' }));\n else if (msg.type === 'subscribe') {\n // Replay only the run/session the client asks for. Unscoped replay can\n // flood reconnecting extension workers with unrelated historical logs.\n const sub = msg as SubscribeMessage;\n for (const event of service.bus.replay({ runId: sub.runId, sessionId: sub.sessionId })) {\n send(event);\n }\n }\n });\n\n socket.on('close', unsubscribe);\n socket.on('error', unsubscribe);\n });\n\n return app;\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DaemonService,
|
|
4
4
|
buildServer
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QYIV67WH.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveDaemonConfig,
|
|
8
8
|
startMcp,
|
|
@@ -35,9 +35,9 @@ async function runDaemon(args) {
|
|
|
35
35
|
const app = await buildServer(service);
|
|
36
36
|
await app.listen({ host: config.host, port: config.port });
|
|
37
37
|
config.logger.info(`daemon listening on http://${config.host}:${config.port}`);
|
|
38
|
-
config.logger.
|
|
39
|
-
config.logger.
|
|
40
|
-
config.logger.
|
|
38
|
+
config.logger.debug(`storage: ${config.storageRoot}`);
|
|
39
|
+
config.logger.debug(`repo: ${config.repoRoot ?? "(none \u2014 using OS cache)"}`);
|
|
40
|
+
config.logger.debug(`agents: ${config.agents.agents.map((a) => a.id).join(", ")}`);
|
|
41
41
|
const shutdown = async () => {
|
|
42
42
|
config.logger.info("shutting down");
|
|
43
43
|
await app.close();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { resolveDaemonConfig } from './config.js';\nimport { DaemonService } from './daemon-service.js';\nimport { buildServer } from './server.js';\nimport { startMcp } from './mcp.js';\nimport { version } from './version.js';\nimport { defaultBinExists } from '@clicksmith/agent-config';\n\nconst HELP = `clicksmith ${version}\n\nUsage:\n clicksmith daemon [--port <n>] [--host <h>] [--log <level>]\n clicksmith mcp Run the read-only MCP stdio server\n clicksmith doctor Check daemon config and agent CLIs\n clicksmith version\n clicksmith help\n\nThe daemon binds loopback only and stores state under .clicksmith/ (in a repo)\nor your OS cache directory otherwise.\n`;\n\nasync function runDaemon(args: string[]): Promise<void> {\n const opts = parseFlags(args);\n const config = await resolveDaemonConfig({\n ...(opts.port ? { port: Number(opts.port) } : {}),\n ...(opts.host ? { host: opts.host } : {}),\n ...(opts.log ? { logLevel: opts.log as never } : {}),\n });\n const service = new DaemonService({ config });\n await service.init();\n const app = await buildServer(service);\n\n await app.listen({ host: config.host, port: config.port });\n config.logger.info(`daemon listening on http://${config.host}:${config.port}`);\n config.logger.
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { resolveDaemonConfig } from './config.js';\nimport { DaemonService } from './daemon-service.js';\nimport { buildServer } from './server.js';\nimport { startMcp } from './mcp.js';\nimport { version } from './version.js';\nimport { defaultBinExists } from '@clicksmith/agent-config';\n\nconst HELP = `clicksmith ${version}\n\nUsage:\n clicksmith daemon [--port <n>] [--host <h>] [--log <level>]\n clicksmith mcp Run the read-only MCP stdio server\n clicksmith doctor Check daemon config and agent CLIs\n clicksmith version\n clicksmith help\n\nThe daemon binds loopback only and stores state under .clicksmith/ (in a repo)\nor your OS cache directory otherwise.\n`;\n\nasync function runDaemon(args: string[]): Promise<void> {\n const opts = parseFlags(args);\n const config = await resolveDaemonConfig({\n ...(opts.port ? { port: Number(opts.port) } : {}),\n ...(opts.host ? { host: opts.host } : {}),\n ...(opts.log ? { logLevel: opts.log as never } : {}),\n });\n const service = new DaemonService({ config });\n await service.init();\n const app = await buildServer(service);\n\n await app.listen({ host: config.host, port: config.port });\n config.logger.info(`daemon listening on http://${config.host}:${config.port}`);\n config.logger.debug(`storage: ${config.storageRoot}`);\n config.logger.debug(`repo: ${config.repoRoot ?? '(none — using OS cache)'}`);\n config.logger.debug(`agents: ${config.agents.agents.map((a) => a.id).join(', ')}`);\n\n const shutdown = async () => {\n config.logger.info('shutting down');\n await app.close();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nasync function runDoctor(args: string[]): Promise<void> {\n const opts = parseFlags(args);\n const config = await resolveDaemonConfig({\n ...(opts.port ? { port: Number(opts.port) } : {}),\n ...(opts.host ? { host: opts.host } : {}),\n logLevel: 'silent',\n });\n\n const lines: string[] = [];\n lines.push(`clicksmith ${version} doctor`);\n lines.push(`daemon URL : http://${config.host}:${config.port}`);\n lines.push(`cwd : ${config.cwd}`);\n lines.push(`repo : ${config.repoRoot ?? '(none)'}`);\n lines.push(`storage : ${config.storageRoot}`);\n lines.push(`PATH : ${process.env.PATH ?? '(empty)'}`);\n lines.push('');\n lines.push('Agents:');\n\n for (const agent of config.agents.agents) {\n const bins = agent.detect?.anyOf ?? [agent.command];\n const checks = await Promise.all(\n bins.map(async (bin) => ({ bin, ok: await defaultBinExists(bin) })),\n );\n const ok = checks.some((check) => check.ok);\n lines.push(` ${ok ? '✓' : '✗'} ${agent.id} (${agent.label ?? agent.command})`);\n lines.push(` command: ${agent.command}`);\n lines.push(\n ` checked: ${checks.map((check) => `${check.bin}${check.ok ? ' ✓' : ' ✗'}`).join(', ')}`,\n );\n if (!ok) {\n lines.push(\n ' fix: install the CLI on PATH, or edit .clicksmith/agents.config.json with an absolute command/detect path.',\n );\n }\n }\n\n process.stdout.write(`${lines.join('\\n')}\\n`);\n}\n\nfunction parseFlags(args: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (arg.startsWith('--')) {\n const key = arg.slice(2);\n const next = args[i + 1];\n if (next && !next.startsWith('--')) {\n out[key] = next;\n i++;\n } else {\n out[key] = 'true';\n }\n }\n }\n return out;\n}\n\nasync function main(): Promise<void> {\n const [command, ...rest] = process.argv.slice(2);\n switch (command) {\n case 'daemon':\n return runDaemon(rest);\n case 'mcp':\n return startMcp();\n case 'doctor':\n return runDoctor(rest);\n case 'version':\n case '--version':\n case '-v':\n process.stdout.write(`${version}\\n`);\n return;\n case undefined:\n case 'help':\n case '--help':\n case '-h':\n process.stdout.write(HELP);\n return;\n default:\n process.stderr.write(`Unknown command: ${command}\\n\\n${HELP}`);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`clicksmith failed: ${err instanceof Error ? err.stack : String(err)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ServerEvent, RunStatus, ExecutionMode, Isolation, SandboxInfo, CaptureBundle, Session, Enrichment, ApplyResponse, CaptureRequest, CaptureResponse, RemoveElementResponse, SubmitRequest, SubmitResponse, HealthResponse } from '@clicksmith/core';
|
|
1
|
+
import { ServerEvent, RunStatus, ExecutionMode, Isolation, SandboxInfo, CaptureBundle, Session, Enrichment, ApplyResponse, CaptureRequest, CaptureResponse, RemoveElementResponse, SubmitRequest, SubmitResponse, RunRequest, RunResponse, HealthResponse } from '@clicksmith/core';
|
|
2
2
|
import { AgentsConfig, CommandSpec } from '@clicksmith/agent-config';
|
|
3
3
|
import { FastifyInstance } from 'fastify';
|
|
4
4
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
@@ -187,6 +187,7 @@ interface RunManagerDeps {
|
|
|
187
187
|
declare class RunManager {
|
|
188
188
|
private readonly deps;
|
|
189
189
|
private readonly availabilityCache;
|
|
190
|
+
private _instructionFile;
|
|
190
191
|
constructor(deps: RunManagerDeps);
|
|
191
192
|
/**
|
|
192
193
|
* Prepare a sandbox and start an agent run. The sandbox is prepared
|
|
@@ -209,9 +210,8 @@ declare class RunManager {
|
|
|
209
210
|
private applyConflict;
|
|
210
211
|
private cleanupSandbox;
|
|
211
212
|
/**
|
|
212
|
-
* Resolve the instruction file passed to the agent.
|
|
213
|
-
*
|
|
214
|
-
* corpus before the targeted UI lookup has even started.
|
|
213
|
+
* Resolve the instruction file passed to the agent. Generated once per daemon
|
|
214
|
+
* session (content only varies by port) and reused across all runs.
|
|
215
215
|
*/
|
|
216
216
|
private resolveInstructionFile;
|
|
217
217
|
}
|
|
@@ -238,6 +238,8 @@ declare class DaemonService {
|
|
|
238
238
|
getSession(id: string): Promise<Session | undefined>;
|
|
239
239
|
/** Finalize a session into a bundle and start a run. */
|
|
240
240
|
submit(req: SubmitRequest): Promise<SubmitResponse>;
|
|
241
|
+
/** Fast path: create a run directly from elements + prompt, no prior session needed. */
|
|
242
|
+
run(req: RunRequest): Promise<RunResponse>;
|
|
241
243
|
apply(runId: string): Promise<ApplyResponse>;
|
|
242
244
|
health(): Promise<HealthResponse>;
|
|
243
245
|
}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clicksmith/daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "The ClickSmith localhost daemon: Fastify HTTP + WebSocket, MCP stdio server, persistence, git sandbox orchestration, and config-driven agent launching.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"execa": "^9.5.1",
|
|
25
25
|
"fastify": "^5.1.0",
|
|
26
26
|
"zod": "^3.23.8",
|
|
27
|
-
"@clicksmith/
|
|
28
|
-
"@clicksmith/
|
|
27
|
+
"@clicksmith/agent-config": "0.1.2",
|
|
28
|
+
"@clicksmith/core": "0.1.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.5.13",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/events.ts","../src/launcher.ts","../src/enrichment.ts","../src/run-manager.ts","../src/daemon-service.ts","../src/server.ts"],"sourcesContent":["import type { ServerEvent } from '@clicksmith/core';\n\ntype Listener = (event: ServerEvent) => void;\ninterface ReplayFilter {\n runId?: string;\n sessionId?: string;\n}\n\n/**\n * A tiny synchronous pub/sub for {@link ServerEvent}s. The Fastify WebSocket\n * layer subscribes to fan events out to connected extension clients; the run\n * manager publishes. Kept dependency-free and ordered (listeners fire in\n * registration order, events in emit order).\n */\nexport class EventBus {\n private readonly listeners = new Set<Listener>();\n private readonly history: ServerEvent[] = [];\n private readonly maxHistory: number;\n\n constructor(maxHistory = 500) {\n this.maxHistory = maxHistory;\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n emit(event: ServerEvent): void {\n this.history.push(event);\n if (this.history.length > this.maxHistory) this.history.shift();\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // A misbehaving listener must never break the emit loop.\n }\n }\n }\n\n /** Replay buffered events, scoped to a run or session to avoid noisy reconnects. */\n replay(filter: ReplayFilter = {}): ServerEvent[] {\n if (!filter.runId && !filter.sessionId) return [];\n return this.history.filter((event) => {\n if (filter.runId && 'runId' in event && event.runId === filter.runId) return true;\n if (filter.sessionId && 'sessionId' in event && event.sessionId === filter.sessionId) {\n return true;\n }\n return false;\n });\n }\n}\n","import { execa } from 'execa';\nimport type { CommandSpec } from '@clicksmith/agent-config';\n\nexport interface LaunchHandlers {\n onLog: (stream: 'stdout' | 'stderr', chunk: string) => void;\n signal?: AbortSignal;\n}\n\nexport interface LaunchResult {\n exitCode: number;\n stdout: string;\n canceled: boolean;\n}\n\n/**\n * Spawn a resolved {@link CommandSpec} with execa, streaming stdout/stderr to\n * the caller as they arrive. Never rejects on non-zero exit — the run manager\n * decides what a non-zero code means.\n */\nexport async function launchAgent(\n spec: CommandSpec,\n handlers: LaunchHandlers,\n): Promise<LaunchResult> {\n const subprocess = execa(spec.command, spec.args, {\n cwd: spec.cwd,\n env: { ...process.env, ...spec.env },\n stdin: 'ignore',\n reject: false,\n all: false,\n cancelSignal: handlers.signal,\n });\n\n let stdout = '';\n subprocess.stdout?.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdout += chunk;\n handlers.onLog('stdout', chunk);\n });\n subprocess.stderr?.on('data', (data: Buffer) => {\n handlers.onLog('stderr', data.toString());\n });\n\n const result = await subprocess;\n return {\n exitCode: result.exitCode ?? (result.isCanceled ? 130 : 0),\n stdout,\n canceled: Boolean(result.isCanceled),\n };\n}\n","import type { CaptureBundle, Enrichment } from '@clicksmith/core';\n\n/**\n * Pluggable, best-effort enrichment. When configured (e.g. backed by the\n * code-review-graph MCP), it resolves source locators to attach review context\n * and impact radius per element. Failures must be **non-blocking**: the run\n * manager catches errors and records them as warnings on the bundle.\n */\nexport interface EnrichmentProvider {\n id: string;\n enrich(bundle: CaptureBundle): Promise<Enrichment | null>;\n}\n\n/**\n * Apply an enrichment provider to a bundle, swallowing failures into warnings.\n * Returns a (possibly) new bundle; never throws.\n */\nexport async function enrichBundle(\n bundle: CaptureBundle,\n provider: EnrichmentProvider | undefined,\n): Promise<CaptureBundle> {\n if (!provider) return bundle;\n try {\n const enrichment = await provider.enrich(bundle);\n if (!enrichment) return bundle;\n return { ...bundle, enrichment };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n ...bundle,\n enrichment: {\n source: 'code-review-graph',\n perElement: bundle.enrichment?.perElement ?? [],\n warnings: [...(bundle.enrichment?.warnings ?? []), `enrichment failed: ${message}`],\n },\n };\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n configToAdapter,\n defaultBinExists,\n renderInstructionBody,\n resolveAgent,\n type AgentAdapter,\n type AgentConfig,\n type AgentLaunchContext,\n} from '@clicksmith/agent-config';\nimport {\n newRunId,\n type ApplyResponse,\n type CaptureBundle,\n type CapturedElement,\n type SandboxInfo,\n} from '@clicksmith/core';\nimport { describeSandbox, Git } from './git.js';\nimport { launchAgent } from './launcher.js';\nimport { enrichBundle, type EnrichmentProvider } from './enrichment.js';\nimport type { EventBus } from './events.js';\nimport type { FileStore } from './store.js';\nimport type { Logger } from './logger.js';\nimport type { DaemonConfig } from './config.js';\nimport type { RunRecord } from './types.js';\n\n/** Raised when a non-inplace run is requested against a dirty working tree. */\nexport class RefusalError extends Error {\n readonly code = 'DIRTY_TREE';\n}\n\nexport interface RunManagerDeps {\n store: FileStore;\n config: DaemonConfig;\n bus: EventBus;\n logger: Logger;\n enrichment?: EnrichmentProvider;\n /** Override PATH probing (tests inject a fake). */\n binExists?: (bin: string) => Promise<boolean>;\n}\n\nconst COMMIT_PREFIX = 'ClickSmith';\nconst POSITIVE_AVAILABILITY_CACHE_MS = 60_000;\nconst NEGATIVE_AVAILABILITY_CACHE_MS = 5_000;\nconst LOG_FLUSH_MS = 75;\nconst LOG_FLUSH_BYTES = 16 * 1024;\n\ninterface AvailabilityCacheEntry {\n ok: boolean;\n expiresAt: number;\n}\n\nexport class RunManager {\n private readonly availabilityCache = new Map<string, AvailabilityCacheEntry>();\n\n constructor(private readonly deps: RunManagerDeps) {}\n\n /**\n * Prepare a sandbox and start an agent run. The sandbox is prepared\n * synchronously so a dirty-tree refusal surfaces as an error to the caller;\n * the agent itself runs in the background, emitting WebSocket events.\n */\n async createRun(input: CaptureBundle): Promise<{ run: RunRecord }> {\n const { store, config, bus, logger } = this.deps;\n const agentConfig = resolveAgent(config.agents, input.execution.agentId);\n if (!agentConfig) {\n throw new RefusalError(\n `No agent configured (requested: ${input.execution.agentId ?? 'default'}).`,\n );\n }\n\n const runId = newRunId();\n const now = new Date();\n const repoRoot = config.repoRoot;\n const isolation = repoRoot ? input.execution.isolation : 'inplace';\n\n let sandbox: SandboxInfo | null = null;\n let baseCommit: string | null = null;\n let baseBranch: string | null = null;\n\n if (repoRoot) {\n const git = new Git(repoRoot);\n [baseCommit, baseBranch] = await Promise.all([\n git.headCommit(),\n safe(() => git.currentBranch()),\n ]);\n const baseRef = input.execution.baseRef ?? baseCommit;\n\n if (\n isolation !== 'inplace' &&\n (await git.isDirty({ exclude: ['.clicksmith/', '.clicksmith'] }))\n ) {\n throw new RefusalError(\n `Refusing to run in ${isolation} isolation: the working tree has uncommitted changes. ` +\n `Commit or stash them, or use inplace isolation explicitly.`,\n );\n }\n sandbox = await this.prepareSandbox(\n git,\n runId,\n isolation,\n baseRef,\n repoRoot,\n baseCommit,\n logger,\n );\n }\n\n const enriched = await enrichBundle(input, this.deps.enrichment);\n await store.saveBundle(runId, enriched);\n\n const run: RunRecord = {\n runId,\n sessionId: enriched.sessionId,\n agentId: agentConfig.id,\n status: 'running',\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n mode: enriched.execution.mode,\n isolation,\n prompt: enriched.prompt,\n repoRoot,\n baseCommit,\n baseBranch,\n sandbox,\n revert: null,\n };\n await store.saveRun(run);\n\n bus.emit({\n type: 'agent-started',\n runId,\n sessionId: run.sessionId,\n agentId: run.agentId,\n sandbox,\n });\n\n // Fire-and-forget the actual agent execution.\n void this.execute(run, enriched, agentConfig).catch((err) => {\n logger.error(`run ${runId} crashed`, err);\n });\n\n return { run };\n }\n\n private async prepareSandbox(\n git: Git,\n runId: string,\n isolation: SandboxInfo['isolation'],\n baseRef: string,\n repoRoot: string,\n baseCommit: string,\n logger: Logger,\n ): Promise<SandboxInfo> {\n const branch = `clicksmith/${runId}`;\n if (isolation === 'inplace') {\n return describeSandbox('inplace', repoRoot, null, baseCommit);\n }\n if (isolation === 'worktree') {\n if (await git.supportsWorktree()) {\n const path = this.deps.store.paths.sandboxDir(runId);\n await mkdir(join(path, '..'), { recursive: true });\n await git.createWorktree(path, branch, baseRef);\n return describeSandbox('worktree', path, branch, baseCommit);\n }\n logger.warn('git worktrees unavailable; falling back to a dedicated branch');\n }\n // branch isolation (explicit or worktree fallback)\n await git.createBranch(branch, baseRef);\n return describeSandbox('branch', repoRoot, branch, baseCommit);\n }\n\n private async execute(\n run: RunRecord,\n bundle: CaptureBundle,\n agentConfig: AgentConfig,\n ): Promise<void> {\n const { store, config, bus, logger } = this.deps;\n const sandboxPath = run.sandbox?.path ?? config.cwd;\n\n const instructionFile = await this.resolveInstructionFile(run);\n const agentPrompt = buildAgentPrompt({\n bundle,\n bundlePath: store.bundlePath(run.runId),\n run,\n });\n const ctx: AgentLaunchContext = {\n bundlePath: store.bundlePath(run.runId),\n prompt: bundle.prompt,\n agentPrompt,\n instructionFile,\n mode: bundle.execution.mode,\n mcpServer: 'clicksmith',\n cwd: sandboxPath,\n isolation: run.isolation,\n agentId: agentConfig.id,\n binExists: this.deps.binExists ?? defaultBinExists,\n };\n\n const adapter = configToAdapter(agentConfig);\n if (!(await this.isAgentAvailable(agentConfig, adapter, ctx))) {\n await this.fail(run, unavailableMessage(agentConfig));\n return;\n }\n\n const rawSpec = adapter.buildCommand(ctx);\n const spec = {\n ...rawSpec,\n env: {\n CLICKSMITH_BUNDLE_PATH: ctx.bundlePath,\n CLICKSMITH_INSTRUCTION_FILE: ctx.instructionFile,\n CLICKSMITH_MODE: ctx.mode,\n CLICKSMITH_ISOLATION: ctx.isolation,\n CLICKSMITH_RUN_ID: run.runId,\n ...(rawSpec.env ?? {}),\n },\n };\n logger.info(`run ${run.runId}: ${spec.command} ${spec.args.join(' ')}`);\n\n const logBuffer = createLogBuffer(\n (chunk) => store.appendLog(run.runId, chunk),\n (err) => logger.warn(`run ${run.runId}: failed to persist agent log`, err),\n );\n\n let result;\n try {\n result = await launchAgent(spec, {\n onLog: (stream, chunk) => {\n logBuffer.append(chunk);\n bus.emit({ type: 'agent-log', runId: run.runId, stream, chunk });\n },\n });\n } catch (err) {\n await logBuffer.flush();\n await this.fail(run, err instanceof Error ? err.message : String(err));\n return;\n }\n await logBuffer.flush();\n\n // Capture artifacts from isolated sandboxes. Inplace runs edit the current\n // tree directly, so the extension does not need a daemon-generated patch.\n const plan = result.stdout.trim();\n let diff = '';\n if (run.sandbox && run.repoRoot && run.sandbox.isolation !== 'inplace') {\n diff = await Git.captureDiff(run.sandbox.path);\n }\n if (plan) await store.writeArtifact(run.runId, 'plan.md', plan);\n if (diff) await store.writeArtifact(run.runId, 'diff.patch', diff);\n\n run.exitCode = result.exitCode;\n run.hasPlan = plan.length > 0;\n run.hasDiff = diff.length > 0;\n\n if (result.exitCode !== 0) {\n await this.fail(run, `Agent exited with code ${result.exitCode}.`);\n return;\n }\n\n run.status = 'plan-ready';\n run.updatedAt = new Date().toISOString();\n await store.saveRun(run);\n bus.emit({\n type: 'plan-ready',\n runId: run.runId,\n ...(plan ? { plan } : {}),\n ...(diff ? { diff } : {}),\n });\n bus.emit({ type: 'agent-done', runId: run.runId, exitCode: result.exitCode });\n\n if (bundle.execution.autoApply) {\n logger.info(`run ${run.runId}: autoApply enabled, applying`);\n await this.apply(run.runId);\n }\n }\n\n private async fail(run: RunRecord, message: string): Promise<void> {\n run.status = 'error';\n run.error = message;\n run.updatedAt = new Date().toISOString();\n await this.deps.store.saveRun(run);\n this.deps.bus.emit({ type: 'agent-error', runId: run.runId, message });\n }\n\n private async isAgentAvailable(\n agentConfig: AgentConfig,\n adapter: AgentAdapter,\n ctx: AgentLaunchContext,\n ): Promise<boolean> {\n const key = availabilityCacheKey(agentConfig);\n const now = Date.now();\n const cached = this.availabilityCache.get(key);\n if (cached && cached.expiresAt > now) return cached.ok;\n\n const ok = await adapter.isAvailable(ctx);\n this.availabilityCache.set(key, {\n ok,\n expiresAt: now + (ok ? POSITIVE_AVAILABILITY_CACHE_MS : NEGATIVE_AVAILABILITY_CACHE_MS),\n });\n return ok;\n }\n\n /**\n * Merge a finished run's sandbox changes back into the working tree. Reports\n * conflicts, commits on success, records revert metadata, and cleans up the\n * sandbox.\n */\n async apply(runId: string): Promise<ApplyResponse> {\n const { store, bus, logger } = this.deps;\n const run = await store.getRun(runId);\n if (!run) throw new Error(`Unknown run: ${runId}`);\n if (!run.repoRoot || !run.sandbox) {\n throw new Error(`Run ${runId} has no git sandbox to apply.`);\n }\n\n bus.emit({ type: 'apply-started', runId });\n const git = new Git(run.repoRoot);\n const previousHead = await git.headCommit();\n const message = `${COMMIT_PREFIX} run ${runId}: ${truncate(run.prompt, 72)}`;\n\n try {\n let commit: string | undefined;\n\n if (run.sandbox.isolation === 'worktree') {\n const diff = (await store.readArtifact(runId, 'diff.patch')) ?? '';\n const applied = await git.applyPatch(diff);\n if (!applied.ok) return await this.applyConflict(run, applied.conflicts);\n commit = diff.trim() ? await git.commit(message) : previousHead;\n await this.cleanupSandbox(run);\n } else if (run.sandbox.isolation === 'branch') {\n // Changes are already staged in the repo on the clicksmith branch.\n if (await git.hasChanges()) await git.commit(message);\n if (run.baseBranch) await git.switchTo(run.baseBranch);\n const merged = await git.merge(run.sandbox.branch!, message);\n if (!merged.ok) return await this.applyConflict(run, merged.conflicts);\n commit = await git.headCommit();\n await git.deleteBranch(run.sandbox.branch!);\n } else {\n // inplace: commit whatever the agent changed in the working tree.\n commit = (await git.hasChanges()) ? await git.commit(message) : previousHead;\n }\n\n run.status = 'applied';\n run.applied = { ...(commit ? { commit } : {}), at: new Date().toISOString() };\n run.revert = {\n previousHead,\n ...(commit && commit !== previousHead ? { appliedCommit: commit } : {}),\n instructions:\n commit && commit !== previousHead\n ? `git revert ${commit} # or: git reset --hard ${previousHead}`\n : 'No commit was created; nothing to revert.',\n };\n run.updatedAt = new Date().toISOString();\n await store.saveRun(run);\n\n bus.emit({ type: 'apply-done', runId, ...(commit ? { commit } : {}) });\n return { applied: true, ...(commit ? { commit } : {}) };\n } catch (err) {\n const messageText = err instanceof Error ? err.message : String(err);\n logger.error(`apply ${runId} failed`, messageText);\n run.status = 'apply-error';\n run.error = messageText;\n await store.saveRun(run);\n bus.emit({ type: 'apply-error', runId, message: messageText });\n return { applied: false };\n }\n }\n\n private async applyConflict(run: RunRecord, conflicts: string[]): Promise<ApplyResponse> {\n run.status = 'apply-error';\n run.error = `Apply conflicts in: ${conflicts.join(', ') || 'unknown files'}`;\n run.updatedAt = new Date().toISOString();\n await this.deps.store.saveRun(run);\n this.deps.bus.emit({\n type: 'apply-error',\n runId: run.runId,\n message: run.error,\n conflicts,\n });\n return { applied: false, conflicts };\n }\n\n private async cleanupSandbox(run: RunRecord): Promise<void> {\n if (!run.repoRoot || !run.sandbox) return;\n if (run.sandbox.isolation === 'worktree') {\n const git = new Git(run.repoRoot);\n await git.removeWorktree(run.sandbox.path, run.sandbox.branch ?? undefined);\n }\n }\n\n /**\n * Resolve the instruction file passed to the agent. Use a run-local compact\n * file so ClickSmith runs do not ingest a project's full AGENTS/CLAUDE/rules\n * corpus before the targeted UI lookup has even started.\n */\n private async resolveInstructionFile(run: RunRecord): Promise<string> {\n const { config, store } = this.deps;\n const body = renderInstructionBody({ daemonPort: config.port });\n return store.writeArtifact(run.runId, 'AGENT_INSTRUCTIONS.md', body);\n }\n}\n\nasync function safe<T>(fn: () => Promise<T>): Promise<T | null> {\n try {\n return await fn();\n } catch {\n return null;\n }\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length <= n ? s : `${s.slice(0, n - 1)}…`;\n}\n\nfunction unavailableMessage(agentConfig: AgentConfig): string {\n const checked = agentConfig.detect?.anyOf ?? [agentConfig.command];\n return (\n `Agent \"${agentConfig.id}\" is not available to the ClickSmith daemon. ` +\n `Checked: ${checked.join(', ')}. ` +\n `Install the agent CLI so it is on the daemon PATH, or set command/detect to an absolute path in .clicksmith/agents.config.json.`\n );\n}\n\nfunction availabilityCacheKey(agentConfig: AgentConfig): string {\n return [\n agentConfig.id,\n agentConfig.command,\n ...(agentConfig.detect?.anyOf ?? [agentConfig.command]),\n ].join('\\0');\n}\n\nfunction createLogBuffer(\n write: (chunk: string) => Promise<void>,\n onError: (err: unknown) => void,\n): { append: (chunk: string) => void; flush: () => Promise<void> } {\n let buffer = '';\n let timer: ReturnType<typeof setTimeout> | null = null;\n let flushChain = Promise.resolve();\n\n async function flush(): Promise<void> {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n if (!buffer) return flushChain;\n\n const chunk = buffer;\n buffer = '';\n flushChain = flushChain.then(() => write(chunk)).catch(onError);\n await flushChain;\n }\n\n return {\n append(chunk) {\n buffer += chunk;\n if (buffer.length >= LOG_FLUSH_BYTES) {\n void flush();\n } else if (!timer) {\n timer = setTimeout(() => void flush(), LOG_FLUSH_MS);\n }\n },\n flush,\n };\n}\n\nfunction buildAgentPrompt(input: {\n bundle: CaptureBundle;\n bundlePath: string;\n run: RunRecord;\n}): string {\n const { bundle, bundlePath, run } = input;\n const targets = bundle.elements.map(formatTargetSummary).join('\\n');\n const firstActions = buildFirstActions(bundle, bundlePath).map((action, index) => {\n return `${index + 1}. ${action}`;\n });\n const modeLine =\n bundle.execution.mode === 'edit'\n ? 'Mode: edit. Make the smallest working-tree change; do not ask for confirmation.'\n : 'Mode: plan. Inspect only and return a concise plan.';\n\n return [\n 'ClickSmith fast UI edit.',\n `Request: ${truncateLine(bundle.prompt, 300)}`,\n `Route: ${truncateLine(bundle.app.route, 160)}`,\n `Cwd: ${run.sandbox?.path ?? run.repoRoot ?? '(none)'}`,\n `Isolation: ${run.isolation}`,\n '',\n 'Targets:',\n targets,\n '',\n 'First actions (do these before reading broad project docs):',\n ...firstActions,\n '',\n 'Fast-path rules:',\n '- Do not read AGENTS.md, CLAUDE.md, .cursor/rules, skills, guidelines, or bundle.json first.',\n '- If source file:line exists, open only that file around the line; no grep needed.',\n '- Otherwise run at most two targeted grep searches from First actions, then edit the smallest file.',\n '- If a grep result is only a shared sprite/icon definition, use it to find the component usage.',\n `- Fallback only if the target is still ambiguous: ${bundlePath}`,\n '- Keep final output brief: changed files and checks run.',\n '',\n modeLine,\n ].join('\\n');\n}\n\nfunction formatTargetSummary(element: CapturedElement): string {\n const label = element.el.text || element.el.label || element.el.role || element.el.tag;\n const attrs = formatAttrs(element.el.attrs);\n const locator = formatLocator(element);\n const near = formatNear(element);\n const tokens = collectElementSearchTokens(element).slice(0, 5);\n return [\n `#${element.id} <${element.el.tag}> ${quoteText(label)}`,\n `locator=${locator}`,\n attrs ? `attrs=${attrs}` : '',\n near ? `near=${near}` : '',\n tokens.length ? `tokens=${tokens.map(quoteText).join(', ')}` : '',\n ]\n .filter(Boolean)\n .join(' | ');\n}\n\nfunction formatLocator(element: CapturedElement): string {\n const { locator } = element;\n if (locator.kind === 'source') {\n return `source:${locator.file}:${locator.line}${locator.column != null ? `:${locator.column}` : ''}`;\n }\n if (locator.kind === 'attr') {\n return `attr:${locator.attr}=${quoteText(locator.value)}`;\n }\n if (locator.kind === 'behavioral') {\n return `behavioral:${locator.role} ${quoteText(locator.name)}`;\n }\n return `dom:${truncateLine(locator.selector, 120)}`;\n}\n\nfunction formatAttrs(attrs: Record<string, string>): string {\n return Object.entries(attrs)\n .slice(0, 5)\n .map(([key, value]) => `${key}=${quoteText(value)}`)\n .join(' ');\n}\n\nfunction formatNear(element: CapturedElement): string {\n return [\n ...(element.near.labels ?? []).slice(0, 1).map((label) => `label=${quoteText(label)}`),\n ...(element.near.headings ?? []).slice(0, 1).map((heading) => `heading=${quoteText(heading)}`),\n ...(element.near.landmarks ?? []).slice(0, 1).map((landmark) => `landmark=${quoteText(landmark)}`),\n ].join(' ');\n}\n\nfunction buildFirstActions(bundle: CaptureBundle, bundlePath: string): string[] {\n const sourceActions = bundle.elements\n .filter((element) => element.locator.kind === 'source')\n .map((element) => {\n if (element.locator.kind !== 'source') return '';\n const start = Math.max(1, element.locator.line - 30);\n const end = element.locator.line + 30;\n return `Open #${element.id} source ${element.locator.file}:${element.locator.line} (for example: sed -n '${start},${end}p' ${shellQuote(element.locator.file)}).`;\n })\n .filter(Boolean);\n if (sourceActions.length) return sourceActions.slice(0, 2);\n\n const tokens = collectBundleSearchTokens(bundle);\n const actions: string[] = [];\n if (tokens.length) {\n actions.push(`git grep -n ${tokens.slice(0, 2).map((token) => `-e ${shellQuote(token)}`).join(' ')} -- . 2>/dev/null || true`);\n }\n if (tokens.length > 2) {\n actions.push(`git grep -n ${tokens.slice(2, 4).map((token) => `-e ${shellQuote(token)}`).join(' ')} -- . 2>/dev/null || true`);\n }\n if (actions.length) return actions;\n\n return [`No exact token captured. Read the fallback bundle once: ${bundlePath}`];\n}\n\nfunction collectBundleSearchTokens(bundle: CaptureBundle): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n const add = (token: string) => {\n const key = token.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(token);\n };\n\n for (const element of bundle.elements) {\n for (const token of collectElementSearchTokens(element)) add(token);\n }\n return out.slice(0, 8);\n}\n\nfunction collectElementSearchTokens(element: CapturedElement): string[] {\n const tokens: string[] = [];\n const add = (value: string | undefined) => {\n for (const token of searchTokenVariants(value)) {\n if (!tokens.some((existing) => existing.toLowerCase() === token.toLowerCase())) {\n tokens.push(token);\n }\n }\n };\n\n if (element.locator.kind === 'attr') add(element.locator.value);\n if (element.locator.kind === 'behavioral') add(element.locator.name);\n for (const token of clicksmithHintTokens(element)) add(token);\n for (const value of Object.values(element.el.attrs)) add(value);\n for (const token of element.el.iconHints ?? []) add(token);\n add(element.el.label);\n add(element.el.text);\n for (const label of element.near.labels ?? []) add(label);\n for (const heading of element.near.headings ?? []) add(heading);\n add(element.near.parentText);\n\n return tokens.slice(0, 10);\n}\n\nfunction clicksmithHintTokens(element: CapturedElement): string[] {\n const raw = element.frameworkHints?.clicksmith;\n if (!isRecord(raw)) return [];\n const tokens = raw.searchTokens;\n return Array.isArray(tokens) ? tokens.filter((token): token is string => typeof token === 'string') : [];\n}\n\nfunction searchTokenVariants(value: string | undefined): string[] {\n if (!value) return [];\n const normalized = value.trim().replace(/\\s+/g, ' ');\n if (!normalized || normalized.length > 120) return [];\n const variants = [normalized];\n if (normalized.startsWith('#') && normalized.length > 1) variants.unshift(normalized.slice(1));\n if (normalized.includes('/') && !normalized.includes(' ')) {\n variants.push(normalized.split('/').filter(Boolean).at(-1) ?? '');\n }\n return variants\n .map((token) => token.trim().replace(/^[\"'`#]+|[\"'`]+$/g, ''))\n .filter((token) => token.length >= 3 && token.length <= 80)\n .filter((token) => !COMMON_SEARCH_TOKENS.has(token.toLowerCase()));\n}\n\nfunction quoteText(value: string): string {\n return JSON.stringify(truncateLine(value, 120));\n}\n\nfunction truncateLine(value: string, max: number): string {\n const oneLine = value.replace(/\\s+/g, ' ').trim();\n return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 3)}...`;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nconst COMMON_SEARCH_TOKENS = new Set([\n 'button',\n 'click',\n 'div',\n 'false',\n 'icon',\n 'input',\n 'label',\n 'link',\n 'main',\n 'section',\n 'span',\n 'svg',\n 'true',\n 'use',\n]);\n","import {\n appendElement,\n createSession,\n ExecutionOptionsSchema,\n finalizeSession,\n removeElement,\n touchSession,\n type ApplyResponse,\n type CaptureRequest,\n type CaptureResponse,\n type HealthResponse,\n type RemoveElementResponse,\n type Session,\n type SubmitRequest,\n type SubmitResponse,\n} from '@clicksmith/core';\nimport { EventBus } from './events.js';\nimport { FileStore } from './store.js';\nimport { RunManager, type RunManagerDeps } from './run-manager.js';\nimport type { DaemonConfig } from './config.js';\nimport type { EnrichmentProvider } from './enrichment.js';\nimport { version as DAEMON_VERSION } from './version.js';\n\nexport interface DaemonServiceOptions {\n config: DaemonConfig;\n enrichment?: EnrichmentProvider;\n binExists?: RunManagerDeps['binExists'];\n}\n\n/**\n * The framework-agnostic core of the daemon. The HTTP/WS server and tests both\n * drive this; it owns sessions, runs, the event bus, and persistence.\n */\nexport class DaemonService {\n readonly config: DaemonConfig;\n readonly store: FileStore;\n readonly bus: EventBus;\n readonly runs: RunManager;\n\n constructor(opts: DaemonServiceOptions) {\n this.config = opts.config;\n this.store = new FileStore(opts.config.storageRoot);\n this.bus = new EventBus();\n this.runs = new RunManager({\n store: this.store,\n config: opts.config,\n bus: this.bus,\n logger: opts.config.logger,\n ...(opts.enrichment ? { enrichment: opts.enrichment } : {}),\n ...(opts.binExists ? { binExists: opts.binExists } : {}),\n });\n }\n\n async init(): Promise<void> {\n await this.store.init();\n await this.store.cleanupExpired();\n }\n\n /* ------------------------------- capture ------------------------------ */\n\n /** Create or append to the active session for an app/route. */\n async capture(req: CaptureRequest): Promise<CaptureResponse> {\n const now = new Date();\n let session = req.sessionId ? await this.store.getSession(req.sessionId) : undefined;\n if (!session) {\n session = createSession({ app: req.app, now, ttlMs: this.config.ttlMs });\n } else {\n session = touchSession(session, now, this.config.ttlMs);\n }\n\n const { session: next, element } = appendElement(session, req.element, now);\n await this.store.saveSession(next);\n\n this.bus.emit({ type: 'capture-ack', sessionId: next.id, element });\n return { sessionId: next.id, element };\n }\n\n async removeElement(sessionId: string, elementId: number): Promise<RemoveElementResponse> {\n const session = await this.store.getSession(sessionId);\n if (!session) return { removed: false };\n const { session: next, removed } = removeElement(session, elementId);\n if (removed) {\n await this.store.saveSession(next);\n this.bus.emit({ type: 'element-removed', sessionId, elementId });\n }\n return { removed };\n }\n\n async getSession(id: string): Promise<Session | undefined> {\n return this.store.getSession(id);\n }\n\n /* ------------------------------- submit ------------------------------- */\n\n /** Finalize a session into a bundle and start a run. */\n async submit(req: SubmitRequest): Promise<SubmitResponse> {\n const session = await this.store.getSession(req.sessionId);\n if (!session) throw new NotFoundError(`Unknown session: ${req.sessionId}`);\n\n const execution = ExecutionOptionsSchema.parse(req.execution ?? {});\n const bundle = finalizeSession(session, {\n prompt: req.prompt,\n execution,\n ...(req.enrichment ? { enrichment: req.enrichment } : {}),\n });\n\n const submitted: Session = { ...session, status: 'submitted', prompt: req.prompt };\n await this.store.saveSession(submitted);\n\n const { run } = await this.runs.createRun(bundle);\n return { runId: run.runId, bundle };\n }\n\n async apply(runId: string): Promise<ApplyResponse> {\n return this.runs.apply(runId);\n }\n\n /* ------------------------------- health ------------------------------- */\n\n async health(): Promise<HealthResponse> {\n const sessions = await this.store.listSessions();\n return {\n ok: true,\n name: 'clicksmith-daemon',\n version: DAEMON_VERSION,\n host: this.config.host,\n port: this.config.port,\n repoRoot: this.config.repoRoot,\n activeSessions: sessions.filter((s) => s.status === 'active').length,\n };\n }\n}\n\nexport class NotFoundError extends Error {\n readonly code = 'NOT_FOUND';\n}\n","import Fastify, { type FastifyInstance } from 'fastify';\nimport websocket from '@fastify/websocket';\nimport {\n CaptureRequestSchema,\n SubmitRequestSchema,\n type ClientMessage,\n type ServerEvent,\n} from '@clicksmith/core';\nimport { type DaemonService, NotFoundError } from './daemon-service.js';\nimport { RefusalError } from './run-manager.js';\n\ntype SubscribeMessage = Extract<ClientMessage, { type: 'subscribe' }> & { runId?: string };\n\n/**\n * Build the Fastify app exposing ClickSmith's HTTP + WebSocket surface on top\n * of a {@link DaemonService}. Binds loopback only; CORS is opened for localhost\n * so the browser extension can talk to it.\n */\nexport async function buildServer(service: DaemonService): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n\n // Minimal CORS for the extension (loopback only).\n app.addHook('onRequest', async (req, reply) => {\n reply.header('Access-Control-Allow-Origin', '*');\n reply.header('Access-Control-Allow-Methods', 'GET,POST,DELETE,OPTIONS');\n reply.header('Access-Control-Allow-Headers', 'content-type');\n if (req.method === 'OPTIONS') {\n reply.code(204).send();\n }\n });\n\n await app.register(websocket);\n\n /* ------------------------------- HTTP -------------------------------- */\n\n app.get('/health', async () => service.health());\n\n app.post('/capture', async (req, reply) => {\n const parsed = CaptureRequestSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });\n return service.capture(parsed.data);\n });\n\n app.post('/submit', async (req, reply) => {\n const parsed = SubmitRequestSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.message });\n try {\n return await service.submit(parsed.data);\n } catch (err) {\n if (err instanceof NotFoundError) return reply.code(404).send({ error: err.message });\n if (err instanceof RefusalError)\n return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n app.post<{ Params: { runId: string } }>('/apply/:runId', async (req, reply) => {\n try {\n return await service.apply(req.params.runId);\n } catch (err) {\n return reply.code(404).send({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.get<{ Params: { id: string } }>('/session/:id', async (req, reply) => {\n const session = await service.getSession(req.params.id);\n if (!session) return reply.code(404).send({ error: `Unknown session: ${req.params.id}` });\n return session;\n });\n\n app.delete<{ Params: { sessionId: string; elementId: string } }>(\n '/element/:sessionId/:elementId',\n async (req) => {\n const elementId = Number.parseInt(req.params.elementId, 10);\n return service.removeElement(req.params.sessionId, elementId);\n },\n );\n\n /* ----------------------------- WebSocket ----------------------------- */\n\n app.get('/ws', { websocket: true }, (socket) => {\n const send = (event: ServerEvent) => {\n if (socket.readyState === socket.OPEN) socket.send(JSON.stringify(event));\n };\n const unsubscribe = service.bus.subscribe(send);\n\n socket.on('message', (raw: Buffer) => {\n let msg: ClientMessage;\n try {\n msg = JSON.parse(raw.toString()) as ClientMessage;\n } catch {\n return;\n }\n if (msg.type === 'ping') socket.send(JSON.stringify({ type: 'pong' }));\n else if (msg.type === 'subscribe') {\n // Replay only the run/session the client asks for. Unscoped replay can\n // flood reconnecting extension workers with unrelated historical logs.\n const sub = msg as SubscribeMessage;\n for (const event of service.bus.replay({ runId: sub.runId, sessionId: sub.sessionId })) {\n send(event);\n }\n }\n });\n\n socket.on('close', unsubscribe);\n socket.on('error', unsubscribe);\n });\n\n return app;\n}\n"],"mappings":";;;;;;;;AAcO,IAAM,WAAN,MAAe;AAAA,EACH,YAAY,oBAAI,IAAc;AAAA,EAC9B,UAAyB,CAAC;AAAA,EAC1B;AAAA,EAEjB,YAAY,aAAa,KAAK;AAC5B,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,UAAU,UAAgC;AACxC,SAAK,UAAU,IAAI,QAAQ;AAC3B,WAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA,EAC7C;AAAA,EAEA,KAAK,OAA0B;AAC7B,SAAK,QAAQ,KAAK,KAAK;AACvB,QAAI,KAAK,QAAQ,SAAS,KAAK,WAAY,MAAK,QAAQ,MAAM;AAC9D,eAAW,YAAY,KAAK,WAAW;AACrC,UAAI;AACF,iBAAS,KAAK;AAAA,MAChB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,SAAuB,CAAC,GAAkB;AAC/C,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,UAAW,QAAO,CAAC;AAChD,WAAO,KAAK,QAAQ,OAAO,CAAC,UAAU;AACpC,UAAI,OAAO,SAAS,WAAW,SAAS,MAAM,UAAU,OAAO,MAAO,QAAO;AAC7E,UAAI,OAAO,aAAa,eAAe,SAAS,MAAM,cAAc,OAAO,WAAW;AACpF,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;ACnDA,SAAS,aAAa;AAmBtB,eAAsB,YACpB,MACA,UACuB;AACvB,QAAM,aAAa,MAAM,KAAK,SAAS,KAAK,MAAM;AAAA,IAChD,KAAK,KAAK;AAAA,IACV,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,KAAK,IAAI;AAAA,IACnC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,cAAc,SAAS;AAAA,EACzB,CAAC;AAED,MAAI,SAAS;AACb,aAAW,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AAC9C,UAAM,QAAQ,KAAK,SAAS;AAC5B,cAAU;AACV,aAAS,MAAM,UAAU,KAAK;AAAA,EAChC,CAAC;AACD,aAAW,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AAC9C,aAAS,MAAM,UAAU,KAAK,SAAS,CAAC;AAAA,EAC1C,CAAC;AAED,QAAM,SAAS,MAAM;AACrB,SAAO;AAAA,IACL,UAAU,OAAO,aAAa,OAAO,aAAa,MAAM;AAAA,IACxD;AAAA,IACA,UAAU,QAAQ,OAAO,UAAU;AAAA,EACrC;AACF;;;AC/BA,eAAsB,aACpB,QACA,UACwB;AACxB,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI;AACF,UAAM,aAAa,MAAM,SAAS,OAAO,MAAM;AAC/C,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,EAAE,GAAG,QAAQ,WAAW;AAAA,EACjC,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,QACV,QAAQ;AAAA,QACR,YAAY,OAAO,YAAY,cAAc,CAAC;AAAA,QAC9C,UAAU,CAAC,GAAI,OAAO,YAAY,YAAY,CAAC,GAAI,sBAAsB,OAAO,EAAE;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AACF;;;ACrCA,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,OAKK;AAWA,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC7B,OAAO;AAClB;AAYA,IAAM,gBAAgB;AACtB,IAAM,iCAAiC;AACvC,IAAM,iCAAiC;AACvC,IAAM,eAAe;AACrB,IAAM,kBAAkB,KAAK;AAOtB,IAAM,aAAN,MAAiB;AAAA,EAGtB,YAA6B,MAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAFZ,oBAAoB,oBAAI,IAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS7E,MAAM,UAAU,OAAmD;AACjE,UAAM,EAAE,OAAO,QAAQ,KAAK,OAAO,IAAI,KAAK;AAC5C,UAAM,cAAc,aAAa,OAAO,QAAQ,MAAM,UAAU,OAAO;AACvE,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI;AAAA,QACR,mCAAmC,MAAM,UAAU,WAAW,SAAS;AAAA,MACzE;AAAA,IACF;AAEA,UAAM,QAAQ,SAAS;AACvB,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,WAAW,OAAO;AACxB,UAAM,YAAY,WAAW,MAAM,UAAU,YAAY;AAEzD,QAAI,UAA8B;AAClC,QAAI,aAA4B;AAChC,QAAI,aAA4B;AAEhC,QAAI,UAAU;AACZ,YAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,OAAC,YAAY,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3C,IAAI,WAAW;AAAA,QACf,KAAK,MAAM,IAAI,cAAc,CAAC;AAAA,MAChC,CAAC;AACD,YAAM,UAAU,MAAM,UAAU,WAAW;AAE3C,UACE,cAAc,aACb,MAAM,IAAI,QAAQ,EAAE,SAAS,CAAC,gBAAgB,aAAa,EAAE,CAAC,GAC/D;AACA,cAAM,IAAI;AAAA,UACR,sBAAsB,SAAS;AAAA,QAEjC;AAAA,MACF;AACA,gBAAU,MAAM,KAAK;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,aAAa,OAAO,KAAK,KAAK,UAAU;AAC/D,UAAM,MAAM,WAAW,OAAO,QAAQ;AAEtC,UAAM,MAAiB;AAAA,MACrB;AAAA,MACA,WAAW,SAAS;AAAA,MACpB,SAAS,YAAY;AAAA,MACrB,QAAQ;AAAA,MACR,WAAW,IAAI,YAAY;AAAA,MAC3B,WAAW,IAAI,YAAY;AAAA,MAC3B,MAAM,SAAS,UAAU;AAAA,MACzB;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,UAAM,MAAM,QAAQ,GAAG;AAEvB,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN;AAAA,MACA,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb;AAAA,IACF,CAAC;AAGD,SAAK,KAAK,QAAQ,KAAK,UAAU,WAAW,EAAE,MAAM,CAAC,QAAQ;AAC3D,aAAO,MAAM,OAAO,KAAK,YAAY,GAAG;AAAA,IAC1C,CAAC;AAED,WAAO,EAAE,IAAI;AAAA,EACf;AAAA,EAEA,MAAc,eACZ,KACA,OACA,WACA,SACA,UACA,YACA,QACsB;AACtB,UAAM,SAAS,cAAc,KAAK;AAClC,QAAI,cAAc,WAAW;AAC3B,aAAO,gBAAgB,WAAW,UAAU,MAAM,UAAU;AAAA,IAC9D;AACA,QAAI,cAAc,YAAY;AAC5B,UAAI,MAAM,IAAI,iBAAiB,GAAG;AAChC,cAAM,OAAO,KAAK,KAAK,MAAM,MAAM,WAAW,KAAK;AACnD,cAAM,MAAM,KAAK,MAAM,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACjD,cAAM,IAAI,eAAe,MAAM,QAAQ,OAAO;AAC9C,eAAO,gBAAgB,YAAY,MAAM,QAAQ,UAAU;AAAA,MAC7D;AACA,aAAO,KAAK,+DAA+D;AAAA,IAC7E;AAEA,UAAM,IAAI,aAAa,QAAQ,OAAO;AACtC,WAAO,gBAAgB,UAAU,UAAU,QAAQ,UAAU;AAAA,EAC/D;AAAA,EAEA,MAAc,QACZ,KACA,QACA,aACe;AACf,UAAM,EAAE,OAAO,QAAQ,KAAK,OAAO,IAAI,KAAK;AAC5C,UAAM,cAAc,IAAI,SAAS,QAAQ,OAAO;AAEhD,UAAM,kBAAkB,MAAM,KAAK,uBAAuB,GAAG;AAC7D,UAAM,cAAc,iBAAiB;AAAA,MACnC;AAAA,MACA,YAAY,MAAM,WAAW,IAAI,KAAK;AAAA,MACtC;AAAA,IACF,CAAC;AACD,UAAM,MAA0B;AAAA,MAC9B,YAAY,MAAM,WAAW,IAAI,KAAK;AAAA,MACtC,QAAQ,OAAO;AAAA,MACf;AAAA,MACA;AAAA,MACA,MAAM,OAAO,UAAU;AAAA,MACvB,WAAW;AAAA,MACX,KAAK;AAAA,MACL,WAAW,IAAI;AAAA,MACf,SAAS,YAAY;AAAA,MACrB,WAAW,KAAK,KAAK,aAAa;AAAA,IACpC;AAEA,UAAM,UAAU,gBAAgB,WAAW;AAC3C,QAAI,CAAE,MAAM,KAAK,iBAAiB,aAAa,SAAS,GAAG,GAAI;AAC7D,YAAM,KAAK,KAAK,KAAK,mBAAmB,WAAW,CAAC;AACpD;AAAA,IACF;AAEA,UAAM,UAAU,QAAQ,aAAa,GAAG;AACxC,UAAM,OAAO;AAAA,MACX,GAAG;AAAA,MACH,KAAK;AAAA,QACH,wBAAwB,IAAI;AAAA,QAC5B,6BAA6B,IAAI;AAAA,QACjC,iBAAiB,IAAI;AAAA,QACrB,sBAAsB,IAAI;AAAA,QAC1B,mBAAmB,IAAI;AAAA,QACvB,GAAI,QAAQ,OAAO,CAAC;AAAA,MACtB;AAAA,IACF;AACA,WAAO,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,GAAG,CAAC,EAAE;AAEtE,UAAM,YAAY;AAAA,MAChB,CAAC,UAAU,MAAM,UAAU,IAAI,OAAO,KAAK;AAAA,MAC3C,CAAC,QAAQ,OAAO,KAAK,OAAO,IAAI,KAAK,iCAAiC,GAAG;AAAA,IAC3E;AAEA,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,YAAY,MAAM;AAAA,QAC/B,OAAO,CAAC,QAAQ,UAAU;AACxB,oBAAU,OAAO,KAAK;AACtB,cAAI,KAAK,EAAE,MAAM,aAAa,OAAO,IAAI,OAAO,QAAQ,MAAM,CAAC;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,UAAU,MAAM;AACtB,YAAM,KAAK,KAAK,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AACrE;AAAA,IACF;AACA,UAAM,UAAU,MAAM;AAItB,UAAM,OAAO,OAAO,OAAO,KAAK;AAChC,QAAI,OAAO;AACX,QAAI,IAAI,WAAW,IAAI,YAAY,IAAI,QAAQ,cAAc,WAAW;AACtE,aAAO,MAAM,IAAI,YAAY,IAAI,QAAQ,IAAI;AAAA,IAC/C;AACA,QAAI,KAAM,OAAM,MAAM,cAAc,IAAI,OAAO,WAAW,IAAI;AAC9D,QAAI,KAAM,OAAM,MAAM,cAAc,IAAI,OAAO,cAAc,IAAI;AAEjE,QAAI,WAAW,OAAO;AACtB,QAAI,UAAU,KAAK,SAAS;AAC5B,QAAI,UAAU,KAAK,SAAS;AAE5B,QAAI,OAAO,aAAa,GAAG;AACzB,YAAM,KAAK,KAAK,KAAK,0BAA0B,OAAO,QAAQ,GAAG;AACjE;AAAA,IACF;AAEA,QAAI,SAAS;AACb,QAAI,aAAY,oBAAI,KAAK,GAAE,YAAY;AACvC,UAAM,MAAM,QAAQ,GAAG;AACvB,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,MACX,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACvB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACzB,CAAC;AACD,QAAI,KAAK,EAAE,MAAM,cAAc,OAAO,IAAI,OAAO,UAAU,OAAO,SAAS,CAAC;AAE5E,QAAI,OAAO,UAAU,WAAW;AAC9B,aAAO,KAAK,OAAO,IAAI,KAAK,+BAA+B;AAC3D,YAAM,KAAK,MAAM,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,MAAc,KAAK,KAAgB,SAAgC;AACjE,QAAI,SAAS;AACb,QAAI,QAAQ;AACZ,QAAI,aAAY,oBAAI,KAAK,GAAE,YAAY;AACvC,UAAM,KAAK,KAAK,MAAM,QAAQ,GAAG;AACjC,SAAK,KAAK,IAAI,KAAK,EAAE,MAAM,eAAe,OAAO,IAAI,OAAO,QAAQ,CAAC;AAAA,EACvE;AAAA,EAEA,MAAc,iBACZ,aACA,SACA,KACkB;AAClB,UAAM,MAAM,qBAAqB,WAAW;AAC5C,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,SAAS,KAAK,kBAAkB,IAAI,GAAG;AAC7C,QAAI,UAAU,OAAO,YAAY,IAAK,QAAO,OAAO;AAEpD,UAAM,KAAK,MAAM,QAAQ,YAAY,GAAG;AACxC,SAAK,kBAAkB,IAAI,KAAK;AAAA,MAC9B;AAAA,MACA,WAAW,OAAO,KAAK,iCAAiC;AAAA,IAC1D,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,OAAuC;AACjD,UAAM,EAAE,OAAO,KAAK,OAAO,IAAI,KAAK;AACpC,UAAM,MAAM,MAAM,MAAM,OAAO,KAAK;AACpC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,gBAAgB,KAAK,EAAE;AACjD,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,SAAS;AACjC,YAAM,IAAI,MAAM,OAAO,KAAK,+BAA+B;AAAA,IAC7D;AAEA,QAAI,KAAK,EAAE,MAAM,iBAAiB,MAAM,CAAC;AACzC,UAAM,MAAM,IAAI,IAAI,IAAI,QAAQ;AAChC,UAAM,eAAe,MAAM,IAAI,WAAW;AAC1C,UAAM,UAAU,GAAG,aAAa,QAAQ,KAAK,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC;AAE1E,QAAI;AACF,UAAI;AAEJ,UAAI,IAAI,QAAQ,cAAc,YAAY;AACxC,cAAM,OAAQ,MAAM,MAAM,aAAa,OAAO,YAAY,KAAM;AAChE,cAAM,UAAU,MAAM,IAAI,WAAW,IAAI;AACzC,YAAI,CAAC,QAAQ,GAAI,QAAO,MAAM,KAAK,cAAc,KAAK,QAAQ,SAAS;AACvE,iBAAS,KAAK,KAAK,IAAI,MAAM,IAAI,OAAO,OAAO,IAAI;AACnD,cAAM,KAAK,eAAe,GAAG;AAAA,MAC/B,WAAW,IAAI,QAAQ,cAAc,UAAU;AAE7C,YAAI,MAAM,IAAI,WAAW,EAAG,OAAM,IAAI,OAAO,OAAO;AACpD,YAAI,IAAI,WAAY,OAAM,IAAI,SAAS,IAAI,UAAU;AACrD,cAAM,SAAS,MAAM,IAAI,MAAM,IAAI,QAAQ,QAAS,OAAO;AAC3D,YAAI,CAAC,OAAO,GAAI,QAAO,MAAM,KAAK,cAAc,KAAK,OAAO,SAAS;AACrE,iBAAS,MAAM,IAAI,WAAW;AAC9B,cAAM,IAAI,aAAa,IAAI,QAAQ,MAAO;AAAA,MAC5C,OAAO;AAEL,iBAAU,MAAM,IAAI,WAAW,IAAK,MAAM,IAAI,OAAO,OAAO,IAAI;AAAA,MAClE;AAEA,UAAI,SAAS;AACb,UAAI,UAAU,EAAE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,GAAI,KAAI,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC5E,UAAI,SAAS;AAAA,QACX;AAAA,QACA,GAAI,UAAU,WAAW,eAAe,EAAE,eAAe,OAAO,IAAI,CAAC;AAAA,QACrE,cACE,UAAU,WAAW,eACjB,cAAc,MAAM,4BAA4B,YAAY,KAC5D;AAAA,MACR;AACA,UAAI,aAAY,oBAAI,KAAK,GAAE,YAAY;AACvC,YAAM,MAAM,QAAQ,GAAG;AAEvB,UAAI,KAAK,EAAE,MAAM,cAAc,OAAO,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AACrE,aAAO,EAAE,SAAS,MAAM,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AAAA,IACxD,SAAS,KAAK;AACZ,YAAM,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACnE,aAAO,MAAM,SAAS,KAAK,WAAW,WAAW;AACjD,UAAI,SAAS;AACb,UAAI,QAAQ;AACZ,YAAM,MAAM,QAAQ,GAAG;AACvB,UAAI,KAAK,EAAE,MAAM,eAAe,OAAO,SAAS,YAAY,CAAC;AAC7D,aAAO,EAAE,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,KAAgB,WAA6C;AACvF,QAAI,SAAS;AACb,QAAI,QAAQ,uBAAuB,UAAU,KAAK,IAAI,KAAK,eAAe;AAC1E,QAAI,aAAY,oBAAI,KAAK,GAAE,YAAY;AACvC,UAAM,KAAK,KAAK,MAAM,QAAQ,GAAG;AACjC,SAAK,KAAK,IAAI,KAAK;AAAA,MACjB,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,MACX,SAAS,IAAI;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,EAAE,SAAS,OAAO,UAAU;AAAA,EACrC;AAAA,EAEA,MAAc,eAAe,KAA+B;AAC1D,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,QAAS;AACnC,QAAI,IAAI,QAAQ,cAAc,YAAY;AACxC,YAAM,MAAM,IAAI,IAAI,IAAI,QAAQ;AAChC,YAAM,IAAI,eAAe,IAAI,QAAQ,MAAM,IAAI,QAAQ,UAAU,MAAS;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,uBAAuB,KAAiC;AACpE,UAAM,EAAE,QAAQ,MAAM,IAAI,KAAK;AAC/B,UAAM,OAAO,sBAAsB,EAAE,YAAY,OAAO,KAAK,CAAC;AAC9D,WAAO,MAAM,cAAc,IAAI,OAAO,yBAAyB,IAAI;AAAA,EACrE;AACF;AAEA,eAAe,KAAQ,IAAyC;AAC9D,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,GAAW,GAAmB;AAC9C,SAAO,EAAE,UAAU,IAAI,IAAI,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AACjD;AAEA,SAAS,mBAAmB,aAAkC;AAC5D,QAAM,UAAU,YAAY,QAAQ,SAAS,CAAC,YAAY,OAAO;AACjE,SACE,UAAU,YAAY,EAAE,yDACZ,QAAQ,KAAK,IAAI,CAAC;AAGlC;AAEA,SAAS,qBAAqB,aAAkC;AAC9D,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,GAAI,YAAY,QAAQ,SAAS,CAAC,YAAY,OAAO;AAAA,EACvD,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,gBACP,OACA,SACiE;AACjE,MAAI,SAAS;AACb,MAAI,QAA8C;AAClD,MAAI,aAAa,QAAQ,QAAQ;AAEjC,iBAAe,QAAuB;AACpC,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,cAAQ;AAAA,IACV;AACA,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,QAAQ;AACd,aAAS;AACT,iBAAa,WAAW,KAAK,MAAM,MAAM,KAAK,CAAC,EAAE,MAAM,OAAO;AAC9D,UAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL,OAAO,OAAO;AACZ,gBAAU;AACV,UAAI,OAAO,UAAU,iBAAiB;AACpC,aAAK,MAAM;AAAA,MACb,WAAW,CAAC,OAAO;AACjB,gBAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,YAAY;AAAA,MACrD;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,OAIf;AACT,QAAM,EAAE,QAAQ,YAAY,IAAI,IAAI;AACpC,QAAM,UAAU,OAAO,SAAS,IAAI,mBAAmB,EAAE,KAAK,IAAI;AAClE,QAAM,eAAe,kBAAkB,QAAQ,UAAU,EAAE,IAAI,CAAC,QAAQ,UAAU;AAChF,WAAO,GAAG,QAAQ,CAAC,KAAK,MAAM;AAAA,EAChC,CAAC;AACD,QAAM,WACJ,OAAO,UAAU,SAAS,SACtB,oFACA;AAEN,SAAO;AAAA,IACL;AAAA,IACA,YAAY,aAAa,OAAO,QAAQ,GAAG,CAAC;AAAA,IAC5C,UAAU,aAAa,OAAO,IAAI,OAAO,GAAG,CAAC;AAAA,IAC7C,QAAQ,IAAI,SAAS,QAAQ,IAAI,YAAY,QAAQ;AAAA,IACrD,cAAc,IAAI,SAAS;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qDAAqD,UAAU;AAAA,IAC/D;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,oBAAoB,SAAkC;AAC7D,QAAM,QAAQ,QAAQ,GAAG,QAAQ,QAAQ,GAAG,SAAS,QAAQ,GAAG,QAAQ,QAAQ,GAAG;AACnF,QAAM,QAAQ,YAAY,QAAQ,GAAG,KAAK;AAC1C,QAAM,UAAU,cAAc,OAAO;AACrC,QAAM,OAAO,WAAW,OAAO;AAC/B,QAAM,SAAS,2BAA2B,OAAO,EAAE,MAAM,GAAG,CAAC;AAC7D,SAAO;AAAA,IACL,IAAI,QAAQ,EAAE,KAAK,QAAQ,GAAG,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,IACtD,WAAW,OAAO;AAAA,IAClB,QAAQ,SAAS,KAAK,KAAK;AAAA,IAC3B,OAAO,QAAQ,IAAI,KAAK;AAAA,IACxB,OAAO,SAAS,UAAU,OAAO,IAAI,SAAS,EAAE,KAAK,IAAI,CAAC,KAAK;AAAA,EACjE,EACG,OAAO,OAAO,EACd,KAAK,KAAK;AACf;AAEA,SAAS,cAAc,SAAkC;AACvD,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,QAAQ,SAAS,UAAU;AAC7B,WAAO,UAAU,QAAQ,IAAI,IAAI,QAAQ,IAAI,GAAG,QAAQ,UAAU,OAAO,IAAI,QAAQ,MAAM,KAAK,EAAE;AAAA,EACpG;AACA,MAAI,QAAQ,SAAS,QAAQ;AAC3B,WAAO,QAAQ,QAAQ,IAAI,IAAI,UAAU,QAAQ,KAAK,CAAC;AAAA,EACzD;AACA,MAAI,QAAQ,SAAS,cAAc;AACjC,WAAO,cAAc,QAAQ,IAAI,IAAI,UAAU,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACA,SAAO,OAAO,aAAa,QAAQ,UAAU,GAAG,CAAC;AACnD;AAEA,SAAS,YAAY,OAAuC;AAC1D,SAAO,OAAO,QAAQ,KAAK,EACxB,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,UAAU,KAAK,CAAC,EAAE,EAClD,KAAK,GAAG;AACb;AAEA,SAAS,WAAW,SAAkC;AACpD,SAAO;AAAA,IACL,IAAI,QAAQ,KAAK,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,SAAS,UAAU,KAAK,CAAC,EAAE;AAAA,IACrF,IAAI,QAAQ,KAAK,YAAY,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,YAAY,WAAW,UAAU,OAAO,CAAC,EAAE;AAAA,IAC7F,IAAI,QAAQ,KAAK,aAAa,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,aAAa,YAAY,UAAU,QAAQ,CAAC,EAAE;AAAA,EACnG,EAAE,KAAK,GAAG;AACZ;AAEA,SAAS,kBAAkB,QAAuB,YAA8B;AAC9E,QAAM,gBAAgB,OAAO,SAC1B,OAAO,CAAC,YAAY,QAAQ,QAAQ,SAAS,QAAQ,EACrD,IAAI,CAAC,YAAY;AAChB,QAAI,QAAQ,QAAQ,SAAS,SAAU,QAAO;AAC9C,UAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,QAAQ,OAAO,EAAE;AACnD,UAAM,MAAM,QAAQ,QAAQ,OAAO;AACnC,WAAO,SAAS,QAAQ,EAAE,WAAW,QAAQ,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,0BAA0B,KAAK,IAAI,GAAG,MAAM,WAAW,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC/J,CAAC,EACA,OAAO,OAAO;AACjB,MAAI,cAAc,OAAQ,QAAO,cAAc,MAAM,GAAG,CAAC;AAEzD,QAAM,SAAS,0BAA0B,MAAM;AAC/C,QAAM,UAAoB,CAAC;AAC3B,MAAI,OAAO,QAAQ;AACjB,YAAQ,KAAK,eAAe,OAAO,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,WAAW,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,2BAA2B;AAAA,EAC/H;AACA,MAAI,OAAO,SAAS,GAAG;AACrB,YAAQ,KAAK,eAAe,OAAO,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,WAAW,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,2BAA2B;AAAA,EAC/H;AACA,MAAI,QAAQ,OAAQ,QAAO;AAE3B,SAAO,CAAC,2DAA2D,UAAU,EAAE;AACjF;AAEA,SAAS,0BAA0B,QAAiC;AAClE,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAM,CAAC,UAAkB;AAC7B,UAAM,MAAM,MAAM,YAAY;AAC9B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,QAAI,KAAK,KAAK;AAAA,EAChB;AAEA,aAAW,WAAW,OAAO,UAAU;AACrC,eAAW,SAAS,2BAA2B,OAAO,EAAG,KAAI,KAAK;AAAA,EACpE;AACA,SAAO,IAAI,MAAM,GAAG,CAAC;AACvB;AAEA,SAAS,2BAA2B,SAAoC;AACtE,QAAM,SAAmB,CAAC;AAC1B,QAAM,MAAM,CAAC,UAA8B;AACzC,eAAW,SAAS,oBAAoB,KAAK,GAAG;AAC9C,UAAI,CAAC,OAAO,KAAK,CAAC,aAAa,SAAS,YAAY,MAAM,MAAM,YAAY,CAAC,GAAG;AAC9E,eAAO,KAAK,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ,SAAS,OAAQ,KAAI,QAAQ,QAAQ,KAAK;AAC9D,MAAI,QAAQ,QAAQ,SAAS,aAAc,KAAI,QAAQ,QAAQ,IAAI;AACnE,aAAW,SAAS,qBAAqB,OAAO,EAAG,KAAI,KAAK;AAC5D,aAAW,SAAS,OAAO,OAAO,QAAQ,GAAG,KAAK,EAAG,KAAI,KAAK;AAC9D,aAAW,SAAS,QAAQ,GAAG,aAAa,CAAC,EAAG,KAAI,KAAK;AACzD,MAAI,QAAQ,GAAG,KAAK;AACpB,MAAI,QAAQ,GAAG,IAAI;AACnB,aAAW,SAAS,QAAQ,KAAK,UAAU,CAAC,EAAG,KAAI,KAAK;AACxD,aAAW,WAAW,QAAQ,KAAK,YAAY,CAAC,EAAG,KAAI,OAAO;AAC9D,MAAI,QAAQ,KAAK,UAAU;AAE3B,SAAO,OAAO,MAAM,GAAG,EAAE;AAC3B;AAEA,SAAS,qBAAqB,SAAoC;AAChE,QAAM,MAAM,QAAQ,gBAAgB;AACpC,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO,CAAC;AAC5B,QAAM,SAAS,IAAI;AACnB,SAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IAAI,CAAC;AACzG;AAEA,SAAS,oBAAoB,OAAqC;AAChE,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACnD,MAAI,CAAC,cAAc,WAAW,SAAS,IAAK,QAAO,CAAC;AACpD,QAAM,WAAW,CAAC,UAAU;AAC5B,MAAI,WAAW,WAAW,GAAG,KAAK,WAAW,SAAS,EAAG,UAAS,QAAQ,WAAW,MAAM,CAAC,CAAC;AAC7F,MAAI,WAAW,SAAS,GAAG,KAAK,CAAC,WAAW,SAAS,GAAG,GAAG;AACzD,aAAS,KAAK,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE;AAAA,EAClE;AACA,SAAO,SACJ,IAAI,CAAC,UAAU,MAAM,KAAK,EAAE,QAAQ,qBAAqB,EAAE,CAAC,EAC5D,OAAO,CAAC,UAAU,MAAM,UAAU,KAAK,MAAM,UAAU,EAAE,EACzD,OAAO,CAAC,UAAU,CAAC,qBAAqB,IAAI,MAAM,YAAY,CAAC,CAAC;AACrE;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,KAAK,UAAU,aAAa,OAAO,GAAG,CAAC;AAChD;AAEA,SAAS,aAAa,OAAe,KAAqB;AACxD,QAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAChD,SAAO,QAAQ,UAAU,MAAM,UAAU,GAAG,QAAQ,MAAM,GAAG,MAAM,CAAC,CAAC;AACvE;AAEA,SAAS,WAAW,OAAuB;AACzC,SAAO,IAAI,MAAM,QAAQ,MAAM,OAAO,CAAC;AACzC;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;AC9pBD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OASK;AAkBA,IAAM,gBAAN,MAAoB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAA4B;AACtC,SAAK,SAAS,KAAK;AACnB,SAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,WAAW;AAClD,SAAK,MAAM,IAAI,SAAS;AACxB,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,KAAK,KAAK;AAAA,MACV,QAAQ,KAAK,OAAO;AAAA,MACpB,GAAI,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,MACzD,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACxD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,KAAK,MAAM,KAAK;AACtB,UAAM,KAAK,MAAM,eAAe;AAAA,EAClC;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,KAA+C;AAC3D,UAAM,MAAM,oBAAI,KAAK;AACrB,QAAI,UAAU,IAAI,YAAY,MAAM,KAAK,MAAM,WAAW,IAAI,SAAS,IAAI;AAC3E,QAAI,CAAC,SAAS;AACZ,gBAAU,cAAc,EAAE,KAAK,IAAI,KAAK,KAAK,OAAO,KAAK,OAAO,MAAM,CAAC;AAAA,IACzE,OAAO;AACL,gBAAU,aAAa,SAAS,KAAK,KAAK,OAAO,KAAK;AAAA,IACxD;AAEA,UAAM,EAAE,SAAS,MAAM,QAAQ,IAAI,cAAc,SAAS,IAAI,SAAS,GAAG;AAC1E,UAAM,KAAK,MAAM,YAAY,IAAI;AAEjC,SAAK,IAAI,KAAK,EAAE,MAAM,eAAe,WAAW,KAAK,IAAI,QAAQ,CAAC;AAClE,WAAO,EAAE,WAAW,KAAK,IAAI,QAAQ;AAAA,EACvC;AAAA,EAEA,MAAM,cAAc,WAAmB,WAAmD;AACxF,UAAM,UAAU,MAAM,KAAK,MAAM,WAAW,SAAS;AACrD,QAAI,CAAC,QAAS,QAAO,EAAE,SAAS,MAAM;AACtC,UAAM,EAAE,SAAS,MAAM,QAAQ,IAAI,cAAc,SAAS,SAAS;AACnE,QAAI,SAAS;AACX,YAAM,KAAK,MAAM,YAAY,IAAI;AACjC,WAAK,IAAI,KAAK,EAAE,MAAM,mBAAmB,WAAW,UAAU,CAAC;AAAA,IACjE;AACA,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA,EAEA,MAAM,WAAW,IAA0C;AACzD,WAAO,KAAK,MAAM,WAAW,EAAE;AAAA,EACjC;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,KAA6C;AACxD,UAAM,UAAU,MAAM,KAAK,MAAM,WAAW,IAAI,SAAS;AACzD,QAAI,CAAC,QAAS,OAAM,IAAI,cAAc,oBAAoB,IAAI,SAAS,EAAE;AAEzE,UAAM,YAAY,uBAAuB,MAAM,IAAI,aAAa,CAAC,CAAC;AAClE,UAAM,SAAS,gBAAgB,SAAS;AAAA,MACtC,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,GAAI,IAAI,aAAa,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC;AAAA,IACzD,CAAC;AAED,UAAM,YAAqB,EAAE,GAAG,SAAS,QAAQ,aAAa,QAAQ,IAAI,OAAO;AACjF,UAAM,KAAK,MAAM,YAAY,SAAS;AAEtC,UAAM,EAAE,IAAI,IAAI,MAAM,KAAK,KAAK,UAAU,MAAM;AAChD,WAAO,EAAE,OAAO,IAAI,OAAO,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,MAAM,OAAuC;AACjD,WAAO,KAAK,KAAK,MAAM,KAAK;AAAA,EAC9B;AAAA;AAAA,EAIA,MAAM,SAAkC;AACtC,UAAM,WAAW,MAAM,KAAK,MAAM,aAAa;AAC/C,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM;AAAA,MACN;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,MAAM,KAAK,OAAO;AAAA,MAClB,UAAU,KAAK,OAAO;AAAA,MACtB,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,IAChE;AAAA,EACF;AACF;AAEO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EAC9B,OAAO;AAClB;;;ACvIA,OAAO,aAAuC;AAC9C,OAAO,eAAe;AACtB;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAWP,eAAsB,YAAY,SAAkD;AAClF,QAAM,MAAM,QAAQ,EAAE,QAAQ,MAAM,CAAC;AAGrC,MAAI,QAAQ,aAAa,OAAO,KAAK,UAAU;AAC7C,UAAM,OAAO,+BAA+B,GAAG;AAC/C,UAAM,OAAO,gCAAgC,yBAAyB;AACtE,UAAM,OAAO,gCAAgC,cAAc;AAC3D,QAAI,IAAI,WAAW,WAAW;AAC5B,YAAM,KAAK,GAAG,EAAE,KAAK;AAAA,IACvB;AAAA,EACF,CAAC;AAED,QAAM,IAAI,SAAS,SAAS;AAI5B,MAAI,IAAI,WAAW,YAAY,QAAQ,OAAO,CAAC;AAE/C,MAAI,KAAK,YAAY,OAAO,KAAK,UAAU;AACzC,UAAM,SAAS,qBAAqB,UAAU,IAAI,IAAI;AACtD,QAAI,CAAC,OAAO,QAAS,QAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,OAAO,MAAM,QAAQ,CAAC;AAChF,WAAO,QAAQ,QAAQ,OAAO,IAAI;AAAA,EACpC,CAAC;AAED,MAAI,KAAK,WAAW,OAAO,KAAK,UAAU;AACxC,UAAM,SAAS,oBAAoB,UAAU,IAAI,IAAI;AACrD,QAAI,CAAC,OAAO,QAAS,QAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,OAAO,MAAM,QAAQ,CAAC;AAChF,QAAI;AACF,aAAO,MAAM,QAAQ,OAAO,OAAO,IAAI;AAAA,IACzC,SAAS,KAAK;AACZ,UAAI,eAAe,cAAe,QAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC;AACpF,UAAI,eAAe;AACjB,eAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,IAAI,SAAS,MAAM,IAAI,KAAK,CAAC;AACpE,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AAED,MAAI,KAAoC,iBAAiB,OAAO,KAAK,UAAU;AAC7E,QAAI;AACF,aAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK;AAAA,IAC7C,SAAS,KAAK;AACZ,aAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC;AAAA,IACzF;AAAA,EACF,CAAC;AAED,MAAI,IAAgC,gBAAgB,OAAO,KAAK,UAAU;AACxE,UAAM,UAAU,MAAM,QAAQ,WAAW,IAAI,OAAO,EAAE;AACtD,QAAI,CAAC,QAAS,QAAO,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,oBAAoB,IAAI,OAAO,EAAE,GAAG,CAAC;AACxF,WAAO;AAAA,EACT,CAAC;AAED,MAAI;AAAA,IACF;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,YAAY,OAAO,SAAS,IAAI,OAAO,WAAW,EAAE;AAC1D,aAAO,QAAQ,cAAc,IAAI,OAAO,WAAW,SAAS;AAAA,IAC9D;AAAA,EACF;AAIA,MAAI,IAAI,OAAO,EAAE,WAAW,KAAK,GAAG,CAAC,WAAW;AAC9C,UAAM,OAAO,CAAC,UAAuB;AACnC,UAAI,OAAO,eAAe,OAAO,KAAM,QAAO,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,IAC1E;AACA,UAAM,cAAc,QAAQ,IAAI,UAAU,IAAI;AAE9C,WAAO,GAAG,WAAW,CAAC,QAAgB;AACpC,UAAI;AACJ,UAAI;AACF,cAAM,KAAK,MAAM,IAAI,SAAS,CAAC;AAAA,MACjC,QAAQ;AACN;AAAA,MACF;AACA,UAAI,IAAI,SAAS,OAAQ,QAAO,KAAK,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AAAA,eAC5D,IAAI,SAAS,aAAa;AAGjC,cAAM,MAAM;AACZ,mBAAW,SAAS,QAAQ,IAAI,OAAO,EAAE,OAAO,IAAI,OAAO,WAAW,IAAI,UAAU,CAAC,GAAG;AACtF,eAAK,KAAK;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,GAAG,SAAS,WAAW;AAC9B,WAAO,GAAG,SAAS,WAAW;AAAA,EAChC,CAAC;AAED,SAAO;AACT;","names":[]}
|