@clicksmith/agent-config 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { ExecutionMode, Isolation } from '@clicksmith/core';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /** Every placeholder the launcher knows how to resolve in a command template. */
5
- declare const PLACEHOLDER_KEYS: readonly ["bundlePath", "prompt", "instructionFile", "mode", "mcpServer", "cwd"];
5
+ declare const PLACEHOLDER_KEYS: readonly ["bundlePath", "prompt", "agentPrompt", "instructionFile", "mode", "mcpServer", "cwd"];
6
6
  type PlaceholderKey = (typeof PLACEHOLDER_KEYS)[number];
7
7
  /**
8
8
  * Everything the launcher needs to turn a config-driven command template into a
@@ -13,6 +13,8 @@ interface AgentLaunchContext {
13
13
  bundlePath: string;
14
14
  /** The user's free-text prompt. */
15
15
  prompt: string;
16
+ /** Full agent-ready prompt containing the ClickSmith bundle and instruction paths. */
17
+ agentPrompt: string;
16
18
  /** Absolute path to the rendered instruction file for this agent. */
17
19
  instructionFile: string;
18
20
  /** Execution mode (`plan` | `edit`). */
@@ -369,9 +371,8 @@ interface InstructionTemplateOptions {
369
371
  declare const DEFAULT_MCP_TOOLS: readonly ["get_session", "list_elements", "get_element_by_id", "get_latest_request"];
370
372
  /**
371
373
  * The single, shared instruction body. Every native renderer wraps this exact
372
- * text so Claude, Cursor, Codex, Antigravity and generic agents all learn the
373
- * same three things: the `#N` reference system, locator priority, and the
374
- * plan/worktree safety contract.
374
+ * text so Claude, Cursor, Codex, Antigravity and generic agents all receive the
375
+ * same compact fast-path contract.
375
376
  */
376
377
  declare function renderInstructionBody(options?: InstructionTemplateOptions): string;
377
378
 
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { LOCATOR_PRIORITY } from '@clicksmith/core';
7
7
  var PLACEHOLDER_KEYS = [
8
8
  "bundlePath",
9
9
  "prompt",
10
+ "agentPrompt",
10
11
  "instructionFile",
11
12
  "mode",
12
13
  "mcpServer",
@@ -65,6 +66,7 @@ function placeholderValues(ctx) {
65
66
  return {
66
67
  bundlePath: ctx.bundlePath,
67
68
  prompt: ctx.prompt,
69
+ agentPrompt: ctx.agentPrompt,
68
70
  instructionFile: ctx.instructionFile,
69
71
  mode: ctx.mode,
70
72
  mcpServer: ctx.mcpServer,
@@ -167,55 +169,30 @@ var DEFAULT_MCP_TOOLS = [
167
169
  function renderInstructionBody(options = {}) {
168
170
  const tools = options.mcpTools ?? DEFAULT_MCP_TOOLS;
169
171
  const attrs = options.stableAttrs ?? [];
170
- const locatorList = LOCATOR_PRIORITY.map((kind, i) => `${i + 1}. **${kind}**`).join(" \u2192 ");
171
- return `# ClickSmith \u2014 working with captured UI requests
172
+ const locatorList = LOCATOR_PRIORITY.map((kind, i) => `${i + 1}. ${kind}`).join(" -> ");
173
+ return `# ClickSmith fast UI edits
172
174
 
173
- You are being asked to change UI elements that a human pointed at in their browser
174
- with ClickSmith. Each request arrives as a **capture bundle** (a JSON file whose
175
- path is provided to you) describing one or more elements and a free-text prompt.
175
+ ClickSmith sends a small browser-capture summary for UI changes. Optimize for a
176
+ targeted edit, not broad repo exploration.
176
177
 
177
- ## 1. The \`#N\` reference system
178
+ Fast path:
178
179
 
179
- Elements are numbered \`#1\`, \`#2\`, \u2026 in the order they were captured. The user's
180
- prompt refers to them by number, e.g. _"make #1 match #2's style"_. Always resolve
181
- \`#N\` to \`elements[]\` entries with the matching \`id\` field. Never guess which
182
- element is meant \u2014 read the bundle.
180
+ - Resolve \`#N\` from the prompt's target summaries first. Read the bundle only if
181
+ the summaries are ambiguous.
182
+ - Locator order: ${locatorList}. Source means exact file:line. Attr means grep the
183
+ stable value${attrs.length ? ` (project attrs: ${attrs.join(", ")})` : ""}. Behavioral means grep the label/text. Dom means use captured attrs, searchTokens,
184
+ nearby headings, and route.
185
+ - Before opening broad docs, run at most two targeted searches, preferably
186
+ \`git grep -n -e 'exact-token' -- .\`.
187
+ - Do not read AGENTS.md, CLAUDE.md, .cursor/rules, guidelines, skills, or tool
188
+ docs before the targeted lookup.
189
+ - Do not edit shared sprite/icon definitions unless the request asks for the
190
+ shared asset; edit the component/template usage instead.
191
+ - Keep edits minimal, non-destructive, and inside the current working directory.
192
+ - In worktree/branch isolation, ClickSmith reviews and applies changes in a later
193
+ Apply step. In inplace mode, edits affect the current tree immediately.
183
194
 
184
- ## 2. Locator priority
185
-
186
- Each element carries a \`locator\`. Trust them in this exact order, best first:
187
-
188
- ${locatorList}
189
-
190
- - **source** gives an exact \`file:line\` (injected in dev by @clicksmith/unplugin) \u2014
191
- edit there directly.
192
- - **attr** is a stable attribute${attrs.length ? ` (this project uses: ${attrs.map((a) => `\`${a}\``).join(", ")})` : ""}; grep for it to find the JSX/template.
193
- - **behavioral** is an ARIA role + accessible name; search for the visible text/label.
194
- - **dom** is a structural fallback; use \`el.text\`, \`el.attrs\`, and \`near\` context to
195
- locate the component, and prefer adding a stable attribute while you're there.
196
-
197
- ## 3. Plan / worktree safety (read carefully)
198
-
199
- ClickSmith runs you inside an **isolated git worktree** by default. The execution
200
- mode is in \`execution.mode\`:
201
-
202
- - **plan** (the default): produce a clear plan and, if helpful, a diff \u2014 but **do
203
- not** assume your edits ship. The human reviews your plan/diff and explicitly
204
- clicks **Apply**. Your job is to propose, precisely.
205
- - **edit**: you may modify files in the sandbox. They still do **not** reach the
206
- user's main working tree until they click Apply.
207
-
208
- Never run destructive git commands, never push, and never touch files outside the
209
- sandbox working directory.
210
-
211
- ## 4. Reading the request
212
-
213
- The bundle path is passed on the command line / via your harness. ${tools.length ? `You can also use these MCP tools (server \`clicksmith\`): ${tools.map((t) => `\`${t}\``).join(", ")}. Use \`get_latest_request\` to fetch the most recent submission, then \`get_element_by_id\` to resolve a specific \`#N\`.` : ""}
214
-
215
- Each element includes: \`locator\`, \`el\` (tag/text/role/label/attrs/icon hints),
216
- \`near\` (surrounding labels & headings), \`conditions\` (viewport/theme), and an
217
- optional \`screenshot\` thumbnail. Use \`near\` and \`app.route\` to disambiguate when
218
- multiple elements look similar.
195
+ MCP is optional. ${tools.length ? `If needed, the \`clicksmith\` server exposes: ${tools.map((t) => `\`${t}\``).join(", ")}.` : ""}
219
196
  ${options.daemonPort ? `
220
197
  The ClickSmith daemon is at http://127.0.0.1:${options.daemonPort}.
221
198
  ` : ""}`;
@@ -294,7 +271,7 @@ var DEFAULT_AGENTS = [
294
271
  id: "claude",
295
272
  label: "Claude Code",
296
273
  command: "claude",
297
- args: ["-p", "{prompt}", "--append-system-prompt", "@{instructionFile}"],
274
+ args: ["-p", "{agentPrompt}", "--append-system-prompt", "@{instructionFile}"],
298
275
  detect: { anyOf: ["claude"] },
299
276
  instructions: { target: "claude", file: "CLAUDE.md" },
300
277
  mcp: { register: "claude" },
@@ -304,7 +281,7 @@ var DEFAULT_AGENTS = [
304
281
  id: "cursor",
305
282
  label: "Cursor Agent",
306
283
  command: "cursor-agent",
307
- args: ["--print", "{prompt}"],
284
+ args: ["--print", "{agentPrompt}"],
308
285
  detect: { anyOf: ["cursor-agent", "cursor"] },
309
286
  instructions: { target: "cursor", file: ".cursor/rules/clicksmith.mdc" },
310
287
  mcp: { register: "cursor" }
@@ -313,7 +290,18 @@ var DEFAULT_AGENTS = [
313
290
  id: "codex",
314
291
  label: "OpenAI Codex",
315
292
  command: "codex",
316
- args: ["exec", "{prompt}"],
293
+ args: [
294
+ "exec",
295
+ "--cd",
296
+ "{cwd}",
297
+ "--sandbox",
298
+ "workspace-write",
299
+ "--skip-git-repo-check",
300
+ "--ephemeral",
301
+ "-c",
302
+ 'model_reasoning_effort="low"',
303
+ "{agentPrompt}"
304
+ ],
317
305
  detect: { anyOf: ["codex"] },
318
306
  instructions: { target: "codex", file: "AGENTS.md" },
319
307
  mcp: { register: "codex" }
@@ -322,7 +310,7 @@ var DEFAULT_AGENTS = [
322
310
  id: "antigravity",
323
311
  label: "Antigravity",
324
312
  command: "antigravity",
325
- args: ["run", "--prompt", "{prompt}"],
313
+ args: ["run", "--prompt", "{agentPrompt}"],
326
314
  detect: { anyOf: ["antigravity"] },
327
315
  instructions: { target: "antigravity", file: ".antigravity/rules/clicksmith.md" },
328
316
  mcp: { register: "mcp-json" }
@@ -333,7 +321,7 @@ var DEFAULT_AGENTS = [
333
321
  command: "sh",
334
322
  args: [
335
323
  "-c",
336
- 'echo "ClickSmith request: {prompt}"; echo "Bundle: {bundlePath}"; echo "Instructions: {instructionFile}"; echo "Mode: {mode}"'
324
+ 'echo "ClickSmith request: {prompt}"; echo "Bundle: {bundlePath}"; echo "Instructions: {instructionFile}"; echo "Mode: {mode}"; echo "Prompt: {agentPrompt}"'
337
325
  ],
338
326
  instructions: { target: "generic", file: ".clicksmith/AGENT_INSTRUCTIONS.md" },
339
327
  mcp: { register: "mcp-json" }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/config-schema.ts","../src/placeholders.ts","../src/bin-exists.ts","../src/adapter.ts","../src/instruction-template.ts","../src/renderers.ts","../src/defaults.ts","../src/merge.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ExecutionMode, Isolation } from '@clicksmith/core';\n\n/** Every placeholder the launcher knows how to resolve in a command template. */\nexport const PLACEHOLDER_KEYS = [\n 'bundlePath',\n 'prompt',\n 'instructionFile',\n 'mode',\n 'mcpServer',\n 'cwd',\n] as const;\n\nexport type PlaceholderKey = (typeof PLACEHOLDER_KEYS)[number];\n\n/**\n * Everything the launcher needs to turn a config-driven command template into a\n * concrete process invocation. This is also the `ctx` passed to adapter hooks.\n */\nexport interface AgentLaunchContext {\n /** Absolute path to the serialized capture bundle. */\n bundlePath: string;\n /** The user's free-text prompt. */\n prompt: string;\n /** Absolute path to the rendered instruction file for this agent. */\n instructionFile: string;\n /** Execution mode (`plan` | `edit`). */\n mode: ExecutionMode;\n /** A reference the agent can use to reach the ClickSmith MCP server. */\n mcpServer: string;\n /** Working directory for the spawned process (the sandbox). */\n cwd: string;\n /** Isolation strategy in effect for this run. */\n isolation: Isolation;\n /** The agent id being launched. */\n agentId: string;\n /**\n * Resolves whether an executable exists on PATH. Injected by the daemon so\n * adapters never have to spawn processes themselves. Defaults to a PATH scan.\n */\n binExists?: (bin: string) => Promise<boolean>;\n}\n\n/** A concrete, ready-to-spawn process specification. */\nexport interface CommandSpec {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/** A normalized event parsed from an agent's stdout/stderr stream. */\nexport type AgentEvent =\n | { type: 'plan-ready'; plan?: string; diff?: string }\n | { type: 'progress'; message: string }\n | { type: 'error'; message: string };\n\n/**\n * The adapter contract. Built-in adapters are produced from `agents.config.json`\n * by {@link configToAdapter}; the launcher only resolves placeholders. Authors\n * may also hand-write adapters that satisfy this interface.\n */\nexport interface AgentAdapter {\n id: string;\n /** Whether the agent's CLI is installed/usable in this context. */\n isAvailable(ctx: AgentLaunchContext): Promise<boolean>;\n /** Build the concrete command to spawn. */\n buildCommand(ctx: AgentLaunchContext): CommandSpec;\n /** Optionally map a raw output chunk into structured events. */\n parseEvents?(chunk: string, ctx: AgentLaunchContext): AgentEvent[];\n}\n","import { z } from 'zod';\n\n/** Which native instruction format a renderer should target. */\nexport const InstructionTargetSchema = z.enum([\n 'claude',\n 'cursor',\n 'codex',\n 'antigravity',\n 'generic',\n]);\nexport type InstructionTarget = z.infer<typeof InstructionTargetSchema>;\n\n/** How (and whether) to register the daemon's MCP server for this agent. */\nexport const McpRegistrationSchema = z.enum(['claude', 'cursor', 'codex', 'mcp-json', 'none']);\nexport type McpRegistration = z.infer<typeof McpRegistrationSchema>;\n\n/**\n * One agent definition. The `command`/`args` are templates containing\n * placeholders like `{prompt}` — they are **data**, never code. Changing a\n * vendor flag is an edit here, not a code change.\n */\nexport const AgentConfigSchema = z.object({\n id: z.string().min(1),\n label: z.string().optional(),\n /** Executable name or path. May contain placeholders. */\n command: z.string().min(1),\n /** Argument templates; each entry may contain placeholders. */\n args: z.array(z.string()).default([]),\n /** Extra environment variables (values may contain placeholders). */\n env: z.record(z.string()).optional(),\n /** Working directory override (placeholders allowed). Defaults to the sandbox. */\n cwd: z.string().optional(),\n /** How to detect availability: any of these executables must be on PATH. */\n detect: z\n .object({\n anyOf: z.array(z.string()).min(1),\n })\n .optional(),\n /** Where to render this agent's instruction file. */\n instructions: z\n .object({\n target: InstructionTargetSchema,\n file: z.string().min(1),\n })\n .optional(),\n /** How to register the daemon MCP server for this agent. */\n mcp: z\n .object({\n register: McpRegistrationSchema,\n })\n .optional(),\n /** Optional regexes that map log lines to structured events. */\n parse: z\n .object({\n planReady: z.string().optional(),\n error: z.string().optional(),\n })\n .optional(),\n});\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\n\n/** The top-level `agents.config.json` document. */\nexport const AgentsConfigSchema = z.object({\n version: z.literal(1).default(1),\n defaultAgent: z.string().optional(),\n agents: z.array(AgentConfigSchema).default([]),\n});\nexport type AgentsConfig = z.infer<typeof AgentsConfigSchema>;\n\n/** Parse and validate an `agents.config.json` value without throwing. */\nexport function parseAgentsConfig(value: unknown):\n | { ok: true; config: AgentsConfig }\n | { ok: false; error: z.ZodError } {\n const result = AgentsConfigSchema.safeParse(value);\n return result.success\n ? { ok: true, config: result.data }\n : { ok: false, error: result.error };\n}\n","import { PLACEHOLDER_KEYS, type AgentLaunchContext, type CommandSpec, type PlaceholderKey } from './types.js';\nimport type { AgentConfig } from './config-schema.js';\n\n/** Build the placeholder → value map from a launch context. */\nexport function placeholderValues(ctx: AgentLaunchContext): Record<PlaceholderKey, string> {\n return {\n bundlePath: ctx.bundlePath,\n prompt: ctx.prompt,\n instructionFile: ctx.instructionFile,\n mode: ctx.mode,\n mcpServer: ctx.mcpServer,\n cwd: ctx.cwd,\n };\n}\n\nconst PLACEHOLDER_RE = /\\{([a-zA-Z]+)\\}/g;\n\n/**\n * Replace every known `{placeholder}` in a template string with its value.\n * Unknown placeholders are left untouched (so literal braces survive). This is\n * the *entire* job of the launcher — no vendor-specific knowledge lives here.\n */\nexport function resolvePlaceholders(template: string, ctx: AgentLaunchContext): string {\n const values = placeholderValues(ctx);\n return template.replace(PLACEHOLDER_RE, (match, key: string) => {\n return key in values ? values[key as PlaceholderKey] : match;\n });\n}\n\n/** Resolve an entire {@link AgentConfig} into a concrete {@link CommandSpec}. */\nexport function resolveCommand(config: AgentConfig, ctx: AgentLaunchContext): CommandSpec {\n const env = config.env\n ? Object.fromEntries(\n Object.entries(config.env).map(([k, v]) => [k, resolvePlaceholders(v, ctx)]),\n )\n : undefined;\n return {\n command: resolvePlaceholders(config.command, ctx),\n args: config.args.map((a) => resolvePlaceholders(a, ctx)),\n cwd: config.cwd ? resolvePlaceholders(config.cwd, ctx) : ctx.cwd,\n ...(env ? { env } : {}),\n };\n}\n\n/** List the placeholders actually referenced by a template string. */\nexport function referencedPlaceholders(template: string): PlaceholderKey[] {\n const found = new Set<PlaceholderKey>();\n for (const m of template.matchAll(PLACEHOLDER_RE)) {\n const key = m[1] as string;\n if ((PLACEHOLDER_KEYS as readonly string[]).includes(key)) {\n found.add(key as PlaceholderKey);\n }\n }\n return [...found];\n}\n","import { access, constants } from 'node:fs/promises';\nimport { delimiter, join } from 'node:path';\n\n/**\n * Default executable-on-PATH check. Scans `PATH` for the given binary,\n * honoring `PATHEXT` on Windows. Adapters receive this via the launch context\n * but the daemon may override it (e.g. for tests).\n */\nexport async function defaultBinExists(bin: string): Promise<boolean> {\n // An explicit path: just check it directly.\n if (bin.includes('/') || bin.includes('\\\\')) {\n return canExecute(bin);\n }\n const pathEnv = process.env.PATH ?? '';\n const exts = process.platform === 'win32' ? (process.env.PATHEXT ?? '.EXE;.CMD;.BAT').split(';') : [''];\n for (const dir of pathEnv.split(delimiter)) {\n if (!dir) continue;\n for (const ext of exts) {\n if (await canExecute(join(dir, bin + ext))) return true;\n }\n }\n return false;\n}\n\nasync function canExecute(file: string): Promise<boolean> {\n try {\n await access(file, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { defaultBinExists } from './bin-exists.js';\nimport { resolveCommand } from './placeholders.js';\nimport type { AgentConfig } from './config-schema.js';\nimport type { AgentAdapter, AgentEvent, AgentLaunchContext } from './types.js';\n\n/**\n * Turn a config entry into a live {@link AgentAdapter}. This is the bridge that\n * lets *data* (`agents.config.json`) behave like a built-in adapter:\n *\n * - `isAvailable` checks the configured `detect.anyOf` executables on PATH.\n * - `buildCommand` resolves placeholders into a concrete command.\n * - `parseEvents` applies the optional regexes from `config.parse`.\n */\nexport function configToAdapter(config: AgentConfig): AgentAdapter {\n const planRe = config.parse?.planReady ? new RegExp(config.parse.planReady, 'i') : undefined;\n const errRe = config.parse?.error ? new RegExp(config.parse.error, 'i') : undefined;\n\n return {\n id: config.id,\n\n async isAvailable(ctx: AgentLaunchContext): Promise<boolean> {\n const bins = config.detect?.anyOf ?? [config.command];\n const exists = ctx.binExists ?? defaultBinExists;\n for (const bin of bins) {\n if (await exists(bin)) return true;\n }\n return false;\n },\n\n buildCommand(ctx: AgentLaunchContext) {\n return resolveCommand(config, ctx);\n },\n\n parseEvents(chunk: string): AgentEvent[] {\n if (!planRe && !errRe) return [];\n const events: AgentEvent[] = [];\n for (const line of chunk.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n if (errRe?.test(line)) events.push({ type: 'error', message: line.trim() });\n else if (planRe?.test(line)) events.push({ type: 'plan-ready' });\n }\n return events;\n },\n };\n}\n\n/** Build adapters for every agent in a config, keyed by id. */\nexport function buildAdapters(configs: readonly AgentConfig[]): Map<string, AgentAdapter> {\n const map = new Map<string, AgentAdapter>();\n for (const config of configs) {\n map.set(config.id, configToAdapter(config));\n }\n return map;\n}\n","import { LOCATOR_PRIORITY } from '@clicksmith/core';\n\nexport interface InstructionTemplateOptions {\n /** MCP tool names exposed by the daemon. */\n mcpTools?: readonly string[];\n /** The daemon port, for the agent's reference. */\n daemonPort?: number;\n /** Project-specific stable attributes the project relies on (e.g. data-testid). */\n stableAttrs?: readonly string[];\n}\n\nexport const DEFAULT_MCP_TOOLS = [\n 'get_session',\n 'list_elements',\n 'get_element_by_id',\n 'get_latest_request',\n] as const;\n\n/**\n * The single, shared instruction body. Every native renderer wraps this exact\n * text — so Claude, Cursor, Codex, Antigravity and generic agents all learn the\n * same three things: the `#N` reference system, locator priority, and the\n * plan/worktree safety contract.\n */\nexport function renderInstructionBody(options: InstructionTemplateOptions = {}): string {\n const tools = options.mcpTools ?? DEFAULT_MCP_TOOLS;\n const attrs = options.stableAttrs ?? [];\n const locatorList = LOCATOR_PRIORITY.map((kind, i) => `${i + 1}. **${kind}**`).join(' → ');\n\n return `# ClickSmith — working with captured UI requests\n\nYou are being asked to change UI elements that a human pointed at in their browser\nwith ClickSmith. Each request arrives as a **capture bundle** (a JSON file whose\npath is provided to you) describing one or more elements and a free-text prompt.\n\n## 1. The \\`#N\\` reference system\n\nElements are numbered \\`#1\\`, \\`#2\\`, … in the order they were captured. The user's\nprompt refers to them by number, e.g. _\"make #1 match #2's style\"_. Always resolve\n\\`#N\\` to \\`elements[]\\` entries with the matching \\`id\\` field. Never guess which\nelement is meant — read the bundle.\n\n## 2. Locator priority\n\nEach element carries a \\`locator\\`. Trust them in this exact order, best first:\n\n${locatorList}\n\n- **source** gives an exact \\`file:line\\` (injected in dev by @clicksmith/unplugin) —\n edit there directly.\n- **attr** is a stable attribute${attrs.length ? ` (this project uses: ${attrs.map((a) => `\\`${a}\\``).join(', ')})` : ''}; grep for it to find the JSX/template.\n- **behavioral** is an ARIA role + accessible name; search for the visible text/label.\n- **dom** is a structural fallback; use \\`el.text\\`, \\`el.attrs\\`, and \\`near\\` context to\n locate the component, and prefer adding a stable attribute while you're there.\n\n## 3. Plan / worktree safety (read carefully)\n\nClickSmith runs you inside an **isolated git worktree** by default. The execution\nmode is in \\`execution.mode\\`:\n\n- **plan** (the default): produce a clear plan and, if helpful, a diff — but **do\n not** assume your edits ship. The human reviews your plan/diff and explicitly\n clicks **Apply**. Your job is to propose, precisely.\n- **edit**: you may modify files in the sandbox. They still do **not** reach the\n user's main working tree until they click Apply.\n\nNever run destructive git commands, never push, and never touch files outside the\nsandbox working directory.\n\n## 4. Reading the request\n\nThe bundle path is passed on the command line / via your harness. ${\n tools.length\n ? `You can also use these MCP tools (server \\`clicksmith\\`): ${tools\n .map((t) => `\\`${t}\\``)\n .join(', ')}. Use \\`get_latest_request\\` to fetch the most recent submission, then \\`get_element_by_id\\` to resolve a specific \\`#N\\`.`\n : ''\n}\n\nEach element includes: \\`locator\\`, \\`el\\` (tag/text/role/label/attrs/icon hints),\n\\`near\\` (surrounding labels & headings), \\`conditions\\` (viewport/theme), and an\noptional \\`screenshot\\` thumbnail. Use \\`near\\` and \\`app.route\\` to disambiguate when\nmultiple elements look similar.\n${options.daemonPort ? `\\nThe ClickSmith daemon is at http://127.0.0.1:${options.daemonPort}.\\n` : ''}`;\n}\n","import { renderInstructionBody, type InstructionTemplateOptions } from './instruction-template.js';\nimport type { InstructionTarget } from './config-schema.js';\n\nexport const MANAGED_BEGIN = '<!-- BEGIN CLICKSMITH (managed — do not edit by hand) -->';\nexport const MANAGED_END = '<!-- END CLICKSMITH (managed) -->';\n\nexport interface RenderedInstruction {\n target: InstructionTarget;\n /** Default relative path for this target's native file. */\n path: string;\n /**\n * `true` when the target file commonly holds other content (e.g. `CLAUDE.md`,\n * `AGENTS.md`). The installer then inserts {@link content} as a managed block\n * rather than overwriting the whole file.\n */\n shared: boolean;\n /** Full file content (dedicated files) or managed-block body (shared files). */\n content: string;\n}\n\n/** Wrap a body in the managed-block markers. */\nexport function wrapManagedBlock(body: string): string {\n return `${MANAGED_BEGIN}\\n${body.trim()}\\n${MANAGED_END}\\n`;\n}\n\n/**\n * Insert or replace the ClickSmith managed block within existing file content,\n * preserving everything the user wrote outside the markers.\n */\nexport function applyManagedBlock(existing: string | undefined, body: string): string {\n const block = wrapManagedBlock(body);\n if (!existing || !existing.trim()) return block;\n const begin = existing.indexOf(MANAGED_BEGIN);\n const end = existing.indexOf(MANAGED_END);\n if (begin !== -1 && end !== -1 && end > begin) {\n const before = existing.slice(0, begin);\n const after = existing.slice(end + MANAGED_END.length);\n return `${before}${block.trimEnd()}${after}`.replace(/\\n{3,}/g, '\\n\\n');\n }\n return `${existing.trimEnd()}\\n\\n${block}`;\n}\n\nfunction cursorMdc(body: string): string {\n // Cursor \"Project Rules\" use MDC frontmatter; alwaysApply keeps it active.\n return `---\ndescription: ClickSmith — how to handle captured UI change requests\nalwaysApply: true\n---\n\n${body.trim()}\n`;\n}\n\n/** Render the shared instruction body into a target's native file. */\nexport function renderInstructions(\n target: InstructionTarget,\n options: InstructionTemplateOptions = {},\n): RenderedInstruction {\n const body = renderInstructionBody(options);\n switch (target) {\n case 'claude':\n return { target, path: 'CLAUDE.md', shared: true, content: body };\n case 'codex':\n return { target, path: 'AGENTS.md', shared: true, content: body };\n case 'cursor':\n return { target, path: '.cursor/rules/clicksmith.mdc', shared: false, content: cursorMdc(body) };\n case 'antigravity':\n return {\n target,\n path: '.antigravity/rules/clicksmith.md',\n shared: false,\n content: `${body.trim()}\\n`,\n };\n case 'generic':\n return {\n target,\n path: '.clicksmith/AGENT_INSTRUCTIONS.md',\n shared: false,\n content: `${body.trim()}\\n`,\n };\n default: {\n const _exhaustive: never = target;\n throw new Error(`Unknown instruction target: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** Render instruction files for several targets at once. */\nexport function renderAllInstructions(\n targets: readonly InstructionTarget[],\n options: InstructionTemplateOptions = {},\n): RenderedInstruction[] {\n return targets.map((t) => renderInstructions(t, options));\n}\n","import type { AgentConfig, AgentsConfig } from './config-schema.js';\n\n/**\n * Built-in agent templates. **These are example defaults — data, not launcher\n * logic.** Changing a vendor's CLI flag means editing `agents.config.json`\n * (or these defaults), never the daemon. The launcher only resolves the\n * `{placeholders}` below; it has no idea what `claude` or `codex` actually do.\n */\nexport const DEFAULT_AGENTS: AgentConfig[] = [\n {\n id: 'claude',\n label: 'Claude Code',\n command: 'claude',\n args: ['-p', '{prompt}', '--append-system-prompt', '@{instructionFile}'],\n detect: { anyOf: ['claude'] },\n instructions: { target: 'claude', file: 'CLAUDE.md' },\n mcp: { register: 'claude' },\n parse: { planReady: 'plan ready|here is the plan|## plan', error: '^error:|fatal:' },\n },\n {\n id: 'cursor',\n label: 'Cursor Agent',\n command: 'cursor-agent',\n args: ['--print', '{prompt}'],\n detect: { anyOf: ['cursor-agent', 'cursor'] },\n instructions: { target: 'cursor', file: '.cursor/rules/clicksmith.mdc' },\n mcp: { register: 'cursor' },\n },\n {\n id: 'codex',\n label: 'OpenAI Codex',\n command: 'codex',\n args: ['exec', '{prompt}'],\n detect: { anyOf: ['codex'] },\n instructions: { target: 'codex', file: 'AGENTS.md' },\n mcp: { register: 'codex' },\n },\n {\n id: 'antigravity',\n label: 'Antigravity',\n command: 'antigravity',\n args: ['run', '--prompt', '{prompt}'],\n detect: { anyOf: ['antigravity'] },\n instructions: { target: 'antigravity', file: '.antigravity/rules/clicksmith.md' },\n mcp: { register: 'mcp-json' },\n },\n {\n id: 'generic',\n label: 'Generic agent (customize me)',\n command: 'sh',\n args: [\n '-c',\n 'echo \"ClickSmith request: {prompt}\"; echo \"Bundle: {bundlePath}\"; echo \"Instructions: {instructionFile}\"; echo \"Mode: {mode}\"',\n ],\n instructions: { target: 'generic', file: '.clicksmith/AGENT_INSTRUCTIONS.md' },\n mcp: { register: 'mcp-json' },\n },\n];\n\n/** The full default `agents.config.json` document. */\nexport const DEFAULT_AGENTS_CONFIG: AgentsConfig = {\n version: 1,\n defaultAgent: 'claude',\n agents: DEFAULT_AGENTS,\n};\n","import type { AgentConfig, AgentsConfig } from './config-schema.js';\n\n/**\n * Layer agent configs: shipped defaults → project config → user config. Agents\n * with the same `id` are replaced by later layers; new ids are appended in\n * order. `defaultAgent` from the last layer that sets it wins.\n */\nexport function mergeAgentsConfig(base: AgentsConfig, ...overlays: AgentsConfig[]): AgentsConfig {\n let agents = [...base.agents];\n let defaultAgent = base.defaultAgent;\n\n for (const overlay of overlays) {\n agents = mergeAgentList(agents, overlay.agents);\n if (overlay.defaultAgent) defaultAgent = overlay.defaultAgent;\n }\n\n return {\n version: 1,\n ...(defaultAgent ? { defaultAgent } : {}),\n agents,\n };\n}\n\nfunction mergeAgentList(base: AgentConfig[], overlay: AgentConfig[]): AgentConfig[] {\n const byId = new Map(base.map((a) => [a.id, a]));\n const order = base.map((a) => a.id);\n for (const agent of overlay) {\n if (!byId.has(agent.id)) order.push(agent.id);\n byId.set(agent.id, agent);\n }\n return order.map((id) => byId.get(id)!);\n}\n\n/** Resolve the effective agent for a run: explicit id → defaultAgent → first. */\nexport function resolveAgent(config: AgentsConfig, agentId?: string): AgentConfig | undefined {\n if (agentId) return config.agents.find((a) => a.id === agentId);\n if (config.defaultAgent) {\n const found = config.agents.find((a) => a.id === config.defaultAgent);\n if (found) return found;\n }\n return config.agents[0];\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/config-schema.ts","../src/placeholders.ts","../src/bin-exists.ts","../src/adapter.ts","../src/instruction-template.ts","../src/renderers.ts","../src/defaults.ts","../src/merge.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ExecutionMode, Isolation } from '@clicksmith/core';\n\n/** Every placeholder the launcher knows how to resolve in a command template. */\nexport const PLACEHOLDER_KEYS = [\n 'bundlePath',\n 'prompt',\n 'agentPrompt',\n 'instructionFile',\n 'mode',\n 'mcpServer',\n 'cwd',\n] as const;\n\nexport type PlaceholderKey = (typeof PLACEHOLDER_KEYS)[number];\n\n/**\n * Everything the launcher needs to turn a config-driven command template into a\n * concrete process invocation. This is also the `ctx` passed to adapter hooks.\n */\nexport interface AgentLaunchContext {\n /** Absolute path to the serialized capture bundle. */\n bundlePath: string;\n /** The user's free-text prompt. */\n prompt: string;\n /** Full agent-ready prompt containing the ClickSmith bundle and instruction paths. */\n agentPrompt: string;\n /** Absolute path to the rendered instruction file for this agent. */\n instructionFile: string;\n /** Execution mode (`plan` | `edit`). */\n mode: ExecutionMode;\n /** A reference the agent can use to reach the ClickSmith MCP server. */\n mcpServer: string;\n /** Working directory for the spawned process (the sandbox). */\n cwd: string;\n /** Isolation strategy in effect for this run. */\n isolation: Isolation;\n /** The agent id being launched. */\n agentId: string;\n /**\n * Resolves whether an executable exists on PATH. Injected by the daemon so\n * adapters never have to spawn processes themselves. Defaults to a PATH scan.\n */\n binExists?: (bin: string) => Promise<boolean>;\n}\n\n/** A concrete, ready-to-spawn process specification. */\nexport interface CommandSpec {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/** A normalized event parsed from an agent's stdout/stderr stream. */\nexport type AgentEvent =\n | { type: 'plan-ready'; plan?: string; diff?: string }\n | { type: 'progress'; message: string }\n | { type: 'error'; message: string };\n\n/**\n * The adapter contract. Built-in adapters are produced from `agents.config.json`\n * by {@link configToAdapter}; the launcher only resolves placeholders. Authors\n * may also hand-write adapters that satisfy this interface.\n */\nexport interface AgentAdapter {\n id: string;\n /** Whether the agent's CLI is installed/usable in this context. */\n isAvailable(ctx: AgentLaunchContext): Promise<boolean>;\n /** Build the concrete command to spawn. */\n buildCommand(ctx: AgentLaunchContext): CommandSpec;\n /** Optionally map a raw output chunk into structured events. */\n parseEvents?(chunk: string, ctx: AgentLaunchContext): AgentEvent[];\n}\n","import { z } from 'zod';\n\n/** Which native instruction format a renderer should target. */\nexport const InstructionTargetSchema = z.enum([\n 'claude',\n 'cursor',\n 'codex',\n 'antigravity',\n 'generic',\n]);\nexport type InstructionTarget = z.infer<typeof InstructionTargetSchema>;\n\n/** How (and whether) to register the daemon's MCP server for this agent. */\nexport const McpRegistrationSchema = z.enum(['claude', 'cursor', 'codex', 'mcp-json', 'none']);\nexport type McpRegistration = z.infer<typeof McpRegistrationSchema>;\n\n/**\n * One agent definition. The `command`/`args` are templates containing\n * placeholders like `{prompt}` — they are **data**, never code. Changing a\n * vendor flag is an edit here, not a code change.\n */\nexport const AgentConfigSchema = z.object({\n id: z.string().min(1),\n label: z.string().optional(),\n /** Executable name or path. May contain placeholders. */\n command: z.string().min(1),\n /** Argument templates; each entry may contain placeholders. */\n args: z.array(z.string()).default([]),\n /** Extra environment variables (values may contain placeholders). */\n env: z.record(z.string()).optional(),\n /** Working directory override (placeholders allowed). Defaults to the sandbox. */\n cwd: z.string().optional(),\n /** How to detect availability: any of these executables must be on PATH. */\n detect: z\n .object({\n anyOf: z.array(z.string()).min(1),\n })\n .optional(),\n /** Where to render this agent's instruction file. */\n instructions: z\n .object({\n target: InstructionTargetSchema,\n file: z.string().min(1),\n })\n .optional(),\n /** How to register the daemon MCP server for this agent. */\n mcp: z\n .object({\n register: McpRegistrationSchema,\n })\n .optional(),\n /** Optional regexes that map log lines to structured events. */\n parse: z\n .object({\n planReady: z.string().optional(),\n error: z.string().optional(),\n })\n .optional(),\n});\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\n\n/** The top-level `agents.config.json` document. */\nexport const AgentsConfigSchema = z.object({\n version: z.literal(1).default(1),\n defaultAgent: z.string().optional(),\n agents: z.array(AgentConfigSchema).default([]),\n});\nexport type AgentsConfig = z.infer<typeof AgentsConfigSchema>;\n\n/** Parse and validate an `agents.config.json` value without throwing. */\nexport function parseAgentsConfig(value: unknown):\n | { ok: true; config: AgentsConfig }\n | { ok: false; error: z.ZodError } {\n const result = AgentsConfigSchema.safeParse(value);\n return result.success\n ? { ok: true, config: result.data }\n : { ok: false, error: result.error };\n}\n","import {\n PLACEHOLDER_KEYS,\n type AgentLaunchContext,\n type CommandSpec,\n type PlaceholderKey,\n} from './types.js';\nimport type { AgentConfig } from './config-schema.js';\n\n/** Build the placeholder → value map from a launch context. */\nexport function placeholderValues(ctx: AgentLaunchContext): Record<PlaceholderKey, string> {\n return {\n bundlePath: ctx.bundlePath,\n prompt: ctx.prompt,\n agentPrompt: ctx.agentPrompt,\n instructionFile: ctx.instructionFile,\n mode: ctx.mode,\n mcpServer: ctx.mcpServer,\n cwd: ctx.cwd,\n };\n}\n\nconst PLACEHOLDER_RE = /\\{([a-zA-Z]+)\\}/g;\n\n/**\n * Replace every known `{placeholder}` in a template string with its value.\n * Unknown placeholders are left untouched (so literal braces survive). This is\n * the *entire* job of the launcher — no vendor-specific knowledge lives here.\n */\nexport function resolvePlaceholders(template: string, ctx: AgentLaunchContext): string {\n const values = placeholderValues(ctx);\n return template.replace(PLACEHOLDER_RE, (match, key: string) => {\n return key in values ? values[key as PlaceholderKey] : match;\n });\n}\n\n/** Resolve an entire {@link AgentConfig} into a concrete {@link CommandSpec}. */\nexport function resolveCommand(config: AgentConfig, ctx: AgentLaunchContext): CommandSpec {\n const env = config.env\n ? Object.fromEntries(\n Object.entries(config.env).map(([k, v]) => [k, resolvePlaceholders(v, ctx)]),\n )\n : undefined;\n return {\n command: resolvePlaceholders(config.command, ctx),\n args: config.args.map((a) => resolvePlaceholders(a, ctx)),\n cwd: config.cwd ? resolvePlaceholders(config.cwd, ctx) : ctx.cwd,\n ...(env ? { env } : {}),\n };\n}\n\n/** List the placeholders actually referenced by a template string. */\nexport function referencedPlaceholders(template: string): PlaceholderKey[] {\n const found = new Set<PlaceholderKey>();\n for (const m of template.matchAll(PLACEHOLDER_RE)) {\n const key = m[1] as string;\n if ((PLACEHOLDER_KEYS as readonly string[]).includes(key)) {\n found.add(key as PlaceholderKey);\n }\n }\n return [...found];\n}\n","import { access, constants } from 'node:fs/promises';\nimport { delimiter, join } from 'node:path';\n\n/**\n * Default executable-on-PATH check. Scans `PATH` for the given binary,\n * honoring `PATHEXT` on Windows. Adapters receive this via the launch context\n * but the daemon may override it (e.g. for tests).\n */\nexport async function defaultBinExists(bin: string): Promise<boolean> {\n // An explicit path: just check it directly.\n if (bin.includes('/') || bin.includes('\\\\')) {\n return canExecute(bin);\n }\n const pathEnv = process.env.PATH ?? '';\n const exts = process.platform === 'win32' ? (process.env.PATHEXT ?? '.EXE;.CMD;.BAT').split(';') : [''];\n for (const dir of pathEnv.split(delimiter)) {\n if (!dir) continue;\n for (const ext of exts) {\n if (await canExecute(join(dir, bin + ext))) return true;\n }\n }\n return false;\n}\n\nasync function canExecute(file: string): Promise<boolean> {\n try {\n await access(file, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { defaultBinExists } from './bin-exists.js';\nimport { resolveCommand } from './placeholders.js';\nimport type { AgentConfig } from './config-schema.js';\nimport type { AgentAdapter, AgentEvent, AgentLaunchContext } from './types.js';\n\n/**\n * Turn a config entry into a live {@link AgentAdapter}. This is the bridge that\n * lets *data* (`agents.config.json`) behave like a built-in adapter:\n *\n * - `isAvailable` checks the configured `detect.anyOf` executables on PATH.\n * - `buildCommand` resolves placeholders into a concrete command.\n * - `parseEvents` applies the optional regexes from `config.parse`.\n */\nexport function configToAdapter(config: AgentConfig): AgentAdapter {\n const planRe = config.parse?.planReady ? new RegExp(config.parse.planReady, 'i') : undefined;\n const errRe = config.parse?.error ? new RegExp(config.parse.error, 'i') : undefined;\n\n return {\n id: config.id,\n\n async isAvailable(ctx: AgentLaunchContext): Promise<boolean> {\n const bins = config.detect?.anyOf ?? [config.command];\n const exists = ctx.binExists ?? defaultBinExists;\n for (const bin of bins) {\n if (await exists(bin)) return true;\n }\n return false;\n },\n\n buildCommand(ctx: AgentLaunchContext) {\n return resolveCommand(config, ctx);\n },\n\n parseEvents(chunk: string): AgentEvent[] {\n if (!planRe && !errRe) return [];\n const events: AgentEvent[] = [];\n for (const line of chunk.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n if (errRe?.test(line)) events.push({ type: 'error', message: line.trim() });\n else if (planRe?.test(line)) events.push({ type: 'plan-ready' });\n }\n return events;\n },\n };\n}\n\n/** Build adapters for every agent in a config, keyed by id. */\nexport function buildAdapters(configs: readonly AgentConfig[]): Map<string, AgentAdapter> {\n const map = new Map<string, AgentAdapter>();\n for (const config of configs) {\n map.set(config.id, configToAdapter(config));\n }\n return map;\n}\n","import { LOCATOR_PRIORITY } from '@clicksmith/core';\n\nexport interface InstructionTemplateOptions {\n /** MCP tool names exposed by the daemon. */\n mcpTools?: readonly string[];\n /** The daemon port, for the agent's reference. */\n daemonPort?: number;\n /** Project-specific stable attributes the project relies on (e.g. data-testid). */\n stableAttrs?: readonly string[];\n}\n\nexport const DEFAULT_MCP_TOOLS = [\n 'get_session',\n 'list_elements',\n 'get_element_by_id',\n 'get_latest_request',\n] as const;\n\n/**\n * The single, shared instruction body. Every native renderer wraps this exact\n * text so Claude, Cursor, Codex, Antigravity and generic agents all receive the\n * same compact fast-path contract.\n */\nexport function renderInstructionBody(options: InstructionTemplateOptions = {}): string {\n const tools = options.mcpTools ?? DEFAULT_MCP_TOOLS;\n const attrs = options.stableAttrs ?? [];\n const locatorList = LOCATOR_PRIORITY.map((kind, i) => `${i + 1}. ${kind}`).join(' -> ');\n\n return `# ClickSmith fast UI edits\n\nClickSmith sends a small browser-capture summary for UI changes. Optimize for a\ntargeted edit, not broad repo exploration.\n\nFast path:\n\n- Resolve \\`#N\\` from the prompt's target summaries first. Read the bundle only if\n the summaries are ambiguous.\n- Locator order: ${locatorList}. Source means exact file:line. Attr means grep the\n stable value${attrs.length ? ` (project attrs: ${attrs.join(', ')})` : ''}. Behavioral means grep the label/text. Dom means use captured attrs, searchTokens,\n nearby headings, and route.\n- Before opening broad docs, run at most two targeted searches, preferably\n \\`git grep -n -e 'exact-token' -- .\\`.\n- Do not read AGENTS.md, CLAUDE.md, .cursor/rules, guidelines, skills, or tool\n docs before the targeted lookup.\n- Do not edit shared sprite/icon definitions unless the request asks for the\n shared asset; edit the component/template usage instead.\n- Keep edits minimal, non-destructive, and inside the current working directory.\n- In worktree/branch isolation, ClickSmith reviews and applies changes in a later\n Apply step. In inplace mode, edits affect the current tree immediately.\n\nMCP is optional. ${\n tools.length\n ? `If needed, the \\`clicksmith\\` server exposes: ${tools\n .map((t) => `\\`${t}\\``)\n .join(', ')}.`\n : ''\n}\n${options.daemonPort ? `\\nThe ClickSmith daemon is at http://127.0.0.1:${options.daemonPort}.\\n` : ''}`;\n}\n","import { renderInstructionBody, type InstructionTemplateOptions } from './instruction-template.js';\nimport type { InstructionTarget } from './config-schema.js';\n\nexport const MANAGED_BEGIN = '<!-- BEGIN CLICKSMITH (managed — do not edit by hand) -->';\nexport const MANAGED_END = '<!-- END CLICKSMITH (managed) -->';\n\nexport interface RenderedInstruction {\n target: InstructionTarget;\n /** Default relative path for this target's native file. */\n path: string;\n /**\n * `true` when the target file commonly holds other content (e.g. `CLAUDE.md`,\n * `AGENTS.md`). The installer then inserts {@link content} as a managed block\n * rather than overwriting the whole file.\n */\n shared: boolean;\n /** Full file content (dedicated files) or managed-block body (shared files). */\n content: string;\n}\n\n/** Wrap a body in the managed-block markers. */\nexport function wrapManagedBlock(body: string): string {\n return `${MANAGED_BEGIN}\\n${body.trim()}\\n${MANAGED_END}\\n`;\n}\n\n/**\n * Insert or replace the ClickSmith managed block within existing file content,\n * preserving everything the user wrote outside the markers.\n */\nexport function applyManagedBlock(existing: string | undefined, body: string): string {\n const block = wrapManagedBlock(body);\n if (!existing || !existing.trim()) return block;\n const begin = existing.indexOf(MANAGED_BEGIN);\n const end = existing.indexOf(MANAGED_END);\n if (begin !== -1 && end !== -1 && end > begin) {\n const before = existing.slice(0, begin);\n const after = existing.slice(end + MANAGED_END.length);\n return `${before}${block.trimEnd()}${after}`.replace(/\\n{3,}/g, '\\n\\n');\n }\n return `${existing.trimEnd()}\\n\\n${block}`;\n}\n\nfunction cursorMdc(body: string): string {\n // Cursor \"Project Rules\" use MDC frontmatter; alwaysApply keeps it active.\n return `---\ndescription: ClickSmith — how to handle captured UI change requests\nalwaysApply: true\n---\n\n${body.trim()}\n`;\n}\n\n/** Render the shared instruction body into a target's native file. */\nexport function renderInstructions(\n target: InstructionTarget,\n options: InstructionTemplateOptions = {},\n): RenderedInstruction {\n const body = renderInstructionBody(options);\n switch (target) {\n case 'claude':\n return { target, path: 'CLAUDE.md', shared: true, content: body };\n case 'codex':\n return { target, path: 'AGENTS.md', shared: true, content: body };\n case 'cursor':\n return { target, path: '.cursor/rules/clicksmith.mdc', shared: false, content: cursorMdc(body) };\n case 'antigravity':\n return {\n target,\n path: '.antigravity/rules/clicksmith.md',\n shared: false,\n content: `${body.trim()}\\n`,\n };\n case 'generic':\n return {\n target,\n path: '.clicksmith/AGENT_INSTRUCTIONS.md',\n shared: false,\n content: `${body.trim()}\\n`,\n };\n default: {\n const _exhaustive: never = target;\n throw new Error(`Unknown instruction target: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** Render instruction files for several targets at once. */\nexport function renderAllInstructions(\n targets: readonly InstructionTarget[],\n options: InstructionTemplateOptions = {},\n): RenderedInstruction[] {\n return targets.map((t) => renderInstructions(t, options));\n}\n","import type { AgentConfig, AgentsConfig } from './config-schema.js';\n\n/**\n * Built-in agent templates. **These are example defaults — data, not launcher\n * logic.** Changing a vendor's CLI flag means editing `agents.config.json`\n * (or these defaults), never the daemon. The launcher only resolves the\n * `{placeholders}` below; it has no idea what `claude` or `codex` actually do.\n */\nexport const DEFAULT_AGENTS: AgentConfig[] = [\n {\n id: 'claude',\n label: 'Claude Code',\n command: 'claude',\n args: ['-p', '{agentPrompt}', '--append-system-prompt', '@{instructionFile}'],\n detect: { anyOf: ['claude'] },\n instructions: { target: 'claude', file: 'CLAUDE.md' },\n mcp: { register: 'claude' },\n parse: { planReady: 'plan ready|here is the plan|## plan', error: '^error:|fatal:' },\n },\n {\n id: 'cursor',\n label: 'Cursor Agent',\n command: 'cursor-agent',\n args: ['--print', '{agentPrompt}'],\n detect: { anyOf: ['cursor-agent', 'cursor'] },\n instructions: { target: 'cursor', file: '.cursor/rules/clicksmith.mdc' },\n mcp: { register: 'cursor' },\n },\n {\n id: 'codex',\n label: 'OpenAI Codex',\n command: 'codex',\n args: [\n 'exec',\n '--cd',\n '{cwd}',\n '--sandbox',\n 'workspace-write',\n '--skip-git-repo-check',\n '--ephemeral',\n '-c',\n 'model_reasoning_effort=\"low\"',\n '{agentPrompt}',\n ],\n detect: { anyOf: ['codex'] },\n instructions: { target: 'codex', file: 'AGENTS.md' },\n mcp: { register: 'codex' },\n },\n {\n id: 'antigravity',\n label: 'Antigravity',\n command: 'antigravity',\n args: ['run', '--prompt', '{agentPrompt}'],\n detect: { anyOf: ['antigravity'] },\n instructions: { target: 'antigravity', file: '.antigravity/rules/clicksmith.md' },\n mcp: { register: 'mcp-json' },\n },\n {\n id: 'generic',\n label: 'Generic agent (customize me)',\n command: 'sh',\n args: [\n '-c',\n 'echo \"ClickSmith request: {prompt}\"; echo \"Bundle: {bundlePath}\"; echo \"Instructions: {instructionFile}\"; echo \"Mode: {mode}\"; echo \"Prompt: {agentPrompt}\"',\n ],\n instructions: { target: 'generic', file: '.clicksmith/AGENT_INSTRUCTIONS.md' },\n mcp: { register: 'mcp-json' },\n },\n];\n\n/** The full default `agents.config.json` document. */\nexport const DEFAULT_AGENTS_CONFIG: AgentsConfig = {\n version: 1,\n defaultAgent: 'claude',\n agents: DEFAULT_AGENTS,\n};\n","import type { AgentConfig, AgentsConfig } from './config-schema.js';\n\n/**\n * Layer agent configs: shipped defaults → project config → user config. Agents\n * with the same `id` are replaced by later layers; new ids are appended in\n * order. `defaultAgent` from the last layer that sets it wins.\n */\nexport function mergeAgentsConfig(base: AgentsConfig, ...overlays: AgentsConfig[]): AgentsConfig {\n let agents = [...base.agents];\n let defaultAgent = base.defaultAgent;\n\n for (const overlay of overlays) {\n agents = mergeAgentList(agents, overlay.agents);\n if (overlay.defaultAgent) defaultAgent = overlay.defaultAgent;\n }\n\n return {\n version: 1,\n ...(defaultAgent ? { defaultAgent } : {}),\n agents,\n };\n}\n\nfunction mergeAgentList(base: AgentConfig[], overlay: AgentConfig[]): AgentConfig[] {\n const byId = new Map(base.map((a) => [a.id, a]));\n const order = base.map((a) => a.id);\n for (const agent of overlay) {\n if (!byId.has(agent.id)) order.push(agent.id);\n byId.set(agent.id, agent);\n }\n return order.map((id) => byId.get(id)!);\n}\n\n/** Resolve the effective agent for a run: explicit id → defaultAgent → first. */\nexport function resolveAgent(config: AgentsConfig, agentId?: string): AgentConfig | undefined {\n if (agentId) return config.agents.find((a) => a.id === agentId);\n if (config.defaultAgent) {\n const found = config.agents.find((a) => a.id === config.defaultAgent);\n if (found) return found;\n }\n return config.agents[0];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicksmith/agent-config",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Config-driven agent adapters and the shared ClickSmith instruction template, rendered to native files for Claude, Cursor, Codex, Antigravity, and generic agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",