@appsforgood/next-supabase-kit 0.1.3 → 0.1.5

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.5";
150
150
  var DEFAULT_CONFIG = {
151
151
  stack: "next-supabase",
152
152
  projectType: "saas",
@@ -185,6 +185,7 @@ var ROOT_DOCS = [
185
185
  "STYLE_GUIDE.md",
186
186
  "SECURITY.md",
187
187
  "TESTING.md",
188
+ "LOOP_CODING.md",
188
189
  "DEPLOYMENT.md",
189
190
  "UPGRADE.md"
190
191
  ];
@@ -215,6 +216,20 @@ var CURSOR_ADAPTER_FILES = [
215
216
  target: ".cursor/rules/cursor-model-selection.mdc"
216
217
  }
217
218
  ];
219
+ var CURSOR_SCOPED_ADAPTER_FILES = [
220
+ {
221
+ source: "assistant-adapters/cursor-planner.mdc",
222
+ target: ".cursor/rules/cursor-planner.mdc"
223
+ },
224
+ {
225
+ source: "assistant-adapters/cursor-security.mdc",
226
+ target: ".cursor/rules/cursor-security.mdc"
227
+ },
228
+ {
229
+ source: "assistant-adapters/cursor-frontend.mdc",
230
+ target: ".cursor/rules/cursor-frontend.mdc"
231
+ }
232
+ ];
218
233
  var COPILOT_INSTRUCTION_FILES = [
219
234
  {
220
235
  source: "assistant-adapters/github-copilot-instructions.md",
@@ -345,8 +360,8 @@ function unique(values) {
345
360
  }
346
361
 
347
362
  // src/install/audit.ts
348
- import { existsSync as existsSync10, readFileSync as readFileSync7, statSync } from "fs";
349
- import { join as join10 } from "path";
363
+ import { existsSync as existsSync11, readFileSync as readFileSync8, statSync } from "fs";
364
+ import { join as join11 } from "path";
350
365
 
351
366
  // src/config/contracts.ts
352
367
  import { z } from "zod";
@@ -615,6 +630,15 @@ var SessionEventContract = z.object({
615
630
  context2.addIssue({ code: z.ZodIssueCode.custom, message: "required output events require outputName and outputStatus", path: ["outputName"] });
616
631
  }
617
632
  });
633
+ var AgenticLevelCore = z.union([z.literal(3), z.literal(4), z.literal(5), z.literal(6)]);
634
+ var AgenticLevelTarget = z.union([
635
+ z.literal(3),
636
+ z.literal(4),
637
+ z.literal(5),
638
+ z.literal(6),
639
+ z.literal(7),
640
+ z.literal(8)
641
+ ]);
618
642
  var OnboardingStateContract = z.object({
619
643
  schemaVersion: z.literal(1),
620
644
  depth: z.enum(["quick", "standard", "complete", "undecided"]),
@@ -628,7 +652,27 @@ var OnboardingStateContract = z.object({
628
652
  wizardVersion: z.string(),
629
653
  ideSurface: z.enum(["cursor", "copilot", "claude", "codex", "other"]).optional(),
630
654
  ideVerifiedAt: z.string().datetime().optional(),
631
- visualQaTier: z.enum(["baseline", "strong", "mature"]).optional()
655
+ visualQaTier: z.enum(["baseline", "strong", "mature"]).optional(),
656
+ targetAgenticLevel: AgenticLevelTarget.optional(),
657
+ lastAgenticLevel: AgenticLevelCore.optional(),
658
+ lastAgenticComputedAt: z.string().datetime().optional()
659
+ }).strict();
660
+ var AgenticLevelSignalContract = z.object({
661
+ id: z.string().min(1),
662
+ level: AgenticLevelCore,
663
+ label: z.string().min(1),
664
+ pass: z.boolean(),
665
+ evidence: z.string().min(1),
666
+ remediation: z.string().min(1)
667
+ }).strict();
668
+ var AgenticLevelContract = z.object({
669
+ currentLevel: AgenticLevelCore,
670
+ targetLevel: AgenticLevelTarget,
671
+ maintainerProfile: z.boolean(),
672
+ computedAt: z.string().datetime(),
673
+ maintainerNote: z.string().optional(),
674
+ signals: z.array(AgenticLevelSignalContract),
675
+ climbSteps: z.array(AgenticLevelSignalContract)
632
676
  }).strict();
633
677
  function formatContractIssues(error) {
634
678
  return error.issues.map((issue) => {
@@ -1100,11 +1144,15 @@ function onboardingStateExists(cwd) {
1100
1144
  }
1101
1145
 
1102
1146
  // src/install/install.ts
1147
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
1148
+ import { join as join10 } from "path";
1149
+
1150
+ // src/install/ide-activate.ts
1103
1151
  import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
1104
1152
  import { join as join9 } from "path";
1105
1153
 
1106
- // src/install/ide-activate.ts
1107
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
1154
+ // src/install/roster-adapters.ts
1155
+ import { existsSync as existsSync8, readFileSync as readFileSync5, readdirSync as readdirSync2 } from "fs";
1108
1156
  import { join as join8 } from "path";
1109
1157
 
1110
1158
  // src/studio/wizard/roster.ts
@@ -1188,8 +1236,224 @@ function agentBriefFieldName(agentId) {
1188
1236
  return `agentBrief_${agentId}`;
1189
1237
  }
1190
1238
 
1191
- // src/install/ide-activate.ts
1239
+ // src/install/assistant-adapters-table.ts
1240
+ function extractAssistantAdapterRow(adaptersDoc, toolLabel) {
1241
+ for (const line of adaptersDoc.split("\n")) {
1242
+ const trimmed = line.trim();
1243
+ if (!trimmed.startsWith("|")) continue;
1244
+ const cells = trimmed.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
1245
+ if (cells[0] === toolLabel) return trimmed;
1246
+ }
1247
+ return null;
1248
+ }
1249
+ function assistantAdapterRowIsActive(adaptersDoc, toolLabel) {
1250
+ const row = extractAssistantAdapterRow(adaptersDoc, toolLabel);
1251
+ if (!row) return false;
1252
+ const cells = row.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
1253
+ const instructionStatus = cells[2] ?? "";
1254
+ return /^Active/i.test(instructionStatus) && !/^TBD/i.test(instructionStatus);
1255
+ }
1256
+
1257
+ // src/install/roster-adapters.ts
1192
1258
  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`";
1259
+ function quoteYamlScalar(value) {
1260
+ return JSON.stringify(value);
1261
+ }
1262
+ function buildAgentHint(agentId, name) {
1263
+ if (agentId === "planner") return "Start with the Planner workflow.";
1264
+ if (agentId === "lead-architect") return "Convene council for core changes before implementation.";
1265
+ if (agentId === "frontend-design-lead") {
1266
+ return "Require brand/content intake, creative-direction rationale, and visual QA evidence for UI changes.";
1267
+ }
1268
+ if (agentId === "security-reviewer") {
1269
+ return "Review auth, RLS, data mutation, dependency, external-call, secret, and release-risk changes.";
1270
+ }
1271
+ return `Use for ${name.toLowerCase()} work defined in the roster.`;
1272
+ }
1273
+ function buildProactiveSuffix(agentId) {
1274
+ const suffixes = {
1275
+ planner: "Use proactively for planning, scope breakdown, ambiguous requests, and workflow routing.",
1276
+ "lead-architect": "Use proactively for core changes, architecture, and cross-layer decisions.",
1277
+ "security-reviewer": "Use proactively for auth, RLS, API, Server Action, data mutation, dependency, secret, and release-risk changes.",
1278
+ "frontend-design-lead": "Use proactively for UI, design system, accessibility, and visual QA work.",
1279
+ "qa-engineer": "Use proactively after behavior changes to add or verify tests and acceptance evidence.",
1280
+ "supabase-postgres-engineer": "Use proactively for schema, migrations, RLS, auth, and SQL changes.",
1281
+ "nextjs-engineer": "Use proactively for App Router, Server Components, route handlers, and UI state work.",
1282
+ "marketing-copy-lead": "Use proactively for public-facing copy, positioning, and conversion surfaces.",
1283
+ "docs-maintainer": "Use proactively after significant changes to update living documentation.",
1284
+ "deployment-observability-engineer": "Use proactively for release, env var, migration order, monitoring, and rollback work."
1285
+ };
1286
+ return suffixes[agentId] ?? "";
1287
+ }
1288
+ function buildSubagentDescription(agent, proactive) {
1289
+ const base = agent.roleSummary.length > 140 ? `${agent.roleSummary.slice(0, 137)}...` : agent.roleSummary;
1290
+ if (!proactive) return base;
1291
+ const suffix = buildProactiveSuffix(agent.id);
1292
+ return suffix ? `${base} ${suffix}` : base;
1293
+ }
1294
+ function buildSubagentMarkdown(agent, options = {}) {
1295
+ const description = buildSubagentDescription(agent, Boolean(options.proactive));
1296
+ const agentFile = agent.file ?? `.agent-kit/agents/${agent.id}.md`;
1297
+ const hint = buildAgentHint(agent.id, agent.name);
1298
+ return `---
1299
+ name: ${quoteYamlScalar(agent.id)}
1300
+ description: ${quoteYamlScalar(description)}
1301
+ ---
1302
+
1303
+ Read ${CANONICAL_READ_LIST} before making routing or implementation decisions.
1304
+
1305
+ Also read \`${agentFile}\` for this role's detailed contract.
1306
+
1307
+ ${hint}
1308
+
1309
+ For council work, delegate to this subagent instead of role-playing the council in the main thread.
1310
+
1311
+ Record meaningful decisions, risks, handoffs, human corrections, artifacts, evidence, and verification through \`agent-kit session checkpoint\` or individual \`agent-kit session ...\` commands when available.
1312
+ `;
1313
+ }
1314
+ function writeGeneratedAgentFile(cwd, relativePath, content, force, result) {
1315
+ const targetPath = join8(cwd, relativePath);
1316
+ if (!force && existsSync8(targetPath)) {
1317
+ const existing = readFileSync5(targetPath, "utf8");
1318
+ if (existing === content) {
1319
+ result.unchanged.push(relativePath);
1320
+ return;
1321
+ }
1322
+ const conflictPath = join8(cwd, ".agent-kit", "conflicts", relativePath.replace(/\//g, "__"));
1323
+ ensureDir(join8(cwd, ".agent-kit", "conflicts"));
1324
+ writeText(conflictPath, existing);
1325
+ result.conflicts.push(`${relativePath} -> ${conflictPath}`);
1326
+ return;
1327
+ }
1328
+ ensureDir(join8(cwd, relativePath.split("/").slice(0, -1).join("/")));
1329
+ writeText(targetPath, content);
1330
+ result.copied.push(relativePath);
1331
+ }
1332
+ function generateMarkdownSubagents(cwd, agentsDir, options) {
1333
+ ensureDir(join8(cwd, agentsDir));
1334
+ for (const agent of loadProjectRosterAgents(cwd)) {
1335
+ const relativePath = `${agentsDir}/${agent.id}.md`;
1336
+ writeGeneratedAgentFile(cwd, relativePath, buildSubagentMarkdown(agent, options), options.force, options.result);
1337
+ }
1338
+ }
1339
+ var CURSOR_AGENTS_README = `# Cursor council subagents
1340
+
1341
+ 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.
1342
+
1343
+ ## Delegation
1344
+
1345
+ | Risk / work type | Subagent |
1346
+ | --- | --- |
1347
+ | Planning / scope | \`@planner\` |
1348
+ | Core architecture | \`@lead-architect\` |
1349
+ | Auth / RLS / secrets | \`@security-reviewer\` or Task \`security-review\` |
1350
+ | Frontend UI | \`@frontend-design-lead\` |
1351
+ | QA / tests | \`@qa-engineer\` |
1352
+
1353
+ Record handoffs with \`agent-kit session checkpoint --file <json>\` when the CLI is available.
1354
+
1355
+ Regenerate with \`agent-kit init --activate cursor\` after roster changes.
1356
+ `;
1357
+ function generateCursorSubagents(cwd, force, result) {
1358
+ generateMarkdownSubagents(cwd, ".cursor/agents", { proactive: true, force, result });
1359
+ writeGeneratedAgentFile(cwd, ".cursor/agents/README.md", CURSOR_AGENTS_README, force, result);
1360
+ }
1361
+ function loadAgentReasoningEffortMap(cwd) {
1362
+ const path = join8(cwd, ".agent-kit/model-routing.json");
1363
+ const map = /* @__PURE__ */ new Map();
1364
+ if (!existsSync8(path)) return map;
1365
+ try {
1366
+ const parsed = JSON.parse(readFileSync5(path, "utf8"));
1367
+ const profileEffort = /* @__PURE__ */ new Map();
1368
+ for (const profile of parsed.profiles ?? []) {
1369
+ if (profile.id && profile.reasoningEffort) {
1370
+ const effort = profile.reasoningEffort;
1371
+ if (effort === "low" || effort === "medium" || effort === "high") {
1372
+ profileEffort.set(profile.id, effort);
1373
+ }
1374
+ }
1375
+ }
1376
+ for (const binding of parsed.agentRoutes ?? []) {
1377
+ if (!binding.agentId) continue;
1378
+ const direct = binding.defaultEffort;
1379
+ if (direct === "low" || direct === "medium" || direct === "high") {
1380
+ map.set(binding.agentId, direct);
1381
+ continue;
1382
+ }
1383
+ if (binding.profileId && profileEffort.has(binding.profileId)) {
1384
+ map.set(binding.agentId, profileEffort.get(binding.profileId));
1385
+ }
1386
+ }
1387
+ } catch {
1388
+ return map;
1389
+ }
1390
+ return map;
1391
+ }
1392
+ function escapeTomlString(value) {
1393
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1394
+ }
1395
+ function buildCodexAgentToml(agent, effort) {
1396
+ const description = buildSubagentDescription(agent, true);
1397
+ const agentFile = agent.file ?? `.agent-kit/agents/${agent.id}.md`;
1398
+ const hint = buildAgentHint(agent.id, agent.name);
1399
+ const instructions = [
1400
+ `Read AGENTS.md, AGENT_ROSTER.md, .agent-kit/agent-roster.json, MODEL_ROUTING.md,`,
1401
+ `.agent-kit/model-routing.json, project context, corrections, COUNCIL.md, QUALITY_GATES.md,`,
1402
+ `and ${agentFile} before reviewing or implementing.`,
1403
+ "",
1404
+ hint,
1405
+ "",
1406
+ "Record meaningful decisions, risks, handoffs, and verification through agent-kit session checkpoint when available."
1407
+ ].join("\n");
1408
+ return `name = "${agent.id}"
1409
+ description = "${escapeTomlString(description)}"
1410
+ # model = "gpt-5.5" # verify in your Codex environment; see MODEL_ROUTING.md
1411
+ model_reasoning_effort = "${effort}"
1412
+
1413
+ developer_instructions = """
1414
+ ${instructions}
1415
+ """
1416
+ `;
1417
+ }
1418
+ function generateCodexCustomAgents(cwd, force, result) {
1419
+ ensureDir(join8(cwd, ".codex/agents"));
1420
+ const effortMap = loadAgentReasoningEffortMap(cwd);
1421
+ for (const agent of loadProjectRosterAgents(cwd)) {
1422
+ const effort = effortMap.get(agent.id) ?? "medium";
1423
+ const relativePath = `.codex/agents/${agent.id}.toml`;
1424
+ writeGeneratedAgentFile(cwd, relativePath, buildCodexAgentToml(agent, effort), force, result);
1425
+ }
1426
+ }
1427
+ function skillDescriptionFromMarkdown(text, skillId) {
1428
+ const useWhen = text.match(/## Use When\s*\n+\s*([^\n#]+)/);
1429
+ if (useWhen?.[1]) return useWhen[1].trim().slice(0, 200);
1430
+ const firstHeading = text.match(/^#\s+(.+)/m);
1431
+ if (firstHeading?.[1]) return `${firstHeading[1].trim()} \u2014 Agent Kit council skill.`;
1432
+ return `Agent Kit skill for ${skillId.replace(/-/g, " ")}.`;
1433
+ }
1434
+ function kitSkillToCursorSkill(skillId, kitMarkdown) {
1435
+ const description = skillDescriptionFromMarkdown(kitMarkdown, skillId);
1436
+ const body = kitMarkdown.replace(/^#\s+.+\n+/, "").trimStart();
1437
+ return `---
1438
+ name: ${quoteYamlScalar(skillId)}
1439
+ description: ${quoteYamlScalar(description)}
1440
+ ---
1441
+
1442
+ ${body.trim()}
1443
+ `;
1444
+ }
1445
+ function generateCursorSkillsFromKit(cwd, force, result) {
1446
+ const skillsRoot = join8(cwd, ".agent-kit/skills");
1447
+ if (!existsSync8(skillsRoot)) return;
1448
+ for (const file of readdirSync2(skillsRoot).filter((name) => name.endsWith(".md"))) {
1449
+ const skillId = file.replace(/\.md$/, "");
1450
+ const kitMarkdown = readFileSync5(join8(skillsRoot, file), "utf8");
1451
+ const relativePath = `.cursor/skills/${skillId}/SKILL.md`;
1452
+ writeGeneratedAgentFile(cwd, relativePath, kitSkillToCursorSkill(skillId, kitMarkdown), force, result);
1453
+ }
1454
+ }
1455
+
1456
+ // src/install/ide-activate.ts
1193
1457
  function normalizeTargets(targets) {
1194
1458
  const allowed = /* @__PURE__ */ new Set(["cursor", "claude", "codex", "copilot", "antigravity"]);
1195
1459
  const normalized = /* @__PURE__ */ new Set();
@@ -1204,9 +1468,9 @@ function normalizeTargets(targets) {
1204
1468
  return [...normalized];
1205
1469
  }
1206
1470
  function copyAdapterFile(cwd, packageRoot, source, target, force, result) {
1207
- const copyResult = copyTextWithConflict(join8(packageRoot, source), cwd, target, {
1471
+ const copyResult = copyTextWithConflict(join9(packageRoot, source), cwd, target, {
1208
1472
  force,
1209
- conflictRoot: join8(cwd, ".agent-kit", "conflicts")
1473
+ conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1210
1474
  });
1211
1475
  if (copyResult.action === "created") result.copied.push(copyResult.target);
1212
1476
  if (copyResult.action === "unchanged") result.unchanged.push(copyResult.target);
@@ -1215,53 +1479,18 @@ function copyAdapterFile(cwd, packageRoot, source, target, force, result) {
1215
1479
  result.conflicts.push(`${copyResult.target} -> ${copyResult.conflictPath}`);
1216
1480
  }
1217
1481
  }
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
1482
  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
- }
1483
+ generateMarkdownSubagents(cwd, ".claude/agents", { proactive: false, force, result });
1255
1484
  copyAdapterFile(cwd, packageRoot, CLAUDE_TEMPLATE, "CLAUDE.md", force, result);
1256
1485
  }
1257
1486
  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);
1487
+ for (const file of listFilesRecursive(join9(packageRoot, sourceDir))) {
1488
+ copyAdapterFile(cwd, packageRoot, join9(sourceDir, file), join9(targetDir, file).replace(/\\/g, "/"), force, result);
1260
1489
  }
1261
1490
  }
1262
1491
  function installAntigravityAdapter(cwd, packageRoot, force, result) {
1263
- ensureDir(join8(cwd, ".antigravity", "agent-kit", "commands"));
1264
- ensureDir(join8(cwd, ".antigravity", "runtime-skills"));
1492
+ ensureDir(join9(cwd, ".antigravity", "agent-kit", "commands"));
1493
+ ensureDir(join9(cwd, ".antigravity", "runtime-skills"));
1265
1494
  for (const file of ANTIGRAVITY_PLUGIN_FILES) {
1266
1495
  copyAdapterFile(cwd, packageRoot, file.source, file.target, force, result);
1267
1496
  }
@@ -1283,38 +1512,38 @@ function installAntigravityAdapter(cwd, packageRoot, force, result) {
1283
1512
  );
1284
1513
  }
1285
1514
  function updateAssistantAdaptersTable(cwd, activated) {
1286
- const path = join8(cwd, "ASSISTANT_ADAPTERS.md");
1287
- if (!existsSync8(path)) return;
1288
- let content = readFileSync5(path, "utf8");
1515
+ const path = join9(cwd, "ASSISTANT_ADAPTERS.md");
1516
+ if (!existsSync9(path)) return;
1517
+ let content = readFileSync6(path, "utf8");
1289
1518
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1290
1519
  if (activated.has("cursor") && content.includes("| Cursor |")) {
1291
1520
  content = content.replace(
1292
1521
  /\| 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`. |"
1522
+ `| 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
1523
  );
1295
1524
  }
1296
1525
  if (activated.has("copilot") && content.includes("| GitHub Copilot")) {
1297
1526
  content = content.replace(
1298
1527
  /\| 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. |"
1528
+ `| 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
1529
  );
1301
1530
  }
1302
1531
  if (activated.has("claude") && content.includes("| Claude Code |")) {
1303
1532
  content = content.replace(
1304
1533
  /\| 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. |"
1534
+ `| 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
1535
  );
1307
1536
  }
1308
1537
  if (activated.has("codex") && content.includes("| Codex / AGENTS.md-compatible tools |")) {
1309
1538
  content = content.replace(
1310
1539
  /\| 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. |"
1540
+ `| 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
1541
  );
1313
1542
  }
1314
1543
  if (activated.has("antigravity") && content.includes("| Antigravity |")) {
1315
1544
  content = content.replace(
1316
1545
  /\| 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. |"
1546
+ `| 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
1547
  );
1319
1548
  }
1320
1549
  writeText(path, content);
@@ -1341,9 +1570,14 @@ function activateIdeTargets(options) {
1341
1570
  for (const adapter2 of CURSOR_ADAPTER_FILES) {
1342
1571
  copyAdapterFile(cwd, packageRoot, adapter2.source, adapter2.target, force, result);
1343
1572
  }
1573
+ for (const adapter2 of CURSOR_SCOPED_ADAPTER_FILES) {
1574
+ copyAdapterFile(cwd, packageRoot, adapter2.source, adapter2.target, force, result);
1575
+ }
1576
+ generateCursorSubagents(cwd, force, result);
1577
+ generateCursorSkillsFromKit(cwd, force, result);
1344
1578
  }
1345
1579
  if (activated.has("copilot")) {
1346
- ensureDir(join8(cwd, ".github", "instructions"));
1580
+ ensureDir(join9(cwd, ".github", "instructions"));
1347
1581
  for (const file of COPILOT_INSTRUCTION_FILES) {
1348
1582
  copyAdapterFile(cwd, packageRoot, file.source, file.target, force, result);
1349
1583
  }
@@ -1352,8 +1586,9 @@ function activateIdeTargets(options) {
1352
1586
  generateClaudeSubagents(cwd, packageRoot, force, result);
1353
1587
  }
1354
1588
  if (activated.has("codex")) {
1355
- ensureDir(join8(cwd, ".codex"));
1589
+ ensureDir(join9(cwd, ".codex"));
1356
1590
  copyAdapterFile(cwd, packageRoot, CODEX_CONFIG_SOURCE, ".codex/config.toml", force, result);
1591
+ generateCodexCustomAgents(cwd, force, result);
1357
1592
  }
1358
1593
  if (activated.has("antigravity")) {
1359
1594
  installAntigravityAdapter(cwd, packageRoot, force, result);
@@ -1361,18 +1596,25 @@ function activateIdeTargets(options) {
1361
1596
  updateAssistantAdaptersTable(cwd, activated);
1362
1597
  return result;
1363
1598
  }
1599
+ function ideSurfaceToActivateTarget(ideSurface) {
1600
+ const value = ideSurface.trim().toLowerCase();
1601
+ if (value === "cursor" || value === "claude" || value === "codex" || value === "copilot") {
1602
+ return value;
1603
+ }
1604
+ return null;
1605
+ }
1364
1606
 
1365
1607
  // src/install/install.ts
1366
1608
  function initProject(options) {
1367
1609
  const cwd = options.cwd;
1368
1610
  const stack = options.stack ?? DEFAULT_CONFIG.stack;
1369
1611
  const packageRoot = findPackageRoot();
1370
- const templateRoot = join9(packageRoot, "templates", stack);
1371
- if (!existsSync9(templateRoot)) {
1612
+ const templateRoot = join10(packageRoot, "templates", stack);
1613
+ if (!existsSync10(templateRoot)) {
1372
1614
  throw new Error(`Unsupported stack profile: ${stack}`);
1373
1615
  }
1374
- ensureDir(join9(cwd, ".agent-kit"));
1375
- ensureDir(join9(cwd, ".agent-kit", "conflicts"));
1616
+ ensureDir(join10(cwd, ".agent-kit"));
1617
+ ensureDir(join10(cwd, ".agent-kit", "conflicts"));
1376
1618
  const result = {
1377
1619
  copied: [],
1378
1620
  unchanged: [],
@@ -1382,11 +1624,11 @@ function initProject(options) {
1382
1624
  };
1383
1625
  const templateHashes = {};
1384
1626
  for (const doc of ROOT_DOCS) {
1385
- const templatePath = join9(templateRoot, doc);
1386
- templateHashes[doc] = sha256(readFileSync6(templatePath, "utf8"));
1627
+ const templatePath = join10(templateRoot, doc);
1628
+ templateHashes[doc] = sha256(readFileSync7(templatePath, "utf8"));
1387
1629
  const copyResult = copyTextWithConflict(templatePath, cwd, doc, {
1388
1630
  force: Boolean(options.force),
1389
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1631
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1390
1632
  });
1391
1633
  if (copyResult.action === "created") result.copied.push(copyResult.target);
1392
1634
  if (copyResult.action === "unchanged") result.unchanged.push(copyResult.target);
@@ -1396,12 +1638,12 @@ function initProject(options) {
1396
1638
  }
1397
1639
  }
1398
1640
  for (const folder of LIBRARY_FOLDERS) {
1399
- copyDirectory(join9(packageRoot, folder), join9(cwd, ".agent-kit", folder));
1641
+ copyDirectory(join10(packageRoot, folder), join10(cwd, ".agent-kit", folder));
1400
1642
  }
1401
1643
  for (const adapter2 of CURSOR_ADAPTER_FILES) {
1402
- const adapterCopy = copyTextWithConflict(join9(packageRoot, adapter2.source), cwd, adapter2.target, {
1644
+ const adapterCopy = copyTextWithConflict(join10(packageRoot, adapter2.source), cwd, adapter2.target, {
1403
1645
  force: Boolean(options.force),
1404
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1646
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1405
1647
  });
1406
1648
  if (adapterCopy.action === "created") result.copied.push(adapterCopy.target);
1407
1649
  if (adapterCopy.action === "unchanged") result.unchanged.push(adapterCopy.target);
@@ -1410,17 +1652,17 @@ function initProject(options) {
1410
1652
  result.conflicts.push(`${adapterCopy.target} -> ${adapterCopy.conflictPath}`);
1411
1653
  }
1412
1654
  }
1413
- const rosterCopy = copyTextWithConflict(join9(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE), cwd, DEFAULT_AGENT_ROSTER_TARGET, {
1655
+ const rosterCopy = copyTextWithConflict(join10(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE), cwd, DEFAULT_AGENT_ROSTER_TARGET, {
1414
1656
  force: Boolean(options.force),
1415
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1657
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1416
1658
  });
1417
1659
  if (rosterCopy.action === "created") result.copied.push(rosterCopy.target);
1418
1660
  if (rosterCopy.action === "unchanged") result.unchanged.push(rosterCopy.target);
1419
1661
  if (rosterCopy.action === "overwritten") result.overwritten.push(rosterCopy.target);
1420
1662
  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, {
1663
+ const modelRoutingCopy = copyTextWithConflict(join10(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE), cwd, DEFAULT_MODEL_ROUTING_TARGET, {
1422
1664
  force: Boolean(options.force),
1423
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1665
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1424
1666
  });
1425
1667
  if (modelRoutingCopy.action === "created") result.copied.push(modelRoutingCopy.target);
1426
1668
  if (modelRoutingCopy.action === "unchanged") result.unchanged.push(modelRoutingCopy.target);
@@ -1437,17 +1679,17 @@ function initProject(options) {
1437
1679
  modelRouting: DEFAULT_MODEL_ROUTING_TARGET,
1438
1680
  templateHashes
1439
1681
  };
1440
- writeText(join9(cwd, ".agent-kit", "manifest.json"), `${JSON.stringify(manifest, null, 2)}
1682
+ writeText(join10(cwd, ".agent-kit", "manifest.json"), `${JSON.stringify(manifest, null, 2)}
1441
1683
  `);
1442
- writeText(join9(cwd, ".agent-kit", "config.json"), `${JSON.stringify(DEFAULT_CONFIG, null, 2)}
1684
+ writeText(join10(cwd, ".agent-kit", "config.json"), `${JSON.stringify(DEFAULT_CONFIG, null, 2)}
1443
1685
  `);
1444
- const overridesPath = join9(cwd, ".agent-kit", "overrides.json");
1445
- if (!existsSync9(overridesPath)) writeText(overridesPath, `${JSON.stringify({ templates: {} }, null, 2)}
1686
+ const overridesPath = join10(cwd, ".agent-kit", "overrides.json");
1687
+ if (!existsSync10(overridesPath)) writeText(overridesPath, `${JSON.stringify({ templates: {} }, null, 2)}
1446
1688
  `);
1447
1689
  for (const template of CI_TEMPLATE_FILES) {
1448
- const ciCopy = copyTextWithConflict(join9(packageRoot, template.source), cwd, template.target, {
1690
+ const ciCopy = copyTextWithConflict(join10(packageRoot, template.source), cwd, template.target, {
1449
1691
  force: Boolean(options.force),
1450
- conflictRoot: join9(cwd, ".agent-kit", "conflicts")
1692
+ conflictRoot: join10(cwd, ".agent-kit", "conflicts")
1451
1693
  });
1452
1694
  if (ciCopy.action === "created") result.copied.push(ciCopy.target);
1453
1695
  if (ciCopy.action === "unchanged") result.unchanged.push(ciCopy.target);
@@ -1471,9 +1713,9 @@ function initProject(options) {
1471
1713
  return result;
1472
1714
  }
1473
1715
  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"));
1716
+ const manifestPath = join10(cwd, ".agent-kit", "manifest.json");
1717
+ if (!existsSync10(manifestPath)) return null;
1718
+ return JSON.parse(readFileSync7(manifestPath, "utf8"));
1477
1719
  }
1478
1720
 
1479
1721
  // src/install/audit.ts
@@ -1523,7 +1765,8 @@ var REQUIRED_SCHEMA_FILES = [
1523
1765
  "correction-rules.schema.json",
1524
1766
  "session-event.schema.json",
1525
1767
  "studio-session.schema.json",
1526
- "onboarding-state.schema.json"
1768
+ "onboarding-state.schema.json",
1769
+ "agentic-level.schema.json"
1527
1770
  ];
1528
1771
  var COUNCIL_SESSION_DIR = ".agent-kit/council-sessions";
1529
1772
  var READINESS_ORDER = ["needs-setup", "baseline-setup", "needs-improvement", "best-practice-candidate"];
@@ -1542,24 +1785,24 @@ function includesAll(text, values) {
1542
1785
  return values.every((value) => lower.includes(value.toLowerCase()));
1543
1786
  }
1544
1787
  function readDoc(cwd, file) {
1545
- const path = join10(cwd, file);
1546
- return existsSync10(path) ? readFileSync7(path, "utf8") : "";
1788
+ const path = join11(cwd, file);
1789
+ return existsSync11(path) ? readFileSync8(path, "utf8") : "";
1547
1790
  }
1548
1791
  function isPackageRepository(cwd) {
1549
- const packagePath = join10(cwd, "package.json");
1550
- if (!existsSync10(packagePath)) return false;
1792
+ const packagePath = join11(cwd, "package.json");
1793
+ if (!existsSync11(packagePath)) return false;
1551
1794
  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"));
1795
+ const packageJson = JSON.parse(readFileSync8(packagePath, "utf8"));
1796
+ 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
1797
  } catch {
1555
1798
  return false;
1556
1799
  }
1557
1800
  }
1558
1801
  function readOverrides(cwd) {
1559
- const path = join10(cwd, ".agent-kit", "overrides.json");
1560
- if (!existsSync10(path)) return {};
1802
+ const path = join11(cwd, ".agent-kit", "overrides.json");
1803
+ if (!existsSync11(path)) return {};
1561
1804
  try {
1562
- const parsed = JSON.parse(readFileSync7(path, "utf8"));
1805
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
1563
1806
  const templates = parsed.templates ?? {};
1564
1807
  return Object.fromEntries(
1565
1808
  Object.entries(templates).map(([file, override]) => [
@@ -1572,8 +1815,8 @@ function readOverrides(cwd) {
1572
1815
  }
1573
1816
  }
1574
1817
  function readTemplate(stack, file) {
1575
- const path = join10(findPackageRoot(), "templates", stack, file);
1576
- return existsSync10(path) ? readFileSync7(path, "utf8") : null;
1818
+ const path = join11(findPackageRoot(), "templates", stack, file);
1819
+ return existsSync11(path) ? readFileSync8(path, "utf8") : null;
1577
1820
  }
1578
1821
  function asStringArray(value) {
1579
1822
  if (!Array.isArray(value)) return [];
@@ -1583,8 +1826,8 @@ function isRecord(value) {
1583
1826
  return typeof value === "object" && value !== null;
1584
1827
  }
1585
1828
  function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGENT_ROSTER_TARGET) {
1586
- const rosterPath = join10(cwd, rosterRelativePath);
1587
- if (!existsSync10(rosterPath)) {
1829
+ const rosterPath = join11(cwd, rosterRelativePath);
1830
+ if (!existsSync11(rosterPath)) {
1588
1831
  findings.push({
1589
1832
  level: "fail",
1590
1833
  area: "agents",
@@ -1595,7 +1838,7 @@ function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGEN
1595
1838
  }
1596
1839
  let roster;
1597
1840
  try {
1598
- const parsed = JSON.parse(readFileSync7(rosterPath, "utf8"));
1841
+ const parsed = JSON.parse(readFileSync8(rosterPath, "utf8"));
1599
1842
  if (!isRecord(parsed)) throw new Error("Roster must be a JSON object.");
1600
1843
  const contractResult = AgentRosterContract.safeParse(parsed);
1601
1844
  if (!contractResult.success) {
@@ -1782,15 +2025,15 @@ function addAgentRosterFindings(cwd, findings, rosterRelativePath = DEFAULT_AGEN
1782
2025
  }
1783
2026
  }
1784
2027
  function addCouncilSessionRecordFindings(cwd, findings) {
1785
- const sessionsRoot = join10(cwd, COUNCIL_SESSION_DIR);
1786
- if (!existsSync10(sessionsRoot)) return;
2028
+ const sessionsRoot = join11(cwd, COUNCIL_SESSION_DIR);
2029
+ if (!existsSync11(sessionsRoot)) return;
1787
2030
  const sessionFiles = listFilesRecursive(sessionsRoot).filter((file) => file.endsWith(".json") && !/[\\/]/.test(file));
1788
2031
  if (sessionFiles.length === 0) return;
1789
2032
  let invalidCount = 0;
1790
2033
  for (const sessionFile of sessionFiles) {
1791
2034
  const displayPath = `${COUNCIL_SESSION_DIR}/${sessionFile}`;
1792
2035
  try {
1793
- const parsed = JSON.parse(readFileSync7(join10(sessionsRoot, sessionFile), "utf8"));
2036
+ const parsed = JSON.parse(readFileSync8(join11(sessionsRoot, sessionFile), "utf8"));
1794
2037
  const contractResult = CouncilSessionContract.safeParse(parsed);
1795
2038
  if (!contractResult.success) {
1796
2039
  invalidCount += 1;
@@ -1821,8 +2064,8 @@ function addCouncilSessionRecordFindings(cwd, findings) {
1821
2064
  }
1822
2065
  function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/schemas") {
1823
2066
  for (const schemaFile of REQUIRED_SCHEMA_FILES) {
1824
- const schemaPath = join10(cwd, schemaRootRelativePath, schemaFile);
1825
- if (!existsSync10(schemaPath)) {
2067
+ const schemaPath = join11(cwd, schemaRootRelativePath, schemaFile);
2068
+ if (!existsSync11(schemaPath)) {
1826
2069
  findings.push({
1827
2070
  level: "warn",
1828
2071
  area: "agents",
@@ -1832,7 +2075,7 @@ function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/s
1832
2075
  continue;
1833
2076
  }
1834
2077
  try {
1835
- const parsed = JSON.parse(readFileSync7(schemaPath, "utf8"));
2078
+ const parsed = JSON.parse(readFileSync8(schemaPath, "utf8"));
1836
2079
  if (!isRecord(parsed) || typeof parsed.$schema !== "string" || !isRecord(parsed.properties)) {
1837
2080
  throw new Error("Schema file is missing JSON Schema metadata.");
1838
2081
  }
@@ -1852,8 +2095,8 @@ function addSchemaFindings(cwd, findings, schemaRootRelativePath = ".agent-kit/s
1852
2095
  }
1853
2096
  }
1854
2097
  function addAgentStudioFindings(cwd, findings) {
1855
- const contextPath = join10(cwd, CONTEXT_JSON);
1856
- if (!existsSync10(contextPath)) {
2098
+ const contextPath = join11(cwd, CONTEXT_JSON);
2099
+ if (!existsSync11(contextPath)) {
1857
2100
  findings.push({
1858
2101
  level: "warn",
1859
2102
  area: "studio",
@@ -1862,7 +2105,7 @@ function addAgentStudioFindings(cwd, findings) {
1862
2105
  });
1863
2106
  } else {
1864
2107
  try {
1865
- const parsed = JSON.parse(readFileSync7(contextPath, "utf8"));
2108
+ const parsed = JSON.parse(readFileSync8(contextPath, "utf8"));
1866
2109
  const result = ProjectContextContract.safeParse(parsed);
1867
2110
  if (!result.success) {
1868
2111
  findings.push({
@@ -1926,8 +2169,8 @@ function addAgentStudioFindings(cwd, findings) {
1926
2169
  });
1927
2170
  }
1928
2171
  }
1929
- const contextMdPath = join10(cwd, CONTEXT_MD);
1930
- if (existsSync10(contextPath) && !existsSync10(contextMdPath)) {
2172
+ const contextMdPath = join11(cwd, CONTEXT_MD);
2173
+ if (existsSync11(contextPath) && !existsSync11(contextMdPath)) {
1931
2174
  findings.push({
1932
2175
  level: "warn",
1933
2176
  area: "studio",
@@ -1936,10 +2179,10 @@ function addAgentStudioFindings(cwd, findings) {
1936
2179
  });
1937
2180
  }
1938
2181
  for (const relativePath of [PROJECT_RULES_JSON, AGENT_RULES_JSON]) {
1939
- const path = join10(cwd, relativePath);
1940
- if (!existsSync10(path)) continue;
2182
+ const path = join11(cwd, relativePath);
2183
+ if (!existsSync11(path)) continue;
1941
2184
  try {
1942
- const parsed = JSON.parse(readFileSync7(path, "utf8"));
2185
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
1943
2186
  const result = CorrectionRulesContract.safeParse(parsed);
1944
2187
  if (!result.success) {
1945
2188
  findings.push({
@@ -1964,9 +2207,9 @@ function addAgentStudioFindings(cwd, findings) {
1964
2207
  });
1965
2208
  }
1966
2209
  }
1967
- const studioExportPath = join10(cwd, STUDIO_EXPORT_HTML);
1968
- if (existsSync10(studioExportPath)) {
1969
- const exportHtml = readFileSync7(studioExportPath, "utf8");
2210
+ const studioExportPath = join11(cwd, STUDIO_EXPORT_HTML);
2211
+ if (existsSync11(studioExportPath)) {
2212
+ const exportHtml = readFileSync8(studioExportPath, "utf8");
1970
2213
  if (containsLikelySecret(exportHtml)) {
1971
2214
  findings.push({
1972
2215
  level: "fail",
@@ -1989,8 +2232,8 @@ function addAgentStudioFindings(cwd, findings) {
1989
2232
  });
1990
2233
  }
1991
2234
  }
1992
- const sessionsRoot = join10(cwd, COUNCIL_SESSION_DIR);
1993
- if (!existsSync10(sessionsRoot)) return;
2235
+ const sessionsRoot = join11(cwd, COUNCIL_SESSION_DIR);
2236
+ if (!existsSync11(sessionsRoot)) return;
1994
2237
  const files = listFilesRecursive(sessionsRoot);
1995
2238
  const studioSessionFiles = files.filter((file) => /[\\/]session\.json$/.test(file));
1996
2239
  for (const sessionFile of studioSessionFiles) {
@@ -2001,10 +2244,10 @@ function addAgentStudioFindings(cwd, findings) {
2001
2244
  const eventsRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/events.jsonl`;
2002
2245
  const indexRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/index.md`;
2003
2246
  const transcriptRelative = `${COUNCIL_SESSION_DIR}/${normalizedSessionDir}/transcript.md`;
2004
- const sessionDirPath = join10(sessionsRoot, sessionDir2);
2247
+ const sessionDirPath = join11(sessionsRoot, sessionDir2);
2005
2248
  let sessionResult = null;
2006
2249
  try {
2007
- sessionResult = StudioSessionContract.safeParse(JSON.parse(readFileSync7(join10(sessionDirPath, "session.json"), "utf8")));
2250
+ sessionResult = StudioSessionContract.safeParse(JSON.parse(readFileSync8(join11(sessionDirPath, "session.json"), "utf8")));
2008
2251
  if (!sessionResult.success) {
2009
2252
  findings.push({
2010
2253
  level: "fail",
@@ -2023,8 +2266,8 @@ function addAgentStudioFindings(cwd, findings) {
2023
2266
  });
2024
2267
  continue;
2025
2268
  }
2026
- const eventsPath2 = join10(sessionDirPath, "events.jsonl");
2027
- if (!existsSync10(eventsPath2)) {
2269
+ const eventsPath2 = join11(sessionDirPath, "events.jsonl");
2270
+ if (!existsSync11(eventsPath2)) {
2028
2271
  findings.push({
2029
2272
  level: "fail",
2030
2273
  area: "studio",
@@ -2033,7 +2276,7 @@ function addAgentStudioFindings(cwd, findings) {
2033
2276
  });
2034
2277
  continue;
2035
2278
  }
2036
- const eventText = readFileSync7(eventsPath2, "utf8");
2279
+ const eventText = readFileSync8(eventsPath2, "utf8");
2037
2280
  if (containsLikelySecret(eventText)) {
2038
2281
  findings.push({
2039
2282
  level: "fail",
@@ -2068,7 +2311,7 @@ function addAgentStudioFindings(cwd, findings) {
2068
2311
  });
2069
2312
  }
2070
2313
  }
2071
- if (!existsSync10(join10(sessionDirPath, "index.md")) || !existsSync10(join10(sessionDirPath, "transcript.md"))) {
2314
+ if (!existsSync11(join11(sessionDirPath, "index.md")) || !existsSync11(join11(sessionDirPath, "transcript.md"))) {
2072
2315
  findings.push({
2073
2316
  level: "warn",
2074
2317
  area: "studio",
@@ -2076,8 +2319,8 @@ function addAgentStudioFindings(cwd, findings) {
2076
2319
  remediation: "Run agent-kit session render so humans can inspect the current agent transcript and handoffs."
2077
2320
  });
2078
2321
  } else {
2079
- const indexText = readFileSync7(join10(sessionDirPath, "index.md"), "utf8");
2080
- const transcriptText = readFileSync7(join10(sessionDirPath, "transcript.md"), "utf8");
2322
+ const indexText = readFileSync8(join11(sessionDirPath, "index.md"), "utf8");
2323
+ const transcriptText = readFileSync8(join11(sessionDirPath, "transcript.md"), "utf8");
2081
2324
  if (containsLikelySecret(indexText) || containsLikelySecret(transcriptText)) {
2082
2325
  findings.push({
2083
2326
  level: "fail",
@@ -2086,7 +2329,7 @@ function addAgentStudioFindings(cwd, findings) {
2086
2329
  remediation: "Regenerate Markdown after redacting sensitive values from the event log."
2087
2330
  });
2088
2331
  }
2089
- if (statSync(eventsPath2).mtimeMs > statSync(join10(sessionDirPath, "index.md")).mtimeMs) {
2332
+ if (statSync(eventsPath2).mtimeMs > statSync(join11(sessionDirPath, "index.md")).mtimeMs) {
2090
2333
  findings.push({
2091
2334
  level: "warn",
2092
2335
  area: "studio",
@@ -2136,8 +2379,8 @@ function addCouncilDocFindings(cwd, findings) {
2136
2379
  }
2137
2380
  function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".agent-kit/assistant-adapters", docsCwd = cwd) {
2138
2381
  const adaptersDoc = readDoc(docsCwd, "ASSISTANT_ADAPTERS.md");
2139
- const adapterRoot = join10(cwd, adapterRootRelativePath);
2140
- if (!existsSync10(adapterRoot)) {
2382
+ const adapterRoot = join11(cwd, adapterRootRelativePath);
2383
+ if (!existsSync11(adapterRoot)) {
2141
2384
  findings.push({
2142
2385
  level: "warn",
2143
2386
  area: "agents",
@@ -2157,7 +2400,7 @@ function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".
2157
2400
  level: "warn",
2158
2401
  area: "agents",
2159
2402
  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."
2403
+ 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
2404
  });
2162
2405
  } else {
2163
2406
  findings.push({
@@ -2166,6 +2409,22 @@ function addAssistantAdapterFindings(cwd, findings, adapterRootRelativePath = ".
2166
2409
  message: "ASSISTANT_ADAPTERS.md maps the council roster to tool-specific instruction surfaces."
2167
2410
  });
2168
2411
  }
2412
+ if (assistantAdapterRowIsActive(adaptersDoc, "Cursor") && !existsSync11(join11(cwd, ".cursor/agents/planner.md"))) {
2413
+ findings.push({
2414
+ level: "warn",
2415
+ area: "agents",
2416
+ message: "Cursor is marked Active but .cursor/agents/planner.md is missing.",
2417
+ remediation: "Run agent-kit init --activate cursor to generate council subagents from the roster."
2418
+ });
2419
+ }
2420
+ if (assistantAdapterRowIsActive(adaptersDoc, "Codex / AGENTS.md-compatible tools") && !existsSync11(join11(cwd, ".codex/agents/planner.toml"))) {
2421
+ findings.push({
2422
+ level: "warn",
2423
+ area: "agents",
2424
+ message: "Codex is marked Active but .codex/agents/planner.toml is missing.",
2425
+ remediation: "Run agent-kit init --activate codex to generate council custom agents from the roster."
2426
+ });
2427
+ }
2169
2428
  if (!includesAll(adaptersDoc, ["model selection", "enforcement", "MODEL_ROUTING.md", "model-routing.json"])) {
2170
2429
  findings.push({
2171
2430
  level: "warn",
@@ -2206,8 +2465,8 @@ function addModelRoutingFindings(cwd, findings, routingRelativePath = DEFAULT_MO
2206
2465
  message: "MODEL_ROUTING.md documents agent model profiles and IDE enforcement limits."
2207
2466
  });
2208
2467
  }
2209
- const routingPath = join10(cwd, routingRelativePath);
2210
- if (!existsSync10(routingPath)) {
2468
+ const routingPath = join11(cwd, routingRelativePath);
2469
+ if (!existsSync11(routingPath)) {
2211
2470
  findings.push({
2212
2471
  level: "warn",
2213
2472
  area: "models",
@@ -2218,7 +2477,7 @@ function addModelRoutingFindings(cwd, findings, routingRelativePath = DEFAULT_MO
2218
2477
  }
2219
2478
  let routing;
2220
2479
  try {
2221
- routing = JSON.parse(readFileSync7(routingPath, "utf8"));
2480
+ routing = JSON.parse(readFileSync8(routingPath, "utf8"));
2222
2481
  } catch {
2223
2482
  findings.push({
2224
2483
  level: "warn",
@@ -2276,11 +2535,11 @@ function addTemplateHashFindings(cwd, findings) {
2276
2535
  if (!manifest) return;
2277
2536
  const overrides = readOverrides(cwd);
2278
2537
  for (const doc of ROOT_DOCS) {
2279
- const targetPath = join10(cwd, doc);
2280
- if (!existsSync10(targetPath)) continue;
2538
+ const targetPath = join11(cwd, doc);
2539
+ if (!existsSync11(targetPath)) continue;
2281
2540
  const currentTemplate = readTemplate(manifest.stack, doc);
2282
2541
  if (!currentTemplate) continue;
2283
- const targetHash = sha256(readFileSync7(targetPath, "utf8"));
2542
+ const targetHash = sha256(readFileSync8(targetPath, "utf8"));
2284
2543
  const currentTemplateHash = sha256(currentTemplate);
2285
2544
  const installedTemplateHash = manifest.templateHashes?.[doc];
2286
2545
  const override = overrides[doc];
@@ -2584,7 +2843,7 @@ function auditProject(cwd) {
2584
2843
  const manifest = readManifest(cwd);
2585
2844
  const packageRepository = isPackageRepository(cwd);
2586
2845
  const packageSourceMode = packageRepository && !manifest;
2587
- const docsCwd = packageSourceMode ? join10(cwd, "templates", "next-supabase") : cwd;
2846
+ const docsCwd = packageSourceMode ? join11(cwd, "templates", "next-supabase") : cwd;
2588
2847
  if (!manifest) {
2589
2848
  if (packageRepository) {
2590
2849
  findings.push({
@@ -2611,13 +2870,13 @@ function auditProject(cwd) {
2611
2870
  addAgentRosterFindings(cwd, findings, packageSourceMode ? "rosters/next-supabase-default-council.json" : DEFAULT_AGENT_ROSTER_TARGET);
2612
2871
  addSchemaFindings(cwd, findings, packageSourceMode ? "schemas" : ".agent-kit/schemas");
2613
2872
  addCouncilSessionRecordFindings(cwd, findings);
2614
- if (!packageRepository || existsSync10(join10(cwd, CONTEXT_JSON)) || existsSync10(join10(cwd, COUNCIL_SESSION_DIR))) {
2873
+ if (!packageRepository || existsSync11(join11(cwd, CONTEXT_JSON)) || existsSync11(join11(cwd, COUNCIL_SESSION_DIR))) {
2615
2874
  addAgentStudioFindings(cwd, findings);
2616
2875
  }
2617
2876
  for (const doc of ROOT_DOCS) {
2618
- const docPath = join10(docsCwd, doc);
2877
+ const docPath = join11(docsCwd, doc);
2619
2878
  const displayPath = packageSourceMode ? `templates/next-supabase/${doc}` : doc;
2620
- if (existsSync10(docPath)) {
2879
+ if (existsSync11(docPath)) {
2621
2880
  findings.push({ level: "pass", area: "docs", message: `${displayPath} exists.` });
2622
2881
  } else {
2623
2882
  findings.push({
@@ -2682,10 +2941,10 @@ function auditProject(cwd) {
2682
2941
  return findings;
2683
2942
  }
2684
2943
  function readPackageJson2(cwd) {
2685
- const path = join10(cwd, "package.json");
2686
- if (!existsSync10(path)) return null;
2944
+ const path = join11(cwd, "package.json");
2945
+ if (!existsSync11(path)) return null;
2687
2946
  try {
2688
- return JSON.parse(readFileSync7(path, "utf8"));
2947
+ return JSON.parse(readFileSync8(path, "utf8"));
2689
2948
  } catch {
2690
2949
  return null;
2691
2950
  }
@@ -2699,8 +2958,8 @@ function containsLikelySecretForAudit(relativeFile, content) {
2699
2958
  return containsLikelySecret(content);
2700
2959
  }
2701
2960
  function addProjectRealityFindings(cwd, findings, options = {}) {
2702
- const migrationsDir = join10(cwd, "supabase", "migrations");
2703
- if (existsSync10(migrationsDir)) {
2961
+ const migrationsDir = join11(cwd, "supabase", "migrations");
2962
+ if (existsSync11(migrationsDir)) {
2704
2963
  const sqlFiles = listFilesRecursive(migrationsDir).filter((file) => file.endsWith(".sql"));
2705
2964
  if (sqlFiles.length === 0) {
2706
2965
  findings.push({
@@ -2711,7 +2970,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2711
2970
  });
2712
2971
  } else {
2713
2972
  const rlsFiles = sqlFiles.filter((file) => {
2714
- const content = readFileSync7(join10(migrationsDir, file), "utf8");
2973
+ const content = readFileSync8(join11(migrationsDir, file), "utf8");
2715
2974
  return /enable\s+row\s+level\s+security/i.test(content);
2716
2975
  });
2717
2976
  if (rlsFiles.length === 0) {
@@ -2761,7 +3020,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2761
3020
  return /\.(ts|tsx|js|jsx|env|json)$/.test(file);
2762
3021
  });
2763
3022
  const secretHits = trackedSourceFiles.map((file) => {
2764
- const content = readFileSync7(join10(cwd, file), "utf8");
3023
+ const content = readFileSync8(join11(cwd, file), "utf8");
2765
3024
  return containsLikelySecretForAudit(file, content) ? file : null;
2766
3025
  }).filter((file) => file !== null).slice(0, 5);
2767
3026
  if (secretHits.length > 0) {
@@ -2784,7 +3043,7 @@ function addProjectRealityFindings(cwd, findings, options = {}) {
2784
3043
  area: "project-reality",
2785
3044
  message: "Package source repository mode does not require installed-project context files."
2786
3045
  });
2787
- } else if (!existsSync10(join10(cwd, CONTEXT_JSON))) {
3046
+ } else if (!existsSync11(join11(cwd, CONTEXT_JSON))) {
2788
3047
  findings.push({
2789
3048
  level: "warn",
2790
3049
  area: "project-reality",
@@ -2850,7 +3109,7 @@ function report(target, findings) {
2850
3109
  }
2851
3110
  function readJson(path) {
2852
3111
  try {
2853
- return JSON.parse(readFileSync8(path, "utf8"));
3112
+ return JSON.parse(readFileSync9(path, "utf8"));
2854
3113
  } catch {
2855
3114
  return null;
2856
3115
  }
@@ -2864,24 +3123,24 @@ function isSafeRelativePath(path) {
2864
3123
  return !normalized.startsWith("/") && !normalized.startsWith("../") && !normalized.includes("/../");
2865
3124
  }
2866
3125
  function findAntigravityLayout(cwd) {
2867
- const sourcePlugin = join11(cwd, "antigravity", "plugin.json");
2868
- if (existsSync11(sourcePlugin)) {
3126
+ const sourcePlugin = join12(cwd, "antigravity", "plugin.json");
3127
+ if (existsSync12(sourcePlugin)) {
2869
3128
  return {
2870
3129
  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")
3130
+ pluginRoot: join12(cwd, "antigravity"),
3131
+ commandsRoot: join12(cwd, ANTIGRAVITY_COMMANDS_SOURCE_DIR),
3132
+ runtimeSkillsRoot: join12(cwd, RUNTIME_SKILLS_SOURCE_DIR),
3133
+ adapterDocPath: join12(cwd, "assistant-adapters", "antigravity.md")
2875
3134
  };
2876
3135
  }
2877
- const installedPlugin = join11(cwd, ".antigravity", "agent-kit", "plugin.json");
2878
- if (existsSync11(installedPlugin)) {
3136
+ const installedPlugin = join12(cwd, ".antigravity", "agent-kit", "plugin.json");
3137
+ if (existsSync12(installedPlugin)) {
2879
3138
  return {
2880
3139
  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")
3140
+ pluginRoot: join12(cwd, ".antigravity", "agent-kit"),
3141
+ commandsRoot: join12(cwd, ANTIGRAVITY_COMMANDS_TARGET_DIR),
3142
+ runtimeSkillsRoot: join12(cwd, ANTIGRAVITY_RUNTIME_SKILLS_TARGET_DIR),
3143
+ adapterDocPath: join12(cwd, ".antigravity", "agent-kit", "README.md")
2885
3144
  };
2886
3145
  }
2887
3146
  return null;
@@ -2905,8 +3164,8 @@ function validateAntigravityCommands(layout, findings) {
2905
3164
  const commandNames = /* @__PURE__ */ new Set();
2906
3165
  for (const command of REQUIRED_COMMANDS) {
2907
3166
  const relativePath = `${command}.toml`;
2908
- const path = join11(layout.commandsRoot, relativePath);
2909
- if (!existsSync11(path)) {
3167
+ const path = join12(layout.commandsRoot, relativePath);
3168
+ if (!existsSync12(path)) {
2910
3169
  findings.push({
2911
3170
  level: "fail",
2912
3171
  area: "commands",
@@ -2915,7 +3174,7 @@ function validateAntigravityCommands(layout, findings) {
2915
3174
  });
2916
3175
  continue;
2917
3176
  }
2918
- const text = readFileSync8(path, "utf8");
3177
+ const text = readFileSync9(path, "utf8");
2919
3178
  addSecretFinding(relativePath, text, findings);
2920
3179
  const name = commandField(text, "name");
2921
3180
  const description = commandField(text, "description");
@@ -2972,7 +3231,7 @@ function validateAntigravityCommands(layout, findings) {
2972
3231
  }
2973
3232
  }
2974
3233
  function validateAntigravityPlugin(layout, findings) {
2975
- const pluginPath = join11(layout.pluginRoot, "plugin.json");
3234
+ const pluginPath = join12(layout.pluginRoot, "plugin.json");
2976
3235
  const plugin = readJson(pluginPath);
2977
3236
  if (!plugin || !isRecord2(plugin)) {
2978
3237
  findings.push({
@@ -3012,8 +3271,8 @@ function validateAntigravityPlugin(layout, findings) {
3012
3271
  });
3013
3272
  continue;
3014
3273
  }
3015
- const resolved = join11(layout.pluginRoot, path);
3016
- if (!existsSync11(resolved)) {
3274
+ const resolved = join12(layout.pluginRoot, path);
3275
+ if (!existsSync12(resolved)) {
3017
3276
  findings.push({
3018
3277
  level: "fail",
3019
3278
  area: "manifest",
@@ -3022,7 +3281,7 @@ function validateAntigravityPlugin(layout, findings) {
3022
3281
  });
3023
3282
  }
3024
3283
  }
3025
- const pluginText = readFileSync8(pluginPath, "utf8");
3284
+ const pluginText = readFileSync9(pluginPath, "utf8");
3026
3285
  addSecretFinding("plugin.json", pluginText, findings);
3027
3286
  if (Array.isArray(plugin.sourceOfTruth) && plugin.sourceOfTruth.includes("AGENTS.md") && plugin.sourceOfTruth.includes(".agent-kit/agent-roster.json")) {
3028
3287
  findings.push({
@@ -3040,13 +3299,13 @@ function validateAntigravityPlugin(layout, findings) {
3040
3299
  }
3041
3300
  }
3042
3301
  function validateRuntimeSkills(cwd, layout, findings) {
3043
- const canonicalSkillsRoot = existsSync11(join11(cwd, "skills")) ? join11(cwd, "skills") : join11(cwd, ".agent-kit", "skills");
3302
+ const canonicalSkillsRoot = existsSync12(join12(cwd, "skills")) ? join12(cwd, "skills") : join12(cwd, ".agent-kit", "skills");
3044
3303
  const canonicalSkillNames = listFilesRecursive(canonicalSkillsRoot).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, ""));
3045
3304
  const runtimeSkillFiles = listFilesRecursive(layout.runtimeSkillsRoot).filter((file) => file.endsWith("/SKILL.md") || file === "SKILL.md");
3046
3305
  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
3306
  for (const skillName of canonicalSkillNames) {
3048
- const runtimePath = join11(layout.runtimeSkillsRoot, skillName, "SKILL.md");
3049
- if (!existsSync11(runtimePath)) {
3307
+ const runtimePath = join12(layout.runtimeSkillsRoot, skillName, "SKILL.md");
3308
+ if (!existsSync12(runtimePath)) {
3050
3309
  findings.push({
3051
3310
  level: "fail",
3052
3311
  area: "runtime-skills",
@@ -3055,7 +3314,7 @@ function validateRuntimeSkills(cwd, layout, findings) {
3055
3314
  });
3056
3315
  continue;
3057
3316
  }
3058
- const text = readFileSync8(runtimePath, "utf8");
3317
+ const text = readFileSync9(runtimePath, "utf8");
3059
3318
  addSecretFinding(`${skillName}/SKILL.md`, text, findings);
3060
3319
  if (!/^---\nname: .+\ndescription: .+\n---/m.test(text)) {
3061
3320
  findings.push({
@@ -3083,7 +3342,7 @@ function validateRuntimeSkills(cwd, layout, findings) {
3083
3342
  remediation: "Add canonical skills or remove orphan runtime wrappers."
3084
3343
  });
3085
3344
  }
3086
- if (canonicalSkillNames.length > 0 && canonicalSkillNames.every((skillName) => existsSync11(join11(layout.runtimeSkillsRoot, skillName, "SKILL.md")))) {
3345
+ if (canonicalSkillNames.length > 0 && canonicalSkillNames.every((skillName) => existsSync12(join12(layout.runtimeSkillsRoot, skillName, "SKILL.md")))) {
3087
3346
  findings.push({
3088
3347
  level: "pass",
3089
3348
  area: "runtime-skills",
@@ -3104,7 +3363,7 @@ function validateAntigravity(cwd) {
3104
3363
  }
3105
3364
  ]);
3106
3365
  }
3107
- const adapterDoc = existsSync11(layout.adapterDocPath) ? readFileSync8(layout.adapterDocPath, "utf8") : "";
3366
+ const adapterDoc = existsSync12(layout.adapterDocPath) ? readFileSync9(layout.adapterDocPath, "utf8") : "";
3108
3367
  if (!adapterDoc) {
3109
3368
  findings.push({
3110
3369
  level: "fail",
@@ -3133,7 +3392,7 @@ function validateAntigravity(cwd) {
3133
3392
  validateAntigravityCommands(layout, findings);
3134
3393
  validateRuntimeSkills(cwd, layout, findings);
3135
3394
  if (layout.mode === "source") {
3136
- const packageJson = readJson(join11(cwd, "package.json"));
3395
+ const packageJson = readJson(join12(cwd, "package.json"));
3137
3396
  const files = isRecord2(packageJson) && Array.isArray(packageJson.files) ? packageJson.files : [];
3138
3397
  for (const requiredFile of ["antigravity", "runtime-skills", "assistant-adapters"]) {
3139
3398
  if (!files.includes(requiredFile)) {
@@ -3157,40 +3416,145 @@ function validateAntigravity(cwd) {
3157
3416
  }
3158
3417
  function validateBasicAdapter(cwd, target) {
3159
3418
  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)) {
3419
+ const isPackageSource = existsSync12(join12(cwd, "package.json")) && existsSync12(join12(cwd, "src")) && existsSync12(join12(cwd, "templates"));
3420
+ if (isPackageSource) {
3421
+ const sourcePaths = {
3422
+ cursor: [
3423
+ "assistant-adapters/cursor-agent-kit.mdc",
3424
+ "assistant-adapters/model-selection/cursor-model-selection.mdc",
3425
+ "assistant-adapters/cursor-planner.mdc"
3426
+ ],
3427
+ claude: ["assistant-adapters/claude-code-subagents.md"],
3428
+ codex: ["assistant-adapters/codex-agents.md", "assistant-adapters/model-selection/codex-config.example.toml"],
3429
+ copilot: ["assistant-adapters/github-copilot-instructions.md", "assistant-adapters/github-next-supabase.instructions.md"]
3430
+ };
3431
+ for (const relativePath of sourcePaths[target]) {
3432
+ const path = join12(cwd, relativePath);
3433
+ if (!existsSync12(path)) {
3434
+ findings.push({
3435
+ level: "fail",
3436
+ area: "adapter",
3437
+ message: `${relativePath} is missing.`,
3438
+ remediation: "Restore the adapter template or run agent-kit update."
3439
+ });
3440
+ continue;
3441
+ }
3442
+ const text = readFileSync9(path, "utf8");
3443
+ addSecretFinding(relativePath, text, findings);
3444
+ if (!text.includes("AGENTS.md") && !text.includes("MODEL_ROUTING.md")) {
3445
+ findings.push({
3446
+ level: "warn",
3447
+ area: "adapter",
3448
+ message: `${relativePath} does not clearly reference Agent Kit source-of-truth files.`,
3449
+ remediation: "Adapter templates should point back to AGENTS.md, MODEL_ROUTING.md, and the roster contract."
3450
+ });
3451
+ }
3452
+ }
3453
+ } else {
3454
+ findings.push(...validateInstalledIdeAdapter(cwd, target).findings);
3455
+ }
3456
+ if (findings.every((finding) => finding.level !== "fail")) {
3457
+ findings.push({
3458
+ level: "pass",
3459
+ area: "adapter",
3460
+ message: `${target} adapter ${isPackageSource ? "templates are present" : "activation assets are present"}.`
3461
+ });
3462
+ }
3463
+ return report(target, findings);
3464
+ }
3465
+ function readAssistantAdaptersDoc(cwd) {
3466
+ const path = join12(cwd, "ASSISTANT_ADAPTERS.md");
3467
+ return existsSync12(path) ? readFileSync9(path, "utf8") : "";
3468
+ }
3469
+ function adaptersRowIsActive(doc, toolLabel) {
3470
+ return assistantAdapterRowIsActive(doc, toolLabel);
3471
+ }
3472
+ function validateInstalledIdeAdapter(cwd, target) {
3473
+ const findings = [];
3474
+ const adaptersDoc = readAssistantAdaptersDoc(cwd);
3475
+ if (target === "cursor") {
3476
+ const rulesPath = join12(cwd, ".cursor/rules/cursor-agent-kit.mdc");
3477
+ if (!existsSync12(rulesPath)) {
3169
3478
  findings.push({
3170
3479
  level: "fail",
3171
3480
  area: "adapter",
3172
- message: `${relativePath} is missing.`,
3173
- remediation: "Restore the adapter template or run agent-kit update."
3481
+ message: ".cursor/rules/cursor-agent-kit.mdc is missing.",
3482
+ remediation: "Run agent-kit init or agent-kit init --activate cursor."
3174
3483
  });
3175
- continue;
3484
+ } else {
3485
+ addSecretFinding(".cursor/rules/cursor-agent-kit.mdc", readFileSync9(rulesPath, "utf8"), findings);
3176
3486
  }
3177
- const text = readFileSync8(path, "utf8");
3178
- addSecretFinding(relativePath, text, findings);
3179
- if (!text.includes("AGENTS.md") && !text.includes("MODEL_ROUTING.md")) {
3487
+ const plannerAgent = join12(cwd, ".cursor/agents/planner.md");
3488
+ if (existsSync12(plannerAgent)) {
3489
+ findings.push({
3490
+ level: "pass",
3491
+ area: "adapter",
3492
+ message: ".cursor/agents/planner.md is installed."
3493
+ });
3494
+ } else if (adaptersRowIsActive(adaptersDoc, "Cursor")) {
3180
3495
  findings.push({
3181
3496
  level: "warn",
3182
3497
  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."
3498
+ message: "Cursor is marked Active but .cursor/agents/planner.md is missing.",
3499
+ remediation: "Run agent-kit init --activate cursor to generate council subagents from the roster."
3500
+ });
3501
+ }
3502
+ const skillSample = join12(cwd, ".cursor/skills/planning-council/SKILL.md");
3503
+ if (existsSync12(skillSample)) {
3504
+ findings.push({
3505
+ level: "pass",
3506
+ area: "adapter",
3507
+ message: ".cursor/skills/*/SKILL.md project skills are installed."
3185
3508
  });
3186
3509
  }
3187
3510
  }
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
- });
3511
+ if (target === "claude") {
3512
+ const plannerAgent = join12(cwd, ".claude/agents/planner.md");
3513
+ if (!existsSync12(plannerAgent)) {
3514
+ findings.push({
3515
+ level: "fail",
3516
+ area: "adapter",
3517
+ message: ".claude/agents/planner.md is missing.",
3518
+ remediation: "Run agent-kit init --activate claude."
3519
+ });
3520
+ }
3521
+ }
3522
+ if (target === "codex") {
3523
+ const configPath = join12(cwd, ".codex/config.toml");
3524
+ if (!existsSync12(configPath)) {
3525
+ findings.push({
3526
+ level: "fail",
3527
+ area: "adapter",
3528
+ message: ".codex/config.toml is missing.",
3529
+ remediation: "Run agent-kit init --activate codex."
3530
+ });
3531
+ }
3532
+ const plannerAgent = join12(cwd, ".codex/agents/planner.toml");
3533
+ if (existsSync12(plannerAgent)) {
3534
+ findings.push({
3535
+ level: "pass",
3536
+ area: "adapter",
3537
+ message: ".codex/agents/planner.toml is installed."
3538
+ });
3539
+ } else if (adaptersRowIsActive(adaptersDoc, "Codex / AGENTS.md-compatible tools")) {
3540
+ findings.push({
3541
+ level: "warn",
3542
+ area: "adapter",
3543
+ message: "Codex is marked Active but .codex/agents/planner.toml is missing.",
3544
+ remediation: "Run agent-kit init --activate codex to generate council custom agents from the roster."
3545
+ });
3546
+ }
3547
+ }
3548
+ if (target === "copilot") {
3549
+ const instructions = join12(cwd, ".github/copilot-instructions.md");
3550
+ if (!existsSync12(instructions)) {
3551
+ findings.push({
3552
+ level: "fail",
3553
+ area: "adapter",
3554
+ message: ".github/copilot-instructions.md is missing.",
3555
+ remediation: "Run agent-kit init --activate copilot."
3556
+ });
3557
+ }
3194
3558
  }
3195
3559
  return report(target, findings);
3196
3560
  }
@@ -3207,7 +3571,7 @@ function validateAdapter(cwd, target = "antigravity") {
3207
3571
  }
3208
3572
  function validatePackage(cwd) {
3209
3573
  const findings = [];
3210
- const sourceMode = existsSync11(join11(cwd, "package.json")) && existsSync11(join11(cwd, "src")) && existsSync11(join11(cwd, "templates"));
3574
+ const sourceMode = existsSync12(join12(cwd, "package.json")) && existsSync12(join12(cwd, "src")) && existsSync12(join12(cwd, "templates"));
3211
3575
  if (!sourceMode) {
3212
3576
  return report("package", [
3213
3577
  {
@@ -3220,8 +3584,8 @@ function validatePackage(cwd) {
3220
3584
  }
3221
3585
  findings.push(...validateAntigravity(cwd).findings);
3222
3586
  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") : "";
3587
+ const path = join12(cwd, doc);
3588
+ const text = existsSync12(path) ? readFileSync9(path, "utf8") : "";
3225
3589
  const lower = text.toLowerCase();
3226
3590
  if (!lower.includes("antigravity") && !lower.includes("runtime command") && !lower.includes("runtime adapter")) {
3227
3591
  findings.push({
@@ -3238,7 +3602,7 @@ function validatePackage(cwd) {
3238
3602
  "examples/next-supabase-installed/.agent-kit/manifest.json",
3239
3603
  "examples/next-supabase-installed/audit-output.json"
3240
3604
  ]) {
3241
- if (!existsSync11(join11(cwd, examplePath))) {
3605
+ if (!existsSync12(join12(cwd, examplePath))) {
3242
3606
  findings.push({
3243
3607
  level: "fail",
3244
3608
  area: "examples",
@@ -3273,17 +3637,17 @@ function validatePackage(cwd) {
3273
3637
  }
3274
3638
 
3275
3639
  // src/install/diff.ts
3276
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
3277
- import { join as join12 } from "path";
3640
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
3641
+ import { join as join13 } from "path";
3278
3642
  function statusForTextFile(target, template) {
3279
- if (!existsSync12(target)) return "missing";
3280
- const targetHash = sha256(readFileSync9(target, "utf8"));
3281
- const templateHash = sha256(readFileSync9(template, "utf8"));
3643
+ if (!existsSync13(target)) return "missing";
3644
+ const targetHash = sha256(readFileSync10(target, "utf8"));
3645
+ const templateHash = sha256(readFileSync10(template, "utf8"));
3282
3646
  return targetHash === templateHash ? "unchanged" : "changed";
3283
3647
  }
3284
3648
  function diffProject(cwd, stack = "next-supabase") {
3285
3649
  const packageRoot = findPackageRoot();
3286
- const templateRoot = join12(packageRoot, "templates", stack);
3650
+ const templateRoot = join13(packageRoot, "templates", stack);
3287
3651
  const libraryFolders = {
3288
3652
  missing: [],
3289
3653
  present: [],
@@ -3307,8 +3671,8 @@ function diffProject(cwd, stack = "next-supabase") {
3307
3671
  }
3308
3672
  };
3309
3673
  for (const doc of ROOT_DOCS) {
3310
- const target = join12(cwd, doc);
3311
- const template = join12(templateRoot, doc);
3674
+ const target = join13(cwd, doc);
3675
+ const template = join13(templateRoot, doc);
3312
3676
  const status = statusForTextFile(target, template);
3313
3677
  if (status === "missing") {
3314
3678
  result.missing.push(doc);
@@ -3321,7 +3685,7 @@ function diffProject(cwd, stack = "next-supabase") {
3321
3685
  result.preview.wouldWriteConflicts.push(doc);
3322
3686
  }
3323
3687
  }
3324
- result.agentRoster = statusForTextFile(join12(cwd, DEFAULT_AGENT_ROSTER_TARGET), join12(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE));
3688
+ result.agentRoster = statusForTextFile(join13(cwd, DEFAULT_AGENT_ROSTER_TARGET), join13(packageRoot, DEFAULT_AGENT_ROSTER_SOURCE));
3325
3689
  if (result.agentRoster === "missing") {
3326
3690
  result.preview.wouldCreate.push(DEFAULT_AGENT_ROSTER_TARGET);
3327
3691
  result.preview.wouldCreateAgentRoster = true;
@@ -3330,7 +3694,7 @@ function diffProject(cwd, stack = "next-supabase") {
3330
3694
  result.preview.wouldWriteConflicts.push(DEFAULT_AGENT_ROSTER_TARGET);
3331
3695
  result.preview.wouldWriteAgentRosterConflict = true;
3332
3696
  }
3333
- result.modelRouting = statusForTextFile(join12(cwd, DEFAULT_MODEL_ROUTING_TARGET), join12(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE));
3697
+ result.modelRouting = statusForTextFile(join13(cwd, DEFAULT_MODEL_ROUTING_TARGET), join13(packageRoot, DEFAULT_MODEL_ROUTING_SOURCE));
3334
3698
  if (result.modelRouting === "missing") {
3335
3699
  result.preview.wouldCreate.push(DEFAULT_MODEL_ROUTING_TARGET);
3336
3700
  result.preview.wouldCreateModelRouting = true;
@@ -3340,8 +3704,8 @@ function diffProject(cwd, stack = "next-supabase") {
3340
3704
  result.preview.wouldWriteModelRoutingConflict = true;
3341
3705
  }
3342
3706
  for (const folder of LIBRARY_FOLDERS) {
3343
- const target = join12(cwd, ".agent-kit", folder);
3344
- if (existsSync12(target)) libraryFolders.present.push(folder);
3707
+ const target = join13(cwd, ".agent-kit", folder);
3708
+ if (existsSync13(target)) libraryFolders.present.push(folder);
3345
3709
  else libraryFolders.missing.push(folder);
3346
3710
  }
3347
3711
  return result;
@@ -3349,8 +3713,8 @@ function diffProject(cwd, stack = "next-supabase") {
3349
3713
 
3350
3714
  // src/research/discover.ts
3351
3715
  import { Octokit } from "@octokit/rest";
3352
- import { readFileSync as readFileSync10 } from "fs";
3353
- import { join as join13 } from "path";
3716
+ import { readFileSync as readFileSync11 } from "fs";
3717
+ import { join as join14 } from "path";
3354
3718
 
3355
3719
  // src/research/config.ts
3356
3720
  import { z as z2 } from "zod";
@@ -3375,8 +3739,8 @@ var researchConfigSchema = z2.object({
3375
3739
  // src/research/discover.ts
3376
3740
  async function discoverRepos(options) {
3377
3741
  const packageRoot = findPackageRoot();
3378
- const configPath = join13(packageRoot, "research", "scan-config.json");
3379
- const config = researchConfigSchema.parse(JSON.parse(readFileSync10(configPath, "utf8")));
3742
+ const configPath = join14(packageRoot, "research", "scan-config.json");
3743
+ const config = researchConfigSchema.parse(JSON.parse(readFileSync11(configPath, "utf8")));
3380
3744
  const token = options.token ?? process.env.GITHUB_TOKEN;
3381
3745
  if (!token) {
3382
3746
  throw new Error("GITHUB_TOKEN is required for GitHub API research discovery.");
@@ -3437,20 +3801,20 @@ async function discoverRepos(options) {
3437
3801
  }
3438
3802
  }
3439
3803
  const candidates = [...deduped.values()].slice(0, maxRepos);
3440
- const output = options.output ?? join13(options.cwd, "research", "repo-candidates.json");
3804
+ const output = options.output ?? join14(options.cwd, "research", "repo-candidates.json");
3441
3805
  writeText(output, `${JSON.stringify(candidates, null, 2)}
3442
3806
  `);
3443
3807
  return candidates;
3444
3808
  }
3445
3809
 
3446
3810
  // 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";
3811
+ import { existsSync as existsSync16, mkdirSync as mkdirSync2, readFileSync as readFileSync13, rmSync } from "fs";
3812
+ import { join as join16 } from "path";
3449
3813
  import { simpleGit } from "simple-git";
3450
3814
 
3451
3815
  // src/research/analyze.ts
3452
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
3453
- import { join as join14 } from "path";
3816
+ import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
3817
+ import { join as join15 } from "path";
3454
3818
  function normalizeRelativePath(file) {
3455
3819
  return file.replace(/\\/g, "/");
3456
3820
  }
@@ -3458,8 +3822,8 @@ function hasFile(files, matcher) {
3458
3822
  return files.some((file) => matcher.test(normalizeRelativePath(file)));
3459
3823
  }
3460
3824
  function fileText(root, file) {
3461
- const path = join14(root, file);
3462
- return existsSync14(path) ? readFileSync11(path, "utf8") : "";
3825
+ const path = join15(root, file);
3826
+ return existsSync15(path) ? readFileSync12(path, "utf8") : "";
3463
3827
  }
3464
3828
  function textIncludes(root, files, matcher, terms) {
3465
3829
  const lowerTerms = terms.map((term) => term.toLowerCase());
@@ -3590,24 +3954,24 @@ ${finding.impactOnKit.map((item) => `- ${item}`).join("\n")}
3590
3954
  `;
3591
3955
  }
3592
3956
  async function scanRepos(options) {
3593
- const candidatesPath = options.candidatesPath ?? join15(options.cwd, "research", "repo-candidates.json");
3594
- if (!existsSync15(candidatesPath)) {
3957
+ const candidatesPath = options.candidatesPath ?? join16(options.cwd, "research", "repo-candidates.json");
3958
+ if (!existsSync16(candidatesPath)) {
3595
3959
  throw new Error(`Candidates file not found: ${candidatesPath}`);
3596
3960
  }
3597
- const candidates = JSON.parse(readFileSync12(candidatesPath, "utf8"));
3598
- const workdir = options.workdir ?? join15(options.cwd, "research", "workdir");
3961
+ const candidates = JSON.parse(readFileSync13(candidatesPath, "utf8"));
3962
+ const workdir = options.workdir ?? join16(options.cwd, "research", "workdir");
3599
3963
  mkdirSync2(workdir, { recursive: true });
3600
- mkdirSync2(join15(options.cwd, "research", "findings"), { recursive: true });
3964
+ mkdirSync2(join16(options.cwd, "research", "findings"), { recursive: true });
3601
3965
  const findings = [];
3602
3966
  const git = simpleGit();
3603
3967
  for (const candidate of candidates) {
3604
3968
  const repoSlug = candidate.fullName.replace("/", "__");
3605
- const repoPath = join15(workdir, repoSlug);
3606
- if (existsSync15(repoPath)) rmSync(repoPath, { recursive: true, force: true });
3969
+ const repoPath = join16(workdir, repoSlug);
3970
+ if (existsSync16(repoPath)) rmSync(repoPath, { recursive: true, force: true });
3607
3971
  await git.raw(["clone", "--depth", "1", candidate.htmlUrl, repoPath]);
3608
3972
  const finding = analyzeRepository(candidate, repoPath);
3609
3973
  findings.push(finding);
3610
- writeText(join15(options.cwd, "research", "findings", `${repoSlug}.md`), findingToMarkdown(finding));
3974
+ writeText(join16(options.cwd, "research", "findings", `${repoSlug}.md`), findingToMarkdown(finding));
3611
3975
  if (!options.keepClones) {
3612
3976
  rmSync(repoPath, { recursive: true, force: true });
3613
3977
  }
@@ -3616,8 +3980,8 @@ async function scanRepos(options) {
3616
3980
  }
3617
3981
 
3618
3982
  // src/research/summarize.ts
3619
- import { existsSync as existsSync16, readFileSync as readFileSync13, readdirSync as readdirSync2 } from "fs";
3620
- import { join as join16 } from "path";
3983
+ import { existsSync as existsSync17, readFileSync as readFileSync14, readdirSync as readdirSync3 } from "fs";
3984
+ import { join as join17 } from "path";
3621
3985
  var SUMMARY_TARGETS = {
3622
3986
  "nextjs-patterns": {
3623
3987
  title: "Next.js Patterns",
@@ -3720,12 +4084,12 @@ function renderRepoList(findings, scoreKeys) {
3720
4084
  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
4085
  }
3722
4086
  function summarizeFindings(cwd) {
3723
- const findingsDir = join16(cwd, "research", "findings");
3724
- if (!existsSync16(findingsDir)) {
4087
+ const findingsDir = join17(cwd, "research", "findings");
4088
+ if (!existsSync17(findingsDir)) {
3725
4089
  throw new Error("No research/findings directory exists. Run agent-kit research scan first.");
3726
4090
  }
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);
4091
+ const findingFiles = readdirSync3(findingsDir).filter((file) => file.endsWith(".md"));
4092
+ const findings = findingFiles.map((file) => parseFinding(file, readFileSync14(join17(findingsDir, file), "utf8"))).filter((finding) => finding !== null);
3729
4093
  const categoryCounts = countBy(findings.map((finding) => finding.category));
3730
4094
  const outputs = [];
3731
4095
  const overview = `# Research Scan Overview
@@ -3744,13 +4108,13 @@ ${countBy(findings.flatMap((finding) => finding.strongPractices)).slice(0, 12).m
3744
4108
  ## Most Repeated Gaps
3745
4109
  ${countBy(findings.flatMap((finding) => finding.weakPractices)).slice(0, 12).map(([practice, count]) => `- ${practice} (${count})`).join("\n")}
3746
4110
  `;
3747
- const overviewPath = join16(cwd, "research", "summaries", "scan-overview.md");
4111
+ const overviewPath = join17(cwd, "research", "summaries", "scan-overview.md");
3748
4112
  writeText(overviewPath, overview);
3749
4113
  outputs.push(overviewPath);
3750
4114
  for (const [target, config] of Object.entries(SUMMARY_TARGETS)) {
3751
4115
  const categories = config.categories;
3752
4116
  const scopedFindings = findings.filter((finding) => categories.includes(finding.category));
3753
- const path = join16(cwd, "research", "summaries", `${target}.md`);
4117
+ const path = join17(cwd, "research", "summaries", `${target}.md`);
3754
4118
  const summary2 = `# ${config.title}
3755
4119
 
3756
4120
  Generated from ${scopedFindings.length} relevant repository findings.
@@ -3791,7 +4155,7 @@ Review the generated research summaries, then convert repeated best practices in
3791
4155
 
3792
4156
  Do not copy source code from scanned repositories. Adopt only generalized practices with clear rationale.
3793
4157
  `;
3794
- const path = join16(cwd, "research", "proposed-updates.md");
4158
+ const path = join17(cwd, "research", "proposed-updates.md");
3795
4159
  writeText(path, output);
3796
4160
  return path;
3797
4161
  }
@@ -3900,8 +4264,8 @@ function proposeCorrectionUpstream(cwd, id) {
3900
4264
  }
3901
4265
 
3902
4266
  // 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";
4267
+ import { existsSync as existsSync18, readFileSync as readFileSync15, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
4268
+ import { join as join18 } from "path";
3905
4269
  function sessionDir(sessionId) {
3906
4270
  return `${COUNCIL_SESSIONS_DIR}/${safeSlug(sessionId)}`;
3907
4271
  }
@@ -3958,9 +4322,9 @@ function startSession(cwd, options) {
3958
4322
  return { sessionId, sessionPath: sessionDir(sessionId) };
3959
4323
  }
3960
4324
  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));
4325
+ const root = join18(cwd, COUNCIL_SESSIONS_DIR);
4326
+ if (!existsSync18(root)) return [];
4327
+ 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
4328
  }
3965
4329
  function getActiveSessionId(cwd) {
3966
4330
  const active = readTextFile(cwd, ACTIVE_SESSION_FILE)?.trim();
@@ -4658,13 +5022,13 @@ function parseSetupFormPayload(raw) {
4658
5022
  }
4659
5023
 
4660
5024
  // src/studio/wizard/checklist.ts
4661
- import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
4662
- import { join as join18 } from "path";
5025
+ import { existsSync as existsSync19, readFileSync as readFileSync16 } from "fs";
5026
+ import { join as join19 } from "path";
4663
5027
  var IDE_PATHS = {
4664
- cursor: ".cursor/rules/cursor-agent-kit.mdc",
5028
+ cursor: ".cursor/agents/planner.md",
4665
5029
  copilot: ".github/copilot-instructions.md",
4666
- claude: ".claude/agents/",
4667
- codex: "AGENTS.md",
5030
+ claude: ".claude/agents/planner.md",
5031
+ codex: ".codex/agents/planner.toml",
4668
5032
  other: "ASSISTANT_ADAPTERS.md"
4669
5033
  };
4670
5034
  function saveIdeChecklist(cwd, ideSurface) {
@@ -4679,10 +5043,13 @@ function saveIdeChecklist(cwd, ideSurface) {
4679
5043
  }
4680
5044
  function detectIdeRulePresent(cwd, ideSurface) {
4681
5045
  const rel = IDE_PATHS[ideSurface];
5046
+ if (ideSurface === "cursor") {
5047
+ return existsSync19(join19(cwd, rel)) || existsSync19(join19(cwd, ".cursor/rules/cursor-agent-kit.mdc"));
5048
+ }
4682
5049
  if (rel.endsWith("/")) {
4683
- return existsSync18(join18(cwd, rel));
5050
+ return existsSync19(join19(cwd, rel));
4684
5051
  }
4685
- return existsSync18(join18(cwd, rel));
5052
+ return existsSync19(join19(cwd, rel));
4686
5053
  }
4687
5054
  var VISUAL_QA_MARKER = "## Visual QA Tier";
4688
5055
  var VISUAL_QA_BLOCKS = {
@@ -4710,11 +5077,11 @@ This project uses the **Mature** visual QA tier.
4710
5077
  };
4711
5078
  function writeVisualQaTier(cwd, tier) {
4712
5079
  const path = "TESTING.md";
4713
- const fullPath = join18(cwd, path);
4714
- if (!existsSync18(fullPath)) {
5080
+ const fullPath = join19(cwd, path);
5081
+ if (!existsSync19(fullPath)) {
4715
5082
  return { updated: false, path, reason: "TESTING.md not found in project root." };
4716
5083
  }
4717
- const current = readFileSync15(fullPath, "utf8");
5084
+ const current = readFileSync16(fullPath, "utf8");
4718
5085
  if (current.includes(VISUAL_QA_MARKER)) {
4719
5086
  return {
4720
5087
  updated: false,
@@ -4890,8 +5257,8 @@ function extractSetupFormFromWizardForm(form) {
4890
5257
  }
4891
5258
 
4892
5259
  // src/studio/wizard/drafts.ts
4893
- import { existsSync as existsSync19, readFileSync as readFileSync16 } from "fs";
4894
- import { join as join19 } from "path";
5260
+ import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
5261
+ import { join as join20 } from "path";
4895
5262
  var DESIGN_DRAFT_JSON = ".agent-kit/onboarding/design-draft.json";
4896
5263
  var MESSAGING_DRAFT_JSON = ".agent-kit/onboarding/messaging-draft.json";
4897
5264
  function loadDesignDraft(cwd) {
@@ -4936,11 +5303,11 @@ function previewMessagingMarkdown(draft) {
4936
5303
  `;
4937
5304
  }
4938
5305
  function appendSectionToDoc(cwd, doc, sectionMarkdown) {
4939
- const fullPath = join19(cwd, doc);
4940
- if (!existsSync19(fullPath)) {
5306
+ const fullPath = join20(cwd, doc);
5307
+ if (!existsSync20(fullPath)) {
4941
5308
  return { target: doc, action: "missing" };
4942
5309
  }
4943
- const current = readFileSync16(fullPath, "utf8");
5310
+ const current = readFileSync17(fullPath, "utf8");
4944
5311
  if (current.includes("(wizard draft)")) {
4945
5312
  return { target: doc, action: "conflict", conflictPath: `.agent-kit/conflicts/wizard-${doc}` };
4946
5313
  }
@@ -4979,8 +5346,8 @@ function applyDrafts(cwd) {
4979
5346
  }
4980
5347
 
4981
5348
  // src/studio/office/render.ts
4982
- import { readFileSync as readFileSync17 } from "fs";
4983
- import { join as join20 } from "path";
5349
+ import { readFileSync as readFileSync18 } from "fs";
5350
+ import { join as join21 } from "path";
4984
5351
 
4985
5352
  // src/studio/office/map.ts
4986
5353
  var MAP_WIDTH = 28;
@@ -5114,12 +5481,12 @@ var PRODUCT_CATEGORIES = [
5114
5481
  var TENANT_MODELS = ["single-user", "team", "tenant", "marketplace", "admin", "public-content"];
5115
5482
  function readOfficeAsset(name) {
5116
5483
  const root = findPackageRoot();
5117
- const distPath = join20(root, "dist", "studio", "office", "assets", name);
5118
- const srcPath = join20(root, "src", "studio", "office", "assets", name);
5484
+ const distPath = join21(root, "dist", "studio", "office", "assets", name);
5485
+ const srcPath = join21(root, "src", "studio", "office", "assets", name);
5119
5486
  try {
5120
- return readFileSync17(distPath, "utf8");
5487
+ return readFileSync18(distPath, "utf8");
5121
5488
  } catch {
5122
- return readFileSync17(srcPath, "utf8");
5489
+ return readFileSync18(srcPath, "utf8");
5123
5490
  }
5124
5491
  }
5125
5492
  function buildOfficeBootConfig(cwd, viewModel) {
@@ -5182,14 +5549,21 @@ function renderOfficeHtml(boot, mode) {
5182
5549
  </div>
5183
5550
  <div class="header-actions">
5184
5551
  <span class="progress-pill" id="progress-pill">${isStudio ? "Live" : "0% ready"}</span>
5552
+ ${isStudio ? "" : '<span class="level-pill" id="level-pill" aria-live="polite">L3 \u2192 L5</span>'}
5185
5553
  ${isStudio ? '<span class="session-pill" id="session-pill">No session</span>' : '<a class="btn secondary" href="/wizard">Form view</a>'}
5186
5554
  ${isStudio ? "" : '<button type="button" class="btn primary" id="review-btn">Review &amp; save</button>'}
5187
5555
  </div>
5188
5556
  </header>
5557
+ ${isStudio ? "" : '<div class="iceberg-strip" id="iceberg-strip" aria-label="Agentic engineering levels L3 through L8"></div>'}
5189
5558
  <main class="office-main${isStudio ? " studio-layout" : ""}">
5190
5559
  <aside class="station-list${isStudio ? " hidden" : ""}" aria-label="Setup stations">
5191
5560
  <h2>Stations</h2>
5192
5561
  <p class="hint">Keyboard-friendly list \u2014 same actions as the office floor.</p>
5562
+ <div class="climb-panel" id="climb-panel" hidden>
5563
+ <h3>Climb checklist</h3>
5564
+ <ol id="climb-list"></ol>
5565
+ <button type="button" class="btn secondary climb-refresh" id="climb-refresh">Refresh level</button>
5566
+ </div>
5193
5567
  <ul id="station-list"></ul>
5194
5568
  </aside>
5195
5569
  <div class="canvas-wrap">
@@ -5286,8 +5660,8 @@ function allAgentBriefsComplete(form, agentIds) {
5286
5660
  }
5287
5661
 
5288
5662
  // src/studio/wizard/render.ts
5289
- import { readFileSync as readFileSync18 } from "fs";
5290
- import { join as join21 } from "path";
5663
+ import { readFileSync as readFileSync19 } from "fs";
5664
+ import { join as join22 } from "path";
5291
5665
  var PRODUCT_CATEGORIES2 = [
5292
5666
  "content-app",
5293
5667
  "saas",
@@ -5304,12 +5678,12 @@ var PRODUCT_CATEGORIES2 = [
5304
5678
  var TENANT_MODELS2 = ["single-user", "team", "tenant", "marketplace", "admin", "public-content"];
5305
5679
  function readWizardAsset(name) {
5306
5680
  const root = findPackageRoot();
5307
- const distPath = join21(root, "dist", "studio", "wizard", "assets", name);
5308
- const srcPath = join21(root, "src", "studio", "wizard", "assets", name);
5681
+ const distPath = join22(root, "dist", "studio", "wizard", "assets", name);
5682
+ const srcPath = join22(root, "src", "studio", "wizard", "assets", name);
5309
5683
  try {
5310
- return readFileSync18(distPath, "utf8");
5684
+ return readFileSync19(distPath, "utf8");
5311
5685
  } catch {
5312
- return readFileSync18(srcPath, "utf8");
5686
+ return readFileSync19(srcPath, "utf8");
5313
5687
  }
5314
5688
  }
5315
5689
  function mergeWizardSteps(cwd) {
@@ -5363,6 +5737,7 @@ function renderSetupWizardHtml(boot) {
5363
5737
  <div>
5364
5738
  <div style="font-weight:600;color:#f8fafc">Setup progress</div>
5365
5739
  <div style="font-size:13px;color:#94a3b8">Save anytime \u2014 resume with agent-kit setup</div>
5740
+ <div class="wizard-level-pill" id="wizard-level-pill" hidden aria-live="polite">L3 \u2192 L5</div>
5366
5741
  </div>
5367
5742
  </div>
5368
5743
  <ul class="section-nav" id="section-nav"></ul>
@@ -5397,6 +5772,291 @@ function renderSetupWizardHtmlWithContext(cwd) {
5397
5772
  return renderSetupWizardHtml({ ...boot, stackSignals: [...new Set(stackSignals)] });
5398
5773
  }
5399
5774
 
5775
+ // src/studio/agentic-level.ts
5776
+ import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
5777
+ import { join as join23 } from "path";
5778
+ var CACHE_TTL_MS = 3e4;
5779
+ var cache = /* @__PURE__ */ new Map();
5780
+ function isMaintainerSourceRepo(cwd) {
5781
+ return existsSync21(join23(cwd, "package.json")) && existsSync21(join23(cwd, "src")) && existsSync21(join23(cwd, "templates"));
5782
+ }
5783
+ function signal(id, level, label, pass, evidence, remediation) {
5784
+ return { id, level, label, pass, evidence, remediation };
5785
+ }
5786
+ function detectIdePresent(cwd) {
5787
+ const onboarding = loadOnboardingState(cwd);
5788
+ if (onboarding.ideSurface && detectIdeRulePresent(cwd, onboarding.ideSurface)) {
5789
+ return { pass: true, evidence: `${onboarding.ideSurface} adapter configured` };
5790
+ }
5791
+ const surfaces = ["cursor", "copilot", "claude", "codex"];
5792
+ for (const surface of surfaces) {
5793
+ if (detectIdeRulePresent(cwd, surface)) {
5794
+ return { pass: true, evidence: `${surface} adapter files detected` };
5795
+ }
5796
+ }
5797
+ if (existsSync21(join23(cwd, ".cursor/rules/cursor-agent-kit.mdc"))) {
5798
+ return { pass: true, evidence: "Cursor council rules from init" };
5799
+ }
5800
+ return { pass: false, evidence: "No IDE adapter rules or subagents detected" };
5801
+ }
5802
+ function detectTierBSubagents(cwd) {
5803
+ const paths = [
5804
+ ".cursor/agents/planner.md",
5805
+ ".codex/agents/planner.toml",
5806
+ ".claude/agents/planner.md",
5807
+ ".github/copilot-instructions.md"
5808
+ ];
5809
+ const found = paths.filter((rel) => existsSync21(join23(cwd, rel)));
5810
+ if (found.length > 0) {
5811
+ return { pass: true, evidence: `Specialist surface: ${found[0]}` };
5812
+ }
5813
+ return { pass: false, evidence: "No council subagents or Copilot instructions installed" };
5814
+ }
5815
+ function readDocSnippet(cwd, name, needles) {
5816
+ const path = join23(cwd, name);
5817
+ if (!existsSync21(path)) return false;
5818
+ const lower = readFileSync20(path, "utf8").toLowerCase();
5819
+ return needles.every((needle) => lower.includes(needle.toLowerCase()));
5820
+ }
5821
+ function adapterTargetForIde(ide) {
5822
+ if (ide === "cursor" || ide === "codex" || ide === "claude" || ide === "copilot") return ide;
5823
+ return null;
5824
+ }
5825
+ function buildSignals(cwd, maintainerProfile) {
5826
+ const signals = [];
5827
+ const ide = detectIdePresent(cwd);
5828
+ signals.push(
5829
+ signal(
5830
+ "l3-ide",
5831
+ 3,
5832
+ "AI-native IDE or adapter rules",
5833
+ ide.pass,
5834
+ ide.evidence,
5835
+ "Run agent-kit init and complete the IDE station, or agent-kit init --activate cursor|codex"
5836
+ )
5837
+ );
5838
+ const context2 = scanProjectContext(cwd);
5839
+ const openQuestions = context2.openQuestions.length;
5840
+ const contextReady = Boolean(context2.productSummary.trim()) && Boolean(context2.primaryAudience.trim()) && Boolean(context2.authModel.trim()) && context2.primaryWorkflows.length > 0 && openQuestions === 0;
5841
+ signals.push(
5842
+ signal(
5843
+ "l4-agents-md",
5844
+ 4,
5845
+ "Council contract (AGENTS.md)",
5846
+ existsSync21(join23(cwd, "AGENTS.md")),
5847
+ existsSync21(join23(cwd, "AGENTS.md")) ? "AGENTS.md installed" : "AGENTS.md missing",
5848
+ "Run agent-kit init --stack next-supabase"
5849
+ )
5850
+ );
5851
+ signals.push(
5852
+ signal(
5853
+ "l4-adapters-doc",
5854
+ 4,
5855
+ "Assistant activation doc",
5856
+ existsSync21(join23(cwd, "ASSISTANT_ADAPTERS.md")),
5857
+ existsSync21(join23(cwd, "ASSISTANT_ADAPTERS.md")) ? "ASSISTANT_ADAPTERS.md installed" : "ASSISTANT_ADAPTERS.md missing",
5858
+ "Run agent-kit init or agent-kit update"
5859
+ )
5860
+ );
5861
+ signals.push(
5862
+ signal(
5863
+ "l4-roster",
5864
+ 4,
5865
+ "Machine-readable council roster",
5866
+ existsSync21(join23(cwd, ".agent-kit/agent-roster.json")),
5867
+ existsSync21(join23(cwd, ".agent-kit/agent-roster.json")) ? ".agent-kit/agent-roster.json present" : "Roster missing",
5868
+ "Run agent-kit init or agent-kit update"
5869
+ )
5870
+ );
5871
+ signals.push(
5872
+ signal(
5873
+ "l4-project-context",
5874
+ 4,
5875
+ "Project context without open questions",
5876
+ contextReady,
5877
+ contextReady ? "Core project context fields complete" : openQuestions > 0 ? `${openQuestions} open question(s) remain` : "Fill product, audience, auth, and workflows in setup",
5878
+ "Complete setup wizard or edit .agent-kit/project-context.json"
5879
+ )
5880
+ );
5881
+ const tierB = detectTierBSubagents(cwd);
5882
+ signals.push(
5883
+ signal(
5884
+ "l5-subagents",
5885
+ 5,
5886
+ "Tier-B specialist activation",
5887
+ tierB.pass,
5888
+ tierB.evidence,
5889
+ "Run agent-kit init --activate cursor|codex|claude|copilot"
5890
+ )
5891
+ );
5892
+ const loopCoding = existsSync21(join23(cwd, "LOOP_CODING.md"));
5893
+ signals.push(
5894
+ signal(
5895
+ "l6-loop-coding",
5896
+ 6,
5897
+ "Loop coding playbook",
5898
+ loopCoding,
5899
+ loopCoding ? "LOOP_CODING.md installed" : "LOOP_CODING.md missing",
5900
+ "Run agent-kit update or agent-kit init on a current kit version"
5901
+ )
5902
+ );
5903
+ let auditPass = false;
5904
+ let auditEvidence = "Audit not run";
5905
+ try {
5906
+ const audit = createAuditReport(cwd);
5907
+ auditPass = audit.summary.fail === 0 && audit.readiness.level !== "needs-setup";
5908
+ auditEvidence = `${audit.summary.pass} pass / ${audit.summary.warn} warn / ${audit.summary.fail} fail \xB7 ${audit.readiness.level}`;
5909
+ } catch (error) {
5910
+ auditEvidence = error instanceof Error ? error.message : String(error);
5911
+ }
5912
+ signals.push(
5913
+ signal(
5914
+ "l6-audit-gate",
5915
+ 6,
5916
+ "Audit gate at baseline-setup or better",
5917
+ auditPass,
5918
+ auditEvidence,
5919
+ "Run agent-kit audit --min-readiness baseline-setup and fix failures"
5920
+ )
5921
+ );
5922
+ if (maintainerProfile) {
5923
+ const pkgPath = join23(cwd, "package.json");
5924
+ let releaseCheck = false;
5925
+ if (existsSync21(pkgPath)) {
5926
+ try {
5927
+ const pkg = JSON.parse(readFileSync20(pkgPath, "utf8"));
5928
+ releaseCheck = Boolean(pkg.scripts?.["release:check"]) && existsSync21(join23(cwd, "scripts/release-check.mjs"));
5929
+ } catch {
5930
+ releaseCheck = false;
5931
+ }
5932
+ }
5933
+ signals.push(
5934
+ signal(
5935
+ "l6-maintainer-release-check",
5936
+ 6,
5937
+ "Maintainer release-check gate",
5938
+ releaseCheck,
5939
+ releaseCheck ? "npm run release:check wired in package.json" : "release:check script missing",
5940
+ "Use npm run release:check before merge; see MAINTAINER_RELEASE.md"
5941
+ )
5942
+ );
5943
+ const maintainerDocs = existsSync21(join23(cwd, "MAINTAINER_RELEASE.md")) || readDocSnippet(cwd, "DOCS.md", ["maintainer dogfood", "dogfood:init"]);
5944
+ signals.push(
5945
+ signal(
5946
+ "l6-maintainer-docs",
5947
+ 6,
5948
+ "Maintainer dogfood and release evidence docs",
5949
+ maintainerDocs,
5950
+ maintainerDocs ? "Maintainer climb docs present" : "Add MAINTAINER_RELEASE.md / DOCS maintainer section",
5951
+ "Read MAINTAINER_RELEASE.md and run npm run dogfood:init locally"
5952
+ )
5953
+ );
5954
+ } else {
5955
+ const onboarding = loadOnboardingState(cwd);
5956
+ const adapterTarget = adapterTargetForIde(onboarding.ideSurface);
5957
+ let adapterPass = false;
5958
+ let adapterEvidence = "No IDE surface selected for validation";
5959
+ if (adapterTarget) {
5960
+ const report2 = validateAdapter(cwd, adapterTarget);
5961
+ adapterPass = report2.summary.fail === 0;
5962
+ adapterEvidence = `${adapterTarget}: ${report2.summary.pass} pass / ${report2.summary.warn} warn / ${report2.summary.fail} fail`;
5963
+ } else if (tierB.pass) {
5964
+ const report2 = validateAdapter(cwd, "cursor");
5965
+ adapterPass = report2.summary.fail === 0;
5966
+ adapterEvidence = `cursor (detected): ${report2.summary.pass} pass / ${report2.summary.fail} fail`;
5967
+ }
5968
+ signals.push(
5969
+ signal(
5970
+ "l6-adapter-validate",
5971
+ 6,
5972
+ "Adapter validate for active IDE",
5973
+ adapterPass,
5974
+ adapterEvidence,
5975
+ "Run agent-kit adapter validate cursor|codex|all"
5976
+ )
5977
+ );
5978
+ const ciWorkflow = existsSync21(join23(cwd, ".github/workflows/agent-kit-audit.yml"));
5979
+ const testingEval = existsSync21(join23(cwd, "TESTING.md")) && readDocSnippet(cwd, "TESTING.md", ["agent-kit audit", "eval"]);
5980
+ const evalLoop = ciWorkflow || testingEval;
5981
+ signals.push(
5982
+ signal(
5983
+ "l6-eval-loop",
5984
+ 6,
5985
+ "Eval-driven loop documented in CI or TESTING.md",
5986
+ evalLoop,
5987
+ ciWorkflow ? ".github/workflows/agent-kit-audit.yml present" : testingEval ? "TESTING.md documents eval/audit loop" : "No CI audit workflow or TESTING eval section",
5988
+ "Enable agent-kit-audit.yml or add eval loop section to TESTING.md (see LOOP_CODING.md)"
5989
+ )
5990
+ );
5991
+ }
5992
+ return signals;
5993
+ }
5994
+ function computeCurrentLevel(signals) {
5995
+ let current = 3;
5996
+ for (const level of [3, 4, 5, 6]) {
5997
+ const tier = signals.filter((item) => item.level === level);
5998
+ if (tier.length === 0) continue;
5999
+ if (tier.every((item) => item.pass)) {
6000
+ current = level;
6001
+ } else {
6002
+ break;
6003
+ }
6004
+ }
6005
+ return current;
6006
+ }
6007
+ function defaultTargetLevel(maintainerProfile) {
6008
+ return maintainerProfile ? 6 : 5;
6009
+ }
6010
+ function resolveTargetLevel(cwd, maintainerProfile) {
6011
+ const onboarding = loadOnboardingState(cwd);
6012
+ const raw = onboarding.targetAgenticLevel;
6013
+ if (raw && raw >= 3 && raw <= 8) return raw;
6014
+ return defaultTargetLevel(maintainerProfile);
6015
+ }
6016
+ function computeAgenticLevel(cwd, options = {}) {
6017
+ const cacheKey = cwd;
6018
+ const cached = cache.get(cacheKey);
6019
+ if (!options.forceRefresh && cached && Date.now() - cached.at < CACHE_TTL_MS) {
6020
+ return cached.report;
6021
+ }
6022
+ const maintainerProfile = isMaintainerSourceRepo(cwd);
6023
+ const signals = buildSignals(cwd, maintainerProfile);
6024
+ const currentLevel = computeCurrentLevel(signals);
6025
+ const targetLevel = resolveTargetLevel(cwd, maintainerProfile);
6026
+ const climbSteps = signals.filter((item) => !item.pass && item.level <= Math.min(targetLevel, 6)).slice(0, 5);
6027
+ const report2 = AgenticLevelContract.parse({
6028
+ currentLevel,
6029
+ targetLevel,
6030
+ maintainerProfile,
6031
+ computedAt: nowIso(),
6032
+ maintainerNote: maintainerProfile ? "Kit source repo \u2014 run npm run dogfood:init locally; overlay is gitignored." : void 0,
6033
+ signals,
6034
+ climbSteps
6035
+ });
6036
+ cache.set(cacheKey, { at: Date.now(), report: report2 });
6037
+ saveOnboardingState(cwd, {
6038
+ lastAgenticLevel: currentLevel,
6039
+ lastAgenticComputedAt: report2.computedAt
6040
+ });
6041
+ return report2;
6042
+ }
6043
+ function summarizeAdapterValidation(cwd, ideSurface) {
6044
+ const target = adapterTargetForIde(ideSurface);
6045
+ if (!target) {
6046
+ return { pass: 0, warn: 0, fail: 0, target: null };
6047
+ }
6048
+ const report2 = validateAdapter(cwd, target);
6049
+ return {
6050
+ pass: report2.summary.pass,
6051
+ warn: report2.summary.warn,
6052
+ fail: report2.summary.fail,
6053
+ target
6054
+ };
6055
+ }
6056
+ function invalidateAgenticLevelCache(cwd) {
6057
+ cache.delete(cwd);
6058
+ }
6059
+
5400
6060
  // src/studio/setup-server.ts
5401
6061
  var DEFAULT_PORT = 9321;
5402
6062
  var DEFAULT_HOST = "127.0.0.1";
@@ -5440,7 +6100,7 @@ function sendHtml(response, html) {
5440
6100
  });
5441
6101
  response.end(html);
5442
6102
  }
5443
- function buildStatePayload(cwd) {
6103
+ function buildStatePayload(cwd, options = {}) {
5444
6104
  ensureProjectContextForSetup(cwd);
5445
6105
  const viewModel = getSetupFormViewModel(cwd);
5446
6106
  const onboarding = loadOnboardingState(cwd);
@@ -5448,6 +6108,10 @@ function buildStatePayload(cwd) {
5448
6108
  const designDraft = loadDesignDraft(cwd);
5449
6109
  const messagingDraft = loadMessagingDraft(cwd);
5450
6110
  const draft = loadWizardDraft(cwd);
6111
+ const agenticLevel = computeAgenticLevel(
6112
+ cwd,
6113
+ options.forceAgenticRefresh ? { forceRefresh: true } : {}
6114
+ );
5451
6115
  return {
5452
6116
  projectName: viewModel.projectName,
5453
6117
  form: buildWizardFormState(cwd),
@@ -5458,6 +6122,7 @@ function buildStatePayload(cwd) {
5458
6122
  hasSupabase: viewModel.hasSupabase,
5459
6123
  onboarding,
5460
6124
  progress,
6125
+ agenticLevel,
5461
6126
  designDraft,
5462
6127
  messagingDraft,
5463
6128
  draftUpdatedAt: draft.updatedAt,
@@ -5519,8 +6184,10 @@ async function handleRequest(cwd, request, response) {
5519
6184
  if (body.currentSection) patch.currentSection = String(body.currentSection);
5520
6185
  if (typeof body.currentStep === "number") patch.currentStep = body.currentStep;
5521
6186
  if (Array.isArray(body.completedSections)) patch.completedSections = body.completedSections;
6187
+ if (typeof body.targetAgenticLevel === "number") patch.targetAgenticLevel = body.targetAgenticLevel;
5522
6188
  if (Object.keys(patch).length > 0) saveOnboardingState(cwd, patch);
5523
- sendJson(response, 200, buildStatePayload(cwd));
6189
+ invalidateAgenticLevelCache(cwd);
6190
+ sendJson(response, 200, buildStatePayload(cwd, { forceAgenticRefresh: true }));
5524
6191
  } catch (error) {
5525
6192
  sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) });
5526
6193
  }
@@ -5533,8 +6200,9 @@ async function handleRequest(cwd, request, response) {
5533
6200
  const result = applySetupFormAnswers(cwd, payload);
5534
6201
  saveAgentBriefs(cwd, extractAgentBriefsFromForm(raw));
5535
6202
  markQuickPathComplete(cwd);
6203
+ invalidateAgenticLevelCache(cwd);
5536
6204
  sendJson(response, 200, {
5537
- ...buildStatePayload(cwd),
6205
+ ...buildStatePayload(cwd, { forceAgenticRefresh: true }),
5538
6206
  saved: true,
5539
6207
  contextPath: result.contextPath,
5540
6208
  markdownPath: result.markdownPath,
@@ -5574,9 +6242,27 @@ async function handleRequest(cwd, request, response) {
5574
6242
  try {
5575
6243
  const body = await readJsonBody(request);
5576
6244
  if (!body.ideSurface) throw new Error("ideSurface is required.");
6245
+ const activateTarget = ideSurfaceToActivateTarget(body.ideSurface);
6246
+ let activation;
6247
+ if (activateTarget) {
6248
+ const activateResult = activateIdeTargets({ cwd, targets: [activateTarget] });
6249
+ activation = {
6250
+ activated: activateResult.activated,
6251
+ copied: activateResult.copied,
6252
+ unchanged: activateResult.unchanged,
6253
+ conflicts: activateResult.conflicts
6254
+ };
6255
+ }
5577
6256
  const result = saveIdeChecklist(cwd, body.ideSurface);
5578
6257
  markSectionComplete(cwd, "ide");
5579
- sendJson(response, 200, { ...result, ...buildStatePayload(cwd) });
6258
+ invalidateAgenticLevelCache(cwd);
6259
+ const adapterValidation = summarizeAdapterValidation(cwd, body.ideSurface);
6260
+ sendJson(response, 200, {
6261
+ ...result,
6262
+ activation,
6263
+ adapterValidation,
6264
+ ...buildStatePayload(cwd, { forceAgenticRefresh: true })
6265
+ });
5580
6266
  } catch (error) {
5581
6267
  sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) });
5582
6268
  }
@@ -5634,6 +6320,11 @@ async function handleRequest(cwd, request, response) {
5634
6320
  }
5635
6321
  return;
5636
6322
  }
6323
+ if (request.method === "POST" && url.pathname === "/api/agentic-level/refresh") {
6324
+ invalidateAgenticLevelCache(cwd);
6325
+ sendJson(response, 200, buildStatePayload(cwd, { forceAgenticRefresh: true }));
6326
+ return;
6327
+ }
5637
6328
  sendJson(response, 404, { error: "Not found." });
5638
6329
  }
5639
6330
  function listen(server, host, port) {
@@ -5689,7 +6380,7 @@ async function startSetupServer(options) {
5689
6380
  // src/studio/studio-server.ts
5690
6381
  import { watch } from "fs";
5691
6382
  import { createServer as createServer2 } from "http";
5692
- import { join as join22 } from "path";
6383
+ import { join as join24 } from "path";
5693
6384
  var DEFAULT_PORT2 = 9331;
5694
6385
  var DEFAULT_HOST2 = "127.0.0.1";
5695
6386
  var sseClients = /* @__PURE__ */ new Set();
@@ -5731,7 +6422,7 @@ function stopWatcher() {
5731
6422
  }
5732
6423
  }
5733
6424
  function watchSessionEvents(cwd, sessionId) {
5734
- const eventsPath2 = join22(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
6425
+ const eventsPath2 = join24(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
5735
6426
  if (watchedEventsPath === eventsPath2 && activeWatcher) return;
5736
6427
  stopWatcher();
5737
6428
  watchedEventsPath = eventsPath2;
@@ -5887,8 +6578,8 @@ async function startStudioServer(options) {
5887
6578
  }
5888
6579
 
5889
6580
  // src/studio/session-checkpoint.ts
5890
- import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
5891
- import { extname, join as join23 } from "path";
6581
+ import { existsSync as existsSync22, readFileSync as readFileSync21 } from "fs";
6582
+ import { extname, join as join25 } from "path";
5892
6583
  function parseCheckpointMarkdown(content) {
5893
6584
  const payload = { notes: [], decisions: [], handoffs: [], outputs: [] };
5894
6585
  const sections = content.split(/^## /m).slice(1);
@@ -5944,7 +6635,7 @@ function parseCheckpointMarkdown(content) {
5944
6635
  return payload;
5945
6636
  }
5946
6637
  function parseCheckpointFile(filePath) {
5947
- const content = readFileSync19(filePath, "utf8");
6638
+ const content = readFileSync21(filePath, "utf8");
5948
6639
  const ext = extname(filePath).toLowerCase();
5949
6640
  if (ext === ".json") {
5950
6641
  const parsed = JSON.parse(content);
@@ -6020,8 +6711,8 @@ function applySessionCheckpoint(cwd, payload) {
6020
6711
  };
6021
6712
  }
6022
6713
  function checkpointSessionFromFile(cwd, filePath) {
6023
- const absolute = join23(cwd, filePath);
6024
- if (!existsSync20(absolute)) throw new Error(`Checkpoint file not found: ${filePath}`);
6714
+ const absolute = join25(cwd, filePath);
6715
+ if (!existsSync22(absolute)) throw new Error(`Checkpoint file not found: ${filePath}`);
6025
6716
  return applySessionCheckpoint(cwd, parseCheckpointFile(absolute));
6026
6717
  }
6027
6718