@tablation/crew 0.110.0 → 0.111.0

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 +35 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1800,6 +1800,29 @@ function answerCredential(action, input, forges, stateDir, env = process.env) {
1800
1800
  password=${token}
1801
1801
  `;
1802
1802
  }
1803
+ var missesPath = (stateDir) => join9(stateDir, "forge-misses.json");
1804
+ function readForgeMisses(stateDir) {
1805
+ try {
1806
+ const raw = JSON.parse(readFileSync8(missesPath(stateDir), "utf8"));
1807
+ return Object.entries(raw).filter(([, t]) => typeof t === "string").map(([host, lastMissAt]) => ({ host, lastMissAt })).sort((a, b) => a.host.localeCompare(b.host));
1808
+ } catch {
1809
+ return [];
1810
+ }
1811
+ }
1812
+ function noteForgeMiss(stateDir, host, at) {
1813
+ try {
1814
+ const bare = bareHost(host);
1815
+ const cur = {};
1816
+ for (const m of readForgeMisses(stateDir)) cur[m.host] = m.lastMissAt;
1817
+ if (at === null) {
1818
+ if (!(bare in cur)) return;
1819
+ delete cur[bare];
1820
+ } else cur[bare] = at;
1821
+ mkdirSync5(stateDir, { recursive: true });
1822
+ writeFileSync6(missesPath(stateDir), JSON.stringify(cur), { mode: 384 });
1823
+ } catch {
1824
+ }
1825
+ }
1803
1826
  function gitCredentialEnv(o, base = process.env) {
1804
1827
  const start = Number.parseInt(base.GIT_CONFIG_COUNT ?? "0", 10) || 0;
1805
1828
  const helper = `!${o.crewCommand} credential`;
@@ -12831,6 +12854,7 @@ async function runPoolMember(deps) {
12831
12854
  body.lastRunEndedAt = act.lastRunEndedAt;
12832
12855
  }
12833
12856
  if (act) busy = act.activeRuns > 0;
12857
+ if (state === "running" && deps.missingForgeHosts) body.missingForgeHosts = deps.missingForgeHosts();
12834
12858
  const r = await settle("status", () => deps.api.status(body));
12835
12859
  if (!r) return "stopped";
12836
12860
  if (r.status === 401) return "credential";
@@ -12957,7 +12981,7 @@ async function runPoolMember(deps) {
12957
12981
  }
12958
12982
  if (ans.status === 204) {
12959
12983
  const url = current ? deps.relayUrl() : null;
12960
- if (current && (url !== relayReported && url || deps.activity)) {
12984
+ if (current && (url !== relayReported && url || deps.activity || deps.missingForgeHosts)) {
12961
12985
  const r2 = await report("running", { leaseId: current });
12962
12986
  if (r2 === "credential") return POOL_EXIT.credential;
12963
12987
  relayReported = url ?? relayReported;
@@ -14034,6 +14058,10 @@ function realPoolMemberDeps(o) {
14034
14058
  }
14035
14059
  return null;
14036
14060
  },
14061
+ missingForgeHosts() {
14062
+ const cfg = loadShip(o.crewHome);
14063
+ return cfg ? readForgeMisses(cfg.ship.stateDir) : [];
14064
+ },
14037
14065
  activity() {
14038
14066
  const cfg = loadShip(o.crewHome);
14039
14067
  return cfg ? runActivity(cfg.ship.stateDir) : { activeRuns: 0, lastRunEndedAt: null };
@@ -17632,7 +17660,12 @@ function formatProjectsReport(report) {
17632
17660
  import { parseDocument as parseDocument4 } from "yaml";
17633
17661
  function runCredential(action, stdin, forges, stateDir, env = process.env) {
17634
17662
  try {
17635
- return { code: 0, out: answerCredential(action ?? "", parseCredentialInput(stdin), forges, stateDir, env), err: "" };
17663
+ const input = parseCredentialInput(stdin);
17664
+ const out = answerCredential(action ?? "", input, forges, stateDir, env);
17665
+ if (action === "get" && input.host && (!input.protocol || input.protocol === "https")) {
17666
+ noteForgeMiss(stateDir, input.host, out ? null : (/* @__PURE__ */ new Date()).toISOString());
17667
+ }
17668
+ return { code: 0, out, err: "" };
17636
17669
  } catch (e) {
17637
17670
  return { code: 0, out: "", err: `crew credential: ${e.message}
17638
17671
  ` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.110.0",
3
+ "version": "0.111.0",
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",