@tablation/crew 0.130.0 → 0.130.1
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 +31 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7314,6 +7314,27 @@ async function revokeSeatKeys(route2, o) {
|
|
|
7314
7314
|
}
|
|
7315
7315
|
const host = hostFromUrl2(route2.baseUrl);
|
|
7316
7316
|
const base = route2.baseUrl.replace(/\/+$/, "");
|
|
7317
|
+
const headers = { Authorization: `Bearer ${resolveApiKey(route2)}`, "User-Agent": o.userAgent ?? "Mozilla/5.0 TablationCrewAgent/1.0" };
|
|
7318
|
+
const sweepNamedKeys = async (role, agentId) => {
|
|
7319
|
+
const prefix = `crew ${o.shipName} `;
|
|
7320
|
+
try {
|
|
7321
|
+
const res = await doFetch(`${base}/api/workspaces/${resolved.workspaceId}/agents/${agentId}/api-keys`, { headers });
|
|
7322
|
+
if (!res.ok) return;
|
|
7323
|
+
const keys = await res.json();
|
|
7324
|
+
for (const k of Array.isArray(keys) ? keys : []) {
|
|
7325
|
+
if (!k.id || k.revokedAt || !k.name?.startsWith(prefix)) continue;
|
|
7326
|
+
if (o.dryRun) {
|
|
7327
|
+
out.push({ role, action: "revoked", detail: `dry run; key "${k.name}" found on the server` });
|
|
7328
|
+
continue;
|
|
7329
|
+
}
|
|
7330
|
+
const del2 = await doFetch(`${base}/api/workspaces/${resolved.workspaceId}/agents/${agentId}/api-keys/${k.id}`, { method: "DELETE", headers });
|
|
7331
|
+
if (del2.ok || del2.status === 404) out.push({ role, action: "revoked", detail: `key "${k.name}" found on the server, not in the keychain` });
|
|
7332
|
+
else out.push({ role, action: "failed", detail: `key "${k.name}": ${del2.status} ${del2.statusText}` });
|
|
7333
|
+
}
|
|
7334
|
+
} catch (e) {
|
|
7335
|
+
out.push({ role, action: "failed", detail: `could not sweep keys named for this ship (${e.message})` });
|
|
7336
|
+
}
|
|
7337
|
+
};
|
|
7317
7338
|
for (const { role, agentId } of targets) {
|
|
7318
7339
|
if (!agentId) {
|
|
7319
7340
|
out.push({ role, action: "no_agent" });
|
|
@@ -7324,6 +7345,7 @@ async function revokeSeatKeys(route2, o) {
|
|
|
7324
7345
|
const session = await store.get(host, slug2);
|
|
7325
7346
|
if (!session?.apiKey) {
|
|
7326
7347
|
out.push({ role, action: "not_stored" });
|
|
7348
|
+
if (o.shipName) await sweepNamedKeys(role, agentId);
|
|
7327
7349
|
continue;
|
|
7328
7350
|
}
|
|
7329
7351
|
if (!session.keyId) {
|
|
@@ -7344,6 +7366,7 @@ async function revokeSeatKeys(route2, o) {
|
|
|
7344
7366
|
}
|
|
7345
7367
|
await store.clear(host, slug2);
|
|
7346
7368
|
out.push({ role, action: "revoked", detail: del2.ok ? void 0 : "server already had no such key" });
|
|
7369
|
+
if (o.shipName) await sweepNamedKeys(role, agentId);
|
|
7347
7370
|
} catch (e) {
|
|
7348
7371
|
out.push({ role, action: "failed", detail: /Command failed|security|sk_|-w /i.test(e.message) ? describeStoreError(e) : e.message });
|
|
7349
7372
|
}
|
|
@@ -12904,7 +12927,12 @@ function labeledDocker() {
|
|
|
12904
12927
|
if (!dockerAvailable()) return { volumes: [], images: [] };
|
|
12905
12928
|
return {
|
|
12906
12929
|
volumes: lines(docker(["volume", "ls", "-q", "--filter", `label=${DOCKER_LABEL_OWNER}`, "--filter", `label=${DOCKER_LABEL_CACHE}`])),
|
|
12907
|
-
|
|
12930
|
+
// CREW-2984: the repository and ship layers are tagged `crew-sandbox/<name>:<hash>` but carry only an `io.crew.sandbox.*` label,
|
|
12931
|
+
// so the label filter alone missed them. The tag namespace is crew's own; the base and crew layers are `crew-sandbox-base`/`-crew`.
|
|
12932
|
+
images: [.../* @__PURE__ */ new Set([
|
|
12933
|
+
...lines(docker(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}", "--filter", "reference=crew-sandbox/*"])),
|
|
12934
|
+
...lines(docker(["image", "ls", "-q", "--filter", `label=${DOCKER_LABEL_OWNER}`, "--filter", `label=${DOCKER_LABEL_REPO_LAYER}`]))
|
|
12935
|
+
])]
|
|
12908
12936
|
};
|
|
12909
12937
|
}
|
|
12910
12938
|
function realDeprovisionDeps(cfg, emit, crewHome, getStore) {
|
|
@@ -28212,7 +28240,7 @@ ${cu.tail.trimEnd()}
|
|
|
28212
28240
|
}
|
|
28213
28241
|
const { personaResult, skillResult } = run3;
|
|
28214
28242
|
if (flag("revoke-seat-keys")) {
|
|
28215
|
-
for (const o of await revokeSeatKeys(target, { userAgent: cfg.ship.userAgent, dryRun })) {
|
|
28243
|
+
for (const o of await revokeSeatKeys(target, { userAgent: cfg.ship.userAgent, dryRun, shipName: cfg.ship.name })) {
|
|
28216
28244
|
process.stdout.write(`${describeRevokeOutcome(o)}
|
|
28217
28245
|
`);
|
|
28218
28246
|
}
|
|
@@ -30585,7 +30613,7 @@ ${where.join("\n")}`);
|
|
|
30585
30613
|
},
|
|
30586
30614
|
removePair: removePairEntries,
|
|
30587
30615
|
async revokeSeatKeys(r, dry) {
|
|
30588
|
-
const outcomes = await revokeSeatKeys(r, { userAgent: cfg.ship.userAgent, dryRun: dry });
|
|
30616
|
+
const outcomes = await revokeSeatKeys(r, { userAgent: cfg.ship.userAgent, dryRun: dry, shipName: cfg.ship.name });
|
|
30589
30617
|
return outcomes.map((o) => ({ line: describeRevokeOutcome(o), ok: o.action !== "failed" }));
|
|
30590
30618
|
},
|
|
30591
30619
|
async credential(r) {
|
package/package.json
CHANGED