@appsforgood/next-supabase-kit 0.1.3 → 0.1.4

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.js CHANGED
@@ -141,12 +141,12 @@ function addSkill(cwd, skillName, options = {}) {
141
141
  }
142
142
 
143
143
  // src/install/adapter-validate.ts
144
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
145
- import { join as join11, normalize } from "path";
144
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
145
+ import { join as join12, normalize } from "path";
146
146
 
147
147
  // src/config/defaults.ts
148
148
  var PACKAGE_NAME = "@appsforgood/next-supabase-kit";
149
- var PACKAGE_VERSION = "0.1.3";
149
+ var PACKAGE_VERSION = "0.1.4";
150
150
  var DEFAULT_CONFIG = {
151
151
  stack: "next-supabase",
152
152
  projectType: "saas",
@@ -215,6 +215,20 @@ var CURSOR_ADAPTER_FILES = [
215
215
  target: ".cursor/rules/cursor-model-selection.mdc"
216
216
  }
217
217
  ];
218
+ var CURSOR_SCOPED_ADAPTER_FILES = [
219
+ {
220
+ source: "assistant-adapters/cursor-planner.mdc",
221
+ target: ".cursor/rules/cursor-planner.mdc"
222
+ },
223
+ {
224
+ source: "assistant-adapters/cursor-security.mdc",
225
+ target: ".cursor/rules/cursor-security.mdc"
226
+ },
227
+ {
228
+ source: "assistant-adapters/cursor-frontend.mdc",
229
+ target: ".cursor/rules/cursor-frontend.mdc"
230
+ }
231
+ ];
218
232
  var COPILOT_INSTRUCTION_FILES = [
219
233
  {
220
234
  source: "assistant-adapters/github-copilot-instructions.md",
@@ -345,8 +359,8 @@ function unique(values) {
345
359
  }
346
360
 
347
361
  // src/install/audit.ts
348
- import { existsSync as existsSync10, readFileSync as readFileSync7, statSync } from "fs";
349
- import { join as join10 } from "path";
362
+ import { existsSync as existsSync11, readFileSync as readFileSync8, statSync } from "fs";
363
+ import { join as join11 } from "path";
350
364
 
351
365
  // src/config/contracts.ts
352
366
  import { z } from "zod";
@@ -1100,11 +1114,15 @@ function onboardingStateExists(cwd) {
1100
1114
  }
1101
1115
 
1102
1116
  // src/install/install.ts
1117
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
1118
+ import { join as join10 } from "path";
1119
+
1120
+ // src/install/ide-activate.ts
1103
1121
  import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
1104
1122
  import { join as join9 } from "path";
1105
1123
 
1106
- // src/install/ide-activate.ts
1107
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
1124
+ // src/install/roster-adapters.ts
1125
+ import { existsSync as existsSync8, readFileSync as readFileSync5, readdirSync as readdirSync2 } from "fs";
1108
1126
  import { join as join8 } from "path";
1109
1127
 
1110
1128
  // src/studio/wizard/roster.ts
@@ -1188,8 +1206,224 @@ function agentBriefFieldName(agentId) {
1188
1206
  return `agentBrief_${agentId}`;
1189
1207
  }
1190
1208
 
1191
- // src/install/ide-activate.ts
1209
+ // src/install/assistant-adapters-table.ts
1210
+ function extractAssistantAdapterRow(adaptersDoc, toolLabel) {
1211
+ for (const line of adaptersDoc.split("\n")) {
1212
+ const trimmed = line.trim();
1213
+ if (!trimmed.startsWith("|")) continue;
1214
+ const cells = trimmed.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
1215
+ if (cells[0] === toolLabel) return trimmed;
1216
+ }
1217
+ return null;
1218
+ }
1219
+ function assistantAdapterRowIsActive(adaptersDoc, toolLabel) {
1220
+ const row = extractAssistantAdapterRow(adaptersDoc, toolLabel);
1221
+ if (!row) return false;
1222
+ const cells = row.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
1223
+ const instructionStatus = cells[2] ?? "";
1224
+ return /^Active/i.test(instructionStatus) && !/^TBD/i.test(instructionStatus);
1225
+ }
1226
+
1227
+ // src/install/roster-adapters.ts
1192
1228
  var CANONICAL_READ_LIST = "`AGENTS.md`, `AGENT_ROSTER.md`, `.agent-kit/agent-roster.json`, `MODEL_ROUTING.md`, `.agent-kit/model-routing.json`, `.agent-kit/project-context.json`, `.agent-kit/project-context.md`, `.agent-kit/agent-briefs.md` when present, `.agent-kit/corrections/project-rules.json`, `.agent-kit/corrections/agent-rules.json`, `COUNCIL.md`, `.agent-kit/council-sessions/`, and `QUALITY_GATES.md`";
1229
+ function quoteYamlScalar(value) {
1230
+ return JSON.stringify(value);
1231
+ }
1232
+ function buildAgentHint(agentId, name) {
1233
+ if (agentId === "planner") return "Start with the Planner workflow.";
1234
+ if (agentId === "lead-architect") return "Convene council for core changes before implementation.";
1235
+ if (agentId === "frontend-design-lead") {
1236
+ return "Require brand/content intake, creative-direction rationale, and visual QA evidence for UI changes.";
1237
+ }
1238
+ if (agentId === "security-reviewer") {
1239
+ return "Review auth, RLS, data mutation, dependency, external-call, secret, and release-risk changes.";
1240
+ }
1241
+ return `Use for ${name.toLowerCase()} work defined in the roster.`;
1242
+ }
1243
+ function buildProactiveSuffix(agentId) {
1244
+ const suffixes = {
1245
+ planner: "Use proactively for planning, scope breakdown, ambiguous requests, and workflow routing.",
1246
+ "lead-architect": "Use proactively for core changes, architecture, and cross-layer decisions.",
1247
+ "security-reviewer": "Use proactively for auth, RLS, API, Server Action, data mutation, dependency, secret, and release-risk changes.",
1248
+ "frontend-design-lead": "Use proactively for UI, design system, accessibility, and visual QA work.",
1249
+ "qa-engineer": "Use proactively after behavior changes to add or verify tests and acceptance evidence.",
1250
+ "supabase-postgres-engineer": "Use proactively for schema, migrations, RLS, auth, and SQL changes.",
1251
+ "nextjs-engineer": "Use proactively for App Router, Server Components, route handlers, and UI state work.",
1252
+ "marketing-copy-lead": "Use proactively for public-facing copy, positioning, and conversion surfaces.",
1253
+ "docs-maintainer": "Use proactively after significant changes to update living documentation.",
1254
+ "deployment-observability-engineer": "Use proactively for release, env var, migration order, monitoring, and rollback work."
1255
+ };
1256
+ return suffixes[agentId] ?? "";
1257
+ }
1258
+ function buildSubagentDescription(agent, proactive) {
1259
+ const base = agent.roleSummary.length > 140 ? `${agent.roleSummary.slice(0, 137)}...` : agent.roleSummary;
1260
+ if (!proactive) return base;
1261
+ const suffix = buildProactiveSuffix(agent.id);
1262
+ return suffix ? `${base} ${suffix}` : base;
1263
+ }
1264
+ function buildSubagentMarkdown(agent, options = {}) {
1265
+ const description = buildSubagentDescription(agent, Boolean(options.proactive));
1266
+ const agentFile = agent.file ?? `.agent-kit/agents/${agent.id}.md`;
1267
+ const hint = buildAgentHint(agent.id, agent.name);
1268
+ return `---
1269
+ name: ${quoteYamlScalar(agent.id)}
1270
+ description: ${quoteYamlScalar(description)}
1271
+ ---
1272
+
1273
+ Read ${CANONICAL_READ_LIST} before making routing or implementation decisions.
1274
+
1275
+ Also read \`${agentFile}\` for this role's detailed contract.
1276
+
1277
+ ${hint}
1278
+
1279
+ For council work, delegate to this subagent instead of role-playing the council in the main thread.
1280
+
1281
+ Record meaningful decisions, risks, handoffs, human corrections, artifacts, evidence, and verification through \`agent-kit session checkpoint\` or individual \`agent-kit session ...\` commands when available.
1282
+ `;
1283
+ }
1284
+ function writeGeneratedAgentFile(cwd, relativePath, content, force, result) {
1285
+ const targetPath = join8(cwd, relativePath);
1286
+ if (!force && existsSync8(targetPath)) {
1287
+ const existing = readFileSync5(targetPath, "utf8");
1288
+ if (existing === content) {
1289
+ result.unchanged.push(relativePath);
1290
+ return;
1291
+ }
1292
+ const conflictPath = join8(cwd, ".agent-kit", "conflicts", relativePath.replace(/\//g, "__"));
1293
+ ensureDir(join8(cwd, ".agent-kit", "conflicts"));
1294
+ writeText(conflictPath, existing);
1295
+ result.conflicts.push(`${relativePath} -> ${conflictPath}`);
1296
+ return;
1297
+ }
1298
+ ensureDir(join8(cwd, relativePath.split("/").slice(0, -1).join("/")));
1299
+ writeText(targetPath, content);
1300
+ result.copied.push(relativePath);
1301
+ }
1302
+ function generateMarkdownSubagents(cwd, agentsDir, options) {
1303
+ ensureDir(join8(cwd, agentsDir));
1304
+ for (const agent of loadProjectRosterAgents(cwd)) {
1305
+ const relativePath = `${agentsDir}/${agent.id}.md`;
1306
+ writeGeneratedAgentFile(cwd, relativePath, buildSubagentMarkdown(agent, options), options.force, options.result);
1307
+ }
1308
+ }
1309
+ var CURSOR_AGENTS_README = `# Cursor council subagents
1310
+
1311
+ Project subagents generated from \`.agent-kit/agent-roster.json\`. Use them for isolated specialist context instead of role-playing the whole council in one chat.
1312
+
1313
+ ## Delegation
1314
+
1315
+ | Risk / work type | Subagent |
1316
+ | --- | --- |
1317
+ | Planning / scope | \`@planner\` |
1318
+ | Core architecture | \`@lead-architect\` |
1319
+ | Auth / RLS / secrets | \`@security-reviewer\` or Task \`security-review\` |
1320
+ | Frontend UI | \`@frontend-design-lead\` |
1321
+ | QA / tests | \`@qa-engineer\` |
1322
+
1323
+ Record handoffs with \`agent-kit session checkpoint --file <json>\` when the CLI is available.
1324
+
1325
+ Regenerate with \`agent-kit init --activate cursor\` after roster changes.
1326
+ `;
1327
+ function generateCursorSubagents(cwd, force, result) {
1328
+ generateMarkdownSubagents(cwd, ".cursor/agents", { proactive: true, force, result });
1329
+ writeGeneratedAgentFile(cwd, ".cursor/agents/README.md", CURSOR_AGENTS_README, force, result);
1330
+ }
1331
+ function loadAgentReasoningEffortMap(cwd) {
1332
+ const path = join8(cwd, ".agent-kit/model-routing.json");
1333
+ const map = /* @__PURE__ */ new Map();
1334
+ if (!existsSync8(path)) return map;
1335
+ try {
1336
+ const parsed = JSON.parse(readFileSync5(path, "utf8"));
1337
+ const profileEffort = /* @__PURE__ */ new Map();
1338
+ for (const profile of parsed.profiles ?? []) {
1339
+ if (profile.id && profile.reasoningEffort) {
1340
+ const effort = profile.reasoningEffort;
1341
+ if (effort === "low" || effort === "medium" || effort === "high") {
1342
+ profileEffort.set(profile.id, effort);
1343
+ }
1344
+ }
1345
+ }
1346
+ for (const binding of parsed.agentRoutes ?? []) {
1347
+ if (!binding.agentId) continue;
1348
+ const direct = binding.defaultEffort;
1349
+ if (direct === "low" || direct === "medium" || direct === "high") {
1350
+ map.set(binding.agentId, direct);
1351
+ continue;
1352
+ }
1353
+ if (binding.profileId && profileEffort.has(binding.profileId)) {
1354
+ map.set(binding.agentId, profileEffort.get(binding.profileId));
1355
+ }
1356
+ }
1357
+ } catch {
1358
+ return map;
1359
+ }
1360
+ return map;
1361
+ }
1362
+ function escapeTomlString(value) {
1363
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1364
+ }
1365
+ function buildCodexAgentToml(agent, effort) {
1366
+ const description = buildSubagentDescription(agent, true);
1367
+ const agentFile = agent.file ?? `.agent-kit/agents/${agent.id}.md`;
1368
+ const hint = buildAgentHint(agent.id, agent.name);
1369
+ const instructions = [
1370
+ `Read AGENTS.md, AGENT_ROSTER.md, .agent-kit/agent-roster.json, MODEL_ROUTING.md,`,
1371
+ `.agent-kit/model-routing.json, project context, corrections, COUNCIL.md, QUALITY_GATES.md,`,
1372
+ `and ${agentFile} before reviewing or implementing.`,
1373
+ "",
1374
+ hint,
1375
+ "",
1376
+ "Record meaningful decisions, risks, handoffs, and verification through agent-kit session checkpoint when available."
1377
+ ].join("\n");
1378
+ return `name = "${agent.id}"
1379
+ description = "${escapeTomlString(description)}"
1380
+ # model = "gpt-5.5" # verify in your Codex environment; see MODEL_ROUTING.md
1381
+ model_reasoning_effort = "${effort}"
1382
+
1383
+ developer_instructions = """
1384
+ ${instructions}
1385
+ """
1386
+ `;
1387
+ }
1388
+ function generateCodexCustomAgents(cwd, force, result) {
1389
+ ensureDir(join8(cwd, ".codex/agents"));
1390
+ const effortMap = loadAgentReasoningEffortMap(cwd);
1391
+ for (const agent of loadProjectRosterAgents(cwd)) {
1392
+ const effort = effortMap.get(agent.id) ?? "medium";
1393
+ const relativePath = `.codex/agents/${agent.id}.toml`;
1394
+ writeGeneratedAgentFile(cwd, relativePath, buildCodexAgentToml(agent, effort), force, result);
1395
+ }
1396
+ }
1397
+ function skillDescriptionFromMarkdown(text, skillId) {
1398
+ const useWhen = text.match(/## Use When\s*\n+\s*([^\n#]+)/);
1399
+ if (useWhen?.[1]) return useWhen[1].trim().slice(0, 200);
1400
+ const firstHeading = text.match(/^#\s+(.+)/m);
1401
+ if (firstHeading?.[1]) return `${firstHeading[1].trim()} \u2014 Agent Kit council skill.`;
1402
+ return `Agent Kit skill for ${skillId.replace(/-/g, " ")}.`;
1403
+ }
1404
+ function kitSkillToCursorSkill(skillId, kitMarkdown) {
1405
+ const description = skillDescriptionFromMarkdown(kitMarkdown, skillId);
1406
+ const body = kitMarkdown.replace(/^#\s+.+\n+/, "").trimStart();
1407
+ return `---
1408
+ name: ${quoteYamlScalar(skillId)}
1409
+ description: ${quoteYamlScalar(description)}
1410
+ ---
1411
+
1412
+ ${body.trim()}
1413
+ `;
1414
+ }
1415
+ function generateCursorSkillsFromKit(cwd, force, result) {
1416
+ const skillsRoot = join8(cwd, ".agent-kit/skills");
1417
+ if (!existsSync8(skillsRoot)) return;
1418
+ for (const file of readdirSync2(skillsRoot).filter((name) => name.endsWith(".md"))) {
1419
+ const skillId = file.replace(/\.md$/, "");
1420
+ const kitMarkdown = readFileSync5(join8(skillsRoot, file), "utf8");
1421
+ const relativePath = `.cursor/skills/${skillId}/SKILL.md`;
1422
+ writeGeneratedAgentFile(cwd, relativePath, kitSkillToCursorSkill(skillId, kitMarkdown), force, result);
1423
+ }
1424
+ }
1425
+
1426
+ // src/install/ide-activate.ts
1193
1427
  function normalizeTargets(targets) {
1194
1428
  const allowed = /* @__PURE__ */ new Set(["cursor", "claude", "codex", "copilot", "antigravity"]);
1195
1429
  const normalized = /* @__PURE__ */ new Set();
@@ -1204,9 +1438,9 @@ function normalizeTargets(targets) {
1204
1438
  return [...normalized];
1205
1439
  }
1206
1440
  function copyAdapterFile(cwd, packageRoot, source, target, force, result) {
1207
- const copyResult = copyTextWithConflict(join8(packageRoot, source), cwd, target, {
1441
+ const copyResult = copyTextWithConflict(join9(packageRoot, source), cwd, target, {
1208
1442
  force,
1209
- conflictRoot: join8(cwd, ".agent-kit", "conflicts")
1443
+ conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1210
1444
  });
1211
1445
  if (copyResult.action === "created") result.copied.push(copyResult.target);
1212
1446
  if (copyResult.action === "unchanged") result.unchanged.push(copyResult.target);
@@ -1215,53 +1449,18 @@ function copyAdapterFile(cwd, packageRoot, source, target, force, result) {
1215
1449
  result.conflicts.push(`${copyResult.target} -> ${copyResult.conflictPath}`);
1216
1450
  }
1217
1451
  }
1218
- function buildClaudeSubagentMarkdown(agentId, name, description) {
1219
- const defaultForHint = agentId === "planner" ? "Start with the Planner workflow." : agentId === "lead-architect" ? "Convene council for core changes before implementation." : agentId === "frontend-design-lead" ? "Require brand/content intake, creative-direction rationale, and visual QA evidence for UI changes." : agentId === "security-reviewer" ? "Review auth, RLS, data mutation, dependency, external-call, secret, and release-risk changes." : `Use for ${name.toLowerCase()} work defined in the roster.`;
1220
- return `---
1221
- name: ${agentId}
1222
- description: ${description}
1223
- ---
1224
-
1225
- Read ${CANONICAL_READ_LIST} before making routing or implementation decisions.
1226
-
1227
- ${defaultForHint}
1228
-
1229
- Record meaningful decisions, risks, handoffs, human corrections, artifacts, evidence, and verification through \`agent-kit session checkpoint\` or individual \`agent-kit session ...\` commands when available.
1230
- `;
1231
- }
1232
1452
  function generateClaudeSubagents(cwd, packageRoot, force, result) {
1233
- ensureDir(join8(cwd, ".claude", "agents"));
1234
- const agents = loadProjectRosterAgents(cwd);
1235
- for (const agent of agents) {
1236
- const description = agent.roleSummary.length > 180 ? `${agent.roleSummary.slice(0, 177)}...` : agent.roleSummary;
1237
- const target = `.claude/agents/${agent.id}.md`;
1238
- const content = buildClaudeSubagentMarkdown(agent.id, agent.name, description);
1239
- const targetPath = join8(cwd, target);
1240
- if (!force && existsSync8(targetPath)) {
1241
- const existing = readFileSync5(targetPath, "utf8");
1242
- if (existing === content) {
1243
- result.unchanged.push(target);
1244
- continue;
1245
- }
1246
- const conflictPath = join8(cwd, ".agent-kit", "conflicts", target.replace(/\//g, "__"));
1247
- ensureDir(join8(cwd, ".agent-kit", "conflicts"));
1248
- writeText(conflictPath, existing);
1249
- result.conflicts.push(`${target} -> ${conflictPath}`);
1250
- continue;
1251
- }
1252
- writeText(targetPath, content);
1253
- result.copied.push(target);
1254
- }
1453
+ generateMarkdownSubagents(cwd, ".claude/agents", { proactive: false, force, result });
1255
1454
  copyAdapterFile(cwd, packageRoot, CLAUDE_TEMPLATE, "CLAUDE.md", force, result);
1256
1455
  }
1257
1456
  function copyDirectoryAsConflicts(cwd, packageRoot, sourceDir, targetDir, force, result) {
1258
- for (const file of listFilesRecursive(join8(packageRoot, sourceDir))) {
1259
- copyAdapterFile(cwd, packageRoot, join8(sourceDir, file), join8(targetDir, file).replace(/\\/g, "/"), force, result);
1457
+ for (const file of listFilesRecursive(join9(packageRoot, sourceDir))) {
1458
+ copyAdapterFile(cwd, packageRoot, join9(sourceDir, file), join9(targetDir, file).replace(/\\/g, "/"), force, result);
1260
1459
  }
1261
1460
  }
1262
1461
  function installAntigravityAdapter(cwd, packageRoot, force, result) {
1263
- ensureDir(join8(cwd, ".antigravity", "agent-kit", "commands"));
1264
- ensureDir(join8(cwd, ".antigravity", "runtime-skills"));
1462
+ ensureDir(join9(cwd, ".antigravity", "agent-kit", "commands"));
1463
+ ensureDir(join9(cwd, ".antigravity", "runtime-skills"));
1265
1464
  for (const file of ANTIGRAVITY_PLUGIN_FILES) {
1266
1465
  copyAdapterFile(cwd, packageRoot, file.source, file.target, force, result);
1267
1466
  }
@@ -1283,38 +1482,38 @@ function installAntigravityAdapter(cwd, packageRoot, force, result) {
1283
1482
  );
1284
1483
  }
1285
1484
  function updateAssistantAdaptersTable(cwd, activated) {
1286
- const path = join8(cwd, "ASSISTANT_ADAPTERS.md");
1287
- if (!existsSync8(path)) return;
1288
- let content = readFileSync5(path, "utf8");
1485
+ const path = join9(cwd, "ASSISTANT_ADAPTERS.md");
1486
+ if (!existsSync9(path)) return;
1487
+ let content = readFileSync6(path, "utf8");
1289
1488
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1290
1489
  if (activated.has("cursor") && content.includes("| Cursor |")) {
1291
1490
  content = content.replace(
1292
1491
  /\| Cursor \|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|/,
1293
- "| Cursor | `.cursor/rules/cursor-agent-kit.mdc` and `.cursor/rules/cursor-model-selection.mdc` | Active on init | Advisory | Advisory | `agent-kit init` copies rules; verify in Cursor Settings > Rules. | Installed via `agent-kit init` or `agent-kit init --activate cursor`. |"
1492
+ `| Cursor | \`.cursor/rules/*.mdc\`, \`.cursor/agents/*.md\`, \`.cursor/skills/*/SKILL.md\` | Active | Partial | Partial | \`agent-kit init --activate cursor\` on ${today}; verify subagents in Cursor. | Delegate to council subagents instead of role-playing; run \`agent-kit adapter validate cursor\`. |`
1294
1493
  );
1295
1494
  }
1296
1495
  if (activated.has("copilot") && content.includes("| GitHub Copilot")) {
1297
1496
  content = content.replace(
1298
1497
  /\| GitHub Copilot[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|/,
1299
- "| GitHub Copilot / VS Code | `.github/copilot-instructions.md` and `.github/instructions/next-supabase.instructions.md` | Active | Advisory | Advisory | `agent-kit init --activate copilot` on ${today}. | Copilot loads repository and path-specific instructions automatically in VS Code. |"
1498
+ `| GitHub Copilot / VS Code | \`.github/copilot-instructions.md\` and \`.github/instructions/next-supabase.instructions.md\` | Active | Advisory | Advisory | \`agent-kit init --activate copilot\` on ${today}. | Copilot loads repository and path-specific instructions automatically in VS Code. |`
1300
1499
  );
1301
1500
  }
1302
1501
  if (activated.has("claude") && content.includes("| Claude Code |")) {
1303
1502
  content = content.replace(
1304
1503
  /\| Claude Code \|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|/,
1305
- "| Claude Code | `.claude/agents/*.md` and `CLAUDE.md` | Active | Partial | Partial | `agent-kit init --activate claude` generated subagents on ${today}. | Subagents generated from `.agent-kit/agent-roster.json`; verify in Claude Code project settings. |"
1504
+ `| Claude Code | \`.claude/agents/*.md\` and \`CLAUDE.md\` | Active | Partial | Partial | \`agent-kit init --activate claude\` generated subagents on ${today}. | Subagents generated from \`.agent-kit/agent-roster.json\`; verify in Claude Code project settings. |`
1306
1505
  );
1307
1506
  }
1308
1507
  if (activated.has("codex") && content.includes("| Codex / AGENTS.md-compatible tools |")) {
1309
1508
  content = content.replace(
1310
1509
  /\| Codex \/ AGENTS\.md-compatible tools \|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|/,
1311
- "| Codex / AGENTS.md-compatible tools | `AGENTS.md`, `.codex/config.toml` | Active | Partial | Partial | Root `AGENTS.md` on init; optional `.codex/config.toml` via `agent-kit init --activate codex`. | Confirm Codex loads root `AGENTS.md` and optional model routing comments. |"
1510
+ `| Codex / AGENTS.md-compatible tools | \`AGENTS.md\`, \`.codex/config.toml\`, \`.codex/agents/*.toml\` | Active | Partial | Partial | \`agent-kit init --activate codex\` on ${today}. | Spawn council custom agents from \`.codex/agents/\`; run \`agent-kit adapter validate codex\`. |`
1312
1511
  );
1313
1512
  }
1314
1513
  if (activated.has("antigravity") && content.includes("| Antigravity |")) {
1315
1514
  content = content.replace(
1316
1515
  /\| Antigravity \|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|/,
1317
- "| Antigravity | `.antigravity/agent-kit/plugin.json`, `.antigravity/agent-kit/commands/*.toml`, `.antigravity/runtime-skills/*/SKILL.md` | Active | Advisory | Advisory | `agent-kit init --activate antigravity` on ${today}; run `agent-kit adapter validate antigravity`. | Native commands wrap the Agent Kit council/session contract; runtime validation is structural unless `agy` is installed. |"
1516
+ `| Antigravity | \`.antigravity/agent-kit/plugin.json\`, \`.antigravity/agent-kit/commands/*.toml\`, \`.antigravity/runtime-skills/*/SKILL.md\` | Active | Advisory | Advisory | \`agent-kit init --activate antigravity\` on ${today}; run \`agent-kit adapter validate antigravity\`. | Native commands wrap the Agent Kit council/session contract; runtime validation is structural unless \`agy\` is installed. |`
1318
1517
  );
1319
1518
  }
1320
1519
  writeText(path, content);
@@ -1341,9 +1540,14 @@ function activateIdeTargets(options) {
1341
1540
  for (const adapter2 of CURSOR_ADAPTER_FILES) {
1342
1541
  copyAdapterFile(cwd, packageRoot, adapter2.source, adapter2.target, force, result);
1343
1542
  }
1543
+ for (const adapter2 of CURSOR_SCOPED_ADAPTER_FILES) {
1544
+ copyAdapterFile(cwd, packageRoot, adapter2.source, adapter2.target, force, result);
1545
+ }
1546
+ generateCursorSubagents(cwd, force, result);
1547
+ generateCursorSkillsFromKit(cwd, force, result);
1344
1548
  }
1345
1549
  if (activated.has("copilot")) {
1346
- ensureDir(join8(cwd, ".github", "instructions"));
1550
+ ensureDir(join9(cwd, ".github", "instructions"));
1347
1551
  for (const file of COPILOT_INSTRUCTION_FILES) {
1348
1552
  copyAdapterFile(cwd, packageRoot, file.source, file.target, force, result);
1349
1553
  }
@@ -1352,8 +1556,9 @@ function activateIdeTargets(options) {
1352
1556
  generateClaudeSubagents(cwd, packageRoot, force, result);
1353
1557
  }
1354
1558
  if (activated.has("codex")) {
1355
- ensureDir(join8(cwd, ".codex"));
1559
+ ensureDir(join9(cwd, ".codex"));
1356
1560
  copyAdapterFile(cwd, packageRoot, CODEX_CONFIG_SOURCE, ".codex/config.toml", force, result);
1561
+ generateCodexCustomAgents(cwd, force, result);
1357
1562
  }
1358
1563
  if (activated.has("antigravity")) {
1359
1564
  installAntigravityAdapter(cwd, packageRoot, force, result);
@@ -1361,18 +1566,25 @@ function activateIdeTargets(options) {
1361
1566
  updateAssistantAdaptersTable(cwd, activated);
1362
1567
  return result;
1363
1568
  }
1569
+ function ideSurfaceToActivateTarget(ideSurface) {
1570
+ const value = ideSurface.trim().toLowerCase();
1571
+ if (value === "cursor" || value === "claude" || value === "codex" || value === "copilot") {
1572
+ return value;
1573
+ }
1574
+ return null;
1575
+ }
1364
1576
 
1365
1577
  // src/install/install.ts
1366
1578
  function initProject(options) {
1367
1579
  const cwd = options.cwd;
1368
1580
  const stack = options.stack ?? DEFAULT_CONFIG.stack;
1369
1581
  const packageRoot = findPackageRoot();
1370
- const templateRoot = join9(packageRoot, "templates", stack);
1371
- if (!existsSync9(templateRoot)) {
1582
+ const templateRoot = join10(packageRoot, "templates", stack);
1583
+ if (!existsSync10(templateRoot)) {
1372
1584
  throw new Error(`Unsupported stack profile: ${stack}`);
1373
1585
  }
1374
- ensureDir(join9(cwd, ".agent-kit"));
1375
- ensureDir(join9(cwd, ".agent-kit", "conflicts"));
1586
+ ensureDir(join10(cwd, ".agent-kit"));
1587
+ ensureDir(join10(cwd, ".agent-kit", "conflicts"));
1376
1588
  const result = {
1377
1589
  copied: [],
1378
1590
  unchanged: [],
@@ -1382,11 +1594,11 @@ function initProject(options) {
1382
1594
  };
1383
1595
  const templateHashes = {};
1384
1596
  for (const doc of ROOT_DOCS) {
1385
- const templatePath = join9(templateRoot, doc);
1386
- templateHashes[doc] = sha256(readFileSync6(templatePath, "utf8"));
1597
+ const templatePath = join10(templateRoot, doc);
1598
+ templateHashes[doc] = sha256(readFileSync7(templatePath, "utf8"));
1387
1599
  const copyResult = copyTextWithConflict(templatePath, cwd, doc, {
1388
1600
  force: Boolean(options.force),
1389
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1601
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1390
1602
  });
1391
1603
  if (copyResult.action === "created") result.copied.push(copyResult.target);
1392
1604
  if (copyResult.action === "unchanged") result.unchanged.push(copyResult.target);
@@ -1396,12 +1608,12 @@ function initProject(options) {
1396
1608
  }
1397
1609
  }
1398
1610
  for (const folder of LIBRARY_FOLDERS) {
1399
- copyDirectory(join9(packageRoot, folder), join9(cwd, ".agent-kit", folder));
1611
+ copyDirectory(join10(packageRoot, folder), join10(cwd, ".agent-kit", folder));
1400
1612
  }
1401
1613
  for (const adapter2 of CURSOR_ADAPTER_FILES) {
1402
- const adapterCopy = copyTextWithConflict(join9(packageRoot, adapter2.source), cwd, adapter2.target, {
1614
+ const adapterCopy = copyTextWithConflict(join10(packageRoot, adapter2.source), cwd, adapter2.target, {
1403
1615
  force: Boolean(options.force),
1404
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1616
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1405
1617
  });
1406
1618
  if (adapterCopy.action === "created") result.copied.push(adapterCopy.target);
1407
1619
  if (adapterCopy.action === "unchanged") result.unchanged.push(adapterCopy.target);
@@ -1410,17 +1622,17 @@ function initProject(options) {
1410
1622
  result.conflicts.push(`${adapterCopy.target} -> ${adapterCopy.conflictPath}`);
1411
1623
  }
1412
1624
  }
1413
- const rosterCopy = copyTextWithConflict(join9(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE), cwd, DEFAULT_AGENT_ROSTER_TARGET, {
1625
+ const rosterCopy = copyTextWithConflict(join10(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE), cwd, DEFAULT_AGENT_ROSTER_TARGET, {
1414
1626
  force: Boolean(options.force),
1415
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1627
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1416
1628
  });
1417
1629
  if (rosterCopy.action === "created") result.copied.push(rosterCopy.target);
1418
1630
  if (rosterCopy.action === "unchanged") result.unchanged.push(rosterCopy.target);
1419
1631
  if (rosterCopy.action === "overwritten") result.overwritten.push(rosterCopy.target);
1420
1632
  if (rosterCopy.action === "conflict") result.conflicts.push(`${rosterCopy.target} -> ${rosterCopy.conflictPath}`);
1421
- const modelRoutingCopy = copyTextWithConflict(join9(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE), cwd, DEFAULT_MODEL_ROUTING_TARGET, {
1633
+ const modelRoutingCopy = copyTextWithConflict(join10(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE), cwd, DEFAULT_MODEL_ROUTING_TARGET, {
1422
1634
  force: Boolean(options.force),
1423
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1635
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1424
1636
  });
1425
1637
  if (modelRoutingCopy.action === "created") result.copied.push(modelRoutingCopy.target);
1426
1638
  if (modelRoutingCopy.action === "unchanged") result.unchanged.push(modelRoutingCopy.target);
@@ -1437,17 +1649,17 @@ function initProject(options) {
1437
1649
  modelRouting: DEFAULT_MODEL_ROUTING_TARGET,
1438
1650
  templateHashes
1439
1651
  };
1440
- writeText(join9(cwd, ".agent-kit", "manifest.json"), `${JSON.stringify(manifest, null, 2)}
1652
+ writeText(join10(cwd, ".agent-kit", "manifest.json"), `${JSON.stringify(manifest, null, 2)}
1441
1653
  `);
1442
- writeText(join9(cwd, ".agent-kit", "config.json"), `${JSON.stringify(DEFAULT_CONFIG, null, 2)}
1654
+ writeText(join10(cwd, ".agent-kit", "config.json"), `${JSON.stringify(DEFAULT_CONFIG, null, 2)}
1443
1655
  `);
1444
- const overridesPath = join9(cwd, ".agent-kit", "overrides.json");
1445
- if (!existsSync9(overridesPath)) writeText(overridesPath, `${JSON.stringify({ templates: {} }, null, 2)}
1656
+ const overridesPath = join10(cwd, ".agent-kit", "overrides.json");
1657
+ if (!existsSync10(overridesPath)) writeText(overridesPath, `${JSON.stringify({ templates: {} }, null, 2)}
1446
1658
  `);
1447
1659
  for (const template of CI_TEMPLATE_FILES) {
1448
- const ciCopy = copyTextWithConflict(join9(packageRoot, template.source), cwd, template.target, {
1660
+ const ciCopy = copyTextWithConflict(join10(packageRoot, template.source), cwd, template.target, {
1449
1661
  force: Boolean(options.force),
1450
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1662
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1451
1663
  });
1452
1664
  if (ciCopy.action === "created") result.copied.push(ciCopy.target);
1453
1665
  if (ciCopy.action === "unchanged") result.unchanged.push(ciCopy.target);
@@ -1471,9 +1683,9 @@ function initProject(options) {
1471
1683
  return result;
1472
1684
  }
1473
1685
  function readManifest(cwd) {
1474
- const manifestPath = join9(cwd, ".agent-kit", "manifest.json");
1475
- if (!existsSync9(manifestPath)) return null;
1476
- return JSON.parse(readFileSync6(manifestPath, "utf8"));
1686
+ const manifestPath = join10(cwd, ".agent-kit", "manifest.json");
1687
+ if (!existsSync10(manifestPath)) return null;
1688
+ return JSON.parse(readFileSync7(manifestPath, "utf8"));
1477
1689
  }
1478
1690
 
1479
1691
  // src/install/audit.ts
@@ -1542,24 +1754,24 @@ function includesAll(text, values) {
1542
1754
  return values.every((value) => lower.includes(value.toLowerCase()));
1543
1755
  }
1544
1756
  function readDoc(cwd, file) {
1545
- const path = join10(cwd, file);
1546
- return existsSync10(path) ? readFileSync7(path, "utf8") : "";
1757
+ const path = join11(cwd, file);
1758
+ return existsSync11(path) ? readFileSync8(path, "utf8") : "";
1547
1759
  }
1548
1760
  function isPackageRepository(cwd) {
1549
- const packagePath = join10(cwd, "package.json");
1550
- if (!existsSync10(packagePath)) return false;
1761
+ const packagePath = join11(cwd, "package.json");
1762
+ if (!existsSync11(packagePath)) return false;
1551
1763
  try {
1552
- const packageJson = JSON.parse(readFileSync7(packagePath, "utf8"));
1553
- return packageJson.name === "@appsforgood/next-supabase-kit" && existsSync10(join10(cwd, "src", "cli", "index.ts")) && existsSync10(join10(cwd, "templates", "next-supabase")) && existsSync10(join10(cwd, "rosters", "next-supabase-default-council.json"));
1764
+ const packageJson = JSON.parse(readFileSync8(packagePath, "utf8"));
1765
+ return packageJson.name === "@appsforgood/next-supabase-kit" && existsSync11(join11(cwd, "src", "cli", "index.ts")) && existsSync11(join11(cwd, "templates", "next-supabase")) && existsSync11(join11(cwd, "rosters", "next-supabase-default-council.json"));
1554
1766
  } catch {
1555
1767
  return false;
1556
1768
  }
1557
1769
  }
1558
1770
  function readOverrides(cwd) {
1559
- const path = join10(cwd, ".agent-kit", "overrides.json");
1560
- if (!existsSync10(path)) return {};
1771
+ const path = join11(cwd, ".agent-kit", "overrides.json");
1772
+ if (!existsSync11(path)) return {};
1561
1773
  try {
1562
- const parsed = JSON.parse(readFileSync7(path, "utf8"));
1774
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
1563
1775
  const templates = parsed.templates ?? {};
1564
1776
  return Object.fromEntries(
1565
1777
  Object.entries(templates).map(([file, override]) => [
@@ -1572,8 +1784,8 @@ function readOverrides(cwd) {
1572
1784
  }
1573
1785
  }
1574
1786
  function readTemplate(stack, file) {
1575
- const path = join10(findPackageRoot(), "templates", stack, file);
1576
- return existsSync10(path) ? readFileSync7(path, "utf8") : null;
1787
+ const path = join11(findPackageRoot(), "templates", stack, file);
1788
+ return existsSync11(path) ? readFileSync8(path, "utf8") : null;
1577
1789
  }
1578
1790
  function asStringArray(value) {
1579
1791
  if (!Array.isArray(value)) return [];
@@ -1583,8 +1795,8 @@ function isRecord(value) {
1583
1795
  return typeof value === "object" && value !== null;
1584
1796
  }
1585
1797
  function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGENT_ROSTER_TARGET) {
1586
- const rosterPath = join10(cwd, rosterRelativePath);
1587
- if (!existsSync10(rosterPath)) {
1798
+ const rosterPath = join11(cwd, rosterRelativePath);
1799
+ if (!existsSync11(rosterPath)) {
1588
1800
  findings.push({
1589
1801
  level: "fail",
1590
1802
  area: "agents",
@@ -1595,7 +1807,7 @@ function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGEN
1595
1807
  }
1596
1808
  let roster;
1597
1809
  try {
1598
- const parsed = JSON.parse(readFileSync7(rosterPath, "utf8"));
1810
+ const parsed = JSON.parse(readFileSync8(rosterPath, "utf8"));
1599
1811
  if (!isRecord(parsed)) throw new Error("Roster must be a JSON object.");
1600
1812
  const contractResult = AgentRosterContract.safeParse(parsed);
1601
1813
  if (!contractResult.success) {
@@ -1782,15 +1994,15 @@ function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGEN
1782
1994
  }
1783
1995
  }
1784
1996
  function addCouncilSessionRecordFindings(cwd, findings) {
1785
- const sessionsRoot = join10(cwd, COUNCIL_SESSION_DIR);
1786
- if (!existsSync10(sessionsRoot)) return;
1997
+ const sessionsRoot = join11(cwd, COUNCIL_SESSION_DIR);
1998
+ if (!existsSync11(sessionsRoot)) return;
1787
1999
  const sessionFiles = listFilesRecursive(sessionsRoot).filter((file) => file.endsWith(".json") && !/[\\/]/.test(file));
1788
2000
  if (sessionFiles.length === 0) return;
1789
2001
  let invalidCount = 0;
1790
2002
  for (const sessionFile of sessionFiles) {
1791
2003
  const displayPath = `${COUNCIL_SESSION_DIR}/${sessionFile}`;
1792
2004
  try {
1793
- const parsed = JSON.parse(readFileSync7(join10(sessionsRoot, sessionFile), "utf8"));
2005
+ const parsed = JSON.parse(readFileSync8(join11(sessionsRoot, sessionFile), "utf8"));
1794
2006
  const contractResult = CouncilSessionContract.safeParse(parsed);
1795
2007
  if (!contractResult.success) {
1796
2008
  invalidCount += 1;
@@ -1821,8 +2033,8 @@ function addCouncilSessionRecordFindings(cwd, findings) {
1821
2033
  }
1822
2034
  function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/schemas") {
1823
2035
  for (const schemaFile of REQUIRED_SCHEMA_FILES) {
1824
- const schemaPath = join10(cwd, schemaRootRelativePath, schemaFile);
1825
- if (!existsSync10(schemaPath)) {
2036
+ const schemaPath = join11(cwd, schemaRootRelativePath, schemaFile);
2037
+ if (!existsSync11(schemaPath)) {
1826
2038
  findings.push({
1827
2039
  level: "warn",
1828
2040
  area: "agents",
@@ -1832,7 +2044,7 @@ function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/s
1832
2044
  continue;
1833
2045
  }
1834
2046
  try {
1835
- const parsed = JSON.parse(readFileSync7(schemaPath, "utf8"));
2047
+ const parsed = JSON.parse(readFileSync8(schemaPath, "utf8"));
1836
2048
  if (!isRecord(parsed) || typeof parsed.$schema !== "string" || !isRecord(parsed.properties)) {
1837
2049
  throw new Error("Schema file is missing JSON Schema metadata.");
1838
2050
  }
@@ -1852,8 +2064,8 @@ function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/s
1852
2064
  }
1853
2065
  }
1854
2066
  function addAgentStudioFindings(cwd, findings) {
1855
- const contextPath = join10(cwd, CONTEXT_JSON);
1856
- if (!existsSync10(contextPath)) {
2067
+ const contextPath = join11(cwd, CONTEXT_JSON);
2068
+ if (!existsSync11(contextPath)) {
1857
2069
  findings.push({
1858
2070
  level: "warn",
1859
2071
  area: "studio",
@@ -1862,7 +2074,7 @@ function addAgentStudioFindings(cwd, findings) {
1862
2074
  });
1863
2075
  } else {
1864
2076
  try {
1865
- const parsed = JSON.parse(readFileSync7(contextPath, "utf8"));
2077
+ const parsed = JSON.parse(readFileSync8(contextPath, "utf8"));
1866
2078
  const result = ProjectContextContract.safeParse(parsed);
1867
2079
  if (!result.success) {
1868
2080
  findings.push({
@@ -1926,8 +2138,8 @@ function addAgentStudioFindings(cwd, findings) {
1926
2138
  });
1927
2139
  }
1928
2140
  }
1929
- const contextMdPath = join10(cwd, CONTEXT_MD);
1930
- if (existsSync10(contextPath) && !existsSync10(contextMdPath)) {
2141
+ const contextMdPath = join11(cwd, CONTEXT_MD);
2142
+ if (existsSync11(contextPath) && !existsSync11(contextMdPath)) {
1931
2143
  findings.push({
1932
2144
  level: "warn",
1933
2145
  area: "studio",
@@ -1936,10 +2148,10 @@ function addAgentStudioFindings(cwd, findings) {
1936
2148
  });
1937
2149
  }
1938
2150
  for (const relativePath of [PROJECT_RULES_JSON, AGENT_RULES_JSON]) {
1939
- const path = join10(cwd, relativePath);
1940
- if (!existsSync10(path)) continue;
2151
+ const path = join11(cwd, relativePath);
2152
+ if (!existsSync11(path)) continue;
1941
2153
  try {
1942
- const parsed = JSON.parse(readFileSync7(path, "utf8"));
2154
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
1943
2155
  const result = CorrectionRulesContract.safeParse(parsed);
1944
2156
  if (!result.success) {
1945
2157
  findings.push({
@@ -1964,9 +2176,9 @@ function addAgentStudioFindings(cwd, findings) {
1964
2176
  });
1965
2177
  }
1966
2178
  }
1967
- const studioExportPath = join10(cwd, STUDIO_EXPORT_HTML);
1968
- if (existsSync10(studioExportPath)) {
1969
- const exportHtml = readFileSync7(studioExportPath, "utf8");
2179
+ const studioExportPath = join11(cwd, STUDIO_EXPORT_HTML);
2180
+ if (existsSync11(studioExportPath)) {
2181
+ const exportHtml = readFileSync8(studioExportPath, "utf8");
1970
2182
  if (containsLikelySecret(exportHtml)) {
1971
2183
  findings.push({
1972
2184
  level: "fail",
@@ -1989,8 +2201,8 @@ function addAgentStudioFindings(cwd, findings) {
1989
2201
  });
1990
2202
  }
1991
2203
  }
1992
- const sessionsRoot = join10(cwd, COUNCIL_SESSION_DIR);
1993
- if (!existsSync10(sessionsRoot)) return;
2204
+ const sessionsRoot = join11(cwd, COUNCIL_SESSION_DIR);
2205
+ if (!existsSync11(sessionsRoot)) return;
1994
2206
  const files = listFilesRecursive(sessionsRoot);
1995
2207
  const studioSessionFiles = files.filter((file) => /[\\/]session\.json$/.test(file));
1996
2208
  for (const sessionFile of studioSessionFiles) {
@@ -2001,10 +2213,10 @@ function addAgentStudioFindings(cwd, findings) {
2001
2213
  const eventsRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/events.jsonl`;
2002
2214
  const indexRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/index.md`;
2003
2215
  const transcriptRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/transcript.md`;
2004
- const sessionDirPath = join10(sessionsRoot, sessionDir2);
2216
+ const sessionDirPath = join11(sessionsRoot, sessionDir2);
2005
2217
  let sessionResult = null;
2006
2218
  try {
2007
- sessionResult = StudioSessionContract.safeParse(JSON.parse(readFileSync7(join10(sessionDirPath, "session.json"), "utf8")));
2219
+ sessionResult = StudioSessionContract.safeParse(JSON.parse(readFileSync8(join11(sessionDirPath, "session.json"), "utf8")));
2008
2220
  if (!sessionResult.success) {
2009
2221
  findings.push({
2010
2222
  level: "fail",
@@ -2023,8 +2235,8 @@ function addAgentStudioFindings(cwd, findings) {
2023
2235
  });
2024
2236
  continue;
2025
2237
  }
2026
- const eventsPath2 = join10(sessionDirPath, "events.jsonl");
2027
- if (!existsSync10(eventsPath2)) {
2238
+ const eventsPath2 = join11(sessionDirPath, "events.jsonl");
2239
+ if (!existsSync11(eventsPath2)) {
2028
2240
  findings.push({
2029
2241
  level: "fail",
2030
2242
  area: "studio",
@@ -2033,7 +2245,7 @@ function addAgentStudioFindings(cwd, findings) {
2033
2245
  });
2034
2246
  continue;
2035
2247
  }
2036
- const eventText = readFileSync7(eventsPath2, "utf8");
2248
+ const eventText = readFileSync8(eventsPath2, "utf8");
2037
2249
  if (containsLikelySecret(eventText)) {
2038
2250
  findings.push({
2039
2251
  level: "fail",
@@ -2068,7 +2280,7 @@ function addAgentStudioFindings(cwd, findings) {
2068
2280
  });
2069
2281
  }
2070
2282
  }
2071
- if (!existsSync10(join10(sessionDirPath, "index.md")) || !existsSync10(join10(sessionDirPath, "transcript.md"))) {
2283
+ if (!existsSync11(join11(sessionDirPath, "index.md")) || !existsSync11(join11(sessionDirPath, "transcript.md"))) {
2072
2284
  findings.push({
2073
2285
  level: "warn",
2074
2286
  area: "studio",
@@ -2076,8 +2288,8 @@ function addAgentStudioFindings(cwd, findings) {
2076
2288
  remediation: "Run agent-kit session render so humans can inspect the current agent transcript and handoffs."
2077
2289
  });
2078
2290
  } else {
2079
- const indexText = readFileSync7(join10(sessionDirPath, "index.md"), "utf8");
2080
- const transcriptText = readFileSync7(join10(sessionDirPath, "transcript.md"), "utf8");
2291
+ const indexText = readFileSync8(join11(sessionDirPath, "index.md"), "utf8");
2292
+ const transcriptText = readFileSync8(join11(sessionDirPath, "transcript.md"), "utf8");
2081
2293
  if (containsLikelySecret(indexText) || containsLikelySecret(transcriptText)) {
2082
2294
  findings.push({
2083
2295
  level: "fail",
@@ -2086,7 +2298,7 @@ function addAgentStudioFindings(cwd, findings) {
2086
2298
  remediation: "Regenerate Markdown after redacting sensitive values from the event log."
2087
2299
  });
2088
2300
  }
2089
- if (statSync(eventsPath2).mtimeMs > statSync(join10(sessionDirPath, "index.md")).mtimeMs) {
2301
+ if (statSync(eventsPath2).mtimeMs > statSync(join11(sessionDirPath, "index.md")).mtimeMs) {
2090
2302
  findings.push({
2091
2303
  level: "warn",
2092
2304
  area: "studio",
@@ -2136,8 +2348,8 @@ function addCouncilDocFindings(cwd, findings) {
2136
2348
  }
2137
2349
  function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".agent-kit/assistant-adapters", docsCwd = cwd) {
2138
2350
  const adaptersDoc = readDoc(docsCwd, "ASSISTANT_ADAPTERS.md");
2139
- const adapterRoot = join10(cwd, adapterRootRelativePath);
2140
- if (!existsSync10(adapterRoot)) {
2351
+ const adapterRoot = join11(cwd, adapterRootRelativePath);
2352
+ if (!existsSync11(adapterRoot)) {
2141
2353
  findings.push({
2142
2354
  level: "warn",
2143
2355
  area: "agents",
@@ -2157,7 +2369,7 @@ function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".
2157
2369
  level: "warn",
2158
2370
  area: "agents",
2159
2371
  message: "ASSISTANT_ADAPTERS.md does not map the council roster to supported tool instruction surfaces.",
2160
- remediation: "Document Codex/AGENTS.md, GitHub Copilot, Cursor rules, Claude Code subagents, and the source-of-truth rule for avoiding divergent agent instructions."
2372
+ remediation: "Document Codex/AGENTS.md, GitHub Copilot, Cursor rules and subagents, Claude Code subagents, and the source-of-truth rule for avoiding divergent agent instructions."
2161
2373
  });
2162
2374
  } else {
2163
2375
  findings.push({
@@ -2166,6 +2378,22 @@ function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".
2166
2378
  message: "ASSISTANT_ADAPTERS.md maps the council roster to tool-specific instruction surfaces."
2167
2379
  });
2168
2380
  }
2381
+ if (assistantAdapterRowIsActive(adaptersDoc, "Cursor") && !existsSync11(join11(cwd, ".cursor/agents/planner.md"))) {
2382
+ findings.push({
2383
+ level: "warn",
2384
+ area: "agents",
2385
+ message: "Cursor is marked Active but .cursor/agents/planner.md is missing.",
2386
+ remediation: "Run agent-kit init --activate cursor to generate council subagents from the roster."
2387
+ });
2388
+ }
2389
+ if (assistantAdapterRowIsActive(adaptersDoc, "Codex / AGENTS.md-compatible tools") && !existsSync11(join11(cwd, ".codex/agents/planner.toml"))) {
2390
+ findings.push({
2391
+ level: "warn",
2392
+ area: "agents",
2393
+ message: "Codex is marked Active but .codex/agents/planner.toml is missing.",
2394
+ remediation: "Run agent-kit init --activate codex to generate council custom agents from the roster."
2395
+ });
2396
+ }
2169
2397
  if (!includesAll(adaptersDoc, ["model selection", "enforcement", "MODEL_ROUTING.md", "model-routing.json"])) {
2170
2398
  findings.push({
2171
2399
  level: "warn",
@@ -2206,8 +2434,8 @@ function addModelRoutingFindings(cwd, findings, routingRelativePath = DEFAULT_MO
2206
2434
  message: "MODEL_ROUTING.md documents agent model profiles and IDE enforcement limits."
2207
2435
  });
2208
2436
  }
2209
- const routingPath = join10(cwd, routingRelativePath);
2210
- if (!existsSync10(routingPath)) {
2437
+ const routingPath = join11(cwd, routingRelativePath);
2438
+ if (!existsSync11(routingPath)) {
2211
2439
  findings.push({
2212
2440
  level: "warn",
2213
2441
  area: "models",
@@ -2218,7 +2446,7 @@ function addModelRoutingFindings(cwd, findings, routingRelativePath = DEFAULT_MO
2218
2446
  }
2219
2447
  let routing;
2220
2448
  try {
2221
- routing = JSON.parse(readFileSync7(routingPath, "utf8"));
2449
+ routing = JSON.parse(readFileSync8(routingPath, "utf8"));
2222
2450
  } catch {
2223
2451
  findings.push({
2224
2452
  level: "warn",
@@ -2276,11 +2504,11 @@ function addTemplateHashFindings(cwd, findings) {
2276
2504
  if (!manifest) return;
2277
2505
  const overrides = readOverrides(cwd);
2278
2506
  for (const doc of ROOT_DOCS) {
2279
- const targetPath = join10(cwd, doc);
2280
- if (!existsSync10(targetPath)) continue;
2507
+ const targetPath = join11(cwd, doc);
2508
+ if (!existsSync11(targetPath)) continue;
2281
2509
  const currentTemplate = readTemplate(manifest.stack, doc);
2282
2510
  if (!currentTemplate) continue;
2283
- const targetHash = sha256(readFileSync7(targetPath, "utf8"));
2511
+ const targetHash = sha256(readFileSync8(targetPath, "utf8"));
2284
2512
  const currentTemplateHash = sha256(currentTemplate);
2285
2513
  const installedTemplateHash = manifest.templateHashes?.[doc];
2286
2514
  const override = overrides[doc];
@@ -2584,7 +2812,7 @@ function auditProject(cwd) {
2584
2812
  const manifest = readManifest(cwd);
2585
2813
  const packageRepository = isPackageRepository(cwd);
2586
2814
  const packageSourceMode = packageRepository && !manifest;
2587
- const docsCwd = packageSourceMode ? join10(cwd, "templates", "next-supabase") : cwd;
2815
+ const docsCwd = packageSourceMode ? join11(cwd, "templates", "next-supabase") : cwd;
2588
2816
  if (!manifest) {
2589
2817
  if (packageRepository) {
2590
2818
  findings.push({
@@ -2611,13 +2839,13 @@ function auditProject(cwd) {
2611
2839
  addAgentRosterFindings(cwd, findings, packageSourceMode ? "rosters/next-supabase-default-council.json" : DEFAULT_AGENT_ROSTER_TARGET);
2612
2840
  addSchemaFindings(cwd, findings, packageSourceMode ? "schemas" : ".agent-kit/schemas");
2613
2841
  addCouncilSessionRecordFindings(cwd, findings);
2614
- if (!packageRepository || existsSync10(join10(cwd, CONTEXT_JSON)) || existsSync10(join10(cwd, COUNCIL_SESSION_DIR))) {
2842
+ if (!packageRepository || existsSync11(join11(cwd, CONTEXT_JSON)) || existsSync11(join11(cwd, COUNCIL_SESSION_DIR))) {
2615
2843
  addAgentStudioFindings(cwd, findings);
2616
2844
  }
2617
2845
  for (const doc of ROOT_DOCS) {
2618
- const docPath = join10(docsCwd, doc);
2846
+ const docPath = join11(docsCwd, doc);
2619
2847
  const displayPath = packageSourceMode ? `templates/next-supabase/${doc}` : doc;
2620
- if (existsSync10(docPath)) {
2848
+ if (existsSync11(docPath)) {
2621
2849
  findings.push({ level: "pass", area: "docs", message: `${displayPath} exists.` });
2622
2850
  } else {
2623
2851
  findings.push({
@@ -2682,10 +2910,10 @@ function auditProject(cwd) {
2682
2910
  return findings;
2683
2911
  }
2684
2912
  function readPackageJson2(cwd) {
2685
- const path = join10(cwd, "package.json");
2686
- if (!existsSync10(path)) return null;
2913
+ const path = join11(cwd, "package.json");
2914
+ if (!existsSync11(path)) return null;
2687
2915
  try {
2688
- return JSON.parse(readFileSync7(path, "utf8"));
2916
+ return JSON.parse(readFileSync8(path, "utf8"));
2689
2917
  } catch {
2690
2918
  return null;
2691
2919
  }
@@ -2699,8 +2927,8 @@ function containsLikelySecretForAudit(relativeFile, content) {
2699
2927
  return containsLikelySecret(content);
2700
2928
  }
2701
2929
  function addProjectRealityFindings(cwd, findings, options = {}) {
2702
- const migrationsDir = join10(cwd, "supabase", "migrations");
2703
- if (existsSync10(migrationsDir)) {
2930
+ const migrationsDir = join11(cwd, "supabase", "migrations");
2931
+ if (existsSync11(migrationsDir)) {
2704
2932
  const sqlFiles = listFilesRecursive(migrationsDir).filter((file) => file.endsWith(".sql"));
2705
2933
  if (sqlFiles.length === 0) {
2706
2934
  findings.push({
@@ -2711,7 +2939,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2711
2939
  });
2712
2940
  } else {
2713
2941
  const rlsFiles = sqlFiles.filter((file) => {
2714
- const content = readFileSync7(join10(migrationsDir, file), "utf8");
2942
+ const content = readFileSync8(join11(migrationsDir, file), "utf8");
2715
2943
  return /enable\s+row\s+level\s+security/i.test(content);
2716
2944
  });
2717
2945
  if (rlsFiles.length === 0) {
@@ -2761,7 +2989,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2761
2989
  return /\.(ts|tsx|js|jsx|env|json)$/.test(file);
2762
2990
  });
2763
2991
  const secretHits = trackedSourceFiles.map((file) => {
2764
- const content = readFileSync7(join10(cwd, file), "utf8");
2992
+ const content = readFileSync8(join11(cwd, file), "utf8");
2765
2993
  return containsLikelySecretForAudit(file, content) ? file : null;
2766
2994
  }).filter((file) => file !== null).slice(0, 5);
2767
2995
  if (secretHits.length > 0) {
@@ -2784,7 +3012,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2784
3012
  area: "project-reality",
2785
3013
  message: "Package source repository mode does not require installed-project context files."
2786
3014
  });
2787
- } else if (!existsSync10(join10(cwd, CONTEXT_JSON))) {
3015
+ } else if (!existsSync11(join11(cwd, CONTEXT_JSON))) {
2788
3016
  findings.push({
2789
3017
  level: "warn",
2790
3018
  area: "project-reality",
@@ -2850,7 +3078,7 @@ function report(target, findings) {
2850
3078
  }
2851
3079
  function readJson(path) {
2852
3080
  try {
2853
- return JSON.parse(readFileSync8(path, "utf8"));
3081
+ return JSON.parse(readFileSync9(path, "utf8"));
2854
3082
  } catch {
2855
3083
  return null;
2856
3084
  }
@@ -2864,24 +3092,24 @@ function isSafeRelativePath(path) {
2864
3092
  return !normalized.startsWith("/") && !normalized.startsWith("../") && !normalized.includes("/../");
2865
3093
  }
2866
3094
  function findAntigravityLayout(cwd) {
2867
- const sourcePlugin = join11(cwd, "antigravity", "plugin.json");
2868
- if (existsSync11(sourcePlugin)) {
3095
+ const sourcePlugin = join12(cwd, "antigravity", "plugin.json");
3096
+ if (existsSync12(sourcePlugin)) {
2869
3097
  return {
2870
3098
  mode: "source",
2871
- pluginRoot: join11(cwd, "antigravity"),
2872
- commandsRoot: join11(cwd, ANTIGRAVITY_COMMANDS_SOURCE_DIR),
2873
- runtimeSkillsRoot: join11(cwd, RUNTIME_SKILLS_SOURCE_DIR),
2874
- adapterDocPath: join11(cwd, "assistant-adapters", "antigravity.md")
3099
+ pluginRoot: join12(cwd, "antigravity"),
3100
+ commandsRoot: join12(cwd, ANTIGRAVITY_COMMANDS_SOURCE_DIR),
3101
+ runtimeSkillsRoot: join12(cwd, RUNTIME_SKILLS_SOURCE_DIR),
3102
+ adapterDocPath: join12(cwd, "assistant-adapters", "antigravity.md")
2875
3103
  };
2876
3104
  }
2877
- const installedPlugin = join11(cwd, ".antigravity", "agent-kit", "plugin.json");
2878
- if (existsSync11(installedPlugin)) {
3105
+ const installedPlugin = join12(cwd, ".antigravity", "agent-kit", "plugin.json");
3106
+ if (existsSync12(installedPlugin)) {
2879
3107
  return {
2880
3108
  mode: "installed",
2881
- pluginRoot: join11(cwd, ".antigravity", "agent-kit"),
2882
- commandsRoot: join11(cwd, ANTIGRAVITY_COMMANDS_TARGET_DIR),
2883
- runtimeSkillsRoot: join11(cwd, ANTIGRAVITY_RUNTIME_SKILLS_TARGET_DIR),
2884
- adapterDocPath: join11(cwd, ".antigravity", "agent-kit", "README.md")
3109
+ pluginRoot: join12(cwd, ".antigravity", "agent-kit"),
3110
+ commandsRoot: join12(cwd, ANTIGRAVITY_COMMANDS_TARGET_DIR),
3111
+ runtimeSkillsRoot: join12(cwd, ANTIGRAVITY_RUNTIME_SKILLS_TARGET_DIR),
3112
+ adapterDocPath: join12(cwd, ".antigravity", "agent-kit", "README.md")
2885
3113
  };
2886
3114
  }
2887
3115
  return null;
@@ -2905,8 +3133,8 @@ function validateAntigravityCommands(layout, findings) {
2905
3133
  const commandNames = /* @__PURE__ */ new Set();
2906
3134
  for (const command of REQUIRED_COMMANDS) {
2907
3135
  const relativePath = `${command}.toml`;
2908
- const path = join11(layout.commandsRoot, relativePath);
2909
- if (!existsSync11(path)) {
3136
+ const path = join12(layout.commandsRoot, relativePath);
3137
+ if (!existsSync12(path)) {
2910
3138
  findings.push({
2911
3139
  level: "fail",
2912
3140
  area: "commands",
@@ -2915,7 +3143,7 @@ function validateAntigravityCommands(layout, findings) {
2915
3143
  });
2916
3144
  continue;
2917
3145
  }
2918
- const text = readFileSync8(path, "utf8");
3146
+ const text = readFileSync9(path, "utf8");
2919
3147
  addSecretFinding(relativePath, text, findings);
2920
3148
  const name = commandField(text, "name");
2921
3149
  const description = commandField(text, "description");
@@ -2972,7 +3200,7 @@ function validateAntigravityCommands(layout, findings) {
2972
3200
  }
2973
3201
  }
2974
3202
  function validateAntigravityPlugin(layout, findings) {
2975
- const pluginPath = join11(layout.pluginRoot, "plugin.json");
3203
+ const pluginPath = join12(layout.pluginRoot, "plugin.json");
2976
3204
  const plugin = readJson(pluginPath);
2977
3205
  if (!plugin || !isRecord2(plugin)) {
2978
3206
  findings.push({
@@ -3012,8 +3240,8 @@ function validateAntigravityPlugin(layout, findings) {
3012
3240
  });
3013
3241
  continue;
3014
3242
  }
3015
- const resolved = join11(layout.pluginRoot, path);
3016
- if (!existsSync11(resolved)) {
3243
+ const resolved = join12(layout.pluginRoot, path);
3244
+ if (!existsSync12(resolved)) {
3017
3245
  findings.push({
3018
3246
  level: "fail",
3019
3247
  area: "manifest",
@@ -3022,7 +3250,7 @@ function validateAntigravityPlugin(layout, findings) {
3022
3250
  });
3023
3251
  }
3024
3252
  }
3025
- const pluginText = readFileSync8(pluginPath, "utf8");
3253
+ const pluginText = readFileSync9(pluginPath, "utf8");
3026
3254
  addSecretFinding("plugin.json", pluginText, findings);
3027
3255
  if (Array.isArray(plugin.sourceOfTruth) && plugin.sourceOfTruth.includes("AGENTS.md") && plugin.sourceOfTruth.includes(".agent-kit/agent-roster.json")) {
3028
3256
  findings.push({
@@ -3040,13 +3268,13 @@ function validateAntigravityPlugin(layout, findings) {
3040
3268
  }
3041
3269
  }
3042
3270
  function validateRuntimeSkills(cwd, layout, findings) {
3043
- const canonicalSkillsRoot = existsSync11(join11(cwd, "skills")) ? join11(cwd, "skills") : join11(cwd, ".agent-kit", "skills");
3271
+ const canonicalSkillsRoot = existsSync12(join12(cwd, "skills")) ? join12(cwd, "skills") : join12(cwd, ".agent-kit", "skills");
3044
3272
  const canonicalSkillNames = listFilesRecursive(canonicalSkillsRoot).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, ""));
3045
3273
  const runtimeSkillFiles = listFilesRecursive(layout.runtimeSkillsRoot).filter((file) => file.endsWith("/SKILL.md") || file === "SKILL.md");
3046
3274
  const runtimeSkillNames = runtimeSkillFiles.map((file) => file.split(/[\\/]/)[0]).filter((value) => typeof value === "string" && value.length > 0).filter((value, index, values) => values.indexOf(value) === index);
3047
3275
  for (const skillName of canonicalSkillNames) {
3048
- const runtimePath = join11(layout.runtimeSkillsRoot, skillName, "SKILL.md");
3049
- if (!existsSync11(runtimePath)) {
3276
+ const runtimePath = join12(layout.runtimeSkillsRoot, skillName, "SKILL.md");
3277
+ if (!existsSync12(runtimePath)) {
3050
3278
  findings.push({
3051
3279
  level: "fail",
3052
3280
  area: "runtime-skills",
@@ -3055,7 +3283,7 @@ function validateRuntimeSkills(cwd, layout, findings) {
3055
3283
  });
3056
3284
  continue;
3057
3285
  }
3058
- const text = readFileSync8(runtimePath, "utf8");
3286
+ const text = readFileSync9(runtimePath, "utf8");
3059
3287
  addSecretFinding(`${skillName}/SKILL.md`, text, findings);
3060
3288
  if (!/^---\nname: .+\ndescription: .+\n---/m.test(text)) {
3061
3289
  findings.push({
@@ -3083,7 +3311,7 @@ function validateRuntimeSkills(cwd, layout, findings) {
3083
3311
  remediation: "Add canonical skills or remove orphan runtime wrappers."
3084
3312
  });
3085
3313
  }
3086
- if (canonicalSkillNames.length > 0 && canonicalSkillNames.every((skillName) => existsSync11(join11(layout.runtimeSkillsRoot, skillName, "SKILL.md")))) {
3314
+ if (canonicalSkillNames.length > 0 && canonicalSkillNames.every((skillName) => existsSync12(join12(layout.runtimeSkillsRoot, skillName, "SKILL.md")))) {
3087
3315
  findings.push({
3088
3316
  level: "pass",
3089
3317
  area: "runtime-skills",
@@ -3104,7 +3332,7 @@ function validateAntigravity(cwd) {
3104
3332
  }
3105
3333
  ]);
3106
3334
  }
3107
- const adapterDoc = existsSync11(layout.adapterDocPath) ? readFileSync8(layout.adapterDocPath, "utf8") : "";
3335
+ const adapterDoc = existsSync12(layout.adapterDocPath) ? readFileSync9(layout.adapterDocPath, "utf8") : "";
3108
3336
  if (!adapterDoc) {
3109
3337
  findings.push({
3110
3338
  level: "fail",
@@ -3133,7 +3361,7 @@ function validateAntigravity(cwd) {
3133
3361
  validateAntigravityCommands(layout, findings);
3134
3362
  validateRuntimeSkills(cwd, layout, findings);
3135
3363
  if (layout.mode === "source") {
3136
- const packageJson = readJson(join11(cwd, "package.json"));
3364
+ const packageJson = readJson(join12(cwd, "package.json"));
3137
3365
  const files = isRecord2(packageJson) && Array.isArray(packageJson.files) ? packageJson.files : [];
3138
3366
  for (const requiredFile of ["antigravity", "runtime-skills", "assistant-adapters"]) {
3139
3367
  if (!files.includes(requiredFile)) {
@@ -3157,40 +3385,145 @@ function validateAntigravity(cwd) {
3157
3385
  }
3158
3386
  function validateBasicAdapter(cwd, target) {
3159
3387
  const findings = [];
3160
- const sourcePaths = {
3161
- cursor: ["assistant-adapters/cursor-agent-kit.mdc", "assistant-adapters/model-selection/cursor-model-selection.mdc"],
3162
- claude: ["assistant-adapters/claude-code-subagents.md"],
3163
- codex: ["assistant-adapters/codex-agents.md", "assistant-adapters/model-selection/codex-config.example.toml"],
3164
- copilot: ["assistant-adapters/github-copilot-instructions.md", "assistant-adapters/github-next-supabase.instructions.md"]
3165
- };
3166
- for (const relativePath of sourcePaths[target]) {
3167
- const path = join11(cwd, relativePath);
3168
- if (!existsSync11(path)) {
3388
+ const isPackageSource = existsSync12(join12(cwd, "package.json")) && existsSync12(join12(cwd, "src")) && existsSync12(join12(cwd, "templates"));
3389
+ if (isPackageSource) {
3390
+ const sourcePaths = {
3391
+ cursor: [
3392
+ "assistant-adapters/cursor-agent-kit.mdc",
3393
+ "assistant-adapters/model-selection/cursor-model-selection.mdc",
3394
+ "assistant-adapters/cursor-planner.mdc"
3395
+ ],
3396
+ claude: ["assistant-adapters/claude-code-subagents.md"],
3397
+ codex: ["assistant-adapters/codex-agents.md", "assistant-adapters/model-selection/codex-config.example.toml"],
3398
+ copilot: ["assistant-adapters/github-copilot-instructions.md", "assistant-adapters/github-next-supabase.instructions.md"]
3399
+ };
3400
+ for (const relativePath of sourcePaths[target]) {
3401
+ const path = join12(cwd, relativePath);
3402
+ if (!existsSync12(path)) {
3403
+ findings.push({
3404
+ level: "fail",
3405
+ area: "adapter",
3406
+ message: `${relativePath} is missing.`,
3407
+ remediation: "Restore the adapter template or run agent-kit update."
3408
+ });
3409
+ continue;
3410
+ }
3411
+ const text = readFileSync9(path, "utf8");
3412
+ addSecretFinding(relativePath, text, findings);
3413
+ if (!text.includes("AGENTS.md") && !text.includes("MODEL_ROUTING.md")) {
3414
+ findings.push({
3415
+ level: "warn",
3416
+ area: "adapter",
3417
+ message: `${relativePath} does not clearly reference Agent Kit source-of-truth files.`,
3418
+ remediation: "Adapter templates should point back to AGENTS.md, MODEL_ROUTING.md, and the roster contract."
3419
+ });
3420
+ }
3421
+ }
3422
+ } else {
3423
+ findings.push(...validateInstalledIdeAdapter(cwd, target).findings);
3424
+ }
3425
+ if (findings.every((finding) => finding.level !== "fail")) {
3426
+ findings.push({
3427
+ level: "pass",
3428
+ area: "adapter",
3429
+ message: `${target} adapter ${isPackageSource ? "templates are present" : "activation assets are present"}.`
3430
+ });
3431
+ }
3432
+ return report(target, findings);
3433
+ }
3434
+ function readAssistantAdaptersDoc(cwd) {
3435
+ const path = join12(cwd, "ASSISTANT_ADAPTERS.md");
3436
+ return existsSync12(path) ? readFileSync9(path, "utf8") : "";
3437
+ }
3438
+ function adaptersRowIsActive(doc, toolLabel) {
3439
+ return assistantAdapterRowIsActive(doc, toolLabel);
3440
+ }
3441
+ function validateInstalledIdeAdapter(cwd, target) {
3442
+ const findings = [];
3443
+ const adaptersDoc = readAssistantAdaptersDoc(cwd);
3444
+ if (target === "cursor") {
3445
+ const rulesPath = join12(cwd, ".cursor/rules/cursor-agent-kit.mdc");
3446
+ if (!existsSync12(rulesPath)) {
3169
3447
  findings.push({
3170
3448
  level: "fail",
3171
3449
  area: "adapter",
3172
- message: `${relativePath} is missing.`,
3173
- remediation: "Restore the adapter template or run agent-kit update."
3450
+ message: ".cursor/rules/cursor-agent-kit.mdc is missing.",
3451
+ remediation: "Run agent-kit init or agent-kit init --activate cursor."
3174
3452
  });
3175
- continue;
3453
+ } else {
3454
+ addSecretFinding(".cursor/rules/cursor-agent-kit.mdc", readFileSync9(rulesPath, "utf8"), findings);
3176
3455
  }
3177
- const text = readFileSync8(path, "utf8");
3178
- addSecretFinding(relativePath, text, findings);
3179
- if (!text.includes("AGENTS.md") && !text.includes("MODEL_ROUTING.md")) {
3456
+ const plannerAgent = join12(cwd, ".cursor/agents/planner.md");
3457
+ if (existsSync12(plannerAgent)) {
3458
+ findings.push({
3459
+ level: "pass",
3460
+ area: "adapter",
3461
+ message: ".cursor/agents/planner.md is installed."
3462
+ });
3463
+ } else if (adaptersRowIsActive(adaptersDoc, "Cursor")) {
3180
3464
  findings.push({
3181
3465
  level: "warn",
3182
3466
  area: "adapter",
3183
- message: `${relativePath} does not clearly reference Agent Kit source-of-truth files.`,
3184
- remediation: "Adapter templates should point back to AGENTS.md, MODEL_ROUTING.md, and the roster contract."
3467
+ message: "Cursor is marked Active but .cursor/agents/planner.md is missing.",
3468
+ remediation: "Run agent-kit init --activate cursor to generate council subagents from the roster."
3469
+ });
3470
+ }
3471
+ const skillSample = join12(cwd, ".cursor/skills/planning-council/SKILL.md");
3472
+ if (existsSync12(skillSample)) {
3473
+ findings.push({
3474
+ level: "pass",
3475
+ area: "adapter",
3476
+ message: ".cursor/skills/*/SKILL.md project skills are installed."
3185
3477
  });
3186
3478
  }
3187
3479
  }
3188
- if (findings.every((finding) => finding.level !== "fail")) {
3189
- findings.push({
3190
- level: "pass",
3191
- area: "adapter",
3192
- message: `${target} adapter templates are present.`
3193
- });
3480
+ if (target === "claude") {
3481
+ const plannerAgent = join12(cwd, ".claude/agents/planner.md");
3482
+ if (!existsSync12(plannerAgent)) {
3483
+ findings.push({
3484
+ level: "fail",
3485
+ area: "adapter",
3486
+ message: ".claude/agents/planner.md is missing.",
3487
+ remediation: "Run agent-kit init --activate claude."
3488
+ });
3489
+ }
3490
+ }
3491
+ if (target === "codex") {
3492
+ const configPath = join12(cwd, ".codex/config.toml");
3493
+ if (!existsSync12(configPath)) {
3494
+ findings.push({
3495
+ level: "fail",
3496
+ area: "adapter",
3497
+ message: ".codex/config.toml is missing.",
3498
+ remediation: "Run agent-kit init --activate codex."
3499
+ });
3500
+ }
3501
+ const plannerAgent = join12(cwd, ".codex/agents/planner.toml");
3502
+ if (existsSync12(plannerAgent)) {
3503
+ findings.push({
3504
+ level: "pass",
3505
+ area: "adapter",
3506
+ message: ".codex/agents/planner.toml is installed."
3507
+ });
3508
+ } else if (adaptersRowIsActive(adaptersDoc, "Codex / AGENTS.md-compatible tools")) {
3509
+ findings.push({
3510
+ level: "warn",
3511
+ area: "adapter",
3512
+ message: "Codex is marked Active but .codex/agents/planner.toml is missing.",
3513
+ remediation: "Run agent-kit init --activate codex to generate council custom agents from the roster."
3514
+ });
3515
+ }
3516
+ }
3517
+ if (target === "copilot") {
3518
+ const instructions = join12(cwd, ".github/copilot-instructions.md");
3519
+ if (!existsSync12(instructions)) {
3520
+ findings.push({
3521
+ level: "fail",
3522
+ area: "adapter",
3523
+ message: ".github/copilot-instructions.md is missing.",
3524
+ remediation: "Run agent-kit init --activate copilot."
3525
+ });
3526
+ }
3194
3527
  }
3195
3528
  return report(target, findings);
3196
3529
  }
@@ -3207,7 +3540,7 @@ function validateAdapter(cwd, target = "antigravity") {
3207
3540
  }
3208
3541
  function validatePackage(cwd) {
3209
3542
  const findings = [];
3210
- const sourceMode = existsSync11(join11(cwd, "package.json")) && existsSync11(join11(cwd, "src")) && existsSync11(join11(cwd, "templates"));
3543
+ const sourceMode = existsSync12(join12(cwd, "package.json")) && existsSync12(join12(cwd, "src")) && existsSync12(join12(cwd, "templates"));
3211
3544
  if (!sourceMode) {
3212
3545
  return report("package", [
3213
3546
  {
@@ -3220,8 +3553,8 @@ function validatePackage(cwd) {
3220
3553
  }
3221
3554
  findings.push(...validateAntigravity(cwd).findings);
3222
3555
  for (const doc of ["README.md", "DOCS.md", "SPEC.md", "DECISIONS.md", "QUALITY_GATES.md", "TESTING.md", "UPGRADE.md"]) {
3223
- const path = join11(cwd, doc);
3224
- const text = existsSync11(path) ? readFileSync8(path, "utf8") : "";
3556
+ const path = join12(cwd, doc);
3557
+ const text = existsSync12(path) ? readFileSync9(path, "utf8") : "";
3225
3558
  const lower = text.toLowerCase();
3226
3559
  if (!lower.includes("antigravity") && !lower.includes("runtime command") && !lower.includes("runtime adapter")) {
3227
3560
  findings.push({
@@ -3238,7 +3571,7 @@ function validatePackage(cwd) {
3238
3571
  "examples/next-supabase-installed/.agent-kit/manifest.json",
3239
3572
  "examples/next-supabase-installed/audit-output.json"
3240
3573
  ]) {
3241
- if (!existsSync11(join11(cwd, examplePath))) {
3574
+ if (!existsSync12(join12(cwd, examplePath))) {
3242
3575
  findings.push({
3243
3576
  level: "fail",
3244
3577
  area: "examples",
@@ -3273,17 +3606,17 @@ function validatePackage(cwd) {
3273
3606
  }
3274
3607
 
3275
3608
  // src/install/diff.ts
3276
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
3277
- import { join as join12 } from "path";
3609
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
3610
+ import { join as join13 } from "path";
3278
3611
  function statusForTextFile(target, template) {
3279
- if (!existsSync12(target)) return "missing";
3280
- const targetHash = sha256(readFileSync9(target, "utf8"));
3281
- const templateHash = sha256(readFileSync9(template, "utf8"));
3612
+ if (!existsSync13(target)) return "missing";
3613
+ const targetHash = sha256(readFileSync10(target, "utf8"));
3614
+ const templateHash = sha256(readFileSync10(template, "utf8"));
3282
3615
  return targetHash === templateHash ? "unchanged" : "changed";
3283
3616
  }
3284
3617
  function diffProject(cwd, stack = "next-supabase") {
3285
3618
  const packageRoot = findPackageRoot();
3286
- const templateRoot = join12(packageRoot, "templates", stack);
3619
+ const templateRoot = join13(packageRoot, "templates", stack);
3287
3620
  const libraryFolders = {
3288
3621
  missing: [],
3289
3622
  present: [],
@@ -3307,8 +3640,8 @@ function diffProject(cwd, stack = "next-supabase") {
3307
3640
  }
3308
3641
  };
3309
3642
  for (const doc of ROOT_DOCS) {
3310
- const target = join12(cwd, doc);
3311
- const template = join12(templateRoot, doc);
3643
+ const target = join13(cwd, doc);
3644
+ const template = join13(templateRoot, doc);
3312
3645
  const status = statusForTextFile(target, template);
3313
3646
  if (status === "missing") {
3314
3647
  result.missing.push(doc);
@@ -3321,7 +3654,7 @@ function diffProject(cwd, stack = "next-supabase") {
3321
3654
  result.preview.wouldWriteConflicts.push(doc);
3322
3655
  }
3323
3656
  }
3324
- result.agentRoster = statusForTextFile(join12(cwd, DEFAULT_AGENT_ROSTER_TARGET), join12(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE));
3657
+ result.agentRoster = statusForTextFile(join13(cwd, DEFAULT_AGENT_ROSTER_TARGET), join13(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE));
3325
3658
  if (result.agentRoster === "missing") {
3326
3659
  result.preview.wouldCreate.push(DEFAULT_AGENT_ROSTER_TARGET);
3327
3660
  result.preview.wouldCreateAgentRoster = true;
@@ -3330,7 +3663,7 @@ function diffProject(cwd, stack = "next-supabase") {
3330
3663
  result.preview.wouldWriteConflicts.push(DEFAULT_AGENT_ROSTER_TARGET);
3331
3664
  result.preview.wouldWriteAgentRosterConflict = true;
3332
3665
  }
3333
- result.modelRouting = statusForTextFile(join12(cwd, DEFAULT_MODEL_ROUTING_TARGET), join12(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE));
3666
+ result.modelRouting = statusForTextFile(join13(cwd, DEFAULT_MODEL_ROUTING_TARGET), join13(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE));
3334
3667
  if (result.modelRouting === "missing") {
3335
3668
  result.preview.wouldCreate.push(DEFAULT_MODEL_ROUTING_TARGET);
3336
3669
  result.preview.wouldCreateModelRouting = true;
@@ -3340,8 +3673,8 @@ function diffProject(cwd, stack = "next-supabase") {
3340
3673
  result.preview.wouldWriteModelRoutingConflict = true;
3341
3674
  }
3342
3675
  for (const folder of LIBRARY_FOLDERS) {
3343
- const target = join12(cwd, ".agent-kit", folder);
3344
- if (existsSync12(target)) libraryFolders.present.push(folder);
3676
+ const target = join13(cwd, ".agent-kit", folder);
3677
+ if (existsSync13(target)) libraryFolders.present.push(folder);
3345
3678
  else libraryFolders.missing.push(folder);
3346
3679
  }
3347
3680
  return result;
@@ -3349,8 +3682,8 @@ function diffProject(cwd, stack = "next-supabase") {
3349
3682
 
3350
3683
  // src/research/discover.ts
3351
3684
  import { Octokit } from "@octokit/rest";
3352
- import { readFileSync as readFileSync10 } from "fs";
3353
- import { join as join13 } from "path";
3685
+ import { readFileSync as readFileSync11 } from "fs";
3686
+ import { join as join14 } from "path";
3354
3687
 
3355
3688
  // src/research/config.ts
3356
3689
  import { z as z2 } from "zod";
@@ -3375,8 +3708,8 @@ var researchConfigSchema = z2.object({
3375
3708
  // src/research/discover.ts
3376
3709
  async function discoverRepos(options) {
3377
3710
  const packageRoot = findPackageRoot();
3378
- const configPath = join13(packageRoot, "research", "scan-config.json");
3379
- const config = researchConfigSchema.parse(JSON.parse(readFileSync10(configPath, "utf8")));
3711
+ const configPath = join14(packageRoot, "research", "scan-config.json");
3712
+ const config = researchConfigSchema.parse(JSON.parse(readFileSync11(configPath, "utf8")));
3380
3713
  const token = options.token ?? process.env.GITHUB_TOKEN;
3381
3714
  if (!token) {
3382
3715
  throw new Error("GITHUB_TOKEN is required for GitHub API research discovery.");
@@ -3437,20 +3770,20 @@ async function discoverRepos(options) {
3437
3770
  }
3438
3771
  }
3439
3772
  const candidates = [...deduped.values()].slice(0, maxRepos);
3440
- const output = options.output ?? join13(options.cwd, "research", "repo-candidates.json");
3773
+ const output = options.output ?? join14(options.cwd, "research", "repo-candidates.json");
3441
3774
  writeText(output, `${JSON.stringify(candidates, null, 2)}
3442
3775
  `);
3443
3776
  return candidates;
3444
3777
  }
3445
3778
 
3446
3779
  // src/research/scan.ts
3447
- import { existsSync as existsSync15, mkdirSync as mkdirSync2, readFileSync as readFileSync12, rmSync } from "fs";
3448
- import { join as join15 } from "path";
3780
+ import { existsSync as existsSync16, mkdirSync as mkdirSync2, readFileSync as readFileSync13, rmSync } from "fs";
3781
+ import { join as join16 } from "path";
3449
3782
  import { simpleGit } from "simple-git";
3450
3783
 
3451
3784
  // src/research/analyze.ts
3452
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
3453
- import { join as join14 } from "path";
3785
+ import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
3786
+ import { join as join15 } from "path";
3454
3787
  function normalizeRelativePath(file) {
3455
3788
  return file.replace(/\\/g, "/");
3456
3789
  }
@@ -3458,8 +3791,8 @@ function hasFile(files, matcher) {
3458
3791
  return files.some((file) => matcher.test(normalizeRelativePath(file)));
3459
3792
  }
3460
3793
  function fileText(root, file) {
3461
- const path = join14(root, file);
3462
- return existsSync14(path) ? readFileSync11(path, "utf8") : "";
3794
+ const path = join15(root, file);
3795
+ return existsSync15(path) ? readFileSync12(path, "utf8") : "";
3463
3796
  }
3464
3797
  function textIncludes(root, files, matcher, terms) {
3465
3798
  const lowerTerms = terms.map((term) => term.toLowerCase());
@@ -3590,24 +3923,24 @@ ${finding.impactOnKit.map((item) => `- ${item}`).join("\n")}
3590
3923
  `;
3591
3924
  }
3592
3925
  async function scanRepos(options) {
3593
- const candidatesPath = options.candidatesPath ?? join15(options.cwd, "research", "repo-candidates.json");
3594
- if (!existsSync15(candidatesPath)) {
3926
+ const candidatesPath = options.candidatesPath ?? join16(options.cwd, "research", "repo-candidates.json");
3927
+ if (!existsSync16(candidatesPath)) {
3595
3928
  throw new Error(`Candidates file not found: ${candidatesPath}`);
3596
3929
  }
3597
- const candidates = JSON.parse(readFileSync12(candidatesPath, "utf8"));
3598
- const workdir = options.workdir ?? join15(options.cwd, "research", "workdir");
3930
+ const candidates = JSON.parse(readFileSync13(candidatesPath, "utf8"));
3931
+ const workdir = options.workdir ?? join16(options.cwd, "research", "workdir");
3599
3932
  mkdirSync2(workdir, { recursive: true });
3600
- mkdirSync2(join15(options.cwd, "research", "findings"), { recursive: true });
3933
+ mkdirSync2(join16(options.cwd, "research", "findings"), { recursive: true });
3601
3934
  const findings = [];
3602
3935
  const git = simpleGit();
3603
3936
  for (const candidate of candidates) {
3604
3937
  const repoSlug = candidate.fullName.replace("/", "__");
3605
- const repoPath = join15(workdir, repoSlug);
3606
- if (existsSync15(repoPath)) rmSync(repoPath, { recursive: true, force: true });
3938
+ const repoPath = join16(workdir, repoSlug);
3939
+ if (existsSync16(repoPath)) rmSync(repoPath, { recursive: true, force: true });
3607
3940
  await git.raw(["clone", "--depth", "1", candidate.htmlUrl, repoPath]);
3608
3941
  const finding = analyzeRepository(candidate, repoPath);
3609
3942
  findings.push(finding);
3610
- writeText(join15(options.cwd, "research", "findings", `${repoSlug}.md`), findingToMarkdown(finding));
3943
+ writeText(join16(options.cwd, "research", "findings", `${repoSlug}.md`), findingToMarkdown(finding));
3611
3944
  if (!options.keepClones) {
3612
3945
  rmSync(repoPath, { recursive: true, force: true });
3613
3946
  }
@@ -3616,8 +3949,8 @@ async function scanRepos(options) {
3616
3949
  }
3617
3950
 
3618
3951
  // src/research/summarize.ts
3619
- import { existsSync as existsSync16, readFileSync as readFileSync13, readdirSync as readdirSync2 } from "fs";
3620
- import { join as join16 } from "path";
3952
+ import { existsSync as existsSync17, readFileSync as readFileSync14, readdirSync as readdirSync3 } from "fs";
3953
+ import { join as join17 } from "path";
3621
3954
  var SUMMARY_TARGETS = {
3622
3955
  "nextjs-patterns": {
3623
3956
  title: "Next.js Patterns",
@@ -3720,12 +4053,12 @@ function renderRepoList(findings, scoreKeys) {
3720
4053
  return findings.slice().sort((a, b) => scoreFor(b, scoreKeys) - scoreFor(a, scoreKeys) || b.totalScore - a.totalScore || b.stars - a.stars).slice(0, 12).map((finding) => `- ${finding.fullName} (${finding.category}) - focus score ${scoreFor(finding, scoreKeys)}, total ${finding.totalScore}/${maxTotalScore}`).join("\n");
3721
4054
  }
3722
4055
  function summarizeFindings(cwd) {
3723
- const findingsDir = join16(cwd, "research", "findings");
3724
- if (!existsSync16(findingsDir)) {
4056
+ const findingsDir = join17(cwd, "research", "findings");
4057
+ if (!existsSync17(findingsDir)) {
3725
4058
  throw new Error("No research/findings directory exists. Run agent-kit research scan first.");
3726
4059
  }
3727
- const findingFiles = readdirSync2(findingsDir).filter((file) => file.endsWith(".md"));
3728
- const findings = findingFiles.map((file) => parseFinding(file, readFileSync13(join16(findingsDir, file), "utf8"))).filter((finding) => finding !== null);
4060
+ const findingFiles = readdirSync3(findingsDir).filter((file) => file.endsWith(".md"));
4061
+ const findings = findingFiles.map((file) => parseFinding(file, readFileSync14(join17(findingsDir, file), "utf8"))).filter((finding) => finding !== null);
3729
4062
  const categoryCounts = countBy(findings.map((finding) => finding.category));
3730
4063
  const outputs = [];
3731
4064
  const overview = `# Research Scan Overview
@@ -3744,13 +4077,13 @@ ${countBy(findings.flatMap((finding) => finding.strongPractices)).slice(0, 12).m
3744
4077
  ## Most Repeated Gaps
3745
4078
  ${countBy(findings.flatMap((finding) => finding.weakPractices)).slice(0, 12).map(([practice, count]) => `- ${practice} (${count})`).join("\n")}
3746
4079
  `;
3747
- const overviewPath = join16(cwd, "research", "summaries", "scan-overview.md");
4080
+ const overviewPath = join17(cwd, "research", "summaries", "scan-overview.md");
3748
4081
  writeText(overviewPath, overview);
3749
4082
  outputs.push(overviewPath);
3750
4083
  for (const [target, config] of Object.entries(SUMMARY_TARGETS)) {
3751
4084
  const categories = config.categories;
3752
4085
  const scopedFindings = findings.filter((finding) => categories.includes(finding.category));
3753
- const path = join16(cwd, "research", "summaries", `${target}.md`);
4086
+ const path = join17(cwd, "research", "summaries", `${target}.md`);
3754
4087
  const summary2 = `# ${config.title}
3755
4088
 
3756
4089
  Generated from ${scopedFindings.length} relevant repository findings.
@@ -3791,7 +4124,7 @@ Review the generated research summaries, then convert repeated best practices in
3791
4124
 
3792
4125
  Do not copy source code from scanned repositories. Adopt only generalized practices with clear rationale.
3793
4126
  `;
3794
- const path = join16(cwd, "research", "proposed-updates.md");
4127
+ const path = join17(cwd, "research", "proposed-updates.md");
3795
4128
  writeText(path, output);
3796
4129
  return path;
3797
4130
  }
@@ -3900,8 +4233,8 @@ function proposeCorrectionUpstream(cwd, id) {
3900
4233
  }
3901
4234
 
3902
4235
  // src/studio/session.ts
3903
- import { existsSync as existsSync17, readFileSync as readFileSync14, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
3904
- import { join as join17 } from "path";
4236
+ import { existsSync as existsSync18, readFileSync as readFileSync15, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
4237
+ import { join as join18 } from "path";
3905
4238
  function sessionDir(sessionId) {
3906
4239
  return `${COUNCIL_SESSIONS_DIR}/${safeSlug(sessionId)}`;
3907
4240
  }
@@ -3958,9 +4291,9 @@ function startSession(cwd, options) {
3958
4291
  return { sessionId, sessionPath: sessionDir(sessionId) };
3959
4292
  }
3960
4293
  function listSessions(cwd) {
3961
- const root = join17(cwd, COUNCIL_SESSIONS_DIR);
3962
- if (!existsSync17(root)) return [];
3963
- return readdirSync3(root).filter((entry) => entry !== "active").map((entry) => join17(root, entry, "session.json")).filter((path) => existsSync17(path) && statSync2(path).isFile()).map((path) => StudioSessionContract.parse(JSON.parse(readFileSync14(path, "utf8")))).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
4294
+ const root = join18(cwd, COUNCIL_SESSIONS_DIR);
4295
+ if (!existsSync18(root)) return [];
4296
+ return readdirSync4(root).filter((entry) => entry !== "active").map((entry) => join18(root, entry, "session.json")).filter((path) => existsSync18(path) && statSync2(path).isFile()).map((path) => StudioSessionContract.parse(JSON.parse(readFileSync15(path, "utf8")))).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
3964
4297
  }
3965
4298
  function getActiveSessionId(cwd) {
3966
4299
  const active = readTextFile(cwd, ACTIVE_SESSION_FILE)?.trim();
@@ -4658,13 +4991,13 @@ function parseSetupFormPayload(raw) {
4658
4991
  }
4659
4992
 
4660
4993
  // src/studio/wizard/checklist.ts
4661
- import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
4662
- import { join as join18 } from "path";
4994
+ import { existsSync as existsSync19, readFileSync as readFileSync16 } from "fs";
4995
+ import { join as join19 } from "path";
4663
4996
  var IDE_PATHS = {
4664
- cursor: ".cursor/rules/cursor-agent-kit.mdc",
4997
+ cursor: ".cursor/agents/planner.md",
4665
4998
  copilot: ".github/copilot-instructions.md",
4666
- claude: ".claude/agents/",
4667
- codex: "AGENTS.md",
4999
+ claude: ".claude/agents/planner.md",
5000
+ codex: ".codex/agents/planner.toml",
4668
5001
  other: "ASSISTANT_ADAPTERS.md"
4669
5002
  };
4670
5003
  function saveIdeChecklist(cwd, ideSurface) {
@@ -4679,10 +5012,13 @@ function saveIdeChecklist(cwd, ideSurface) {
4679
5012
  }
4680
5013
  function detectIdeRulePresent(cwd, ideSurface) {
4681
5014
  const rel = IDE_PATHS[ideSurface];
5015
+ if (ideSurface === "cursor") {
5016
+ return existsSync19(join19(cwd, rel)) || existsSync19(join19(cwd, ".cursor/rules/cursor-agent-kit.mdc"));
5017
+ }
4682
5018
  if (rel.endsWith("/")) {
4683
- return existsSync18(join18(cwd, rel));
5019
+ return existsSync19(join19(cwd, rel));
4684
5020
  }
4685
- return existsSync18(join18(cwd, rel));
5021
+ return existsSync19(join19(cwd, rel));
4686
5022
  }
4687
5023
  var VISUAL_QA_MARKER = "## Visual QA Tier";
4688
5024
  var VISUAL_QA_BLOCKS = {
@@ -4710,11 +5046,11 @@ This project uses the **Mature** visual QA tier.
4710
5046
  };
4711
5047
  function writeVisualQaTier(cwd, tier) {
4712
5048
  const path = "TESTING.md";
4713
- const fullPath = join18(cwd, path);
4714
- if (!existsSync18(fullPath)) {
5049
+ const fullPath = join19(cwd, path);
5050
+ if (!existsSync19(fullPath)) {
4715
5051
  return { updated: false, path, reason: "TESTING.md not found in project root." };
4716
5052
  }
4717
- const current = readFileSync15(fullPath, "utf8");
5053
+ const current = readFileSync16(fullPath, "utf8");
4718
5054
  if (current.includes(VISUAL_QA_MARKER)) {
4719
5055
  return {
4720
5056
  updated: false,
@@ -4890,8 +5226,8 @@ function extractSetupFormFromWizardForm(form) {
4890
5226
  }
4891
5227
 
4892
5228
  // src/studio/wizard/drafts.ts
4893
- import { existsSync as existsSync19, readFileSync as readFileSync16 } from "fs";
4894
- import { join as join19 } from "path";
5229
+ import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
5230
+ import { join as join20 } from "path";
4895
5231
  var DESIGN_DRAFT_JSON = ".agent-kit/onboarding/design-draft.json";
4896
5232
  var MESSAGING_DRAFT_JSON = ".agent-kit/onboarding/messaging-draft.json";
4897
5233
  function loadDesignDraft(cwd) {
@@ -4936,11 +5272,11 @@ function previewMessagingMarkdown(draft) {
4936
5272
  `;
4937
5273
  }
4938
5274
  function appendSectionToDoc(cwd, doc, sectionMarkdown) {
4939
- const fullPath = join19(cwd, doc);
4940
- if (!existsSync19(fullPath)) {
5275
+ const fullPath = join20(cwd, doc);
5276
+ if (!existsSync20(fullPath)) {
4941
5277
  return { target: doc, action: "missing" };
4942
5278
  }
4943
- const current = readFileSync16(fullPath, "utf8");
5279
+ const current = readFileSync17(fullPath, "utf8");
4944
5280
  if (current.includes("(wizard draft)")) {
4945
5281
  return { target: doc, action: "conflict", conflictPath: `.agent-kit/conflicts/wizard-${doc}` };
4946
5282
  }
@@ -4979,8 +5315,8 @@ function applyDrafts(cwd) {
4979
5315
  }
4980
5316
 
4981
5317
  // src/studio/office/render.ts
4982
- import { readFileSync as readFileSync17 } from "fs";
4983
- import { join as join20 } from "path";
5318
+ import { readFileSync as readFileSync18 } from "fs";
5319
+ import { join as join21 } from "path";
4984
5320
 
4985
5321
  // src/studio/office/map.ts
4986
5322
  var MAP_WIDTH = 28;
@@ -5114,12 +5450,12 @@ var PRODUCT_CATEGORIES = [
5114
5450
  var TENANT_MODELS = ["single-user", "team", "tenant", "marketplace", "admin", "public-content"];
5115
5451
  function readOfficeAsset(name) {
5116
5452
  const root = findPackageRoot();
5117
- const distPath = join20(root, "dist", "studio", "office", "assets", name);
5118
- const srcPath = join20(root, "src", "studio", "office", "assets", name);
5453
+ const distPath = join21(root, "dist", "studio", "office", "assets", name);
5454
+ const srcPath = join21(root, "src", "studio", "office", "assets", name);
5119
5455
  try {
5120
- return readFileSync17(distPath, "utf8");
5456
+ return readFileSync18(distPath, "utf8");
5121
5457
  } catch {
5122
- return readFileSync17(srcPath, "utf8");
5458
+ return readFileSync18(srcPath, "utf8");
5123
5459
  }
5124
5460
  }
5125
5461
  function buildOfficeBootConfig(cwd, viewModel) {
@@ -5286,8 +5622,8 @@ function allAgentBriefsComplete(form, agentIds) {
5286
5622
  }
5287
5623
 
5288
5624
  // src/studio/wizard/render.ts
5289
- import { readFileSync as readFileSync18 } from "fs";
5290
- import { join as join21 } from "path";
5625
+ import { readFileSync as readFileSync19 } from "fs";
5626
+ import { join as join22 } from "path";
5291
5627
  var PRODUCT_CATEGORIES2 = [
5292
5628
  "content-app",
5293
5629
  "saas",
@@ -5304,12 +5640,12 @@ var PRODUCT_CATEGORIES2 = [
5304
5640
  var TENANT_MODELS2 = ["single-user", "team", "tenant", "marketplace", "admin", "public-content"];
5305
5641
  function readWizardAsset(name) {
5306
5642
  const root = findPackageRoot();
5307
- const distPath = join21(root, "dist", "studio", "wizard", "assets", name);
5308
- const srcPath = join21(root, "src", "studio", "wizard", "assets", name);
5643
+ const distPath = join22(root, "dist", "studio", "wizard", "assets", name);
5644
+ const srcPath = join22(root, "src", "studio", "wizard", "assets", name);
5309
5645
  try {
5310
- return readFileSync18(distPath, "utf8");
5646
+ return readFileSync19(distPath, "utf8");
5311
5647
  } catch {
5312
- return readFileSync18(srcPath, "utf8");
5648
+ return readFileSync19(srcPath, "utf8");
5313
5649
  }
5314
5650
  }
5315
5651
  function mergeWizardSteps(cwd) {
@@ -5574,9 +5910,20 @@ async function handleRequest(cwd, request, response) {
5574
5910
  try {
5575
5911
  const body = await readJsonBody(request);
5576
5912
  if (!body.ideSurface) throw new Error("ideSurface is required.");
5913
+ const activateTarget = ideSurfaceToActivateTarget(body.ideSurface);
5914
+ let activation;
5915
+ if (activateTarget) {
5916
+ const activateResult = activateIdeTargets({ cwd, targets: [activateTarget] });
5917
+ activation = {
5918
+ activated: activateResult.activated,
5919
+ copied: activateResult.copied,
5920
+ unchanged: activateResult.unchanged,
5921
+ conflicts: activateResult.conflicts
5922
+ };
5923
+ }
5577
5924
  const result = saveIdeChecklist(cwd, body.ideSurface);
5578
5925
  markSectionComplete(cwd, "ide");
5579
- sendJson(response, 200, { ...result, ...buildStatePayload(cwd) });
5926
+ sendJson(response, 200, { ...result, activation, ...buildStatePayload(cwd) });
5580
5927
  } catch (error) {
5581
5928
  sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) });
5582
5929
  }
@@ -5689,7 +6036,7 @@ async function startSetupServer(options) {
5689
6036
  // src/studio/studio-server.ts
5690
6037
  import { watch } from "fs";
5691
6038
  import { createServer as createServer2 } from "http";
5692
- import { join as join22 } from "path";
6039
+ import { join as join23 } from "path";
5693
6040
  var DEFAULT_PORT2 = 9331;
5694
6041
  var DEFAULT_HOST2 = "127.0.0.1";
5695
6042
  var sseClients = /* @__PURE__ */ new Set();
@@ -5731,7 +6078,7 @@ function stopWatcher() {
5731
6078
  }
5732
6079
  }
5733
6080
  function watchSessionEvents(cwd, sessionId) {
5734
- const eventsPath2 = join22(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
6081
+ const eventsPath2 = join23(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
5735
6082
  if (watchedEventsPath === eventsPath2 && activeWatcher) return;
5736
6083
  stopWatcher();
5737
6084
  watchedEventsPath = eventsPath2;
@@ -5887,8 +6234,8 @@ async function startStudioServer(options) {
5887
6234
  }
5888
6235
 
5889
6236
  // src/studio/session-checkpoint.ts
5890
- import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
5891
- import { extname, join as join23 } from "path";
6237
+ import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
6238
+ import { extname, join as join24 } from "path";
5892
6239
  function parseCheckpointMarkdown(content) {
5893
6240
  const payload = { notes: [], decisions: [], handoffs: [], outputs: [] };
5894
6241
  const sections = content.split(/^## /m).slice(1);
@@ -5944,7 +6291,7 @@ function parseCheckpointMarkdown(content) {
5944
6291
  return payload;
5945
6292
  }
5946
6293
  function parseCheckpointFile(filePath) {
5947
- const content = readFileSync19(filePath, "utf8");
6294
+ const content = readFileSync20(filePath, "utf8");
5948
6295
  const ext = extname(filePath).toLowerCase();
5949
6296
  if (ext === ".json") {
5950
6297
  const parsed = JSON.parse(content);
@@ -6020,8 +6367,8 @@ function applySessionCheckpoint(cwd, payload) {
6020
6367
  };
6021
6368
  }
6022
6369
  function checkpointSessionFromFile(cwd, filePath) {
6023
- const absolute = join23(cwd, filePath);
6024
- if (!existsSync20(absolute)) throw new Error(`Checkpoint file not found: ${filePath}`);
6370
+ const absolute = join24(cwd, filePath);
6371
+ if (!existsSync21(absolute)) throw new Error(`Checkpoint file not found: ${filePath}`);
6025
6372
  return applySessionCheckpoint(cwd, parseCheckpointFile(absolute));
6026
6373
  }
6027
6374