@tablation/crew 0.50.2 → 0.50.3
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/cli.js +137 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2288,6 +2288,7 @@ function parseResolved(raw, m, where) {
|
|
|
2288
2288
|
contract: raw.contract ?? void 0,
|
|
2289
2289
|
...typeof raw.releaseSeat === "string" && raw.releaseSeat ? { releaseSeat: raw.releaseSeat } : {},
|
|
2290
2290
|
...typeof raw.releaseAgentId === "string" && raw.releaseAgentId ? { releaseAgentId: raw.releaseAgentId } : {},
|
|
2291
|
+
...typeof raw.role === "string" && raw.role ? { role: raw.role } : {},
|
|
2291
2292
|
...Object.keys(agentPersonas).length > 0 ? { agentPersonas } : {},
|
|
2292
2293
|
...Object.keys(agentSkills).length > 0 ? { agentSkills } : {}
|
|
2293
2294
|
};
|
|
@@ -7724,6 +7725,25 @@ async function fetchLatestHistoryId(route, agentsModelId, recordId, userAgent) {
|
|
|
7724
7725
|
return void 0;
|
|
7725
7726
|
}
|
|
7726
7727
|
}
|
|
7728
|
+
function isAdminRole(role) {
|
|
7729
|
+
return role === void 0 || role === "WORKSPACE_ADMIN" || role === "PLATFORM_ADMIN";
|
|
7730
|
+
}
|
|
7731
|
+
async function fetchKeyRole(route, userAgent) {
|
|
7732
|
+
if (!route.resolved) return void 0;
|
|
7733
|
+
try {
|
|
7734
|
+
const res = await fetch(`${route.baseUrl.replace(/\/+$/, "")}/api/auth/me?workspaceId=${route.resolved.workspaceId}`, {
|
|
7735
|
+
headers: { Authorization: `Bearer ${resolveApiKey(route)}`, "User-Agent": userAgent ?? "Mozilla/5.0 TablationCrewAgent/1.0" }
|
|
7736
|
+
});
|
|
7737
|
+
if (!res.ok) return void 0;
|
|
7738
|
+
const me = await res.json();
|
|
7739
|
+
return typeof me.role === "string" ? me.role : void 0;
|
|
7740
|
+
} catch {
|
|
7741
|
+
return void 0;
|
|
7742
|
+
}
|
|
7743
|
+
}
|
|
7744
|
+
function isForbidden(e) {
|
|
7745
|
+
return e instanceof TablationApiError && e.status === 403;
|
|
7746
|
+
}
|
|
7727
7747
|
function promptSourceFields(model, prompt) {
|
|
7728
7748
|
return model.fields?.some((f) => f.columnName === "prompt_baseline") ? { prompt_source: "crew", prompt_baseline: prompt } : {};
|
|
7729
7749
|
}
|
|
@@ -7767,6 +7787,16 @@ async function syncPersonas(route, opts) {
|
|
|
7767
7787
|
const name = PERSONA_NAME[role];
|
|
7768
7788
|
const defaultPrompt = personaDefaultPrompt(route.promptsDir, role);
|
|
7769
7789
|
const row = rows.find((r) => r.name === name);
|
|
7790
|
+
if (opts.readOnly) {
|
|
7791
|
+
if (!row) {
|
|
7792
|
+
outcomes.push({ role, action: "missing", agentId: "" });
|
|
7793
|
+
continue;
|
|
7794
|
+
}
|
|
7795
|
+
const prior = cache[role]?.agentId === row.id ? cache[role] : void 0;
|
|
7796
|
+
agentPersonas[role] = { agentId: row.id, lastSyncedUpdatedAt: prior?.lastSyncedUpdatedAt ?? row.updated_at, ...prior?.historyId ? { historyId: prior.historyId } : {} };
|
|
7797
|
+
outcomes.push({ role, action: "adopted", agentId: row.id });
|
|
7798
|
+
continue;
|
|
7799
|
+
}
|
|
7770
7800
|
if (!row) {
|
|
7771
7801
|
if (opts.dryRun) {
|
|
7772
7802
|
outcomes.push({ role, action: "created", agentId: "(dry run)" });
|
|
@@ -7868,35 +7898,70 @@ async function syncPersonas(route, opts) {
|
|
|
7868
7898
|
throw e;
|
|
7869
7899
|
}
|
|
7870
7900
|
}
|
|
7871
|
-
const crewLinks = opts.dryRun ? [] : await linkCrewSeats(route, client2, agentsModel.id, agentPersonas, opts.userAgent);
|
|
7872
|
-
const
|
|
7873
|
-
return {
|
|
7901
|
+
const crewLinks = opts.dryRun ? [] : await linkCrewSeats(route, client2, agentsModel.id, agentPersonas, opts.userAgent, opts.readOnly === true);
|
|
7902
|
+
const release = opts.dryRun ? { agentId: route.resolved.releaseAgentId } : await linkReleaseSeat(route, client2, agentsModel, opts.userAgent, opts.readOnly === true);
|
|
7903
|
+
return {
|
|
7904
|
+
outcomes,
|
|
7905
|
+
agentPersonas,
|
|
7906
|
+
crewLinks,
|
|
7907
|
+
...release.agentId ? { releaseAgentId: release.agentId } : {},
|
|
7908
|
+
...release.note ? { releaseNote: release.note } : {},
|
|
7909
|
+
...opts.readOnly ? { readOnly: true } : {}
|
|
7910
|
+
};
|
|
7874
7911
|
}
|
|
7875
|
-
async function linkReleaseSeat(route, client2, agentsModel, userAgent) {
|
|
7912
|
+
async function linkReleaseSeat(route, client2, agentsModel, userAgent, readOnly) {
|
|
7876
7913
|
const seatId = route.resolved.releaseSeat;
|
|
7877
|
-
if (!seatId) return
|
|
7914
|
+
if (!seatId) return {};
|
|
7878
7915
|
const rows = await client2.records.list(agentsModel.id, { limit: 200 });
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7916
|
+
let agentId = rows.find((r) => r.name === RELEASE_AGENT_NAME)?.id;
|
|
7917
|
+
if (!agentId) {
|
|
7918
|
+
if (readOnly) return { note: `Release: no "${RELEASE_AGENT_NAME}" Agents row in this workspace \u2014 writes as the ship until a workspace admin runs \`crew agents sync\`` };
|
|
7919
|
+
try {
|
|
7920
|
+
agentId = (await client2.records.create(agentsModel.id, {
|
|
7921
|
+
name: RELEASE_AGENT_NAME,
|
|
7922
|
+
prompt: RELEASE_AGENT_PROMPT,
|
|
7923
|
+
...promptSourceFields(agentsModel, RELEASE_AGENT_PROMPT)
|
|
7924
|
+
})).id;
|
|
7925
|
+
} catch (e) {
|
|
7926
|
+
if (isForbidden(e)) return { note: `Release: could not create the "${RELEASE_AGENT_NAME}" Agents row (${NO_WRITE_NOTE}) \u2014 writes as the ship` };
|
|
7927
|
+
throw e;
|
|
7928
|
+
}
|
|
7929
|
+
}
|
|
7884
7930
|
const crewModelId = route.resolved.models.crew;
|
|
7885
7931
|
const crewModel = await client2.dataModels.get(crewModelId);
|
|
7886
|
-
|
|
7932
|
+
let columnName;
|
|
7933
|
+
try {
|
|
7934
|
+
columnName = await ensureCrewAgentField(route, client2, crewModel, agentsModel.id, userAgent);
|
|
7935
|
+
} catch (e) {
|
|
7936
|
+
if (e instanceof CrewAgentFieldMissing) return { note: `Release: ${CREW_FIELD_MISSING_NOTE}` };
|
|
7937
|
+
throw e;
|
|
7938
|
+
}
|
|
7887
7939
|
const seatRow = await client2.records.get(crewModelId, seatId);
|
|
7888
7940
|
if (seatRow[CREW_AGENT_COLUMN] !== agentId) await client2.records.update(crewModelId, seatId, { [columnName]: agentId });
|
|
7889
|
-
return agentId;
|
|
7941
|
+
return { agentId };
|
|
7890
7942
|
}
|
|
7891
|
-
|
|
7943
|
+
var NO_WRITE_NOTE = "this key has no write access to the Agents table";
|
|
7944
|
+
var CREW_FIELD_MISSING_NOTE = "Crew table has no Agent field yet \u2014 a workspace admin's `crew agents sync` adds it";
|
|
7945
|
+
var CrewAgentFieldMissing = class extends Error {
|
|
7946
|
+
};
|
|
7947
|
+
async function linkCrewSeats(route, client2, agentsModelId, agentPersonas, userAgent, readOnly) {
|
|
7892
7948
|
const seats2 = route.resolved.seats;
|
|
7893
7949
|
const rolesWithSeats = ROLE_NAMES.filter((role) => seats2[role] && agentPersonas[role]);
|
|
7894
7950
|
if (rolesWithSeats.length === 0) {
|
|
7951
|
+
if (readOnly) return ROLE_NAMES.map((role) => ({ role, action: seats2[role] ? "no_agents_row" : "no_seat" }));
|
|
7895
7952
|
return ROLE_NAMES.map((role) => ({ role, action: seats2[role] ? "persona_diverged" : "no_seat" }));
|
|
7896
7953
|
}
|
|
7897
7954
|
const crewModelId = route.resolved.models.crew;
|
|
7898
7955
|
const crewModel = await client2.dataModels.get(crewModelId);
|
|
7899
|
-
|
|
7956
|
+
let columnName;
|
|
7957
|
+
try {
|
|
7958
|
+
columnName = await ensureCrewAgentField(route, client2, crewModel, agentsModelId, userAgent);
|
|
7959
|
+
} catch (e) {
|
|
7960
|
+
if (e instanceof CrewAgentFieldMissing) {
|
|
7961
|
+
return ROLE_NAMES.map((role) => ({ role, action: seats2[role] ? "no_agent_field" : "no_seat" }));
|
|
7962
|
+
}
|
|
7963
|
+
throw e;
|
|
7964
|
+
}
|
|
7900
7965
|
const outcomes = [];
|
|
7901
7966
|
for (const role of ROLE_NAMES) {
|
|
7902
7967
|
const seatId = seats2[role];
|
|
@@ -7906,7 +7971,7 @@ async function linkCrewSeats(route, client2, agentsModelId, agentPersonas, userA
|
|
|
7906
7971
|
continue;
|
|
7907
7972
|
}
|
|
7908
7973
|
if (!agentId) {
|
|
7909
|
-
outcomes.push({ role, action: "persona_diverged" });
|
|
7974
|
+
outcomes.push({ role, action: readOnly ? "no_agents_row" : "persona_diverged" });
|
|
7910
7975
|
continue;
|
|
7911
7976
|
}
|
|
7912
7977
|
const seatRow = await client2.records.get(crewModelId, seatId);
|
|
@@ -7947,6 +8012,7 @@ async function ensureCrewAgentField(route, client2, crewModel, agentsModelId, us
|
|
|
7947
8012
|
description: "The Agents-table row backing this seat's persona \u2014 set by `crew agents sync` (ISSUE-416), never edited by hand."
|
|
7948
8013
|
})
|
|
7949
8014
|
});
|
|
8015
|
+
if (createRes.status === 403) throw new CrewAgentFieldMissing();
|
|
7950
8016
|
if (!createRes.ok) throw new AgentsSyncError(`creating the Crew table's Agent field failed: ${createRes.status} ${createRes.statusText}`);
|
|
7951
8017
|
const created = await createRes.json();
|
|
7952
8018
|
return created.columnName;
|
|
@@ -7964,6 +8030,10 @@ function describeSyncOutcome(o) {
|
|
|
7964
8030
|
return `${label}: HAS LOCAL EDITS \u2014 crew's default is newer but was NOT applied; review ${o.agentId} in the app before syncing again`;
|
|
7965
8031
|
case "overridden":
|
|
7966
8032
|
return `${label}: override in place \u2014 prompt not synced (clear "Customize prompt" on the Agents row to resume)`;
|
|
8033
|
+
case "adopted":
|
|
8034
|
+
return `${label}: using the workspace's existing Agents row (${o.agentId})`;
|
|
8035
|
+
case "missing":
|
|
8036
|
+
return `${label}: no Agents row in this workspace \u2014 writes as the ship until a workspace admin runs \`crew agents sync\``;
|
|
7967
8037
|
case "forced":
|
|
7968
8038
|
return `${label}: --force overwrote local edits (previous prompt was: ${JSON.stringify(o.previousPrompt ?? "")})`;
|
|
7969
8039
|
}
|
|
@@ -7977,6 +8047,10 @@ function describeCrewLink(o) {
|
|
|
7977
8047
|
return `${label}: Crew row already references its Agents row`;
|
|
7978
8048
|
case "no_seat":
|
|
7979
8049
|
return `${label}: no seat configured for this role \u2014 skipped linking`;
|
|
8050
|
+
case "no_agent_field":
|
|
8051
|
+
return `${label}: ${CREW_FIELD_MISSING_NOTE}`;
|
|
8052
|
+
case "no_agents_row":
|
|
8053
|
+
return `${label}: no Agents row to link yet \u2014 a workspace admin's \`crew agents sync\` creates it; run it here afterwards to link this seat`;
|
|
7980
8054
|
case "persona_diverged":
|
|
7981
8055
|
return `${label}: persona has local edits and was not synced this pass \u2014 skipped linking until it's resolved`;
|
|
7982
8056
|
}
|
|
@@ -11474,6 +11548,12 @@ import {
|
|
|
11474
11548
|
// src/seat-keys.ts
|
|
11475
11549
|
import { getSessionStore as getSessionStore2, hostFromUrl as hostFromUrl2 } from "@tablation/client";
|
|
11476
11550
|
var SEAT_KEY_ROLES = ROLE_NAMES.filter((r) => r !== "pair");
|
|
11551
|
+
function keyIsAdmin(route) {
|
|
11552
|
+
const role = route.resolved?.role;
|
|
11553
|
+
return role === void 0 || role === "WORKSPACE_ADMIN" || role === "PLATFORM_ADMIN";
|
|
11554
|
+
}
|
|
11555
|
+
var MEMBER_NO_ROW = "has no linked Agents row \u2014 a workspace admin's `crew agents sync` creates the persona rows; run it here afterwards to link this ship's seats";
|
|
11556
|
+
var MEMBER_NO_KEY = "no agent key for this seat \u2014 minting needs a workspace admin key";
|
|
11477
11557
|
function seatKeySlug(workspaceSlug, agentId) {
|
|
11478
11558
|
return `${workspaceSlug}#agent:${agentId}`;
|
|
11479
11559
|
}
|
|
@@ -11487,11 +11567,11 @@ function seatAgentId(route, role) {
|
|
|
11487
11567
|
async function resolveReleaseKey(route, getStore = getSessionStore2) {
|
|
11488
11568
|
const ship = (reason) => ({ kind: "ship", apiKey: resolveApiKey(route), reason });
|
|
11489
11569
|
const agentId = route.resolved?.releaseAgentId;
|
|
11490
|
-
if (!agentId) return ship("release seat has no linked Agents row (run `crew agents sync`)");
|
|
11570
|
+
if (!agentId) return ship(keyIsAdmin(route) ? "release seat has no linked Agents row (run `crew agents sync`)" : `release seat ${MEMBER_NO_ROW}`);
|
|
11491
11571
|
try {
|
|
11492
11572
|
const session = await getStore().get(hostFromUrl2(route.baseUrl), slugFor(route, agentId));
|
|
11493
11573
|
if (session?.apiKey) return { kind: "agent", apiKey: session.apiKey, agentId };
|
|
11494
|
-
return ship("no agent key stored for the release seat (run `crew agents sync`)");
|
|
11574
|
+
return ship(keyIsAdmin(route) ? "no agent key stored for the release seat (run `crew agents sync`)" : MEMBER_NO_KEY);
|
|
11495
11575
|
} catch {
|
|
11496
11576
|
return ship("OS keychain unavailable");
|
|
11497
11577
|
}
|
|
@@ -11500,11 +11580,11 @@ async function resolveSeatKey(route, role, getStore = getSessionStore2) {
|
|
|
11500
11580
|
const ship = (reason) => ({ kind: "ship", apiKey: resolveApiKey(route), reason });
|
|
11501
11581
|
if (!SEAT_KEY_ROLES.includes(role)) return ship(`${role} always writes as the ship`);
|
|
11502
11582
|
const agentId = seatAgentId(route, role);
|
|
11503
|
-
if (!agentId) return ship("seat has no linked Agents row (run `crew agents sync`)");
|
|
11583
|
+
if (!agentId) return ship(keyIsAdmin(route) ? "seat has no linked Agents row (run `crew agents sync`)" : `seat ${MEMBER_NO_ROW}`);
|
|
11504
11584
|
try {
|
|
11505
11585
|
const session = await getStore().get(hostFromUrl2(route.baseUrl), slugFor(route, agentId));
|
|
11506
11586
|
if (session?.apiKey) return { kind: "agent", apiKey: session.apiKey, agentId };
|
|
11507
|
-
return ship("no agent key stored for this seat (run `crew agents sync`)");
|
|
11587
|
+
return ship(keyIsAdmin(route) ? "no agent key stored for this seat (run `crew agents sync`)" : MEMBER_NO_KEY);
|
|
11508
11588
|
} catch {
|
|
11509
11589
|
return ship("OS keychain unavailable");
|
|
11510
11590
|
}
|
|
@@ -15024,9 +15104,18 @@ ${changed2.map((c) => ` - ${c}
|
|
|
15024
15104
|
`);
|
|
15025
15105
|
process.exit(2);
|
|
15026
15106
|
}
|
|
15107
|
+
const keyRole = target.resolved.role ?? await fetchKeyRole(target, cfg.ship.userAgent);
|
|
15108
|
+
let readOnly = !isAdminRole(keyRole);
|
|
15027
15109
|
let personaResult;
|
|
15110
|
+
const runPersonas = (ro) => syncPersonas(target, { userAgent: cfg.ship.userAgent, dryRun, force, readOnly: ro });
|
|
15028
15111
|
try {
|
|
15029
|
-
|
|
15112
|
+
try {
|
|
15113
|
+
personaResult = await runPersonas(readOnly);
|
|
15114
|
+
} catch (e) {
|
|
15115
|
+
if (readOnly || !isForbidden(e)) throw e;
|
|
15116
|
+
readOnly = true;
|
|
15117
|
+
personaResult = await runPersonas(true);
|
|
15118
|
+
}
|
|
15030
15119
|
} catch (e) {
|
|
15031
15120
|
if (e instanceof AgentsSyncError) {
|
|
15032
15121
|
process.stderr.write(`crew agents sync: ${e.message}
|
|
@@ -15040,28 +15129,32 @@ ${changed2.map((c) => ` - ${c}
|
|
|
15040
15129
|
for (const o of personaResult.outcomes) process.stdout.write(`${describeSyncOutcome(o)}
|
|
15041
15130
|
`);
|
|
15042
15131
|
for (const o of personaResult.crewLinks) process.stdout.write(`${describeCrewLink(o)}
|
|
15132
|
+
`);
|
|
15133
|
+
if (personaResult.releaseNote) process.stdout.write(`${personaResult.releaseNote}
|
|
15043
15134
|
`);
|
|
15044
15135
|
const briefs = Object.fromEntries(ROLE_NAMES.map((r) => [r, personaDefaultPrompt(target.promptsDir, r)]));
|
|
15045
15136
|
for (const w of skillMarkerWarnings(target.promptsDir, briefs)) process.stderr.write(`crew agents sync: warning: ${w}
|
|
15046
15137
|
`);
|
|
15047
15138
|
let skillResult;
|
|
15048
|
-
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15139
|
+
if (!readOnly) {
|
|
15140
|
+
try {
|
|
15141
|
+
skillResult = await syncSkills(target, { userAgent: cfg.ship.userAgent, dryRun, force });
|
|
15142
|
+
} catch (e) {
|
|
15143
|
+
if (isForbidden(e)) readOnly = true;
|
|
15144
|
+
else if (e instanceof SkillSyncError) {
|
|
15145
|
+
process.stderr.write(`crew agents sync: ${e.message}
|
|
15053
15146
|
`);
|
|
15054
|
-
|
|
15147
|
+
process.exit(2);
|
|
15148
|
+
} else throw e;
|
|
15055
15149
|
}
|
|
15056
|
-
throw e;
|
|
15057
15150
|
}
|
|
15058
|
-
for (const o of skillResult
|
|
15151
|
+
for (const o of skillResult?.outcomes ?? []) process.stdout.write(`${describeSkillSyncOutcome(o)}
|
|
15059
15152
|
`);
|
|
15060
15153
|
if (!dryRun) {
|
|
15061
15154
|
const resolvedPath = resolvedPathFor(cfg.ship.stateDir, target.route);
|
|
15062
15155
|
const raw = existsSync26(resolvedPath) ? JSON.parse(readFileSync19(resolvedPath, "utf8")) : {};
|
|
15063
15156
|
raw.agentPersonas = personaResult.agentPersonas;
|
|
15064
|
-
raw.agentSkills = skillResult.agentSkills;
|
|
15157
|
+
if (skillResult) raw.agentSkills = skillResult.agentSkills;
|
|
15065
15158
|
if (personaResult.releaseAgentId) raw.releaseAgentId = personaResult.releaseAgentId;
|
|
15066
15159
|
mkdirSync13(dirOf(resolvedPath), { recursive: true });
|
|
15067
15160
|
writeFileSync14(resolvedPath, `${JSON.stringify(raw, null, 2)}
|
|
@@ -15071,11 +15164,16 @@ ${changed2.map((c) => ` - ${c}
|
|
|
15071
15164
|
target.resolved.agentPersonas = personaResult.agentPersonas;
|
|
15072
15165
|
if (personaResult.releaseAgentId) target.resolved.releaseAgentId = personaResult.releaseAgentId;
|
|
15073
15166
|
}
|
|
15074
|
-
|
|
15075
|
-
process.stdout.write(
|
|
15167
|
+
if (readOnly) {
|
|
15168
|
+
process.stdout.write("personas and skills: not synced (this key is not a workspace admin; the workspace's rows are used as they are)\n");
|
|
15169
|
+
process.stdout.write("seat keys: not minted (needs a workspace admin key)\n");
|
|
15170
|
+
} else {
|
|
15171
|
+
for (const o of await mintMissingSeatKeys(target, { userAgent: cfg.ship.userAgent, dryRun, shipName: cfg.ship.name })) {
|
|
15172
|
+
process.stdout.write(`${describeMintOutcome(o)}
|
|
15076
15173
|
`);
|
|
15174
|
+
}
|
|
15077
15175
|
}
|
|
15078
|
-
if (personaResult.outcomes.some((o) => o.action === "diverged") || skillResult
|
|
15176
|
+
if (personaResult.outcomes.some((o) => o.action === "diverged") || (skillResult?.outcomes.some((o) => o.action === "diverged") ?? false)) {
|
|
15079
15177
|
process.exitCode = 1;
|
|
15080
15178
|
}
|
|
15081
15179
|
break;
|
|
@@ -15524,6 +15622,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
15524
15622
|
seats: found.seats,
|
|
15525
15623
|
holds: found.holds.map((h) => ({ id: h.id, role: h.name })),
|
|
15526
15624
|
...found.releaseSeat ? { releaseSeat: found.releaseSeat } : {},
|
|
15625
|
+
...found.role ?? previous?.role ? { role: found.role ?? previous?.role } : {},
|
|
15527
15626
|
...operator ? { operator } : {},
|
|
15528
15627
|
...contract ? { contract } : {},
|
|
15529
15628
|
...reviewedStatuses.length > 0 ? { reviewedStatuses } : {},
|
|
@@ -16461,16 +16560,20 @@ routes: ${cfg.routes.map((c) => c.route).join(", ")}
|
|
|
16461
16560
|
process.stdout.write(
|
|
16462
16561
|
route.resolved?.releaseSeat ? "release seat: this ship has its own Release Crew row\n" : "release seat: none \u2014 release comments are credited to the dev seat; run `crew connect` once the Crew table has this ship's row\n"
|
|
16463
16562
|
);
|
|
16563
|
+
const keyRole = route.resolved?.role ?? await fetchKeyRole(route, cfg.ship.userAgent);
|
|
16564
|
+
const roleRoute = route.resolved && keyRole ? { ...route, resolved: { ...route.resolved, role: keyRole } } : route;
|
|
16565
|
+
process.stdout.write(`api key role: ${keyRole ?? "unknown"}
|
|
16566
|
+
`);
|
|
16464
16567
|
for (const role of SEAT_KEY_ROLES) {
|
|
16465
16568
|
if (!route.resolved?.seats[role]) continue;
|
|
16466
|
-
const id = await resolveSeatKey(
|
|
16569
|
+
const id = await resolveSeatKey(roleRoute, role);
|
|
16467
16570
|
process.stdout.write(
|
|
16468
16571
|
`seat identity: ${role} writes as ${id.kind === "agent" ? `its own agent (${id.agentId})` : `the ship (${id.reason})`}
|
|
16469
16572
|
`
|
|
16470
16573
|
);
|
|
16471
16574
|
}
|
|
16472
16575
|
if (route.resolved?.releaseSeat) {
|
|
16473
|
-
const id = await resolveReleaseKey(
|
|
16576
|
+
const id = await resolveReleaseKey(roleRoute);
|
|
16474
16577
|
process.stdout.write(
|
|
16475
16578
|
`seat identity: release writes as ${id.kind === "agent" ? `its own agent (${id.agentId})` : `the ship (${id.reason})`}
|
|
16476
16579
|
`
|
package/package.json
CHANGED