@appsforgood/next-supabase-kit 0.1.4 → 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
@@ -146,7 +146,7 @@ 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.4";
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
  ];
@@ -629,6 +630,15 @@ var SessionEventContract = z.object({
629
630
  context2.addIssue({ code: z.ZodIssueCode.custom, message: "required output events require outputName and outputStatus", path: ["outputName"] });
630
631
  }
631
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
+ ]);
632
642
  var OnboardingStateContract = z.object({
633
643
  schemaVersion: z.literal(1),
634
644
  depth: z.enum(["quick", "standard", "complete", "undecided"]),
@@ -642,7 +652,27 @@ var OnboardingStateContract = z.object({
642
652
  wizardVersion: z.string(),
643
653
  ideSurface: z.enum(["cursor", "copilot", "claude", "codex", "other"]).optional(),
644
654
  ideVerifiedAt: z.string().datetime().optional(),
645
- 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)
646
676
  }).strict();
647
677
  function formatContractIssues(error) {
648
678
  return error.issues.map((issue) => {
@@ -1735,7 +1765,8 @@ var REQUIRED_SCHEMA_FILES = [
1735
1765
  "correction-rules.schema.json",
1736
1766
  "session-event.schema.json",
1737
1767
  "studio-session.schema.json",
1738
- "onboarding-state.schema.json"
1768
+ "onboarding-state.schema.json",
1769
+ "agentic-level.schema.json"
1739
1770
  ];
1740
1771
  var COUNCIL_SESSION_DIR = ".agent-kit/council-sessions";
1741
1772
  var READINESS_ORDER = ["needs-setup", "baseline-setup", "needs-improvement", "best-practice-candidate"];
@@ -5518,14 +5549,21 @@ function renderOfficeHtml(boot, mode) {
5518
5549
  </div>
5519
5550
  <div class="header-actions">
5520
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>'}
5521
5553
  ${isStudio ? '<span class="session-pill" id="session-pill">No session</span>' : '<a class="btn secondary" href="/wizard">Form view</a>'}
5522
5554
  ${isStudio ? "" : '<button type="button" class="btn primary" id="review-btn">Review &amp; save</button>'}
5523
5555
  </div>
5524
5556
  </header>
5557
+ ${isStudio ? "" : '<div class="iceberg-strip" id="iceberg-strip" aria-label="Agentic engineering levels L3 through L8"></div>'}
5525
5558
  <main class="office-main${isStudio ? " studio-layout" : ""}">
5526
5559
  <aside class="station-list${isStudio ? " hidden" : ""}" aria-label="Setup stations">
5527
5560
  <h2>Stations</h2>
5528
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>
5529
5567
  <ul id="station-list"></ul>
5530
5568
  </aside>
5531
5569
  <div class="canvas-wrap">
@@ -5699,6 +5737,7 @@ function renderSetupWizardHtml(boot) {
5699
5737
  <div>
5700
5738
  <div style="font-weight:600;color:#f8fafc">Setup progress</div>
5701
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>
5702
5741
  </div>
5703
5742
  </div>
5704
5743
  <ul class="section-nav" id="section-nav"></ul>
@@ -5733,6 +5772,291 @@ function renderSetupWizardHtmlWithContext(cwd) {
5733
5772
  return renderSetupWizardHtml({ ...boot, stackSignals: [...new Set(stackSignals)] });
5734
5773
  }
5735
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
+
5736
6060
  // src/studio/setup-server.ts
5737
6061
  var DEFAULT_PORT = 9321;
5738
6062
  var DEFAULT_HOST = "127.0.0.1";
@@ -5776,7 +6100,7 @@ function sendHtml(response, html) {
5776
6100
  });
5777
6101
  response.end(html);
5778
6102
  }
5779
- function buildStatePayload(cwd) {
6103
+ function buildStatePayload(cwd, options = {}) {
5780
6104
  ensureProjectContextForSetup(cwd);
5781
6105
  const viewModel = getSetupFormViewModel(cwd);
5782
6106
  const onboarding = loadOnboardingState(cwd);
@@ -5784,6 +6108,10 @@ function buildStatePayload(cwd) {
5784
6108
  const designDraft = loadDesignDraft(cwd);
5785
6109
  const messagingDraft = loadMessagingDraft(cwd);
5786
6110
  const draft = loadWizardDraft(cwd);
6111
+ const agenticLevel = computeAgenticLevel(
6112
+ cwd,
6113
+ options.forceAgenticRefresh ? { forceRefresh: true } : {}
6114
+ );
5787
6115
  return {
5788
6116
  projectName: viewModel.projectName,
5789
6117
  form: buildWizardFormState(cwd),
@@ -5794,6 +6122,7 @@ function buildStatePayload(cwd) {
5794
6122
  hasSupabase: viewModel.hasSupabase,
5795
6123
  onboarding,
5796
6124
  progress,
6125
+ agenticLevel,
5797
6126
  designDraft,
5798
6127
  messagingDraft,
5799
6128
  draftUpdatedAt: draft.updatedAt,
@@ -5855,8 +6184,10 @@ async function handleRequest(cwd, request, response) {
5855
6184
  if (body.currentSection) patch.currentSection = String(body.currentSection);
5856
6185
  if (typeof body.currentStep === "number") patch.currentStep = body.currentStep;
5857
6186
  if (Array.isArray(body.completedSections)) patch.completedSections = body.completedSections;
6187
+ if (typeof body.targetAgenticLevel === "number") patch.targetAgenticLevel = body.targetAgenticLevel;
5858
6188
  if (Object.keys(patch).length > 0) saveOnboardingState(cwd, patch);
5859
- sendJson(response, 200, buildStatePayload(cwd));
6189
+ invalidateAgenticLevelCache(cwd);
6190
+ sendJson(response, 200, buildStatePayload(cwd, { forceAgenticRefresh: true }));
5860
6191
  } catch (error) {
5861
6192
  sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) });
5862
6193
  }
@@ -5869,8 +6200,9 @@ async function handleRequest(cwd, request, response) {
5869
6200
  const result = applySetupFormAnswers(cwd, payload);
5870
6201
  saveAgentBriefs(cwd, extractAgentBriefsFromForm(raw));
5871
6202
  markQuickPathComplete(cwd);
6203
+ invalidateAgenticLevelCache(cwd);
5872
6204
  sendJson(response, 200, {
5873
- ...buildStatePayload(cwd),
6205
+ ...buildStatePayload(cwd, { forceAgenticRefresh: true }),
5874
6206
  saved: true,
5875
6207
  contextPath: result.contextPath,
5876
6208
  markdownPath: result.markdownPath,
@@ -5923,7 +6255,14 @@ async function handleRequest(cwd, request, response) {
5923
6255
  }
5924
6256
  const result = saveIdeChecklist(cwd, body.ideSurface);
5925
6257
  markSectionComplete(cwd, "ide");
5926
- sendJson(response, 200, { ...result, activation, ...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
+ });
5927
6266
  } catch (error) {
5928
6267
  sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) });
5929
6268
  }
@@ -5981,6 +6320,11 @@ async function handleRequest(cwd, request, response) {
5981
6320
  }
5982
6321
  return;
5983
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
+ }
5984
6328
  sendJson(response, 404, { error: "Not found." });
5985
6329
  }
5986
6330
  function listen(server, host, port) {
@@ -6036,7 +6380,7 @@ async function startSetupServer(options) {
6036
6380
  // src/studio/studio-server.ts
6037
6381
  import { watch } from "fs";
6038
6382
  import { createServer as createServer2 } from "http";
6039
- import { join as join23 } from "path";
6383
+ import { join as join24 } from "path";
6040
6384
  var DEFAULT_PORT2 = 9331;
6041
6385
  var DEFAULT_HOST2 = "127.0.0.1";
6042
6386
  var sseClients = /* @__PURE__ */ new Set();
@@ -6078,7 +6422,7 @@ function stopWatcher() {
6078
6422
  }
6079
6423
  }
6080
6424
  function watchSessionEvents(cwd, sessionId) {
6081
- const eventsPath2 = join23(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
6425
+ const eventsPath2 = join24(cwd, COUNCIL_SESSIONS_DIR, sessionId, "events.jsonl");
6082
6426
  if (watchedEventsPath === eventsPath2 && activeWatcher) return;
6083
6427
  stopWatcher();
6084
6428
  watchedEventsPath = eventsPath2;
@@ -6234,8 +6578,8 @@ async function startStudioServer(options) {
6234
6578
  }
6235
6579
 
6236
6580
  // src/studio/session-checkpoint.ts
6237
- import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
6238
- import { extname, join as join24 } from "path";
6581
+ import { existsSync as existsSync22, readFileSync as readFileSync21 } from "fs";
6582
+ import { extname, join as join25 } from "path";
6239
6583
  function parseCheckpointMarkdown(content) {
6240
6584
  const payload = { notes: [], decisions: [], handoffs: [], outputs: [] };
6241
6585
  const sections = content.split(/^## /m).slice(1);
@@ -6291,7 +6635,7 @@ function parseCheckpointMarkdown(content) {
6291
6635
  return payload;
6292
6636
  }
6293
6637
  function parseCheckpointFile(filePath) {
6294
- const content = readFileSync20(filePath, "utf8");
6638
+ const content = readFileSync21(filePath, "utf8");
6295
6639
  const ext = extname(filePath).toLowerCase();
6296
6640
  if (ext === ".json") {
6297
6641
  const parsed = JSON.parse(content);
@@ -6367,8 +6711,8 @@ function applySessionCheckpoint(cwd, payload) {
6367
6711
  };
6368
6712
  }
6369
6713
  function checkpointSessionFromFile(cwd, filePath) {
6370
- const absolute = join24(cwd, filePath);
6371
- if (!existsSync21(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}`);
6372
6716
  return applySessionCheckpoint(cwd, parseCheckpointFile(absolute));
6373
6717
  }
6374
6718