@appsforgood/next-supabase-kit 0.1.6 → 0.1.8
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 +15 -0
- package/DOGFOOD.md +41 -0
- package/README.md +209 -42
- package/antigravity/commands/review.toml +16 -0
- package/antigravity/commands/spec.toml +17 -0
- package/antigravity/commands/test.toml +17 -0
- package/antigravity/plugin.json +4 -1
- package/assistant-adapters/antigravity.md +7 -0
- package/dist/index.js +96 -28
- package/dist/index.js.map +1 -1
- package/dist/studio/office/assets/office.css +30 -0
- package/dist/studio/office/assets/office.js +99 -3
- package/examples/next-supabase-installed/.agent-kit/agent-roster.json +46 -11
- package/examples/next-supabase-installed/.agent-kit/manifest.json +2 -2
- package/examples/next-supabase-installed/audit-output.json +380 -380
- package/package.json +3 -1
- package/prompts/lifecycle-command-index.md +180 -0
- package/rosters/next-supabase-default-council.json +16 -2
package/dist/index.js
CHANGED
|
@@ -150,7 +150,7 @@ import { join as join12, normalize } from "path";
|
|
|
150
150
|
|
|
151
151
|
// src/config/defaults.ts
|
|
152
152
|
var PACKAGE_NAME = "@appsforgood/next-supabase-kit";
|
|
153
|
-
var PACKAGE_VERSION = "0.1.
|
|
153
|
+
var PACKAGE_VERSION = "0.1.8";
|
|
154
154
|
var DEFAULT_CONFIG = {
|
|
155
155
|
stack: "next-supabase",
|
|
156
156
|
projectType: "saas",
|
|
@@ -362,6 +362,34 @@ function listMarkdown(items) {
|
|
|
362
362
|
function unique(values) {
|
|
363
363
|
return [...new Set(values.filter(Boolean))].sort();
|
|
364
364
|
}
|
|
365
|
+
function readJsonBody(request) {
|
|
366
|
+
return new Promise((resolve3, reject) => {
|
|
367
|
+
const chunks = [];
|
|
368
|
+
let bodyTooLarge = false;
|
|
369
|
+
request.on("data", (chunk) => {
|
|
370
|
+
if (bodyTooLarge) return;
|
|
371
|
+
chunks.push(chunk);
|
|
372
|
+
if (chunks.reduce((total, item) => total + item.length, 0) > 256e3) {
|
|
373
|
+
bodyTooLarge = true;
|
|
374
|
+
reject(new Error("Request body too large."));
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
request.on("end", () => {
|
|
378
|
+
if (bodyTooLarge) return;
|
|
379
|
+
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
380
|
+
if (!raw) {
|
|
381
|
+
resolve3({});
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
resolve3(JSON.parse(raw));
|
|
386
|
+
} catch {
|
|
387
|
+
reject(new Error("Request body must be valid JSON."));
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
request.on("error", reject);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
365
393
|
|
|
366
394
|
// src/install/audit.ts
|
|
367
395
|
import { existsSync as existsSync11, readFileSync as readFileSync9, statSync } from "fs";
|
|
@@ -3070,6 +3098,7 @@ function createAuditReport(cwd) {
|
|
|
3070
3098
|
// src/install/adapter-validate.ts
|
|
3071
3099
|
var REQUIRED_COMMANDS = [
|
|
3072
3100
|
"setup",
|
|
3101
|
+
"spec",
|
|
3073
3102
|
"audit",
|
|
3074
3103
|
"plan",
|
|
3075
3104
|
"handoff",
|
|
@@ -3082,6 +3111,8 @@ var REQUIRED_COMMANDS = [
|
|
|
3082
3111
|
"distinctiveness-pass",
|
|
3083
3112
|
"screenshot-critique",
|
|
3084
3113
|
"browser-qa",
|
|
3114
|
+
"test",
|
|
3115
|
+
"review",
|
|
3085
3116
|
"security",
|
|
3086
3117
|
"copy",
|
|
3087
3118
|
"ship",
|
|
@@ -4545,7 +4576,10 @@ function redactEvent(event) {
|
|
|
4545
4576
|
};
|
|
4546
4577
|
}
|
|
4547
4578
|
function recordNote(cwd, agentId, text) {
|
|
4548
|
-
return
|
|
4579
|
+
return recordSessionNote(cwd, getActiveSessionId(cwd), agentId, text);
|
|
4580
|
+
}
|
|
4581
|
+
function recordSessionNote(cwd, sessionId, agentId, text) {
|
|
4582
|
+
return appendSessionEvent(cwd, sessionId, { type: "agent_message", createdAt: nowIso(), agentId, text });
|
|
4549
4583
|
}
|
|
4550
4584
|
function recordDecision(cwd, agentId, decision, risk) {
|
|
4551
4585
|
return appendSessionEvent(cwd, getActiveSessionId(cwd), {
|
|
@@ -5706,7 +5740,7 @@ function renderOfficeHtml(boot, mode) {
|
|
|
5706
5740
|
<div id="nameplate-layer" class="nameplate-layer" aria-hidden="true"></div>
|
|
5707
5741
|
<div id="office-hint" class="office-hint hidden" role="status">${isStudio ? "Watching council session events\u2026" : "Click a desk or zone to brief your agent team."}</div>
|
|
5708
5742
|
</div>
|
|
5709
|
-
${isStudio ? '<aside class="transcript-panel" id="transcript-panel" aria-label="Session transcript"><h2>Transcript</h2><ol id="transcript-list"></ol></aside>' : ""}
|
|
5743
|
+
${isStudio ? '<aside class="transcript-panel" id="transcript-panel" aria-label="Session transcript"><div class="studio-controls" id="studio-controls"><label class="studio-label" for="session-picker">Session</label><select id="session-picker" aria-label="Council session"></select><form id="studio-note-form" class="studio-note-form"><select id="studio-note-agent" aria-label="Agent for note"></select><input id="studio-note-text" type="text" maxlength="3999" placeholder="Add council note\u2026" /><button type="submit" class="btn secondary">Add note</button></form><button type="button" class="btn primary" id="studio-render-btn">Render markdown</button></div><h2>Transcript</h2><ol id="transcript-list"></ol></aside>' : ""}
|
|
5710
5744
|
</main>
|
|
5711
5745
|
<div id="status" class="status" role="status" aria-live="polite"></div>
|
|
5712
5746
|
<div id="depth-modal" class="modal modal-blur" hidden>
|
|
@@ -6161,31 +6195,6 @@ function invalidateAgenticLevelCache(cwd) {
|
|
|
6161
6195
|
// src/studio/setup-server.ts
|
|
6162
6196
|
var DEFAULT_PORT = 9321;
|
|
6163
6197
|
var DEFAULT_HOST = "127.0.0.1";
|
|
6164
|
-
function readJsonBody(request) {
|
|
6165
|
-
return new Promise((resolve3, reject) => {
|
|
6166
|
-
const chunks = [];
|
|
6167
|
-
request.on("data", (chunk) => {
|
|
6168
|
-
chunks.push(chunk);
|
|
6169
|
-
if (chunks.reduce((total, item) => total + item.length, 0) > 256e3) {
|
|
6170
|
-
reject(new Error("Request body too large."));
|
|
6171
|
-
request.destroy();
|
|
6172
|
-
}
|
|
6173
|
-
});
|
|
6174
|
-
request.on("end", () => {
|
|
6175
|
-
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
6176
|
-
if (!raw) {
|
|
6177
|
-
resolve3({});
|
|
6178
|
-
return;
|
|
6179
|
-
}
|
|
6180
|
-
try {
|
|
6181
|
-
resolve3(JSON.parse(raw));
|
|
6182
|
-
} catch {
|
|
6183
|
-
reject(new Error("Request body must be valid JSON."));
|
|
6184
|
-
}
|
|
6185
|
-
});
|
|
6186
|
-
request.on("error", reject);
|
|
6187
|
-
});
|
|
6188
|
-
}
|
|
6189
6198
|
function sendJson(response, statusCode, payload) {
|
|
6190
6199
|
response.writeHead(statusCode, {
|
|
6191
6200
|
"Content-Type": "application/json; charset=utf-8",
|
|
@@ -6273,6 +6282,9 @@ async function handleRequest(cwd, request, response) {
|
|
|
6273
6282
|
try {
|
|
6274
6283
|
const body = await readJsonBody(request);
|
|
6275
6284
|
if (typeof body.completeSection === "string") {
|
|
6285
|
+
if (!(body.completeSection in SECTION_LABELS)) {
|
|
6286
|
+
throw new Error("Invalid section id.");
|
|
6287
|
+
}
|
|
6276
6288
|
markSectionComplete(cwd, body.completeSection);
|
|
6277
6289
|
}
|
|
6278
6290
|
const patch = {};
|
|
@@ -6541,6 +6553,11 @@ function safeSessionId(raw) {
|
|
|
6541
6553
|
return raw;
|
|
6542
6554
|
}
|
|
6543
6555
|
function handleRequest2(cwd, request, response) {
|
|
6556
|
+
handleRequestAsync(cwd, request, response).catch((error) => {
|
|
6557
|
+
sendJson2(response, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
6558
|
+
});
|
|
6559
|
+
}
|
|
6560
|
+
async function handleRequestAsync(cwd, request, response) {
|
|
6544
6561
|
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
6545
6562
|
if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/office")) {
|
|
6546
6563
|
sendHtml2(response, renderLiveStudioHtmlWithContext(cwd));
|
|
@@ -6615,6 +6632,57 @@ data: ${JSON.stringify({ sessionId: activeId, events: [] })}
|
|
|
6615
6632
|
});
|
|
6616
6633
|
return;
|
|
6617
6634
|
}
|
|
6635
|
+
const noteMatch = url.pathname.match(/^\/api\/sessions\/([^/]+)\/note$/);
|
|
6636
|
+
if (request.method === "POST" && noteMatch) {
|
|
6637
|
+
const sessionId = safeSessionId(noteMatch[1] ?? "");
|
|
6638
|
+
if (!sessionId) {
|
|
6639
|
+
sendJson2(response, 400, { error: "Invalid session id." });
|
|
6640
|
+
return;
|
|
6641
|
+
}
|
|
6642
|
+
try {
|
|
6643
|
+
const body = await readJsonBody(request);
|
|
6644
|
+
const agent = typeof body.agent === "string" ? body.agent.trim() : "";
|
|
6645
|
+
const text = typeof body.text === "string" ? body.text.trim() : "";
|
|
6646
|
+
if (!agent) {
|
|
6647
|
+
sendJson2(response, 400, { error: "agent is required." });
|
|
6648
|
+
return;
|
|
6649
|
+
}
|
|
6650
|
+
if (!text) {
|
|
6651
|
+
sendJson2(response, 400, { error: "text is required." });
|
|
6652
|
+
return;
|
|
6653
|
+
}
|
|
6654
|
+
if (text.length >= 4e3) {
|
|
6655
|
+
sendJson2(response, 400, { error: "text must be under 4000 characters." });
|
|
6656
|
+
return;
|
|
6657
|
+
}
|
|
6658
|
+
const event = recordSessionNote(cwd, sessionId, agent, text);
|
|
6659
|
+
broadcastSse("event", { sessionId, event, total: readSessionEvents(cwd, sessionId).length });
|
|
6660
|
+
sendJson2(response, 200, { event });
|
|
6661
|
+
} catch (error) {
|
|
6662
|
+
sendJson2(response, 404, { error: error instanceof Error ? error.message : String(error) });
|
|
6663
|
+
}
|
|
6664
|
+
return;
|
|
6665
|
+
}
|
|
6666
|
+
const renderMatch = url.pathname.match(/^\/api\/sessions\/([^/]+)\/render$/);
|
|
6667
|
+
if (request.method === "POST" && renderMatch) {
|
|
6668
|
+
const sessionId = safeSessionId(renderMatch[1] ?? "");
|
|
6669
|
+
if (!sessionId) {
|
|
6670
|
+
sendJson2(response, 400, { error: "Invalid session id." });
|
|
6671
|
+
return;
|
|
6672
|
+
}
|
|
6673
|
+
try {
|
|
6674
|
+
const result = renderSession(cwd, sessionId);
|
|
6675
|
+
sendJson2(response, 200, {
|
|
6676
|
+
rendered: true,
|
|
6677
|
+
sessionId: result.sessionId,
|
|
6678
|
+
sessionPath: result.sessionPath,
|
|
6679
|
+
files: [`${result.sessionPath}/index.md`, `${result.sessionPath}/transcript.md`]
|
|
6680
|
+
});
|
|
6681
|
+
} catch (error) {
|
|
6682
|
+
sendJson2(response, 404, { error: error instanceof Error ? error.message : String(error) });
|
|
6683
|
+
}
|
|
6684
|
+
return;
|
|
6685
|
+
}
|
|
6618
6686
|
sendJson2(response, 404, { error: "Not found." });
|
|
6619
6687
|
}
|
|
6620
6688
|
function listen2(server, host, port) {
|