heyspex 0.2.5 → 0.2.7
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/.claude-plugin/marketplace.json +1 -1
- package/bin/hs.mjs +349 -38
- package/bin/spexcode.mjs +31 -0
- package/dev-factory/lib/dispatch-guard.mjs +75 -0
- package/dev-factory/lib/local-firecrawl.mjs +294 -0
- package/dev-factory/lib/runner-path.mjs +51 -0
- package/dev-factory/lib/seat-context.mjs +20 -4
- package/dev-factory/model-catalog.json +222 -222
- package/dev-factory/spexcrawl/firecrawl-cli.mjs +755 -0
- package/dev-factory/spexcrawl/spexcrawl-cli.mjs +734 -0
- package/dist/cli/hs-connect.mjs +40 -3
- package/dist/cli/hs-defer.mjs +3817 -3741
- package/dist/cli/hs-events.mjs +1296 -0
- package/dist/cli/hs-export-events.mjs +1252 -0
- package/dist/cli/hs-handoff.mjs +2576 -0
- package/dist/cli/hs-index-rebuild.mjs +228 -37
- package/dist/cli/hs-index-reconcile.mjs +231 -40
- package/dist/cli/hs-init.mjs +22 -3
- package/dist/cli/hs-install.mjs +22 -3
- package/dist/cli/hs-join.mjs +40 -3
- package/dist/cli/hs-next-launch.mjs +2777 -0
- package/dist/cli/hs-pin.mjs +1336 -0
- package/dist/cli/hs-prereq.mjs +1380 -0
- package/dist/cli/hs-revalidate.mjs +3257 -0
- package/dist/cli/hs-spawn.mjs +12403 -0
- package/dist/cli/hs-test.mjs +1046 -0
- package/dist/cli/hs-trash.mjs +362 -0
- package/dist/cli/hs-trust.mjs +197 -0
- package/dist/cli/hs-vault-pull.mjs +233 -42
- package/dist/cli/hs-vault-push.mjs +231 -40
- package/dist/cli/hs-vault.mjs +21 -7
- package/dist/cli/hs-workspace.mjs +19 -1
- package/dist/cli-templates/customer-vault/specs/entity-model.md +1728 -1728
- package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +464 -464
- package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -122
- package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +46 -46
- package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +530 -530
- package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -83
- package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -28
- package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -62
- package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -29
- package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -30
- package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -29
- package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -70
- package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -35
- package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -27
- package/dist/cli-templates/harness-commands/claude/hs-res.md +83 -63
- package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -23
- package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -28
- package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -32
- package/dist/cli-templates/harness-commands/claude/prototype.md +91 -91
- package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +22 -22
- package/dist/cli-templates/harness-commands/cursor/hs-capture.md +56 -56
- package/dist/cli-templates/harness-commands/cursor/hs-defer.md +23 -23
- package/dist/cli-templates/harness-commands/cursor/hs-ground.md +24 -24
- package/dist/cli-templates/harness-commands/cursor/hs-next.md +23 -23
- package/dist/cli-templates/harness-commands/cursor/hs-promote.md +64 -64
- package/dist/cli-templates/harness-commands/cursor/hs-push.md +29 -29
- package/dist/cli-templates/harness-commands/cursor/hs-qc.md +21 -21
- package/dist/cli-templates/harness-commands/cursor/hs-res.md +78 -58
- package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +17 -17
- package/dist/cli-templates/harness-commands/cursor/hs-view.md +23 -23
- package/dist/cli-templates/harness-commands/cursor/kill-ports.md +26 -26
- package/dist/cli-templates/harness-commands/cursor/prototype.md +86 -86
- package/docs/copilot-plugin-install.md +9 -2
- package/docs/mcp-client-config.md +6 -0
- package/package.json +266 -257
- package/plugins/heyspex/.claude-plugin/plugin.json +1 -1
- package/plugins/heyspex/.cursor-plugin/plugin.json +1 -1
- package/plugins/heyspex/README.md +6 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +17 -0
- package/plugins/heyspex/hooks/hooks.json +418 -418
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +2 -2
- package/scripts/claude-hooks/wip-checkpoint.mjs +17 -2
- package/scripts/claude-statusline/statusline-command.mjs +287 -27
- package/scripts/hs-companion.mjs +41 -3
- package/scripts/install-claude-code-hooks.mjs +104 -3
- package/scripts/install-copilot-hooks.mjs +21 -1
- package/scripts/install-cursor-hooks.mjs +4 -3
- package/scripts/lib/capture-execution-guard.mjs +221 -0
- package/scripts/lib/companion-install.mjs +768 -0
- package/scripts/lib/customer-kit.mjs +53 -3
- package/scripts/lib/hs-companion-settings.mjs +26 -0
- package/scripts/lib/hs-source-push.mjs +386 -386
- package/scripts/record-grounding.mjs +38 -0
- package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -29
- package/spexharness/src/adapters/copilot-models.mjs +179 -0
- package/spexharness/src/adapters/harness-detect.mjs +148 -0
- package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -132
- package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +153 -125
- package/spexharness/src/seat-context.mjs +10 -5
- package/spexharness/src/session-bootstrap.mjs +6 -3
- package/vendor/heyspex-mcp/cli.mjs +6 -1
- package/vendor/heyspex-mcp/config-seed.yaml +15 -15
- package/vendor/heyspex-mcp/dev-factory-overlay.mjs +142 -0
- package/vendor/heyspex-mcp/http-transport.mjs +1 -1
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -523
- package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -1708
- package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -327
- package/vendor/heyspex-mcp/procedure-tools.mjs +1209 -1181
- package/vendor/heyspex-mcp/research-tools.mjs +22 -2
- package/vendor/heyspex-mcp/seat-assign-cli.mjs +242 -0
- package/vendor/heyspex-mcp/seat-assignment-rules.mjs +96 -0
- package/vendor/heyspex-mcp/seat-assignments-client.mjs +265 -0
- package/vendor/heyspex-mcp/seat-defaults-cli.mjs +45 -0
- package/vendor/heyspex-mcp/seat-defaults.mjs +232 -0
- package/vendor/heyspex-mcp/seat-identity.mjs +171 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +37 -23
- package/vendor/heyspex-mcp/vault-io.mjs +720 -720
- package/bin/postinstall.mjs +0 -88
|
@@ -1073,10 +1073,10 @@ var require_stringify = __commonJS({
|
|
|
1073
1073
|
data = Object.assign({}, file.data, data);
|
|
1074
1074
|
const open = opts.delimiters[0];
|
|
1075
1075
|
const close = opts.delimiters[1];
|
|
1076
|
-
const
|
|
1076
|
+
const matter5 = engine.stringify(data, options2).trim();
|
|
1077
1077
|
let buf = "";
|
|
1078
|
-
if (
|
|
1079
|
-
buf = newline(open) + newline(
|
|
1078
|
+
if (matter5 !== "{}") {
|
|
1079
|
+
buf = newline(open) + newline(matter5) + newline(close);
|
|
1080
1080
|
}
|
|
1081
1081
|
if (typeof file.excerpt === "string" && file.excerpt !== "") {
|
|
1082
1082
|
if (str2.indexOf(file.excerpt.trim()) === -1) {
|
|
@@ -1182,19 +1182,19 @@ var require_gray_matter = __commonJS({
|
|
|
1182
1182
|
var toFile = require_to_file();
|
|
1183
1183
|
var parse2 = require_parse();
|
|
1184
1184
|
var utils = require_utils();
|
|
1185
|
-
function
|
|
1185
|
+
function matter5(input, options2) {
|
|
1186
1186
|
if (input === "") {
|
|
1187
1187
|
return { data: {}, content: input, excerpt: "", orig: input };
|
|
1188
1188
|
}
|
|
1189
1189
|
let file = toFile(input);
|
|
1190
|
-
const cached =
|
|
1190
|
+
const cached = matter5.cache[file.content];
|
|
1191
1191
|
if (!options2) {
|
|
1192
1192
|
if (cached) {
|
|
1193
1193
|
file = Object.assign({}, cached);
|
|
1194
1194
|
file.orig = cached.orig;
|
|
1195
1195
|
return file;
|
|
1196
1196
|
}
|
|
1197
|
-
|
|
1197
|
+
matter5.cache[file.content] = file;
|
|
1198
1198
|
}
|
|
1199
1199
|
return parseMatter(file, options2);
|
|
1200
1200
|
}
|
|
@@ -1216,7 +1216,7 @@ var require_gray_matter = __commonJS({
|
|
|
1216
1216
|
}
|
|
1217
1217
|
str2 = str2.slice(openLen);
|
|
1218
1218
|
const len = str2.length;
|
|
1219
|
-
const language =
|
|
1219
|
+
const language = matter5.language(str2, opts);
|
|
1220
1220
|
if (language.name) {
|
|
1221
1221
|
file.language = language.name;
|
|
1222
1222
|
str2 = str2.slice(language.raw.length);
|
|
@@ -1251,24 +1251,24 @@ var require_gray_matter = __commonJS({
|
|
|
1251
1251
|
}
|
|
1252
1252
|
return file;
|
|
1253
1253
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
if (typeof file === "string") file =
|
|
1254
|
+
matter5.engines = engines2;
|
|
1255
|
+
matter5.stringify = function(file, data, options2) {
|
|
1256
|
+
if (typeof file === "string") file = matter5(file, options2);
|
|
1257
1257
|
return stringify(file, data, options2);
|
|
1258
1258
|
};
|
|
1259
|
-
|
|
1259
|
+
matter5.read = function(filepath, options2) {
|
|
1260
1260
|
const str2 = fs12.readFileSync(filepath, "utf8");
|
|
1261
|
-
const file =
|
|
1261
|
+
const file = matter5(str2, options2);
|
|
1262
1262
|
file.path = filepath;
|
|
1263
1263
|
return file;
|
|
1264
1264
|
};
|
|
1265
|
-
|
|
1265
|
+
matter5.test = function(str2, options2) {
|
|
1266
1266
|
return utils.startsWith(str2, defaults(options2).delimiters[0]);
|
|
1267
1267
|
};
|
|
1268
|
-
|
|
1268
|
+
matter5.language = function(str2, options2) {
|
|
1269
1269
|
const opts = defaults(options2);
|
|
1270
1270
|
const open = opts.delimiters[0];
|
|
1271
|
-
if (
|
|
1271
|
+
if (matter5.test(str2)) {
|
|
1272
1272
|
str2 = str2.slice(open.length);
|
|
1273
1273
|
}
|
|
1274
1274
|
const language = str2.slice(0, str2.search(/\r?\n/));
|
|
@@ -1277,11 +1277,11 @@ var require_gray_matter = __commonJS({
|
|
|
1277
1277
|
name: language ? language.trim() : ""
|
|
1278
1278
|
};
|
|
1279
1279
|
};
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1280
|
+
matter5.cache = {};
|
|
1281
|
+
matter5.clearCache = function() {
|
|
1282
|
+
matter5.cache = {};
|
|
1283
1283
|
};
|
|
1284
|
-
module2.exports =
|
|
1284
|
+
module2.exports = matter5;
|
|
1285
1285
|
}
|
|
1286
1286
|
});
|
|
1287
1287
|
|
|
@@ -1364,7 +1364,7 @@ var init_interfaces = __esm({
|
|
|
1364
1364
|
});
|
|
1365
1365
|
|
|
1366
1366
|
// spex-console/src/lib/db/schema/postgres.ts
|
|
1367
|
-
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
1367
|
+
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, seatAssignments, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
1368
1368
|
var init_postgres = __esm({
|
|
1369
1369
|
"spex-console/src/lib/db/schema/postgres.ts"() {
|
|
1370
1370
|
"use strict";
|
|
@@ -2314,6 +2314,24 @@ var init_postgres = __esm({
|
|
|
2314
2314
|
},
|
|
2315
2315
|
(table) => [primaryKey({ columns: [table.userId, table.vaultId, table.namespace] })]
|
|
2316
2316
|
);
|
|
2317
|
+
seatAssignments = pgTable(
|
|
2318
|
+
"seat_assignments",
|
|
2319
|
+
{
|
|
2320
|
+
accountId: text("account_id").notNull(),
|
|
2321
|
+
vaultId: text("vault_id").notNull(),
|
|
2322
|
+
harness: text("harness").notNull(),
|
|
2323
|
+
seatId: text("seat_id").notNull(),
|
|
2324
|
+
model: text("model").notNull(),
|
|
2325
|
+
// Set when a launch reported the harness REFUSED this model and the run fell
|
|
2326
|
+
// back to auto (Copilot's `heyspex.copilot_model_fallback` event, HS-F4UM);
|
|
2327
|
+
// cleared whenever the user sets a new model.
|
|
2328
|
+
overrideRejectedAt: timestamp("override_rejected_at", { withTimezone: true }),
|
|
2329
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().default(sql`now()`)
|
|
2330
|
+
},
|
|
2331
|
+
(table) => [
|
|
2332
|
+
primaryKey({ columns: [table.accountId, table.vaultId, table.harness, table.seatId] })
|
|
2333
|
+
]
|
|
2334
|
+
);
|
|
2317
2335
|
wipLedger = pgTable(
|
|
2318
2336
|
"wip_ledger",
|
|
2319
2337
|
{
|
|
@@ -3068,11 +3086,12 @@ function getPostgresAdminDb() {
|
|
|
3068
3086
|
function inertClient() {
|
|
3069
3087
|
return false;
|
|
3070
3088
|
}
|
|
3071
|
-
var isNeonPool;
|
|
3089
|
+
var isNeonPool, registerVaultScopedDbAccessor;
|
|
3072
3090
|
var init_postgres_client_cli_shim = __esm({
|
|
3073
3091
|
"dist/cli/._postgres-client.cli-shim.mjs"() {
|
|
3074
3092
|
"use strict";
|
|
3075
3093
|
isNeonPool = inertClient;
|
|
3094
|
+
registerVaultScopedDbAccessor = inertClient;
|
|
3076
3095
|
}
|
|
3077
3096
|
});
|
|
3078
3097
|
|
|
@@ -3323,6 +3342,141 @@ var init_clients = __esm({
|
|
|
3323
3342
|
}
|
|
3324
3343
|
});
|
|
3325
3344
|
|
|
3345
|
+
// spex-console/src/lib/rate-limits.ts
|
|
3346
|
+
var RATE_LIMIT_BUDGETS;
|
|
3347
|
+
var init_rate_limits = __esm({
|
|
3348
|
+
"spex-console/src/lib/rate-limits.ts"() {
|
|
3349
|
+
"use strict";
|
|
3350
|
+
RATE_LIMIT_BUDGETS = {
|
|
3351
|
+
mcp_tool_calls: { daily: 500, hourly: 125 },
|
|
3352
|
+
spec_writes: { daily: 100, hourly: 25 },
|
|
3353
|
+
capture_sessions: { daily: 20, hourly: 5 },
|
|
3354
|
+
// Paul's Advocate free-text chat ([[HS-4YYB-XEBI-TASK-paul-s-advocate-answers-real-questions]]):
|
|
3355
|
+
// a public YC reviewer can otherwise run up LLM spend on an unauthenticated-feeling
|
|
3356
|
+
// widget. 30/hour matches the builder brief's "e.g. 30 messages/hour" starting point;
|
|
3357
|
+
// daily is 4x hourly (looser than the 25%-of-daily pattern above — a reviewer chatting
|
|
3358
|
+
// steadily through a demo session should not get cut off mid-conversation).
|
|
3359
|
+
advocate_chat: { daily: 120, hourly: 30 }
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
});
|
|
3363
|
+
|
|
3364
|
+
// spex-console/src/lib/plan-tier.ts
|
|
3365
|
+
function scaledBudgets(multiplier) {
|
|
3366
|
+
const out = {};
|
|
3367
|
+
for (const [bucket, budget] of Object.entries(RATE_LIMIT_BUDGETS)) {
|
|
3368
|
+
out[bucket] = {
|
|
3369
|
+
daily: Math.round(budget.daily * multiplier),
|
|
3370
|
+
hourly: Math.round(budget.hourly * multiplier)
|
|
3371
|
+
};
|
|
3372
|
+
}
|
|
3373
|
+
return Object.freeze(out);
|
|
3374
|
+
}
|
|
3375
|
+
var PLAN_TIER_RATE_LIMIT_MULTIPLIER, PLAN_TIER_LIMITS;
|
|
3376
|
+
var init_plan_tier = __esm({
|
|
3377
|
+
"spex-console/src/lib/plan-tier.ts"() {
|
|
3378
|
+
"use strict";
|
|
3379
|
+
init_sql_orm_inert_cli_shim();
|
|
3380
|
+
init_postgres_client_cli_shim();
|
|
3381
|
+
init_postgres();
|
|
3382
|
+
init_rate_limits();
|
|
3383
|
+
PLAN_TIER_RATE_LIMIT_MULTIPLIER = {
|
|
3384
|
+
free: 1,
|
|
3385
|
+
pro: 4,
|
|
3386
|
+
enterprise: 20
|
|
3387
|
+
};
|
|
3388
|
+
PLAN_TIER_LIMITS = {
|
|
3389
|
+
free: {
|
|
3390
|
+
statement_timeout_ms: 5e3,
|
|
3391
|
+
read_work_mem: "4MB",
|
|
3392
|
+
rate_limit_budgets: scaledBudgets(PLAN_TIER_RATE_LIMIT_MULTIPLIER.free)
|
|
3393
|
+
},
|
|
3394
|
+
pro: {
|
|
3395
|
+
statement_timeout_ms: 15e3,
|
|
3396
|
+
read_work_mem: "16MB",
|
|
3397
|
+
rate_limit_budgets: scaledBudgets(PLAN_TIER_RATE_LIMIT_MULTIPLIER.pro)
|
|
3398
|
+
},
|
|
3399
|
+
enterprise: {
|
|
3400
|
+
statement_timeout_ms: 3e4,
|
|
3401
|
+
read_work_mem: "64MB",
|
|
3402
|
+
rate_limit_budgets: scaledBudgets(PLAN_TIER_RATE_LIMIT_MULTIPLIER.enterprise)
|
|
3403
|
+
}
|
|
3404
|
+
};
|
|
3405
|
+
}
|
|
3406
|
+
});
|
|
3407
|
+
|
|
3408
|
+
// spex-console/src/lib/db/clients/vault-router.ts
|
|
3409
|
+
import { existsSync as existsSync8, readFileSync as readFileSync13 } from "node:fs";
|
|
3410
|
+
import { homedir as homedir10 } from "node:os";
|
|
3411
|
+
import { join as join11 } from "node:path";
|
|
3412
|
+
var CREDENTIALS_PATH, ROUTER_KEY, globalRouter, router;
|
|
3413
|
+
var init_vault_router = __esm({
|
|
3414
|
+
"spex-console/src/lib/db/clients/vault-router.ts"() {
|
|
3415
|
+
"use strict";
|
|
3416
|
+
init_sql_orm_inert_cli_shim();
|
|
3417
|
+
init_sql_orm_inert_cli_shim();
|
|
3418
|
+
init_postgres();
|
|
3419
|
+
init_postgres_client_cli_shim();
|
|
3420
|
+
CREDENTIALS_PATH = join11(homedir10(), ".heyspex", "credentials.yaml");
|
|
3421
|
+
ROUTER_KEY = Symbol.for("heyspex.vaultRouter");
|
|
3422
|
+
globalRouter = globalThis;
|
|
3423
|
+
if (!globalRouter[ROUTER_KEY]) {
|
|
3424
|
+
globalRouter[ROUTER_KEY] = {
|
|
3425
|
+
dedicated: /* @__PURE__ */ new Map(),
|
|
3426
|
+
refCache: /* @__PURE__ */ new Map(),
|
|
3427
|
+
warnedSchemaMissing: false
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
router = globalRouter[ROUTER_KEY];
|
|
3431
|
+
}
|
|
3432
|
+
});
|
|
3433
|
+
|
|
3434
|
+
// spex-console/src/lib/db/clients/vault-scope.ts
|
|
3435
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3436
|
+
function warnScopeClosedOnce(ctx) {
|
|
3437
|
+
if (ctx.warnedClosed) return;
|
|
3438
|
+
ctx.warnedClosed = true;
|
|
3439
|
+
console.warn(
|
|
3440
|
+
`[vault-scope] db use after vault scope closed; falling back to the pool connection (unscoped) (vaultId: ${ctx.vaultId})`
|
|
3441
|
+
);
|
|
3442
|
+
}
|
|
3443
|
+
function handleScopeClosedAccess(ctx) {
|
|
3444
|
+
if (ctx.onStaleUse === "throw") {
|
|
3445
|
+
throw new VaultScopeClosedError(ctx.vaultId);
|
|
3446
|
+
}
|
|
3447
|
+
warnScopeClosedOnce(ctx);
|
|
3448
|
+
}
|
|
3449
|
+
var VaultScopeClosedError, vaultScopeStorage;
|
|
3450
|
+
var init_vault_scope = __esm({
|
|
3451
|
+
"spex-console/src/lib/db/clients/vault-scope.ts"() {
|
|
3452
|
+
"use strict";
|
|
3453
|
+
init_sql_orm_inert_cli_shim();
|
|
3454
|
+
init_plan_tier();
|
|
3455
|
+
init_postgres_client_cli_shim();
|
|
3456
|
+
init_vault_router();
|
|
3457
|
+
VaultScopeClosedError = class extends Error {
|
|
3458
|
+
vaultId;
|
|
3459
|
+
constructor(vaultId) {
|
|
3460
|
+
super(
|
|
3461
|
+
`Vault scope for "${vaultId}" is closed; this path opted into onStaleUseAfterClose: "throw", so a db handle used after the scope's transaction settled fails loudly instead of silently falling back to the unscoped pool connection.`
|
|
3462
|
+
);
|
|
3463
|
+
this.name = "VaultScopeClosedError";
|
|
3464
|
+
this.vaultId = vaultId;
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3467
|
+
vaultScopeStorage = new AsyncLocalStorage();
|
|
3468
|
+
registerVaultScopedDbAccessor(() => {
|
|
3469
|
+
const ctx = vaultScopeStorage.getStore();
|
|
3470
|
+
if (!ctx) return null;
|
|
3471
|
+
if (ctx.closed) {
|
|
3472
|
+
handleScopeClosedAccess(ctx);
|
|
3473
|
+
return null;
|
|
3474
|
+
}
|
|
3475
|
+
return ctx.proxy;
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3478
|
+
});
|
|
3479
|
+
|
|
3326
3480
|
// spex-console/src/lib/scheduler/types.ts
|
|
3327
3481
|
var init_types2 = __esm({
|
|
3328
3482
|
"spex-console/src/lib/scheduler/types.ts"() {
|
|
@@ -3857,10 +4011,45 @@ var init_config = __esm({
|
|
|
3857
4011
|
}
|
|
3858
4012
|
});
|
|
3859
4013
|
|
|
3860
|
-
// spex-console/src/lib/
|
|
4014
|
+
// spex-console/src/lib/safe-yaml.ts
|
|
3861
4015
|
import yaml2 from "js-yaml";
|
|
4016
|
+
function dropUndefinedDeep(value) {
|
|
4017
|
+
if (Array.isArray(value)) {
|
|
4018
|
+
return value.filter((item) => item !== void 0).map((item) => dropUndefinedDeep(item));
|
|
4019
|
+
}
|
|
4020
|
+
if (value && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
|
|
4021
|
+
const out = {};
|
|
4022
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4023
|
+
if (v === void 0) continue;
|
|
4024
|
+
out[k] = dropUndefinedDeep(v);
|
|
4025
|
+
}
|
|
4026
|
+
return out;
|
|
4027
|
+
}
|
|
4028
|
+
return value;
|
|
4029
|
+
}
|
|
4030
|
+
function safeYamlDump(value, options2 = {}) {
|
|
4031
|
+
const { schema: _ignoredSchema, ...rest } = options2;
|
|
4032
|
+
const data = dropUndefinedDeep(value);
|
|
4033
|
+
if (grayMatterYamlStringify) return grayMatterYamlStringify(data, rest);
|
|
4034
|
+
return yaml2.dump(data, { ...rest, schema: SAFE_YAML_SCHEMA });
|
|
4035
|
+
}
|
|
4036
|
+
var import_gray_matter, SAFE_YAML_SCHEMA, grayMatterYamlStringify, YAML_FAILSAFE_SCHEMA;
|
|
4037
|
+
var init_safe_yaml = __esm({
|
|
4038
|
+
"spex-console/src/lib/safe-yaml.ts"() {
|
|
4039
|
+
"use strict";
|
|
4040
|
+
import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
4041
|
+
SAFE_YAML_SCHEMA = yaml2.DEFAULT_SAFE_SCHEMA ?? yaml2.DEFAULT_SCHEMA;
|
|
4042
|
+
grayMatterYamlStringify = (() => {
|
|
4043
|
+
const engine = import_gray_matter.default.engines?.yaml;
|
|
4044
|
+
return typeof engine?.stringify === "function" ? engine.stringify : void 0;
|
|
4045
|
+
})();
|
|
4046
|
+
YAML_FAILSAFE_SCHEMA = yaml2.FAILSAFE_SCHEMA;
|
|
4047
|
+
}
|
|
4048
|
+
});
|
|
4049
|
+
|
|
4050
|
+
// spex-console/src/lib/vault-frontmatter.ts
|
|
3862
4051
|
function normalizeFrontmatterForYaml(frontmatter) {
|
|
3863
|
-
const processed =
|
|
4052
|
+
const processed = dropUndefinedDeep(frontmatter);
|
|
3864
4053
|
for (const [key, value] of Object.entries(processed)) {
|
|
3865
4054
|
if (value instanceof Date) {
|
|
3866
4055
|
processed[key] = value.toISOString();
|
|
@@ -3869,20 +4058,21 @@ function normalizeFrontmatterForYaml(frontmatter) {
|
|
|
3869
4058
|
return processed;
|
|
3870
4059
|
}
|
|
3871
4060
|
function stringifySpecMarkdown(body, frontmatter) {
|
|
3872
|
-
const fm =
|
|
4061
|
+
const fm = safeYamlDump(normalizeFrontmatterForYaml(frontmatter), YAML_STRINGIFY_OPTIONS).trim();
|
|
3873
4062
|
return `---
|
|
3874
4063
|
${fm}
|
|
3875
4064
|
---
|
|
3876
4065
|
${body}`;
|
|
3877
4066
|
}
|
|
3878
4067
|
function parseSpecMarkdown(raw) {
|
|
3879
|
-
return (0,
|
|
4068
|
+
return (0, import_gray_matter2.default)(raw);
|
|
3880
4069
|
}
|
|
3881
|
-
var
|
|
4070
|
+
var import_gray_matter2, YAML_STRINGIFY_OPTIONS;
|
|
3882
4071
|
var init_vault_frontmatter = __esm({
|
|
3883
4072
|
"spex-console/src/lib/vault-frontmatter.ts"() {
|
|
3884
4073
|
"use strict";
|
|
3885
|
-
|
|
4074
|
+
import_gray_matter2 = __toESM(require_gray_matter(), 1);
|
|
4075
|
+
init_safe_yaml();
|
|
3886
4076
|
YAML_STRINGIFY_OPTIONS = {
|
|
3887
4077
|
quotingType: '"',
|
|
3888
4078
|
skipInvalid: true,
|
|
@@ -4777,11 +4967,11 @@ var init_guardrail_naming = __esm({
|
|
|
4777
4967
|
import { createHash as createHash3 } from "node:crypto";
|
|
4778
4968
|
import { promises as fs6 } from "node:fs";
|
|
4779
4969
|
import path9 from "node:path";
|
|
4780
|
-
var
|
|
4970
|
+
var import_gray_matter3;
|
|
4781
4971
|
var init_parser = __esm({
|
|
4782
4972
|
"spex-console/src/lib/indexer/parser.ts"() {
|
|
4783
4973
|
"use strict";
|
|
4784
|
-
|
|
4974
|
+
import_gray_matter3 = __toESM(require_gray_matter(), 1);
|
|
4785
4975
|
init_vault_id();
|
|
4786
4976
|
init_vault_shared();
|
|
4787
4977
|
}
|
|
@@ -4920,12 +5110,12 @@ var init_linkage_validation = __esm({
|
|
|
4920
5110
|
});
|
|
4921
5111
|
|
|
4922
5112
|
// spex-console/src/lib/perf-timing.ts
|
|
4923
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5113
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
4924
5114
|
var storage;
|
|
4925
5115
|
var init_perf_timing = __esm({
|
|
4926
5116
|
"spex-console/src/lib/perf-timing.ts"() {
|
|
4927
5117
|
"use strict";
|
|
4928
|
-
storage = new
|
|
5118
|
+
storage = new AsyncLocalStorage2();
|
|
4929
5119
|
}
|
|
4930
5120
|
});
|
|
4931
5121
|
|
|
@@ -4947,12 +5137,12 @@ var init_planning_flow_model = __esm({
|
|
|
4947
5137
|
});
|
|
4948
5138
|
|
|
4949
5139
|
// spex-console/src/lib/request-memo.ts
|
|
4950
|
-
import { AsyncLocalStorage as
|
|
5140
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
4951
5141
|
var storage2;
|
|
4952
5142
|
var init_request_memo = __esm({
|
|
4953
5143
|
"spex-console/src/lib/request-memo.ts"() {
|
|
4954
5144
|
"use strict";
|
|
4955
|
-
storage2 = new
|
|
5145
|
+
storage2 = new AsyncLocalStorage3();
|
|
4956
5146
|
}
|
|
4957
5147
|
});
|
|
4958
5148
|
|
|
@@ -5200,18 +5390,17 @@ var init_search_body_hit = __esm({
|
|
|
5200
5390
|
|
|
5201
5391
|
// spex-console/src/lib/vault.ts
|
|
5202
5392
|
import { spawn } from "node:child_process";
|
|
5203
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
5393
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync14, statSync as statSync5 } from "node:fs";
|
|
5204
5394
|
import { promises as fs9 } from "node:fs";
|
|
5205
5395
|
import path14 from "node:path";
|
|
5206
|
-
import yaml3 from "js-yaml";
|
|
5207
5396
|
function vaultRoot() {
|
|
5208
5397
|
return getActiveSpecsDir();
|
|
5209
5398
|
}
|
|
5210
|
-
var
|
|
5399
|
+
var import_gray_matter4, VAULT_CACHE_TTL_WATCHED_MS, VAULT_CACHE_KEY, vaultCacheStore, VAULT_CACHE_DELTA_LISTENERS_KEY, vaultCacheDeltaListeners, SEARCH_TEXT_KEY, searchTextStore, VAULT_SNAPSHOT_KEY, vaultSnapshotStore;
|
|
5211
5400
|
var init_vault = __esm({
|
|
5212
5401
|
"spex-console/src/lib/vault.ts"() {
|
|
5213
5402
|
"use strict";
|
|
5214
|
-
|
|
5403
|
+
import_gray_matter4 = __toESM(require_gray_matter(), 1);
|
|
5215
5404
|
init_diagnose_skeleton();
|
|
5216
5405
|
init_auth();
|
|
5217
5406
|
init_capture_vault();
|
|
@@ -5222,6 +5411,7 @@ var init_vault = __esm({
|
|
|
5222
5411
|
init_skips();
|
|
5223
5412
|
init_clients();
|
|
5224
5413
|
init_postgres_client_cli_shim();
|
|
5414
|
+
init_vault_scope();
|
|
5225
5415
|
init_helpers();
|
|
5226
5416
|
init_index_write_service();
|
|
5227
5417
|
init_spec_read_service();
|
|
@@ -5238,6 +5428,7 @@ var init_vault = __esm({
|
|
|
5238
5428
|
init_planning_flow_model();
|
|
5239
5429
|
init_request_memo();
|
|
5240
5430
|
init_review_mode();
|
|
5431
|
+
init_safe_yaml();
|
|
5241
5432
|
init_active_milestone();
|
|
5242
5433
|
init_area();
|
|
5243
5434
|
init_claim_eligibility();
|
|
@@ -5322,7 +5513,7 @@ var init_vault = __esm({
|
|
|
5322
5513
|
});
|
|
5323
5514
|
|
|
5324
5515
|
// spex-console/bin/hs-vault-push.ts
|
|
5325
|
-
import { readFileSync as
|
|
5516
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
5326
5517
|
import path15 from "node:path";
|
|
5327
5518
|
import process4 from "node:process";
|
|
5328
5519
|
|
|
@@ -5706,7 +5897,7 @@ async function writeDirtyMarker(vaultRoot2, id, now = () => /* @__PURE__ */ new
|
|
|
5706
5897
|
}
|
|
5707
5898
|
|
|
5708
5899
|
// spex-console/src/lib/vault-sync/pull-io.ts
|
|
5709
|
-
import { promises as fs10, readFileSync as
|
|
5900
|
+
import { promises as fs10, readFileSync as readFileSync15 } from "node:fs";
|
|
5710
5901
|
import { EOL } from "node:os";
|
|
5711
5902
|
import nodePath3 from "node:path";
|
|
5712
5903
|
|
|
@@ -6352,7 +6543,7 @@ function runEntry(name, main2, options2 = {}) {
|
|
|
6352
6543
|
// spex-console/bin/hs-vault-push.ts
|
|
6353
6544
|
function readMarkerVaultId(vaultRoot2) {
|
|
6354
6545
|
try {
|
|
6355
|
-
return parseVaultId(
|
|
6546
|
+
return parseVaultId(readFileSync16(path15.join(vaultRoot2, "heyspex.yaml"), "utf8"));
|
|
6356
6547
|
} catch {
|
|
6357
6548
|
return null;
|
|
6358
6549
|
}
|
package/dist/cli/hs-vault.mjs
CHANGED
|
@@ -1107,7 +1107,7 @@ var init_interfaces = __esm({
|
|
|
1107
1107
|
});
|
|
1108
1108
|
|
|
1109
1109
|
// spex-console/src/lib/db/schema/postgres.ts
|
|
1110
|
-
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
1110
|
+
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, seatAssignments, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
1111
1111
|
var init_postgres = __esm({
|
|
1112
1112
|
"spex-console/src/lib/db/schema/postgres.ts"() {
|
|
1113
1113
|
"use strict";
|
|
@@ -2057,6 +2057,24 @@ var init_postgres = __esm({
|
|
|
2057
2057
|
},
|
|
2058
2058
|
(table) => [primaryKey({ columns: [table.userId, table.vaultId, table.namespace] })]
|
|
2059
2059
|
);
|
|
2060
|
+
seatAssignments = pgTable(
|
|
2061
|
+
"seat_assignments",
|
|
2062
|
+
{
|
|
2063
|
+
accountId: text("account_id").notNull(),
|
|
2064
|
+
vaultId: text("vault_id").notNull(),
|
|
2065
|
+
harness: text("harness").notNull(),
|
|
2066
|
+
seatId: text("seat_id").notNull(),
|
|
2067
|
+
model: text("model").notNull(),
|
|
2068
|
+
// Set when a launch reported the harness REFUSED this model and the run fell
|
|
2069
|
+
// back to auto (Copilot's `heyspex.copilot_model_fallback` event, HS-F4UM);
|
|
2070
|
+
// cleared whenever the user sets a new model.
|
|
2071
|
+
overrideRejectedAt: timestamp("override_rejected_at", { withTimezone: true }),
|
|
2072
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().default(sql`now()`)
|
|
2073
|
+
},
|
|
2074
|
+
(table) => [
|
|
2075
|
+
primaryKey({ columns: [table.accountId, table.vaultId, table.harness, table.seatId] })
|
|
2076
|
+
]
|
|
2077
|
+
);
|
|
2060
2078
|
wipLedger = pgTable(
|
|
2061
2079
|
"wip_ledger",
|
|
2062
2080
|
{
|
|
@@ -4519,9 +4537,7 @@ async function listVaultsNeon(accountId2, deps = {}) {
|
|
|
4519
4537
|
githubRemote: vaults.githubRemote,
|
|
4520
4538
|
schemaVersion: vaults.schemaVersion,
|
|
4521
4539
|
createdAt: vaults.createdAt,
|
|
4522
|
-
archived: vaults.archived
|
|
4523
|
-
// [[HS-RRCG-8QDO-DIAG-a-shared-vault-is-labelled-read-only-in]] -- the grant's access level must reach the client.
|
|
4524
|
-
access: vaultGrants.access
|
|
4540
|
+
archived: vaults.archived
|
|
4525
4541
|
}).from(vaultGrants).innerJoin(vaults, eq(vaults.id, vaultGrants.vaultId)).where(and(eq(vaultGrants.accountId, accountId2), ne(vaults.accountId, accountId2)));
|
|
4526
4542
|
const toRecord = (r, granted) => ({
|
|
4527
4543
|
id: r.id,
|
|
@@ -4540,9 +4556,7 @@ async function listVaultsNeon(accountId2, deps = {}) {
|
|
|
4540
4556
|
// `GET /api/vaults` kept listing the vault with no `archived` field.
|
|
4541
4557
|
archived: r.archived,
|
|
4542
4558
|
...r.githubRemote ? { github_remote: r.githubRemote } : {},
|
|
4543
|
-
...granted ? { granted: true } : {}
|
|
4544
|
-
// [[HS-RRCG-8QDO-DIAG-a-shared-vault-is-labelled-read-only-in]]: granted rows only; unknown = read.
|
|
4545
|
-
...granted ? { access: r.access === "write" ? "write" : "read" } : {}
|
|
4559
|
+
...granted ? { granted: true } : {}
|
|
4546
4560
|
});
|
|
4547
4561
|
return [
|
|
4548
4562
|
...ownedRows.map((r) => toRecord(r, false)),
|
|
@@ -376,7 +376,7 @@ var init_interfaces = __esm({
|
|
|
376
376
|
});
|
|
377
377
|
|
|
378
378
|
// spex-console/src/lib/db/schema/postgres.ts
|
|
379
|
-
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
379
|
+
var edgeTypeEnum, validationSeverityEnum, outboxOpEnum, tsvector, specs, tags, edges, wikilinks, specLinks, aliases, validationIssues, indexMeta, frontmatterFields, eventOutbox, captureSessions, handoffContext, claimEventKindEnum, activeClaimStatusEnum, pendingReasonEnum, focusEventKindEnum, specEventKindEnum, focusPin, captureFocusPin, captureFocusSelection, focusSelection, focusSkips, activeClaims, claimWaiters, fileClaims, claimEvents, focusEvents, focusAreas, focusAreasEvents, specEvents, rateLimitBuckets, userVaults, milestoneSnapshots, modelRegistryEntries, launchIntentStatusEnum, launchIntents, companionRelayPresence, companionSettingsStore, consoleSettingsStore, seatAssignments, wipLedger, wipLedgerArchive, gatherResults, agentSessions, usageEvents, streamEvents, jobStreams, resolutionStatusEnum, resolutionFocusPin, resolutionLedger, workspaces, vaults, accountSettings, vaultGrants, pendingVaultGrants, githubInstallations, fleetMachines, fleetTasks, fleetResults, userApiKeys, apiKeys, mcpSessions, pairingCodes, companionSessions, inviteRequests, notifications, webhookIngestions, specSettlements, sessionBranchDeclarations;
|
|
380
380
|
var init_postgres = __esm({
|
|
381
381
|
"spex-console/src/lib/db/schema/postgres.ts"() {
|
|
382
382
|
"use strict";
|
|
@@ -1326,6 +1326,24 @@ var init_postgres = __esm({
|
|
|
1326
1326
|
},
|
|
1327
1327
|
(table) => [primaryKey({ columns: [table.userId, table.vaultId, table.namespace] })]
|
|
1328
1328
|
);
|
|
1329
|
+
seatAssignments = pgTable(
|
|
1330
|
+
"seat_assignments",
|
|
1331
|
+
{
|
|
1332
|
+
accountId: text("account_id").notNull(),
|
|
1333
|
+
vaultId: text("vault_id").notNull(),
|
|
1334
|
+
harness: text("harness").notNull(),
|
|
1335
|
+
seatId: text("seat_id").notNull(),
|
|
1336
|
+
model: text("model").notNull(),
|
|
1337
|
+
// Set when a launch reported the harness REFUSED this model and the run fell
|
|
1338
|
+
// back to auto (Copilot's `heyspex.copilot_model_fallback` event, HS-F4UM);
|
|
1339
|
+
// cleared whenever the user sets a new model.
|
|
1340
|
+
overrideRejectedAt: timestamp("override_rejected_at", { withTimezone: true }),
|
|
1341
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().default(sql`now()`)
|
|
1342
|
+
},
|
|
1343
|
+
(table) => [
|
|
1344
|
+
primaryKey({ columns: [table.accountId, table.vaultId, table.harness, table.seatId] })
|
|
1345
|
+
]
|
|
1346
|
+
);
|
|
1329
1347
|
wipLedger = pgTable(
|
|
1330
1348
|
"wip_ledger",
|
|
1331
1349
|
{
|