@tablation/crew 0.51.0 → 0.51.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.
Files changed (2) hide show
  1. package/dist/cli.js +53 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -11644,6 +11644,13 @@ async function resolveSeatKey(route, role, getStore = getSessionStore2) {
11644
11644
  return ship("OS keychain unavailable");
11645
11645
  }
11646
11646
  }
11647
+ function describeStoreError(e) {
11648
+ const msg = e instanceof Error ? e.message : String(e);
11649
+ if (/User interaction is not allowed/i.test(msg)) {
11650
+ return "keychain unavailable (User interaction is not allowed \u2014 run from a logged-in session, or `security unlock-keychain` first)";
11651
+ }
11652
+ return "keychain unavailable (could not write to the OS keychain)";
11653
+ }
11647
11654
  async function mintMissingSeatKeys(route, o) {
11648
11655
  const out = [];
11649
11656
  if (!route.resolved) return out;
@@ -11660,11 +11667,27 @@ async function mintMissingSeatKeys(route, o) {
11660
11667
  return targets.map(({ role }) => ({
11661
11668
  role,
11662
11669
  action: "failed",
11663
- detail: `OS keychain unavailable: ${e.message}`
11670
+ detail: describeStoreError(e)
11664
11671
  }));
11665
11672
  }
11666
11673
  const host = hostFromUrl2(route.baseUrl);
11667
11674
  const base = route.baseUrl.replace(/\/+$/, "");
11675
+ if (!o.dryRun) {
11676
+ const probeSlug = seatKeySlug(splitRoute(route.route)[0], "_probe");
11677
+ try {
11678
+ await store.set(host, probeSlug, {
11679
+ apiKey: "probe",
11680
+ shipId: "",
11681
+ workspaceId: resolved.workspaceId,
11682
+ identityId: "_probe",
11683
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
11684
+ });
11685
+ await store.clear(host, probeSlug);
11686
+ } catch (e) {
11687
+ const detail = `${describeStoreError(e)}; no keys minted`;
11688
+ return targets.map(({ role, agentId }) => agentId ? { role, action: "failed", detail } : { role, action: "no_agent" });
11689
+ }
11690
+ }
11668
11691
  for (const { role, agentId } of targets) {
11669
11692
  if (!agentId) {
11670
11693
  out.push({ role, action: "no_agent" });
@@ -11698,16 +11721,37 @@ async function mintMissingSeatKeys(route, o) {
11698
11721
  out.push({ role, action: "failed", detail: "response carried no key" });
11699
11722
  continue;
11700
11723
  }
11701
- await store.set(host, slug, {
11702
- apiKey: body.key,
11703
- shipId: o.shipName ?? "",
11704
- workspaceId: resolved.workspaceId,
11705
- identityId: agentId,
11706
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
11707
- });
11724
+ try {
11725
+ await store.set(host, slug, {
11726
+ apiKey: body.key,
11727
+ shipId: o.shipName ?? "",
11728
+ workspaceId: resolved.workspaceId,
11729
+ identityId: agentId,
11730
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
11731
+ });
11732
+ } catch (e) {
11733
+ let revoked = false;
11734
+ if (body.id) {
11735
+ try {
11736
+ const del2 = await doFetch(`${base}/api/workspaces/${resolved.workspaceId}/agents/${agentId}/api-keys/${body.id}`, {
11737
+ method: "DELETE",
11738
+ headers: { Authorization: `Bearer ${resolveApiKey(route)}`, "User-Agent": o.userAgent ?? "Mozilla/5.0 TablationCrewAgent/1.0" }
11739
+ });
11740
+ revoked = del2.ok;
11741
+ } catch {
11742
+ revoked = false;
11743
+ }
11744
+ }
11745
+ out.push({
11746
+ role,
11747
+ action: "failed",
11748
+ detail: revoked ? `minted but could not be stored (${describeStoreError(e)}); revoked` : `a key for ${role} is live on the server and not stored (${describeStoreError(e)}) \u2014 revoke it from that seat's Agents row`
11749
+ });
11750
+ continue;
11751
+ }
11708
11752
  out.push({ role, action: "minted" });
11709
11753
  } catch (e) {
11710
- out.push({ role, action: "failed", detail: e.message });
11754
+ out.push({ role, action: "failed", detail: /Command failed|security|sk_|-w /i.test(e.message) ? describeStoreError(e) : e.message });
11711
11755
  }
11712
11756
  }
11713
11757
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.51.0",
3
+ "version": "0.51.1",
4
4
  "description": "A standing team of headless agents that picks work off a Tablation board, does it on a machine you control, and reports back.",
5
5
  "type": "module",
6
6
  "license": "MIT",