@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/CHANGELOG.md +7 -0
- package/DOGFOOD.md +15 -0
- package/LOOP_CODING.md +107 -0
- package/MAINTAINER_RELEASE.md +100 -0
- package/dist/index.js +358 -14
- package/dist/index.js.map +1 -1
- package/dist/studio/office/assets/office.css +79 -1
- package/dist/studio/office/assets/office.js +72 -1
- package/dist/studio/wizard/assets/wizard.css +52 -0
- package/dist/studio/wizard/assets/wizard.js +76 -5
- package/examples/next-supabase-installed/.agent-kit/manifest.json +5 -3
- package/examples/next-supabase-installed/audit-output.json +17 -2
- package/examples/next-supabase-installed/tree.txt +1 -0
- package/package.json +8 -3
- package/research/summaries/agentic-engineering-maturity-levels.md +54 -0
- package/schemas/agentic-level.schema.json +47 -0
- package/schemas/onboarding-state.schema.json +4 -1
- package/templates/next-supabase/DOCS.md +2 -0
- package/templates/next-supabase/LOOP_CODING.md +98 -0
- package/templates/next-supabase/TESTING.md +10 -0
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.
|
|
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 & 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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
6238
|
-
import { extname, join as
|
|
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 =
|
|
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 =
|
|
6371
|
-
if (!
|
|
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
|
|