@tablation/crew 0.127.1 → 0.127.2
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 +217 -92
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6356,7 +6356,7 @@ function attentionProblems(items, already) {
|
|
|
6356
6356
|
import { createHash as createHash7 } from "crypto";
|
|
6357
6357
|
import { spawn as spawn5 } from "child_process";
|
|
6358
6358
|
import { execFileSync as execFileSync8 } from "child_process";
|
|
6359
|
-
import { existsSync as existsSync30, mkdirSync as mkdirSync19, readFileSync as
|
|
6359
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync19, readFileSync as readFileSync28, renameSync as renameSync3, writeFileSync as writeFileSync20, rmSync as rmSync15 } from "fs";
|
|
6360
6360
|
import { dirname as dirname15, join as join32 } from "path";
|
|
6361
6361
|
import { fileURLToPath } from "url";
|
|
6362
6362
|
import { tmpdir as tmpdir3 } from "os";
|
|
@@ -6374,12 +6374,12 @@ import { spawnSync as spawnSync7 } from "child_process";
|
|
|
6374
6374
|
import { existsSync as existsSync29, readdirSync as readdirSync11 } from "fs";
|
|
6375
6375
|
|
|
6376
6376
|
// src/interrupted.ts
|
|
6377
|
-
import { existsSync as existsSync27, readdirSync as readdirSync9, readFileSync as
|
|
6377
|
+
import { existsSync as existsSync27, readdirSync as readdirSync9, readFileSync as readFileSync27 } from "fs";
|
|
6378
6378
|
import { join as join30 } from "path";
|
|
6379
6379
|
|
|
6380
6380
|
// src/agent.ts
|
|
6381
6381
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
6382
|
-
import { readFileSync as
|
|
6382
|
+
import { readFileSync as readFileSync26, existsSync as existsSync26, statSync as statSync8, mkdirSync as mkdirSync18, writeFileSync as writeFileSync19, createWriteStream, openSync as openSync4, closeSync as closeSync4, readSync } from "fs";
|
|
6383
6383
|
import { StringDecoder } from "string_decoder";
|
|
6384
6384
|
import { finished } from "stream/promises";
|
|
6385
6385
|
import { join as join29, dirname as dirname14, basename as basename9 } from "path";
|
|
@@ -6887,6 +6887,97 @@ var State = class _State {
|
|
|
6887
6887
|
}
|
|
6888
6888
|
};
|
|
6889
6889
|
|
|
6890
|
+
// src/signed-out.ts
|
|
6891
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
6892
|
+
var SIGNED_OUT_PATTERN = /not logged in|please run \/?login|\/login|invalid api key|failed to authenticate|oauth session expired|could not be refreshed|reauthentication is needed|application default credentials/i;
|
|
6893
|
+
function authModeOf(spec, hostEnv = process.env) {
|
|
6894
|
+
const env = { ...hostEnv, ...spec.env };
|
|
6895
|
+
const on = (v) => !!v && v !== "0" && v.toLowerCase() !== "false";
|
|
6896
|
+
if (spec.auth === "subscription") return "login";
|
|
6897
|
+
if (on(env.CLAUDE_CODE_USE_VERTEX)) return "vertex";
|
|
6898
|
+
if (env.ANTHROPIC_API_KEY) return "api-key";
|
|
6899
|
+
return "login";
|
|
6900
|
+
}
|
|
6901
|
+
var SIGNED_OUT_REMEDY = {
|
|
6902
|
+
vertex: "run `gcloud auth application-default login` on this Mac",
|
|
6903
|
+
"api-key": "check the API key the toolchain uses (ANTHROPIC_API_KEY) is valid and unrevoked",
|
|
6904
|
+
login: "run `claude` in a terminal on this Mac and `/login`"
|
|
6905
|
+
};
|
|
6906
|
+
function signedOutMessage(toolchain, mode) {
|
|
6907
|
+
return `toolchain ${toolchain} is signed out \u2014 its runs end at the harness's sign-out error. To fix: ${SIGNED_OUT_REMEDY[mode]}`;
|
|
6908
|
+
}
|
|
6909
|
+
var signedOutKey = (toolchain) => `signed_out:${toolchain}`;
|
|
6910
|
+
function signedOutItem(toolchain, mode, nowIso = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
6911
|
+
return { kind: "signed_out", key: signedOutKey(toolchain), since: nowIso, message: signedOutMessage(toolchain, mode) };
|
|
6912
|
+
}
|
|
6913
|
+
var textOf = (v) => typeof v === "string" ? v : JSON.stringify(v ?? "");
|
|
6914
|
+
function eventsShowSignedOut(events) {
|
|
6915
|
+
let assistantTurns = 0;
|
|
6916
|
+
let toolUse = false;
|
|
6917
|
+
let onlyTurnSignedOut = false;
|
|
6918
|
+
for (const ev of events) {
|
|
6919
|
+
if (typeof ev !== "object" || ev === null) continue;
|
|
6920
|
+
const e = ev;
|
|
6921
|
+
if (e.type === "result") {
|
|
6922
|
+
if (e.is_error === true && SIGNED_OUT_PATTERN.test(textOf(e.result))) return true;
|
|
6923
|
+
} else if (e.type === "assistant") {
|
|
6924
|
+
assistantTurns++;
|
|
6925
|
+
const content = Array.isArray(e.message?.content) ? e.message.content : [];
|
|
6926
|
+
if (content.some((b) => b?.type === "tool_use")) toolUse = true;
|
|
6927
|
+
if (SIGNED_OUT_PATTERN.test(textOf(e.message))) {
|
|
6928
|
+
if (e.isApiErrorMessage === true || e.error !== void 0) return true;
|
|
6929
|
+
onlyTurnSignedOut = true;
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
return assistantTurns === 1 && onlyTurnSignedOut && !toolUse;
|
|
6934
|
+
}
|
|
6935
|
+
function streamShowsSignedOut(streamPath) {
|
|
6936
|
+
let raw;
|
|
6937
|
+
try {
|
|
6938
|
+
raw = readFileSync20(streamPath, "utf8");
|
|
6939
|
+
} catch {
|
|
6940
|
+
return false;
|
|
6941
|
+
}
|
|
6942
|
+
if (!SIGNED_OUT_PATTERN.test(raw)) return false;
|
|
6943
|
+
const events = [];
|
|
6944
|
+
for (const line of raw.split("\n")) {
|
|
6945
|
+
if (!line.trim()) continue;
|
|
6946
|
+
try {
|
|
6947
|
+
events.push(JSON.parse(line));
|
|
6948
|
+
} catch {
|
|
6949
|
+
}
|
|
6950
|
+
}
|
|
6951
|
+
return eventsShowSignedOut(events);
|
|
6952
|
+
}
|
|
6953
|
+
function streamShowsRealTurn(streamPath) {
|
|
6954
|
+
let raw;
|
|
6955
|
+
try {
|
|
6956
|
+
raw = readFileSync20(streamPath, "utf8");
|
|
6957
|
+
} catch {
|
|
6958
|
+
return false;
|
|
6959
|
+
}
|
|
6960
|
+
return raw.split("\n").some((line) => {
|
|
6961
|
+
if (!line.includes('"assistant"')) return false;
|
|
6962
|
+
try {
|
|
6963
|
+
const e = JSON.parse(line);
|
|
6964
|
+
return e.type === "assistant" && e.isApiErrorMessage !== true && e.error === void 0 && !SIGNED_OUT_PATTERN.test(textOf(e.message));
|
|
6965
|
+
} catch {
|
|
6966
|
+
return false;
|
|
6967
|
+
}
|
|
6968
|
+
});
|
|
6969
|
+
}
|
|
6970
|
+
var SignedOutError = class extends Error {
|
|
6971
|
+
toolchain;
|
|
6972
|
+
mode;
|
|
6973
|
+
constructor(toolchain, mode) {
|
|
6974
|
+
super(signedOutMessage(toolchain, mode));
|
|
6975
|
+
this.toolchain = toolchain;
|
|
6976
|
+
this.mode = mode;
|
|
6977
|
+
}
|
|
6978
|
+
};
|
|
6979
|
+
var SIGNED_OUT_PAUSE_MS = 15 * 60 * 1e3;
|
|
6980
|
+
|
|
6890
6981
|
// src/environment.ts
|
|
6891
6982
|
import { basename as basename6 } from "path";
|
|
6892
6983
|
|
|
@@ -7286,7 +7377,7 @@ function renderEnvironment(i) {
|
|
|
7286
7377
|
}
|
|
7287
7378
|
|
|
7288
7379
|
// src/intel-bridge.ts
|
|
7289
|
-
import { existsSync as existsSync20, mkdirSync as mkdirSync14, readFileSync as
|
|
7380
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync14, readFileSync as readFileSync21, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "fs";
|
|
7290
7381
|
import { dirname as dirname11, join as join22 } from "path";
|
|
7291
7382
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
7292
7383
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
@@ -7313,7 +7404,7 @@ function writeAttachFile(file, url) {
|
|
|
7313
7404
|
}
|
|
7314
7405
|
function readAttachFile(file) {
|
|
7315
7406
|
try {
|
|
7316
|
-
const url =
|
|
7407
|
+
const url = readFileSync21(file, "utf8").trim();
|
|
7317
7408
|
return /^https?:\/\/\S+$/i.test(url) ? url : void 0;
|
|
7318
7409
|
} catch {
|
|
7319
7410
|
return void 0;
|
|
@@ -7692,7 +7783,7 @@ var BeforeFirstEditTracker = class {
|
|
|
7692
7783
|
};
|
|
7693
7784
|
|
|
7694
7785
|
// src/agent-log.ts
|
|
7695
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync15, readdirSync as readdirSync6, readFileSync as
|
|
7786
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync15, readdirSync as readdirSync6, readFileSync as readFileSync22, rmSync as rmSync12, writeFileSync as writeFileSync16 } from "fs";
|
|
7696
7787
|
import { join as join23 } from "path";
|
|
7697
7788
|
|
|
7698
7789
|
// src/pending-backoff.ts
|
|
@@ -7909,7 +8000,7 @@ async function replayQueuedAgentRuns(stateDir, route2, keyFor, log, now = /* @__
|
|
|
7909
8000
|
const path = join23(dir, f);
|
|
7910
8001
|
let q2;
|
|
7911
8002
|
try {
|
|
7912
|
-
q2 = JSON.parse(
|
|
8003
|
+
q2 = JSON.parse(readFileSync22(path, "utf8"));
|
|
7913
8004
|
} catch {
|
|
7914
8005
|
continue;
|
|
7915
8006
|
}
|
|
@@ -7962,7 +8053,7 @@ async function replayQueuedTicketCounters(stateDir, route2, keyFor, log, now = /
|
|
|
7962
8053
|
const path = join23(dir, f);
|
|
7963
8054
|
let q2;
|
|
7964
8055
|
try {
|
|
7965
|
-
q2 = JSON.parse(
|
|
8056
|
+
q2 = JSON.parse(readFileSync22(path, "utf8"));
|
|
7966
8057
|
} catch {
|
|
7967
8058
|
continue;
|
|
7968
8059
|
}
|
|
@@ -8184,7 +8275,7 @@ var HandoffTranscriptTracker = class {
|
|
|
8184
8275
|
};
|
|
8185
8276
|
|
|
8186
8277
|
// src/pending-handoff.ts
|
|
8187
|
-
import { existsSync as existsSync23, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as
|
|
8278
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as readFileSync23, rmSync as rmSync13, writeFileSync as writeFileSync17 } from "fs";
|
|
8188
8279
|
import { join as join25 } from "path";
|
|
8189
8280
|
|
|
8190
8281
|
// src/ticket-branch.ts
|
|
@@ -9879,7 +9970,7 @@ function listPendingHandoffs(stateDir, route2) {
|
|
|
9879
9970
|
const out = [];
|
|
9880
9971
|
for (const f of readdirSync7(dir).filter((n) => n.endsWith(".json")).sort()) {
|
|
9881
9972
|
try {
|
|
9882
|
-
const rec = JSON.parse(
|
|
9973
|
+
const rec = JSON.parse(readFileSync23(join25(dir, f), "utf8"));
|
|
9883
9974
|
if (rec.version === 1 && rec.ticketRecordId && (!route2 || rec.route === route2)) out.push(rec);
|
|
9884
9975
|
} catch {
|
|
9885
9976
|
}
|
|
@@ -9997,7 +10088,7 @@ function expandSkillMarkers(text2, lookup2, opts = {}) {
|
|
|
9997
10088
|
}
|
|
9998
10089
|
|
|
9999
10090
|
// src/skills.ts
|
|
10000
|
-
import { readFileSync as
|
|
10091
|
+
import { readFileSync as readFileSync25, readdirSync as readdirSync8, existsSync as existsSync25 } from "fs";
|
|
10001
10092
|
import { join as join27 } from "path";
|
|
10002
10093
|
import { parse as parseYaml } from "yaml";
|
|
10003
10094
|
import { TablationClient as TablationClient3, StaleWriteError as StaleWriteError3, TablationApiError as TablationApiError2 } from "@tablation/client";
|
|
@@ -10014,7 +10105,7 @@ ${additions}`;
|
|
|
10014
10105
|
}
|
|
10015
10106
|
|
|
10016
10107
|
// src/agents.ts
|
|
10017
|
-
import { readFileSync as
|
|
10108
|
+
import { readFileSync as readFileSync24, existsSync as existsSync24 } from "fs";
|
|
10018
10109
|
import { join as join26 } from "path";
|
|
10019
10110
|
import { TablationClient as TablationClient2, StaleWriteError as StaleWriteError2, TablationApiError } from "@tablation/client";
|
|
10020
10111
|
var PERSONA_NAME = {
|
|
@@ -10031,10 +10122,10 @@ var AgentsSyncError = class extends Error {
|
|
|
10031
10122
|
function personaDefaultPrompt(promptsDir, role) {
|
|
10032
10123
|
const briefPath = join26(promptsDir, "personas", `lane-${role}.md`);
|
|
10033
10124
|
if (!existsSync24(briefPath)) throw new AgentsSyncError(`no brief at ${briefPath}`);
|
|
10034
|
-
if (SELF_CONTAINED_ROLES.has(role)) return
|
|
10125
|
+
if (SELF_CONTAINED_ROLES.has(role)) return readFileSync24(briefPath, "utf8");
|
|
10035
10126
|
const commonPath = join26(promptsDir, "personas", "common.md");
|
|
10036
|
-
if (!existsSync24(commonPath)) return
|
|
10037
|
-
return `${
|
|
10127
|
+
if (!existsSync24(commonPath)) return readFileSync24(briefPath, "utf8");
|
|
10128
|
+
return `${readFileSync24(commonPath, "utf8")}${readFileSync24(briefPath, "utf8")}`;
|
|
10038
10129
|
}
|
|
10039
10130
|
async function resolveAgentId(route2, role, opts) {
|
|
10040
10131
|
const cached = route2.resolved?.agentPersonas?.[role]?.agentId;
|
|
@@ -10481,7 +10572,7 @@ function describeCrewLink(o) {
|
|
|
10481
10572
|
var SkillSyncError = class extends Error {
|
|
10482
10573
|
};
|
|
10483
10574
|
function parseSkillFile(path) {
|
|
10484
|
-
const text2 =
|
|
10575
|
+
const text2 = readFileSync25(path, "utf8");
|
|
10485
10576
|
const match = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(text2);
|
|
10486
10577
|
if (!match) throw new SkillSyncError(`${path}: missing YAML frontmatter (expected a leading --- block)`);
|
|
10487
10578
|
const frontmatter = match[1];
|
|
@@ -11061,7 +11152,7 @@ var ALLOWANCE_REFUSAL_MARKER = "AI_ALLOWANCE_EXCEEDED";
|
|
|
11061
11152
|
function streamShowsAllowanceRefusal(streamPath) {
|
|
11062
11153
|
let raw;
|
|
11063
11154
|
try {
|
|
11064
|
-
raw =
|
|
11155
|
+
raw = readFileSync26(streamPath, "utf8");
|
|
11065
11156
|
} catch {
|
|
11066
11157
|
return false;
|
|
11067
11158
|
}
|
|
@@ -11147,10 +11238,10 @@ function planAgentRun(o) {
|
|
|
11147
11238
|
let ageSeconds;
|
|
11148
11239
|
if (existsSync26(digestPath2)) {
|
|
11149
11240
|
ageSeconds = Math.floor((now() - statSync8(digestPath2).mtimeMs) / 1e3);
|
|
11150
|
-
if (ageSeconds <= DIGEST_MAX_AGE_SECONDS) digest =
|
|
11241
|
+
if (ageSeconds <= DIGEST_MAX_AGE_SECONDS) digest = readFileSync26(digestPath2, "utf8");
|
|
11151
11242
|
}
|
|
11152
|
-
const common = usesCommon ?
|
|
11153
|
-
const brief =
|
|
11243
|
+
const common = usesCommon ? readFileSync26(commonPath, "utf8") : "";
|
|
11244
|
+
const brief = readFileSync26(briefPath, "utf8");
|
|
11154
11245
|
const effectiveCommon = o.divergedPrompt ? "" : common;
|
|
11155
11246
|
const effectiveBrief = appendAdditions(o.divergedPrompt ?? brief, o.personaAdditions);
|
|
11156
11247
|
const localSkills = new Map(listLocalSkills(o.route.promptsDir).map((s) => [s.name, s.prompt]));
|
|
@@ -11239,6 +11330,7 @@ function planAgentRun(o) {
|
|
|
11239
11330
|
toolchain: toolchain.name,
|
|
11240
11331
|
harness: toolchain.harness,
|
|
11241
11332
|
workspaceAuth: toolchain.auth === "workspace",
|
|
11333
|
+
authMode: authModeOf(toolchain),
|
|
11242
11334
|
provider: toolchainProvider(toolchain),
|
|
11243
11335
|
maxRunMinutes: resolveMaxRunMinutes(o.route.maxRunMinutes, toolchain.maxRunMinutes),
|
|
11244
11336
|
...o.ship.runner === "sandbox" ? {
|
|
@@ -11305,7 +11397,7 @@ function describePlan(p) {
|
|
|
11305
11397
|
var pidPathFor = (streamPath) => `${streamPath}.pid`;
|
|
11306
11398
|
function readRunSidecar(streamPath) {
|
|
11307
11399
|
try {
|
|
11308
|
-
const sc = JSON.parse(
|
|
11400
|
+
const sc = JSON.parse(readFileSync26(pidPathFor(streamPath), "utf8"));
|
|
11309
11401
|
return typeof sc.pid === "number" && typeof sc.spawnedAt === "string" && typeof sc.role === "string" ? sc : null;
|
|
11310
11402
|
} catch {
|
|
11311
11403
|
return null;
|
|
@@ -11620,10 +11712,11 @@ async function finishRun(id, obs, emit, startedAt, end, agentLogKey, hintMoved)
|
|
|
11620
11712
|
...result?.costUsd !== void 0 ? { totalCostUsd: result.costUsd } : {}
|
|
11621
11713
|
}
|
|
11622
11714
|
});
|
|
11715
|
+
const signedOut = !end.interrupted && streamShowsSignedOut(id.streamPath);
|
|
11623
11716
|
if (id.agentLog && agentLogKey) {
|
|
11624
11717
|
const report = {
|
|
11625
11718
|
ticketReference: attributedTicket,
|
|
11626
|
-
outcome: end.interrupted ? "interrupted" : end.code === 0 || end.code === null && obs.sawResult ? "success" : "error",
|
|
11719
|
+
outcome: end.interrupted ? "interrupted" : signedOut ? "error" : end.code === 0 || end.code === null && obs.sawResult ? "success" : "error",
|
|
11627
11720
|
startedAt,
|
|
11628
11721
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11629
11722
|
cycles: obs.cycles,
|
|
@@ -11878,7 +11971,7 @@ function runFinished(streamPath) {
|
|
|
11878
11971
|
const path = `${streamPath}.meta.json`;
|
|
11879
11972
|
if (!existsSync27(path)) return false;
|
|
11880
11973
|
try {
|
|
11881
|
-
return JSON.parse(
|
|
11974
|
+
return JSON.parse(readFileSync27(path, "utf8")).running !== true;
|
|
11882
11975
|
} catch {
|
|
11883
11976
|
return true;
|
|
11884
11977
|
}
|
|
@@ -12969,7 +13062,7 @@ var SANDBOX_BRIDGE_PATH = `${CREW_PREFIX}/bin/intel-bridge`;
|
|
|
12969
13062
|
function readBridgeBundle() {
|
|
12970
13063
|
const here = dirname15(fileURLToPath(import.meta.url));
|
|
12971
13064
|
for (const p of [join32(here, "sandbox-intel-bridge.cjs"), join32(here, "..", "dist", "sandbox-intel-bridge.cjs")]) {
|
|
12972
|
-
if (existsSync30(p)) return
|
|
13065
|
+
if (existsSync30(p)) return readFileSync28(p, "utf8");
|
|
12973
13066
|
}
|
|
12974
13067
|
return void 0;
|
|
12975
13068
|
}
|
|
@@ -13121,7 +13214,7 @@ var shipSandboxRef = () => ({ name: SHIP_SANDBOX_KEY, decl: { packages: [], setu
|
|
|
13121
13214
|
var sandboxStatePath = (stateDir) => join32(stateDir, "sandbox-images.json");
|
|
13122
13215
|
function readSandboxState(stateDir) {
|
|
13123
13216
|
try {
|
|
13124
|
-
const v = JSON.parse(
|
|
13217
|
+
const v = JSON.parse(readFileSync28(sandboxStatePath(stateDir), "utf8"));
|
|
13125
13218
|
return v && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
13126
13219
|
} catch {
|
|
13127
13220
|
return {};
|
|
@@ -13404,7 +13497,7 @@ function managedGitIdentityWarnings(kind, identity) {
|
|
|
13404
13497
|
|
|
13405
13498
|
// src/selftest.ts
|
|
13406
13499
|
import { spawn as spawn6 } from "child_process";
|
|
13407
|
-
import { existsSync as existsSync31, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync2, readFileSync as
|
|
13500
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync2, readFileSync as readFileSync29, rmSync as rmSync16, writeFileSync as writeFileSync21 } from "fs";
|
|
13408
13501
|
import { tmpdir as tmpdir4 } from "os";
|
|
13409
13502
|
import { join as join33 } from "path";
|
|
13410
13503
|
var SELFTEST_TIMEOUT_MS = 12e4;
|
|
@@ -13538,6 +13631,11 @@ ${seen.texts.join("\n")}`)) {
|
|
|
13538
13631
|
return fail2("mcp-unavailable", "the tracker MCP tool was not available to the session");
|
|
13539
13632
|
}
|
|
13540
13633
|
const answered = seen.texts.length > 0 || seen.finalText;
|
|
13634
|
+
if (SIGNED_OUT_PATTERN.test(`${run3.stderr}
|
|
13635
|
+
${seen.finalText ?? ""}
|
|
13636
|
+
${seen.texts.join("\n")}`)) {
|
|
13637
|
+
return { failure: "login-missing", detail: signedOutMessage(spec.name, authModeOf(spec)) };
|
|
13638
|
+
}
|
|
13541
13639
|
if (!answered || LOGIN.test(run3.stderr) || LOGIN.test(seen.finalText ?? "")) {
|
|
13542
13640
|
return fail2("login-missing", `\`${bin}\` exited${run3.code !== null ? ` (${run3.code})` : ""} before answering; the vendor login is probably missing`);
|
|
13543
13641
|
}
|
|
@@ -13604,7 +13702,7 @@ var fileFor2 = (stateDir) => join33(stateDir, "selftest.json");
|
|
|
13604
13702
|
function readSelftest(stateDir) {
|
|
13605
13703
|
try {
|
|
13606
13704
|
const p = fileFor2(stateDir);
|
|
13607
|
-
return existsSync31(p) ? JSON.parse(
|
|
13705
|
+
return existsSync31(p) ? JSON.parse(readFileSync29(p, "utf8")) : {};
|
|
13608
13706
|
} catch {
|
|
13609
13707
|
return {};
|
|
13610
13708
|
}
|
|
@@ -13823,14 +13921,14 @@ function rosterMarkdown(roster, meId) {
|
|
|
13823
13921
|
}
|
|
13824
13922
|
|
|
13825
13923
|
// src/connect-resume.ts
|
|
13826
|
-
import { mkdirSync as mkdirSync21, readFileSync as
|
|
13924
|
+
import { mkdirSync as mkdirSync21, readFileSync as readFileSync30, rmSync as rmSync17, writeFileSync as writeFileSync22 } from "fs";
|
|
13827
13925
|
import { dirname as dirname16, join as join34 } from "path";
|
|
13828
13926
|
function lastSessionFile(stateDir) {
|
|
13829
13927
|
return join34(stateDir, "connect-session.json");
|
|
13830
13928
|
}
|
|
13831
13929
|
function readPointers(stateDir) {
|
|
13832
13930
|
try {
|
|
13833
|
-
const parsed = JSON.parse(
|
|
13931
|
+
const parsed = JSON.parse(readFileSync30(lastSessionFile(stateDir), "utf8"));
|
|
13834
13932
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
13835
13933
|
const out = {};
|
|
13836
13934
|
for (const [host, v] of Object.entries(parsed)) {
|
|
@@ -13930,7 +14028,7 @@ async function signOutSessions(o) {
|
|
|
13930
14028
|
}
|
|
13931
14029
|
|
|
13932
14030
|
// src/reset.ts
|
|
13933
|
-
import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as
|
|
14031
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync31, readdirSync as readdirSync12, rmSync as rmSync18, statSync as statSync10, writeFileSync as writeFileSync23 } from "fs";
|
|
13934
14032
|
import { dirname as dirname17, join as join35 } from "path";
|
|
13935
14033
|
import { hostFromUrl as hostFromUrl3 } from "@tablation/client";
|
|
13936
14034
|
function clonedCheckoutsFile(stateDir) {
|
|
@@ -13938,7 +14036,7 @@ function clonedCheckoutsFile(stateDir) {
|
|
|
13938
14036
|
}
|
|
13939
14037
|
function readClonedCheckouts(stateDir) {
|
|
13940
14038
|
try {
|
|
13941
|
-
const parsed = JSON.parse(
|
|
14039
|
+
const parsed = JSON.parse(readFileSync31(clonedCheckoutsFile(stateDir), "utf8"));
|
|
13942
14040
|
return Array.isArray(parsed) ? parsed.filter((d) => typeof d === "string") : [];
|
|
13943
14041
|
} catch {
|
|
13944
14042
|
return [];
|
|
@@ -14129,7 +14227,7 @@ async function runDeprovision(o, fx, deps) {
|
|
|
14129
14227
|
}
|
|
14130
14228
|
|
|
14131
14229
|
// src/pool-member.ts
|
|
14132
|
-
import { mkdirSync as mkdirSync23, readFileSync as
|
|
14230
|
+
import { mkdirSync as mkdirSync23, readFileSync as readFileSync32, renameSync as renameSync4, writeFileSync as writeFileSync24 } from "fs";
|
|
14133
14231
|
import { homedir as homedir8 } from "os";
|
|
14134
14232
|
import { dirname as dirname18, join as join36 } from "path";
|
|
14135
14233
|
var POOL_EXIT = { ok: 0, failed: 1, credential: 2 };
|
|
@@ -14369,7 +14467,7 @@ function fileMemberStore(dir) {
|
|
|
14369
14467
|
return {
|
|
14370
14468
|
read() {
|
|
14371
14469
|
try {
|
|
14372
|
-
return JSON.parse(
|
|
14470
|
+
return JSON.parse(readFileSync32(file, "utf8"));
|
|
14373
14471
|
} catch {
|
|
14374
14472
|
return {};
|
|
14375
14473
|
}
|
|
@@ -14435,7 +14533,7 @@ import { hostname as hostname3 } from "os";
|
|
|
14435
14533
|
// src/machine-id.ts
|
|
14436
14534
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
14437
14535
|
import { createHash as createHash8 } from "crypto";
|
|
14438
|
-
import { existsSync as existsSync33, mkdirSync as mkdirSync24, readFileSync as
|
|
14536
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync24, readFileSync as readFileSync33, writeFileSync as writeFileSync25 } from "fs";
|
|
14439
14537
|
import { dirname as dirname19, join as join37 } from "path";
|
|
14440
14538
|
function machineIdPathFor(stateDir) {
|
|
14441
14539
|
return join37(stateDir, "machine-id");
|
|
@@ -14452,7 +14550,7 @@ function readRawMachineId(platform2 = process.platform) {
|
|
|
14452
14550
|
}
|
|
14453
14551
|
for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
14454
14552
|
if (existsSync33(p)) {
|
|
14455
|
-
const id =
|
|
14553
|
+
const id = readFileSync33(p, "utf8").trim();
|
|
14456
14554
|
if (id) return id;
|
|
14457
14555
|
}
|
|
14458
14556
|
}
|
|
@@ -14464,7 +14562,7 @@ function ensureMachineId(stateDir, opts = {}) {
|
|
|
14464
14562
|
if (opts.override?.trim()) return sha256(opts.override.trim());
|
|
14465
14563
|
const path = machineIdPathFor(stateDir);
|
|
14466
14564
|
if (existsSync33(path)) {
|
|
14467
|
-
const cached =
|
|
14565
|
+
const cached = readFileSync33(path, "utf8").trim();
|
|
14468
14566
|
if (/^[0-9a-f]{64}$/.test(cached)) return cached;
|
|
14469
14567
|
}
|
|
14470
14568
|
const raw = (opts.read ?? readRawMachineId)();
|
|
@@ -14484,7 +14582,7 @@ function matchShipRows(ships, shipName2, machineId) {
|
|
|
14484
14582
|
|
|
14485
14583
|
// src/provision.ts
|
|
14486
14584
|
import { spawnSync as spawnSync9 } from "child_process";
|
|
14487
|
-
import { existsSync as existsSync34, readFileSync as
|
|
14585
|
+
import { existsSync as existsSync34, readFileSync as readFileSync34, writeFileSync as writeFileSync26 } from "fs";
|
|
14488
14586
|
import { hostname as hostname2 } from "os";
|
|
14489
14587
|
import { parseDocument as parseDocument3, isMap as isMap2, isScalar } from "yaml";
|
|
14490
14588
|
|
|
@@ -15105,7 +15203,7 @@ function realProvisionDeps(crewHome) {
|
|
|
15105
15203
|
enableRoute(route2) {
|
|
15106
15204
|
const file = configFile();
|
|
15107
15205
|
if (!file) return false;
|
|
15108
|
-
const text2 =
|
|
15206
|
+
const text2 = readFileSync34(file, "utf8");
|
|
15109
15207
|
const doc = parseDocument3(text2);
|
|
15110
15208
|
const routes = doc.get("routes");
|
|
15111
15209
|
const entry = routes?.items?.find((r) => r.get("route") === route2);
|
|
@@ -15131,7 +15229,7 @@ function realProvisionDeps(crewHome) {
|
|
|
15131
15229
|
continue;
|
|
15132
15230
|
}
|
|
15133
15231
|
for (const p of plan.unitPaths) {
|
|
15134
|
-
if (!existsSync34(p) ||
|
|
15232
|
+
if (!existsSync34(p) || readFileSync34(p, "utf8") !== plan.unitContent[p]) unitsStale = true;
|
|
15135
15233
|
}
|
|
15136
15234
|
}
|
|
15137
15235
|
const label = labelFor(crewHome, "run");
|
|
@@ -15155,7 +15253,7 @@ function realProvisionDeps(crewHome) {
|
|
|
15155
15253
|
setShipSetting(key, value2) {
|
|
15156
15254
|
const file = configFile();
|
|
15157
15255
|
if (!file) return false;
|
|
15158
|
-
const doc = parseDocument3(
|
|
15256
|
+
const doc = parseDocument3(readFileSync34(file, "utf8"));
|
|
15159
15257
|
if (doc.getIn(["ship", key]) === value2) return false;
|
|
15160
15258
|
doc.setIn(["ship", key], value2);
|
|
15161
15259
|
writeFileSync26(file, doc.toString());
|
|
@@ -15164,7 +15262,7 @@ function realProvisionDeps(crewHome) {
|
|
|
15164
15262
|
applyManagedDefaults() {
|
|
15165
15263
|
const file = configFile();
|
|
15166
15264
|
if (!file) return [];
|
|
15167
|
-
const doc = parseDocument3(
|
|
15265
|
+
const doc = parseDocument3(readFileSync34(file, "utf8"));
|
|
15168
15266
|
const wrote = applyManagedDefaultsToDoc(doc);
|
|
15169
15267
|
if (wrote.length) writeFileSync26(file, doc.toString());
|
|
15170
15268
|
return wrote;
|
|
@@ -15194,7 +15292,7 @@ host=${host}
|
|
|
15194
15292
|
|
|
15195
15293
|
// src/tunnel.ts
|
|
15196
15294
|
import { spawn as spawn7 } from "child_process";
|
|
15197
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync25, readFileSync as
|
|
15295
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync25, readFileSync as readFileSync35, writeFileSync as writeFileSync27, unlinkSync as unlinkSync3, readdirSync as readdirSync13 } from "fs";
|
|
15198
15296
|
import { randomInt } from "crypto";
|
|
15199
15297
|
import { join as join39 } from "path";
|
|
15200
15298
|
var DEFAULT_SPAWN_OPTIONS = { stdio: "ignore", detached: true };
|
|
@@ -15280,7 +15378,7 @@ function readPersistedTunnel(stateDir, workspaceId) {
|
|
|
15280
15378
|
const path = tunnelStatePath(stateDir, workspaceId);
|
|
15281
15379
|
if (!existsSync35(path)) return void 0;
|
|
15282
15380
|
try {
|
|
15283
|
-
return JSON.parse(
|
|
15381
|
+
return JSON.parse(readFileSync35(path, "utf8"));
|
|
15284
15382
|
} catch {
|
|
15285
15383
|
return void 0;
|
|
15286
15384
|
}
|
|
@@ -16825,7 +16923,7 @@ async function resolveOne(tracker, t, seat, approvedStatus, buildingStatus, affi
|
|
|
16825
16923
|
}
|
|
16826
16924
|
|
|
16827
16925
|
// src/repo-refresh.ts
|
|
16828
|
-
import { existsSync as existsSync37, mkdirSync as mkdirSync26, readFileSync as
|
|
16926
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync26, readFileSync as readFileSync36, writeFileSync as writeFileSync29 } from "fs";
|
|
16829
16927
|
import { dirname as dirname21 } from "path";
|
|
16830
16928
|
var REFRESH_COOLDOWN_MS = 2 * 6e4;
|
|
16831
16929
|
var UNSERVABLE_PASSES_BEFORE_ATTENTION = 3;
|
|
@@ -16856,7 +16954,7 @@ function applyRepoRows(resolved, rows) {
|
|
|
16856
16954
|
function persistRepoRows(stateDir, routeName, rows) {
|
|
16857
16955
|
const path = resolvedPathFor(stateDir, routeName);
|
|
16858
16956
|
if (!existsSync37(path)) return;
|
|
16859
|
-
const raw = JSON.parse(
|
|
16957
|
+
const raw = JSON.parse(readFileSync36(path, "utf8"));
|
|
16860
16958
|
applyRepoRows(raw, rows);
|
|
16861
16959
|
mkdirSync26(dirname21(path), { recursive: true });
|
|
16862
16960
|
writeFileSync29(path, `${JSON.stringify(raw, null, 2)}
|
|
@@ -17509,7 +17607,7 @@ function flagWizardAnswers(f, env) {
|
|
|
17509
17607
|
}
|
|
17510
17608
|
|
|
17511
17609
|
// src/release-run.ts
|
|
17512
|
-
import { readFileSync as
|
|
17610
|
+
import { readFileSync as readFileSync37, writeFileSync as writeFileSync31, existsSync as existsSync39, copyFileSync, mkdirSync as mkdirSync28, mkdtempSync as mkdtempSync3, rmSync as rmSync19 } from "fs";
|
|
17513
17611
|
import { dirname as dirname24, join as join43 } from "path";
|
|
17514
17612
|
import { tmpdir as tmpdir5, hostname as hostname4 } from "os";
|
|
17515
17613
|
|
|
@@ -18286,7 +18384,7 @@ async function bump(o, size) {
|
|
|
18286
18384
|
o.emit.error(`no ${o.repo.release.versionFiles[0]} to read a version from`);
|
|
18287
18385
|
return null;
|
|
18288
18386
|
}
|
|
18289
|
-
const firstText =
|
|
18387
|
+
const firstText = readFileSync37(first, "utf8");
|
|
18290
18388
|
const problem = versionFileProblem(o.repo.release.versionFiles[0], firstText);
|
|
18291
18389
|
if (problem) {
|
|
18292
18390
|
o.emit.error(problem);
|
|
@@ -18305,7 +18403,7 @@ async function bump(o, size) {
|
|
|
18305
18403
|
return version;
|
|
18306
18404
|
}
|
|
18307
18405
|
for (const f of files) {
|
|
18308
|
-
const src =
|
|
18406
|
+
const src = readFileSync37(f, "utf8");
|
|
18309
18407
|
const out = src.replace(/("version"\s*:\s*")[^"]*(")/, `$1${version}$2`);
|
|
18310
18408
|
if (out === src) {
|
|
18311
18409
|
o.emit.error(`no version field in ${f}`);
|
|
@@ -18324,7 +18422,7 @@ function writeChangelog(o, version, entries) {
|
|
|
18324
18422
|
o.emit.emit(`would prepend ${entries.length} entr(ies) to ${file}`);
|
|
18325
18423
|
return;
|
|
18326
18424
|
}
|
|
18327
|
-
const existing = existsSync39(path) ?
|
|
18425
|
+
const existing = existsSync39(path) ? readFileSync37(path, "utf8") : "# Changelog\n";
|
|
18328
18426
|
writeFileSync31(path, insertChangelogSection(existing, section));
|
|
18329
18427
|
}
|
|
18330
18428
|
async function confirm(o, expected) {
|
|
@@ -19841,7 +19939,7 @@ function nextRoles(decision, ran) {
|
|
|
19841
19939
|
}
|
|
19842
19940
|
|
|
19843
19941
|
// src/ship-name.ts
|
|
19844
|
-
import { existsSync as existsSync42, mkdirSync as mkdirSync30, readFileSync as
|
|
19942
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync30, readFileSync as readFileSync38, renameSync as renameSync5, writeFileSync as writeFileSync32 } from "fs";
|
|
19845
19943
|
import { dirname as dirname26 } from "path";
|
|
19846
19944
|
import { parseDocument as parseDocument5 } from "yaml";
|
|
19847
19945
|
var ShipNameError = class extends Error {
|
|
@@ -19905,7 +20003,7 @@ async function syncRouteName(i) {
|
|
|
19905
20003
|
function readSyncedName(resolvedFile) {
|
|
19906
20004
|
if (!existsSync42(resolvedFile)) return void 0;
|
|
19907
20005
|
try {
|
|
19908
|
-
const v = JSON.parse(
|
|
20006
|
+
const v = JSON.parse(readFileSync38(resolvedFile, "utf8")).shipName;
|
|
19909
20007
|
return typeof v === "string" ? v : void 0;
|
|
19910
20008
|
} catch {
|
|
19911
20009
|
return void 0;
|
|
@@ -19915,7 +20013,7 @@ function writeSyncedName(resolvedFile, name) {
|
|
|
19915
20013
|
if (!existsSync42(resolvedFile)) return;
|
|
19916
20014
|
let raw;
|
|
19917
20015
|
try {
|
|
19918
|
-
raw = JSON.parse(
|
|
20016
|
+
raw = JSON.parse(readFileSync38(resolvedFile, "utf8"));
|
|
19919
20017
|
} catch {
|
|
19920
20018
|
return;
|
|
19921
20019
|
}
|
|
@@ -19930,7 +20028,7 @@ function writeSyncedName(resolvedFile, name) {
|
|
|
19930
20028
|
async function reconcileShipName(i) {
|
|
19931
20029
|
let local = i.ship.name;
|
|
19932
20030
|
try {
|
|
19933
|
-
local = shipNameOfYaml(
|
|
20031
|
+
local = shipNameOfYaml(readFileSync38(i.configFile, "utf8")) ?? local;
|
|
19934
20032
|
} catch {
|
|
19935
20033
|
}
|
|
19936
20034
|
const resolvedFile = resolvedPathFor(i.stateDir, i.route);
|
|
@@ -19954,7 +20052,7 @@ async function reconcileShipName(i) {
|
|
|
19954
20052
|
}
|
|
19955
20053
|
if (result.status !== "ok") return result;
|
|
19956
20054
|
if (result.action === "adopt" || result.action === "row-wins") {
|
|
19957
|
-
const text2 =
|
|
20055
|
+
const text2 = readFileSync38(i.configFile, "utf8");
|
|
19958
20056
|
writeFileSync32(i.configFile, setShipNameInYaml(text2, result.name));
|
|
19959
20057
|
i.ship.name = result.name;
|
|
19960
20058
|
if (result.action === "row-wins") {
|
|
@@ -20614,7 +20712,7 @@ function describeCapability(i) {
|
|
|
20614
20712
|
}
|
|
20615
20713
|
|
|
20616
20714
|
// src/agents-sync-run.ts
|
|
20617
|
-
import { existsSync as existsSync43, mkdirSync as mkdirSync31, readFileSync as
|
|
20715
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync33 } from "fs";
|
|
20618
20716
|
import { dirname as dirname27 } from "path";
|
|
20619
20717
|
async function runAgentsSync(target, o) {
|
|
20620
20718
|
const dryRun = o.dryRun ?? false;
|
|
@@ -20648,7 +20746,7 @@ async function runAgentsSync(target, o) {
|
|
|
20648
20746
|
for (const s of skillResult?.outcomes ?? []) o.say(describeSkillSyncOutcome(s));
|
|
20649
20747
|
if (!dryRun) {
|
|
20650
20748
|
const resolvedPath = resolvedPathFor(o.stateDir, target.route);
|
|
20651
|
-
const raw = existsSync43(resolvedPath) ? JSON.parse(
|
|
20749
|
+
const raw = existsSync43(resolvedPath) ? JSON.parse(readFileSync39(resolvedPath, "utf8")) : {};
|
|
20652
20750
|
raw.agentPersonas = personaResult.agentPersonas;
|
|
20653
20751
|
if (skillResult) raw.agentSkills = skillResult.agentSkills;
|
|
20654
20752
|
if (personaResult.releaseAgentId) raw.releaseAgentId = personaResult.releaseAgentId;
|
|
@@ -20770,7 +20868,7 @@ async function showLogEntry(route2, entryId, opts = {}) {
|
|
|
20770
20868
|
|
|
20771
20869
|
// src/repos-check.ts
|
|
20772
20870
|
import { spawnSync as spawnSync11 } from "child_process";
|
|
20773
|
-
import { readFileSync as
|
|
20871
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
20774
20872
|
import { basename as basename11 } from "path";
|
|
20775
20873
|
var POSIX_SHELL = /^(?:ba|z|da|k|a|mk)?sh$|^fish$/;
|
|
20776
20874
|
function checkHookSyntax(script, shell) {
|
|
@@ -20811,7 +20909,7 @@ function checkRepoSpec(dir, opts = {}) {
|
|
|
20811
20909
|
}
|
|
20812
20910
|
let parsed;
|
|
20813
20911
|
try {
|
|
20814
|
-
parsed = parseRepoConfig(
|
|
20912
|
+
parsed = parseRepoConfig(readFileSync40(file, "utf8"), file);
|
|
20815
20913
|
} catch (e) {
|
|
20816
20914
|
if (!(e instanceof RepoConfigError)) throw e;
|
|
20817
20915
|
return { ...empty, file, error: e.message, exitCode: 1 };
|
|
@@ -21343,7 +21441,7 @@ function planSampleTicket(i) {
|
|
|
21343
21441
|
}
|
|
21344
21442
|
|
|
21345
21443
|
// src/worktree-sweep.ts
|
|
21346
|
-
import { existsSync as existsSync44, readFileSync as
|
|
21444
|
+
import { existsSync as existsSync44, readFileSync as readFileSync41, readdirSync as readdirSync14 } from "fs";
|
|
21347
21445
|
import { basename as basename13, dirname as dirname29, join as join45, resolve as resolve5 } from "path";
|
|
21348
21446
|
function planWorktreeSweep(target, tickets, contract) {
|
|
21349
21447
|
const terminal = new Set(contract.statuses.resolved.filter((s) => s !== contract.statuses.verified));
|
|
@@ -21524,7 +21622,7 @@ function isHandBackMerge(path, base) {
|
|
|
21524
21622
|
if (!msgPath) return false;
|
|
21525
21623
|
let first;
|
|
21526
21624
|
try {
|
|
21527
|
-
first =
|
|
21625
|
+
first = readFileSync41(resolve5(path, msgPath), "utf8").split("\n")[0] ?? "";
|
|
21528
21626
|
} catch {
|
|
21529
21627
|
return false;
|
|
21530
21628
|
}
|
|
@@ -21674,11 +21772,11 @@ function planEventsSweep(stateDir, retentionDays, now = Date.now()) {
|
|
|
21674
21772
|
}
|
|
21675
21773
|
|
|
21676
21774
|
// src/cli.ts
|
|
21677
|
-
import { realpathSync as realpathSync3, readFileSync as
|
|
21775
|
+
import { realpathSync as realpathSync3, readFileSync as readFileSync47, existsSync as existsSync52, mkdirSync as mkdirSync38, writeFileSync as writeFileSync38, rmSync as rmSync25, unlinkSync as unlinkSync5, copyFileSync as copyFileSync2, renameSync as renameSync6, statSync as statSync16, readdirSync as readdirSync20 } from "fs";
|
|
21678
21776
|
import { createInterface } from "readline/promises";
|
|
21679
21777
|
|
|
21680
21778
|
// src/periscope-cmd.ts
|
|
21681
|
-
import { existsSync as existsSync46, mkdirSync as mkdirSync32, readFileSync as
|
|
21779
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync32, readFileSync as readFileSync42, rmSync as rmSync21, writeFileSync as writeFileSync34 } from "fs";
|
|
21682
21780
|
import { join as join47 } from "path";
|
|
21683
21781
|
var PeriscopeError = class extends Error {
|
|
21684
21782
|
};
|
|
@@ -21704,7 +21802,7 @@ function writePeriscopePrior(stateDir, ticketRecordId, prior) {
|
|
|
21704
21802
|
function readPeriscopePrior(stateDir, ticketRecordId) {
|
|
21705
21803
|
try {
|
|
21706
21804
|
const p = priorPath(stateDir, ticketRecordId);
|
|
21707
|
-
return existsSync46(p) ? JSON.parse(
|
|
21805
|
+
return existsSync46(p) ? JSON.parse(readFileSync42(p, "utf8")) : void 0;
|
|
21708
21806
|
} catch {
|
|
21709
21807
|
return void 0;
|
|
21710
21808
|
}
|
|
@@ -22259,7 +22357,7 @@ import { dirname as dirOf2, resolve as resolvePath } from "path";
|
|
|
22259
22357
|
|
|
22260
22358
|
// src/ssh-keys.ts
|
|
22261
22359
|
import { execFileSync as execFileSync13 } from "child_process";
|
|
22262
|
-
import { existsSync as existsSync47, mkdirSync as mkdirSync33, readFileSync as
|
|
22360
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync33, readFileSync as readFileSync43, chmodSync as chmodSync3 } from "fs";
|
|
22263
22361
|
import { dirname as dirname30, join as join49 } from "path";
|
|
22264
22362
|
var SshKeyError = class extends Error {
|
|
22265
22363
|
};
|
|
@@ -22293,7 +22391,7 @@ function ensureShipSshKeypair(stateDir) {
|
|
|
22293
22391
|
if (!existsSync47(publicKeyPath)) {
|
|
22294
22392
|
throw new SshKeyError(`${privateKeyPath} exists but ${publicKeyPath} does not \u2014 regenerate or restore it`);
|
|
22295
22393
|
}
|
|
22296
|
-
const publicKey =
|
|
22394
|
+
const publicKey = readFileSync43(publicKeyPath, "utf8").trim();
|
|
22297
22395
|
return { privateKeyPath, publicKeyPath, publicKey };
|
|
22298
22396
|
}
|
|
22299
22397
|
function sshKeygenAvailable() {
|
|
@@ -22457,7 +22555,7 @@ async function unregisterEndpoint(workspaceId, info, d) {
|
|
|
22457
22555
|
import { createServer as createHttpServer } from "http";
|
|
22458
22556
|
import { spawn as spawn9 } from "child_process";
|
|
22459
22557
|
import { randomBytes } from "crypto";
|
|
22460
|
-
import { existsSync as existsSync48, mkdirSync as mkdirSync34, readFileSync as
|
|
22558
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync34, readFileSync as readFileSync44, writeFileSync as writeFileSync35, unlinkSync as unlinkSync4, readdirSync as readdirSync16 } from "fs";
|
|
22461
22559
|
import { join as join50 } from "path";
|
|
22462
22560
|
|
|
22463
22561
|
// src/secret-compare.ts
|
|
@@ -22557,7 +22655,7 @@ function readPersistedSyncDaemon(stateDir, workspaceId) {
|
|
|
22557
22655
|
const path = syncDaemonStatePath(stateDir, workspaceId);
|
|
22558
22656
|
if (!existsSync48(path)) return void 0;
|
|
22559
22657
|
try {
|
|
22560
|
-
return JSON.parse(
|
|
22658
|
+
return JSON.parse(readFileSync44(path, "utf8"));
|
|
22561
22659
|
} catch {
|
|
22562
22660
|
return void 0;
|
|
22563
22661
|
}
|
|
@@ -23106,7 +23204,7 @@ function contractFixers(dir, baseRef, tickets, locate) {
|
|
|
23106
23204
|
}
|
|
23107
23205
|
|
|
23108
23206
|
// src/daemon.ts
|
|
23109
|
-
import { existsSync as existsSync49, mkdirSync as mkdirSync36, readFileSync as
|
|
23207
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync36, readFileSync as readFileSync45, readdirSync as readdirSync17, rmSync as rmSync22, statSync as statSync14, writeFileSync as writeFileSync36 } from "fs";
|
|
23110
23208
|
import { join as join52 } from "path";
|
|
23111
23209
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
23112
23210
|
var DEFAULT_FLOOR_MS = 5e3;
|
|
@@ -23227,7 +23325,7 @@ function noteDaemonStarted(stateDir, now = Date.now()) {
|
|
|
23227
23325
|
}
|
|
23228
23326
|
function readDaemonStarted(stateDir) {
|
|
23229
23327
|
try {
|
|
23230
|
-
const v = JSON.parse(
|
|
23328
|
+
const v = JSON.parse(readFileSync45(daemonStampFor(stateDir), "utf8")).startedAt;
|
|
23231
23329
|
return typeof v === "number" ? v : null;
|
|
23232
23330
|
} catch {
|
|
23233
23331
|
return null;
|
|
@@ -23410,6 +23508,12 @@ async function runOnePassUnguarded(o) {
|
|
|
23410
23508
|
clearShipAttention(o.state, workspaceAllowanceKey(role));
|
|
23411
23509
|
}).catch(async (e) => {
|
|
23412
23510
|
const message = e.message;
|
|
23511
|
+
if (e instanceof SignedOutError) {
|
|
23512
|
+
breaker.pause(role, SIGNED_OUT_PAUSE_MS);
|
|
23513
|
+
emit.warn(`${role} paused: ${message}`, { step: "agent", role });
|
|
23514
|
+
await raiseShipAttention({ state: o.state, emit, route: o.route, ship: o.ship }, signedOutItem(e.toolchain, e.mode));
|
|
23515
|
+
return;
|
|
23516
|
+
}
|
|
23413
23517
|
if (e instanceof WorkspaceAllowanceExhausted) {
|
|
23414
23518
|
breaker.pause(role, ALLOWANCE_PAUSE_MS);
|
|
23415
23519
|
emit.warn(`${role} paused: ${message}`, { step: "agent", role });
|
|
@@ -23751,6 +23855,7 @@ async function runRoleAgentLocked(role, decision, ctx, hooks, held) {
|
|
|
23751
23855
|
if (plan.workspaceAuth && streamShowsAllowanceRefusal(plan.streamPath)) {
|
|
23752
23856
|
throw new WorkspaceAllowanceExhausted("the inference endpoint refused the run: the workspace is past its AI allowance");
|
|
23753
23857
|
}
|
|
23858
|
+
await settleSignOut(plan, tracker, ctx.state, workingId, emit);
|
|
23754
23859
|
}
|
|
23755
23860
|
} finally {
|
|
23756
23861
|
await settleRunEnd({
|
|
@@ -23787,6 +23892,26 @@ async function buildEnvironment(route2, ship, ticket) {
|
|
|
23787
23892
|
const attachments = await tracker.attachmentsProbe().catch(() => null);
|
|
23788
23893
|
return renderEnvironment({ route: route2, userAgent: ship.userAgent, repos: await withRepoMaps(repos, ship.mapTokenBudget, ship.shell), contract, sourceTicket: ticket, authorship, attachments, shipName: ship.name, ...sandboxEnv(ship) });
|
|
23789
23894
|
}
|
|
23895
|
+
async function settleSignOut(plan, tracker, state, ticketId, emit) {
|
|
23896
|
+
const toolchain = plan.toolchain;
|
|
23897
|
+
if (!toolchain) return;
|
|
23898
|
+
if (!streamShowsSignedOut(plan.streamPath)) {
|
|
23899
|
+
if (streamShowsRealTurn(plan.streamPath)) clearShipAttention(state, signedOutKey(toolchain));
|
|
23900
|
+
return;
|
|
23901
|
+
}
|
|
23902
|
+
if (ticketId) {
|
|
23903
|
+
try {
|
|
23904
|
+
const affinity = await tracker.claimAffinity();
|
|
23905
|
+
const current = await tracker.ticket(ticketId);
|
|
23906
|
+
if (affinity && current[affinity.column] === affinity.shipId) {
|
|
23907
|
+
await tracker.updateTicket(ticketId, { [affinity.column]: null }, current.updated_at);
|
|
23908
|
+
}
|
|
23909
|
+
} catch (e) {
|
|
23910
|
+
emit.warn(`could not release the ticket hold after a sign-out: ${e.message}`, { step: "agent" });
|
|
23911
|
+
}
|
|
23912
|
+
}
|
|
23913
|
+
throw new SignedOutError(toolchain, plan.authMode ?? "login");
|
|
23914
|
+
}
|
|
23790
23915
|
|
|
23791
23916
|
// src/control-api.ts
|
|
23792
23917
|
import { createHash as createHash11 } from "crypto";
|
|
@@ -24477,7 +24602,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
24477
24602
|
|
|
24478
24603
|
// src/periscope-endpoints.ts
|
|
24479
24604
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
24480
|
-
import { chmodSync as chmodSync5, existsSync as existsSync51, mkdirSync as mkdirSync37, readdirSync as readdirSync19, readFileSync as
|
|
24605
|
+
import { chmodSync as chmodSync5, existsSync as existsSync51, mkdirSync as mkdirSync37, readdirSync as readdirSync19, readFileSync as readFileSync46, rmSync as rmSync24, writeFileSync as writeFileSync37 } from "fs";
|
|
24481
24606
|
import { join as join54 } from "path";
|
|
24482
24607
|
var secretDir = (stateDir) => join54(stateDir, "periscope-mcp");
|
|
24483
24608
|
var secretFile = (stateDir, id) => join54(secretDir(stateDir), `${id}.json`);
|
|
@@ -24494,7 +24619,7 @@ function mintPeriscopeSecret(stateDir, ticketRecordId) {
|
|
|
24494
24619
|
}
|
|
24495
24620
|
function readPeriscopeSecret(stateDir, ticketRecordId) {
|
|
24496
24621
|
try {
|
|
24497
|
-
const v = JSON.parse(
|
|
24622
|
+
const v = JSON.parse(readFileSync46(secretFile(stateDir, ticketRecordId), "utf8"));
|
|
24498
24623
|
return typeof v.secret === "string" && v.secret ? v.secret : void 0;
|
|
24499
24624
|
} catch {
|
|
24500
24625
|
return void 0;
|
|
@@ -24505,7 +24630,7 @@ function removePeriscopeSecret(stateDir, ticketRecordId) {
|
|
|
24505
24630
|
}
|
|
24506
24631
|
function readPeriscopeEndpoint(stateDir, ticketRecordId) {
|
|
24507
24632
|
try {
|
|
24508
|
-
return JSON.parse(
|
|
24633
|
+
return JSON.parse(readFileSync46(endpointFile(stateDir, ticketRecordId), "utf8"));
|
|
24509
24634
|
} catch {
|
|
24510
24635
|
return void 0;
|
|
24511
24636
|
}
|
|
@@ -25254,7 +25379,7 @@ if (command === "provision") {
|
|
|
25254
25379
|
process.exit(outcome.code);
|
|
25255
25380
|
}
|
|
25256
25381
|
if (command === "pool-member") {
|
|
25257
|
-
const pool = poolConfigFrom(argv, process.env, () =>
|
|
25382
|
+
const pool = poolConfigFrom(argv, process.env, () => readFileSync47(0, "utf8"));
|
|
25258
25383
|
if (typeof pool === "string") {
|
|
25259
25384
|
process.stderr.write(`crew pool-member: ${pool}
|
|
25260
25385
|
`);
|
|
@@ -25518,7 +25643,7 @@ if (command === "passenger-sync-daemon") {
|
|
|
25518
25643
|
throw e;
|
|
25519
25644
|
}
|
|
25520
25645
|
if (command === "credential") {
|
|
25521
|
-
const r = runCredential(positional[1],
|
|
25646
|
+
const r = runCredential(positional[1], readFileSync47(0, "utf8"), cfg.ship.forges, cfg.ship.stateDir);
|
|
25522
25647
|
process.stdout.write(r.out);
|
|
25523
25648
|
process.stderr.write(r.err);
|
|
25524
25649
|
process.exit(r.code);
|
|
@@ -25530,9 +25655,9 @@ if (command === "passenger-sync-daemon") {
|
|
|
25530
25655
|
forges: cfg.ship.forges,
|
|
25531
25656
|
stateDir: cfg.ship.stateDir,
|
|
25532
25657
|
configFile: cfg.configFile,
|
|
25533
|
-
readFile: (p) =>
|
|
25658
|
+
readFile: (p) => readFileSync47(p, "utf8"),
|
|
25534
25659
|
writeFile: (p, t) => writeFileSync38(p, t),
|
|
25535
|
-
stdin: () =>
|
|
25660
|
+
stdin: () => readFileSync47(0, "utf8"),
|
|
25536
25661
|
env: process.env
|
|
25537
25662
|
}
|
|
25538
25663
|
);
|
|
@@ -25929,7 +26054,7 @@ if (command === "passenger-sync-daemon") {
|
|
|
25929
26054
|
for (const a of plan.actions) {
|
|
25930
26055
|
if (a.kind === "enable") {
|
|
25931
26056
|
if (prompter && !await prompter.confirm(`Route ${a.route} passes every check \u2014 set enabled: true in ${cfg.configFile}?`, false)) continue;
|
|
25932
|
-
writeFileSync38(cfg.configFile, planEnable(
|
|
26057
|
+
writeFileSync38(cfg.configFile, planEnable(readFileSync47(cfg.configFile, "utf8"), a.route));
|
|
25933
26058
|
enabledSound.add(a.route);
|
|
25934
26059
|
changed2.push(`enabled route ${a.route} in ${cfg.configFile}`);
|
|
25935
26060
|
} else {
|
|
@@ -27430,7 +27555,7 @@ ${cu.tail.trimEnd()}
|
|
|
27430
27555
|
`);
|
|
27431
27556
|
if (!dryRun) {
|
|
27432
27557
|
const resolvedPath = resolvedPathFor(cfg.ship.stateDir, target.route);
|
|
27433
|
-
const raw = existsSync52(resolvedPath) ? JSON.parse(
|
|
27558
|
+
const raw = existsSync52(resolvedPath) ? JSON.parse(readFileSync47(resolvedPath, "utf8")) : {};
|
|
27434
27559
|
raw.agentSkills = result.agentSkills;
|
|
27435
27560
|
mkdirSync38(dirOf2(resolvedPath), { recursive: true });
|
|
27436
27561
|
writeFileSync38(resolvedPath, `${JSON.stringify(raw, null, 2)}
|
|
@@ -27456,7 +27581,7 @@ ${cu.tail.trimEnd()}
|
|
|
27456
27581
|
throw e;
|
|
27457
27582
|
}
|
|
27458
27583
|
const oldName = cfg.ship.name;
|
|
27459
|
-
writeFileSync38(cfg.configFile, setShipNameInYaml(
|
|
27584
|
+
writeFileSync38(cfg.configFile, setShipNameInYaml(readFileSync47(cfg.configFile, "utf8"), newName));
|
|
27460
27585
|
cfg.ship.name = newName;
|
|
27461
27586
|
let renameMachineId;
|
|
27462
27587
|
try {
|
|
@@ -27503,7 +27628,7 @@ ${cu.tail.trimEnd()}
|
|
|
27503
27628
|
process.exit(2);
|
|
27504
27629
|
};
|
|
27505
27630
|
if (sub !== "add" && sub !== "list" && sub !== "clone" && sub !== "hooks" && sub !== "check") usage2();
|
|
27506
|
-
const configText =
|
|
27631
|
+
const configText = readFileSync47(cfg.configFile, "utf8");
|
|
27507
27632
|
if (sub === "check") {
|
|
27508
27633
|
try {
|
|
27509
27634
|
const routeArg = value("route") ?? positional[2];
|
|
@@ -27544,7 +27669,7 @@ ${cu.tail.trimEnd()}
|
|
|
27544
27669
|
}
|
|
27545
27670
|
}, read: (r) => {
|
|
27546
27671
|
try {
|
|
27547
|
-
return
|
|
27672
|
+
return readFileSync47(resolvePath(dir, r), "utf8");
|
|
27548
27673
|
} catch {
|
|
27549
27674
|
return void 0;
|
|
27550
27675
|
}
|
|
@@ -27695,7 +27820,7 @@ ${cu.tail.trimEnd()}
|
|
|
27695
27820
|
let resolvedRemotes;
|
|
27696
27821
|
if (existsSync52(resolvedFile)) {
|
|
27697
27822
|
try {
|
|
27698
|
-
resolvedRemotes = JSON.parse(
|
|
27823
|
+
resolvedRemotes = JSON.parse(readFileSync47(resolvedFile, "utf8"));
|
|
27699
27824
|
} catch {
|
|
27700
27825
|
}
|
|
27701
27826
|
}
|
|
@@ -27717,7 +27842,7 @@ ${cu.tail.trimEnd()}
|
|
|
27717
27842
|
repoHasHooks: (d) => REPO_CONFIG_FILENAMES.some((f) => {
|
|
27718
27843
|
try {
|
|
27719
27844
|
const path = resolvePath(d, f);
|
|
27720
|
-
return Object.keys(parseRepoConfig(
|
|
27845
|
+
return Object.keys(parseRepoConfig(readFileSync47(path, "utf8"), path).hooks).length > 0;
|
|
27721
27846
|
} catch {
|
|
27722
27847
|
return false;
|
|
27723
27848
|
}
|
|
@@ -27826,7 +27951,7 @@ ${cu.tail.trimEnd()}
|
|
|
27826
27951
|
process.stdout.write(`created Repos row ${String(rowPayload.name)} (${String(rowPayload.remote)}) ${created.id}
|
|
27827
27952
|
`);
|
|
27828
27953
|
if (existsSync52(resolvedFile)) {
|
|
27829
|
-
const raw = JSON.parse(
|
|
27954
|
+
const raw = JSON.parse(readFileSync47(resolvedFile, "utf8"));
|
|
27830
27955
|
raw.repoNames = { ...raw.repoNames, [created.id]: String(rowPayload.name) };
|
|
27831
27956
|
raw.repoRemotes = { ...raw.repoRemotes, [created.id]: String(rowPayload.remote) };
|
|
27832
27957
|
writeFileSync38(resolvedFile, `${JSON.stringify(raw, null, 2)}
|
|
@@ -28204,7 +28329,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
28204
28329
|
process.exit(2);
|
|
28205
28330
|
}
|
|
28206
28331
|
if (found.shipNameAdopted && !dryRun) {
|
|
28207
|
-
writeFileSync38(cfg.configFile, setShipNameInYaml(
|
|
28332
|
+
writeFileSync38(cfg.configFile, setShipNameInYaml(readFileSync47(cfg.configFile, "utf8"), found.shipNameAdopted));
|
|
28208
28333
|
cfg.ship.name = found.shipNameAdopted;
|
|
28209
28334
|
}
|
|
28210
28335
|
if (found.shipRow) {
|
|
@@ -28250,7 +28375,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
28250
28375
|
const hadPreviousFile = existsSync52(resolvedPath);
|
|
28251
28376
|
if (hadPreviousFile) {
|
|
28252
28377
|
try {
|
|
28253
|
-
previous = JSON.parse(
|
|
28378
|
+
previous = JSON.parse(readFileSync47(resolvedPath, "utf8"));
|
|
28254
28379
|
} catch {
|
|
28255
28380
|
}
|
|
28256
28381
|
}
|
|
@@ -29760,7 +29885,7 @@ ${where.join("\n")}`);
|
|
|
29760
29885
|
};
|
|
29761
29886
|
const droppedRoutes = [];
|
|
29762
29887
|
try {
|
|
29763
|
-
const rawCfg = parseYaml2(
|
|
29888
|
+
const rawCfg = parseYaml2(readFileSync47(cfg.configFile, "utf8"));
|
|
29764
29889
|
for (const r of rawCfg?.routes ?? []) {
|
|
29765
29890
|
if (typeof r?.route !== "string" || cfg.routes.some((x) => x.route === r.route)) continue;
|
|
29766
29891
|
try {
|
|
@@ -29879,7 +30004,7 @@ ${where.join("\n")}`);
|
|
|
29879
30004
|
}
|
|
29880
30005
|
case "log": {
|
|
29881
30006
|
try {
|
|
29882
|
-
const text2 =
|
|
30007
|
+
const text2 = readFileSync47(cfg.ship.logFile, "utf8").split("\n");
|
|
29883
30008
|
process.stdout.write(`${text2.slice(-(Number(value("tail")) || 40)).join("\n")}
|
|
29884
30009
|
`);
|
|
29885
30010
|
} catch {
|
|
@@ -29902,7 +30027,7 @@ ${where.join("\n")}`);
|
|
|
29902
30027
|
};
|
|
29903
30028
|
if (!route2.resolved) fail2(`route ${route2.route} is not connected \u2014 run \`crew connect\` first`);
|
|
29904
30029
|
const tracker = new Tracker(route2, cfg.ship);
|
|
29905
|
-
const configText =
|
|
30030
|
+
const configText = readFileSync47(cfg.configFile, "utf8");
|
|
29906
30031
|
const cfgBase = dirname34(cfg.configFile);
|
|
29907
30032
|
const configured2 = configuredRepos(configText, route2.route, cfgBase);
|
|
29908
30033
|
const dir = configured2.find((r) => r.name === SAMPLE_REPO)?.dir ?? sampleDir(configured2.map((r) => r.dir), route2.reposBasePath, route2.route.split("/")[0]);
|
|
@@ -29940,7 +30065,7 @@ ${where.join("\n")}`);
|
|
|
29940
30065
|
if (row) {
|
|
29941
30066
|
await tracker.deleteRepoRow(row.id);
|
|
29942
30067
|
if (existsSync52(resolvedFile)) {
|
|
29943
|
-
const raw = JSON.parse(
|
|
30068
|
+
const raw = JSON.parse(readFileSync47(resolvedFile, "utf8"));
|
|
29944
30069
|
if (raw.repoNames) delete raw.repoNames[row.id];
|
|
29945
30070
|
if (raw.repoRemotes) delete raw.repoRemotes[row.id];
|
|
29946
30071
|
writeFileSync38(resolvedFile, `${JSON.stringify(raw, null, 2)}
|
|
@@ -29980,7 +30105,7 @@ ${where.join("\n")}`);
|
|
|
29980
30105
|
});
|
|
29981
30106
|
repoId = (await tracker.createRepoRow(payload)).id;
|
|
29982
30107
|
if (existsSync52(resolvedFile)) {
|
|
29983
|
-
const raw = JSON.parse(
|
|
30108
|
+
const raw = JSON.parse(readFileSync47(resolvedFile, "utf8"));
|
|
29984
30109
|
raw.repoNames = { ...raw.repoNames, [repoId]: SAMPLE_REPO };
|
|
29985
30110
|
raw.repoRemotes = { ...raw.repoRemotes, [repoId]: SAMPLE_REMOTE };
|
|
29986
30111
|
writeFileSync38(resolvedFile, `${JSON.stringify(raw, null, 2)}
|
|
@@ -30454,7 +30579,7 @@ routes: ${cfg.routes.map((c) => c.route).join(", ")}
|
|
|
30454
30579
|
const unitPlan = planInstall(cfg.ship, CREW_HOME, host, detectSystemd(), "run", installContext());
|
|
30455
30580
|
const abandons = unitAbandonsAgents(unitPlan, (p) => {
|
|
30456
30581
|
try {
|
|
30457
|
-
return
|
|
30582
|
+
return readFileSync47(p, "utf8");
|
|
30458
30583
|
} catch {
|
|
30459
30584
|
return null;
|
|
30460
30585
|
}
|
package/package.json
CHANGED