@archme/cli 0.8.0 → 0.8.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 +168 -50
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10005,9 +10005,23 @@ async function tailLog(opts = {}) {
|
|
|
10005
10005
|
await new Promise((resolve6, reject) => {
|
|
10006
10006
|
let fileWatcher = null;
|
|
10007
10007
|
let dirWatcher = null;
|
|
10008
|
+
let poller = null;
|
|
10009
|
+
let settled = false;
|
|
10008
10010
|
const dir = dirname7(path7);
|
|
10009
10011
|
const name = basename(path7);
|
|
10010
|
-
const
|
|
10012
|
+
const stop = () => {
|
|
10013
|
+
settled = true;
|
|
10014
|
+
fileWatcher?.close();
|
|
10015
|
+
dirWatcher?.close();
|
|
10016
|
+
if (poller) clearInterval(poller);
|
|
10017
|
+
process.removeListener("SIGINT", handleSigint);
|
|
10018
|
+
};
|
|
10019
|
+
const fail = (err2) => {
|
|
10020
|
+
if (settled) return;
|
|
10021
|
+
stop();
|
|
10022
|
+
reject(err2);
|
|
10023
|
+
};
|
|
10024
|
+
const readNew = async () => {
|
|
10011
10025
|
try {
|
|
10012
10026
|
const st = await stat(path7);
|
|
10013
10027
|
if (st.size < offset) offset = 0;
|
|
@@ -10020,61 +10034,50 @@ async function tailLog(opts = {}) {
|
|
|
10020
10034
|
});
|
|
10021
10035
|
offset = st.size;
|
|
10022
10036
|
}
|
|
10037
|
+
if (!fileWatcher && !settled) attachFileWatcher();
|
|
10023
10038
|
} catch (err2) {
|
|
10024
10039
|
if (err2.code === "ENOENT") return;
|
|
10025
|
-
|
|
10040
|
+
fail(err2);
|
|
10026
10041
|
}
|
|
10027
10042
|
};
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
});
|
|
10033
|
-
} catch (err2) {
|
|
10034
|
-
if (err2.code !== "ENOENT") {
|
|
10035
|
-
reject(err2);
|
|
10036
|
-
return;
|
|
10037
|
-
}
|
|
10038
|
-
attachDirWatcher();
|
|
10039
|
-
}
|
|
10043
|
+
let chain = Promise.resolve();
|
|
10044
|
+
const drain = () => {
|
|
10045
|
+
if (settled) return;
|
|
10046
|
+
chain = chain.then(readNew);
|
|
10040
10047
|
};
|
|
10041
|
-
const
|
|
10048
|
+
const attachFileWatcher = () => {
|
|
10042
10049
|
try {
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
attachFileWatcher();
|
|
10049
|
-
});
|
|
10050
|
-
}
|
|
10051
|
-
});
|
|
10052
|
-
} catch (err2) {
|
|
10053
|
-
reject(err2);
|
|
10050
|
+
fileWatcher = watch(path7, () => drain());
|
|
10051
|
+
dirWatcher?.close();
|
|
10052
|
+
dirWatcher = null;
|
|
10053
|
+
} catch {
|
|
10054
|
+
fileWatcher = null;
|
|
10054
10055
|
}
|
|
10055
10056
|
};
|
|
10056
|
-
|
|
10057
|
-
() =>
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
}
|
|
10065
|
-
);
|
|
10057
|
+
try {
|
|
10058
|
+
dirWatcher = watch(dir, (_event, filename) => {
|
|
10059
|
+
if (filename === name) drain();
|
|
10060
|
+
});
|
|
10061
|
+
} catch (err2) {
|
|
10062
|
+
fail(err2);
|
|
10063
|
+
return;
|
|
10064
|
+
}
|
|
10066
10065
|
const handleSigint = () => {
|
|
10067
|
-
|
|
10068
|
-
|
|
10066
|
+
if (settled) return;
|
|
10067
|
+
stop();
|
|
10069
10068
|
resolve6();
|
|
10070
10069
|
};
|
|
10071
10070
|
process.once("SIGINT", handleSigint);
|
|
10071
|
+
poller = setInterval(drain, FOLLOW_POLL_MS);
|
|
10072
|
+
drain();
|
|
10072
10073
|
});
|
|
10073
10074
|
}
|
|
10075
|
+
var FOLLOW_POLL_MS;
|
|
10074
10076
|
var init_logs = __esm({
|
|
10075
10077
|
"src/daemon/service/logs.ts"() {
|
|
10076
10078
|
"use strict";
|
|
10077
10079
|
init_paths();
|
|
10080
|
+
FOLLOW_POLL_MS = 500;
|
|
10078
10081
|
}
|
|
10079
10082
|
});
|
|
10080
10083
|
|
|
@@ -10344,10 +10347,31 @@ var init_preflight = __esm({
|
|
|
10344
10347
|
});
|
|
10345
10348
|
|
|
10346
10349
|
// ../shared/daemonModel.ts
|
|
10347
|
-
|
|
10350
|
+
function parseClaudeCodeVersion(output) {
|
|
10351
|
+
return /(\d+)\.(\d+)\.(\d+)/.exec(output ?? "")?.[0] ?? null;
|
|
10352
|
+
}
|
|
10353
|
+
function versionBelow(version, minimum) {
|
|
10354
|
+
const a2 = version.split(".").map(Number);
|
|
10355
|
+
const b = minimum.split(".").map(Number);
|
|
10356
|
+
for (let i2 = 0; i2 < Math.max(a2.length, b.length); i2++) {
|
|
10357
|
+
const d = (a2[i2] ?? 0) - (b[i2] ?? 0);
|
|
10358
|
+
if (d !== 0) return d < 0;
|
|
10359
|
+
}
|
|
10360
|
+
return false;
|
|
10361
|
+
}
|
|
10362
|
+
function runnableModel(requested, installedVersion) {
|
|
10363
|
+
const needs = MIN_CLAUDE_CODE_VERSION[requested];
|
|
10364
|
+
if (!needs || !installedVersion || !versionBelow(installedVersion, needs)) return { model: requested };
|
|
10365
|
+
return { model: FALLBACK_CLAUDE_MODEL, fellBack: { from: requested, needs } };
|
|
10366
|
+
}
|
|
10367
|
+
var DEFAULT_CLAUDE_MODEL, FALLBACK_CLAUDE_MODEL, MIN_CLAUDE_CODE_VERSION;
|
|
10348
10368
|
var init_daemonModel = __esm({
|
|
10349
10369
|
"../shared/daemonModel.ts"() {
|
|
10350
10370
|
DEFAULT_CLAUDE_MODEL = "claude-opus-5-5";
|
|
10371
|
+
FALLBACK_CLAUDE_MODEL = "claude-opus-4-8";
|
|
10372
|
+
MIN_CLAUDE_CODE_VERSION = {
|
|
10373
|
+
"claude-opus-5-5": "2.1.280"
|
|
10374
|
+
};
|
|
10351
10375
|
}
|
|
10352
10376
|
});
|
|
10353
10377
|
|
|
@@ -10509,6 +10533,39 @@ var init_spawn_claude = __esm({
|
|
|
10509
10533
|
}
|
|
10510
10534
|
});
|
|
10511
10535
|
|
|
10536
|
+
// src/scan/claudeVersion.ts
|
|
10537
|
+
async function runClaudeVersion() {
|
|
10538
|
+
const r = await execa("claude", ["--version"], { reject: false, timeout: 15e3 });
|
|
10539
|
+
return r.exitCode === 0 ? String(r.stdout) : null;
|
|
10540
|
+
}
|
|
10541
|
+
function createClaudeVersionProbe(opts = {}) {
|
|
10542
|
+
const exec = opts.exec ?? runClaudeVersion;
|
|
10543
|
+
const now = opts.now ?? Date.now;
|
|
10544
|
+
const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
10545
|
+
let cached;
|
|
10546
|
+
return async () => {
|
|
10547
|
+
if (cached && now() - cached.at < ttlMs) return cached.version;
|
|
10548
|
+
let version = null;
|
|
10549
|
+
try {
|
|
10550
|
+
version = parseClaudeCodeVersion(await exec());
|
|
10551
|
+
} catch {
|
|
10552
|
+
version = null;
|
|
10553
|
+
}
|
|
10554
|
+
cached = { version, at: now() };
|
|
10555
|
+
return version;
|
|
10556
|
+
};
|
|
10557
|
+
}
|
|
10558
|
+
var DEFAULT_TTL_MS, claudeCodeVersion;
|
|
10559
|
+
var init_claudeVersion = __esm({
|
|
10560
|
+
"src/scan/claudeVersion.ts"() {
|
|
10561
|
+
"use strict";
|
|
10562
|
+
init_execa();
|
|
10563
|
+
init_daemonModel();
|
|
10564
|
+
DEFAULT_TTL_MS = 10 * 6e4;
|
|
10565
|
+
claudeCodeVersion = createClaudeVersionProbe();
|
|
10566
|
+
}
|
|
10567
|
+
});
|
|
10568
|
+
|
|
10512
10569
|
// src/scan/model-pin.ts
|
|
10513
10570
|
async function resolveModelPin(supabase) {
|
|
10514
10571
|
try {
|
|
@@ -10522,10 +10579,30 @@ async function resolveModelPin(supabase) {
|
|
|
10522
10579
|
return DEFAULT_CLAUDE_MODEL;
|
|
10523
10580
|
}
|
|
10524
10581
|
}
|
|
10582
|
+
async function resolveRunnableModel(supabase, deps = {}) {
|
|
10583
|
+
const requested = await resolveModelPin(supabase);
|
|
10584
|
+
const installed = await (deps.version ?? claudeCodeVersion)();
|
|
10585
|
+
const { model, fellBack } = runnableModel(requested, installed);
|
|
10586
|
+
if (fellBack) {
|
|
10587
|
+
const warned = deps.warned ?? warnedFallbacks;
|
|
10588
|
+
const key = `${fellBack.from}@${installed}`;
|
|
10589
|
+
if (!warned.has(key)) {
|
|
10590
|
+
warned.add(key);
|
|
10591
|
+
(deps.warn ?? console.warn)(
|
|
10592
|
+
`Claude Code ${installed} can't run ${fellBack.from} (needs ${fellBack.needs}+); running ${model} instead. Run \`claude update\` to use ${fellBack.from}.`
|
|
10593
|
+
);
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
return model;
|
|
10597
|
+
}
|
|
10598
|
+
var warnedFallbacks;
|
|
10525
10599
|
var init_model_pin = __esm({
|
|
10526
10600
|
"src/scan/model-pin.ts"() {
|
|
10527
10601
|
"use strict";
|
|
10528
10602
|
init_spawn_claude();
|
|
10603
|
+
init_daemonModel();
|
|
10604
|
+
init_claudeVersion();
|
|
10605
|
+
warnedFallbacks = /* @__PURE__ */ new Set();
|
|
10529
10606
|
}
|
|
10530
10607
|
});
|
|
10531
10608
|
|
|
@@ -10646,7 +10723,7 @@ async function runDigestJob(ctx, job, deviceId, inFlight2, mcp) {
|
|
|
10646
10723
|
mcpConfigPath = join8(dir, "mcp.json");
|
|
10647
10724
|
await writeFile5(mcpConfigPath, JSON.stringify({ mcpServers: {} }));
|
|
10648
10725
|
}
|
|
10649
|
-
const model = await
|
|
10726
|
+
const model = await resolveRunnableModel(ctx.supabase);
|
|
10650
10727
|
const proc = spawnClaude({
|
|
10651
10728
|
prompt: buildDigestPrompt(payload),
|
|
10652
10729
|
mcpConfigPath,
|
|
@@ -13220,6 +13297,13 @@ var init_sequenceChapters = __esm({
|
|
|
13220
13297
|
}
|
|
13221
13298
|
});
|
|
13222
13299
|
|
|
13300
|
+
// ../shared/architectureDiff.ts
|
|
13301
|
+
var init_architectureDiff = __esm({
|
|
13302
|
+
"../shared/architectureDiff.ts"() {
|
|
13303
|
+
init_storyChanges();
|
|
13304
|
+
}
|
|
13305
|
+
});
|
|
13306
|
+
|
|
13223
13307
|
// ../shared/walkthrough.ts
|
|
13224
13308
|
var MAX_WALKTHROUGH_STEPS, MAX_STEP_TITLE_CHARS;
|
|
13225
13309
|
var init_walkthrough = __esm({
|
|
@@ -13227,6 +13311,7 @@ var init_walkthrough = __esm({
|
|
|
13227
13311
|
init_storyChanges();
|
|
13228
13312
|
init_sequenceChapters();
|
|
13229
13313
|
init_validationCodes();
|
|
13314
|
+
init_architectureDiff();
|
|
13230
13315
|
MAX_WALKTHROUGH_STEPS = 20;
|
|
13231
13316
|
MAX_STEP_TITLE_CHARS = 60;
|
|
13232
13317
|
}
|
|
@@ -13243,13 +13328,15 @@ var init_walkthroughGuidance = __esm({
|
|
|
13243
13328
|
- **Steps are in reading order, not build order.** This is not an implementation plan and not a restatement of your sequencing section \u2014 start where a reviewer should start, and put each step where it makes the next one make sense.
|
|
13244
13329
|
- **Group by idea.** One step is one coherent change, usually 3\u20138 elements. A one-element step is fine and often valuable: an independent fix that would otherwise be lost among the rest. Aim for a handful of steps; the cap is ${MAX_WALKTHROUGH_STEPS}.
|
|
13245
13330
|
- **Titles are terse** \u2014 a handle, not a summary. Under ${MAX_STEP_TITLE_CHARS} characters. \`Markers move per-repo\`, not \`This step explains how the source marker moves onto a per-repo table\`.
|
|
13246
|
-
- **
|
|
13247
|
-
-
|
|
13331
|
+
- **Every step gets a short description** \u2014 the narration a reader follows while the diagrams move beside it, one step at a time. Two or three plain sentences: what this part of the change is, why it exists, and how it fits the rest, at a high level. Example: \`This is the daemon picking up GitHub's answer after it posts a comment, review or approval on your behalf, and recording whether it worked.\`
|
|
13332
|
+
- Not prescriptive: describe the change, do not tell the reviewer what to check or what to think of it.
|
|
13333
|
+
- Not dense: no condensed paragraph of identifiers, flags and edge cases crammed into one sentence. Never restate the components, stories or connections the step already references \u2014 the reader is looking at them.
|
|
13334
|
+
- **Write it for someone meeting this change for the first time.** They know the system; they have NOT read your proposal body and were not in the design discussion. Say plainly what the step does and why it is there.
|
|
13248
13335
|
- Don't argue with objections the reader hasn't raised \u2014 no \`not just a nicety\`, no \`as discussed\`, no \`this is why it is its own step\`. They don't know how the walkthrough was assembled and haven't disagreed with you. A trade-off worth stating is information (\`X was considered; it breaks Y\`), not a rebuttal.
|
|
13249
13336
|
- Don't use the change's OWN new vocabulary undefined. If the step introduces a term, say what it means in the same breath or use plain words.
|
|
13250
13337
|
- Bad: \`A correctness item, not a phase-3 nicety: anchors are repo-relative paths, so two repos with the same conventional layout collide silently and seed stories from the wrong one.\`
|
|
13251
13338
|
- Good: \`With two repos in one project a path like src/index.ts exists in both, so looking up which component owns a changed file can return the wrong repo's. Each repo now records the container its code lives under, and lookups search only that subtree.\`
|
|
13252
|
-
- **Cover every story the change touches
|
|
13339
|
+
- **Cover every change** \u2014 every story, component and connection the change touches \u2014 or \`set_walkthrough\` rejects the walkthrough and lists what is missing. Guided mode walks the steps and nothing after them, so anything no step reaches is a change the reviewer never sees. A connection is covered when a step names it, names both of its components, or names a story page that draws it as an arrow. Name a connection inside a component as \`<component path>::<id>\` (\`daemon::session_auth->key_account\`); a root connection by its plain id.
|
|
13253
13340
|
- **Skip it for a small change.** A handful of elements needs no walkthrough; omit it rather than writing a step per element.
|
|
13254
13341
|
- **Prefer CHAPTERS to narrow a diagram.** If a story's sequence carries \`%% chapter: <id> | <Label>\` markers, name the ones your step covers as \`chapters: [{ story, chapter }]\`, using the **id**, never the label \u2014 ids are stable across a rename, labels are not. A chapter is a page break the story's author already wrote, so it is sharper than naming components, where one hub the step mentions decides the whole view.`;
|
|
13255
13342
|
}
|
|
@@ -16055,7 +16142,9 @@ function observeGithubPull(p) {
|
|
|
16055
16142
|
createdAt: p.created_at ?? null,
|
|
16056
16143
|
updatedAt: p.updated_at ?? null,
|
|
16057
16144
|
mergedAt: p.merged_at ?? null,
|
|
16058
|
-
closedAt: p.closed_at ?? null
|
|
16145
|
+
closedAt: p.closed_at ?? null,
|
|
16146
|
+
// Before the merge it is GitHub's throwaway test merge.
|
|
16147
|
+
mergeCommitSha: p.merged_at ? p.merge_commit_sha ?? null : null
|
|
16059
16148
|
};
|
|
16060
16149
|
}
|
|
16061
16150
|
function metaKey(o2) {
|
|
@@ -16090,6 +16179,7 @@ function toItem(o2, action, sent) {
|
|
|
16090
16179
|
created_at: o2.createdAt,
|
|
16091
16180
|
merged_at: o2.mergedAt,
|
|
16092
16181
|
closed_at: o2.closedAt,
|
|
16182
|
+
merge_commit_sha: o2.mergeCommitSha,
|
|
16093
16183
|
body: o2.body,
|
|
16094
16184
|
...action === "synchronize" && sent.seq !== void 0 ? { seq: sent.seq } : {}
|
|
16095
16185
|
};
|
|
@@ -16499,6 +16589,22 @@ var init_defaultBranch = __esm({
|
|
|
16499
16589
|
}
|
|
16500
16590
|
});
|
|
16501
16591
|
|
|
16592
|
+
// ../shared/prRefs.ts
|
|
16593
|
+
function pushCommitSubject(message) {
|
|
16594
|
+
if (message == null) return null;
|
|
16595
|
+
const [subject = "", ...body] = message.split("\n");
|
|
16596
|
+
const pr = MERGE_PR_SUBJECT.exec(subject.trim());
|
|
16597
|
+
const title = body.find((line) => line.trim())?.trim();
|
|
16598
|
+
return pr && title && !TRAILER_LINE.test(title) ? `${title} (#${pr[1]})` : subject;
|
|
16599
|
+
}
|
|
16600
|
+
var MERGE_PR_SUBJECT, TRAILER_LINE;
|
|
16601
|
+
var init_prRefs = __esm({
|
|
16602
|
+
"../shared/prRefs.ts"() {
|
|
16603
|
+
MERGE_PR_SUBJECT = /^Merge pull request #(\d+) from \S+$/;
|
|
16604
|
+
TRAILER_LINE = /^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+:\s/;
|
|
16605
|
+
}
|
|
16606
|
+
});
|
|
16607
|
+
|
|
16502
16608
|
// src/daemon/localGit.ts
|
|
16503
16609
|
var localGit_exports = {};
|
|
16504
16610
|
__export(localGit_exports, {
|
|
@@ -16567,13 +16673,14 @@ async function firstParentRange(dir, marker, tip) {
|
|
|
16567
16673
|
async function readCommitMeta(dir, sha) {
|
|
16568
16674
|
const { exitCode, stdout } = await git(
|
|
16569
16675
|
dir,
|
|
16570
|
-
|
|
16676
|
+
// %b last: it spans lines, and `pushCommitSubject` reads a merge commit's title from it.
|
|
16677
|
+
["show", "-s", "--format=%an%n%cI%n%s%n%b", sha],
|
|
16571
16678
|
{ allowFail: true }
|
|
16572
16679
|
);
|
|
16573
16680
|
if (exitCode !== 0) return { message: "", authorName: null, committedAt: null };
|
|
16574
|
-
const [
|
|
16681
|
+
const [authorName = "", committedAt = "", ...message] = stdout.split("\n");
|
|
16575
16682
|
return {
|
|
16576
|
-
message: message.trim(),
|
|
16683
|
+
message: (pushCommitSubject(message.join("\n")) ?? "").trim(),
|
|
16577
16684
|
authorName: authorName.trim() || null,
|
|
16578
16685
|
committedAt: committedAt.trim() || null
|
|
16579
16686
|
};
|
|
@@ -16602,6 +16709,7 @@ var init_localGit = __esm({
|
|
|
16602
16709
|
init_execa();
|
|
16603
16710
|
init_preflight();
|
|
16604
16711
|
init_defaultBranch();
|
|
16712
|
+
init_prRefs();
|
|
16605
16713
|
GIT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
16606
16714
|
}
|
|
16607
16715
|
});
|
|
@@ -17051,6 +17159,7 @@ __export(run_exports, {
|
|
|
17051
17159
|
buildClaudeExitMessage: () => buildClaudeExitMessage,
|
|
17052
17160
|
buildDevices: () => buildDevices,
|
|
17053
17161
|
buildDiffPrompt: () => buildDiffPrompt,
|
|
17162
|
+
claudeFailureDetail: () => claudeFailureDetail,
|
|
17054
17163
|
computeDiff: () => computeDiff,
|
|
17055
17164
|
parseClaudeResult: () => parseClaudeResult,
|
|
17056
17165
|
probeMcpAuth: () => probeMcpAuth,
|
|
@@ -17074,6 +17183,12 @@ function attributeKillCause(result, recorded) {
|
|
|
17074
17183
|
function buildClaudeExitMessage(exitCode, causeSuffix, stderr) {
|
|
17075
17184
|
return `claude exited ${exitCode}${causeSuffix}: ${stderr.slice(0, 4e3)}`;
|
|
17076
17185
|
}
|
|
17186
|
+
function claudeFailureDetail(stderr, stdout) {
|
|
17187
|
+
if (stderr.trim() || !stdout.trim()) return null;
|
|
17188
|
+
const parsed = parseClaudeResult(stdout);
|
|
17189
|
+
const text = (parsed.parsed ? parsed.summary : stdout).trim();
|
|
17190
|
+
return text ? text.slice(-FAILURE_DETAIL_MAX) : null;
|
|
17191
|
+
}
|
|
17077
17192
|
async function routeShutdownInterrupt(id, cancelled2, fail, exitCode) {
|
|
17078
17193
|
if (cancelled2.has(id)) return;
|
|
17079
17194
|
if (exitCode === 0) {
|
|
@@ -18016,7 +18131,7 @@ async function runJob(ctx, job, claimDeviceId) {
|
|
|
18016
18131
|
`MCP auth preflight failed after ${probe.attempts} attempt(s) (last status ${probe.lastStatus ?? "n/a"}): ${probe.detail}. Not spawning claude \u2014 the architecture would not be writable and the run would silently no-op. Failing the job so it retries with a freshly minted token.`
|
|
18017
18132
|
);
|
|
18018
18133
|
}
|
|
18019
|
-
const model = await
|
|
18134
|
+
const model = await resolveRunnableModel(ctx.supabase, { warn: log });
|
|
18020
18135
|
metrics.model = model;
|
|
18021
18136
|
log(`spawning claude (mcp config at ${configPath}, model ${model})`);
|
|
18022
18137
|
const proc = spawnClaude({
|
|
@@ -18054,6 +18169,8 @@ async function runJob(ctx, job, claimDeviceId) {
|
|
|
18054
18169
|
if (result.exitCode !== 0) {
|
|
18055
18170
|
const causeSuffix = cause ? ` (${result.signal ?? "exit"}, cause: ${cause})` : "";
|
|
18056
18171
|
const stderr = result.stderr ? String(result.stderr) : "";
|
|
18172
|
+
const detail = claudeFailureDetail(stderr, result.stdout ? String(result.stdout) : "");
|
|
18173
|
+
if (detail) log(`claude output: ${detail.replace(/\n/g, " ")}`);
|
|
18057
18174
|
throw new Error(buildClaudeExitMessage(result.exitCode, causeSuffix, stderr));
|
|
18058
18175
|
}
|
|
18059
18176
|
const runResult = parseClaudeResult(result.stdout ? String(result.stdout) : "");
|
|
@@ -18557,7 +18674,7 @@ ${signal} received, shutting down`);
|
|
|
18557
18674
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
18558
18675
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
18559
18676
|
}
|
|
18560
|
-
var HEARTBEAT_INTERVAL_MS, CLAUDE_TIMEOUT_MS, CLAUDE_LARGE_DIFF_TIMEOUT_MS, SAFETY_SWEEP_MS, LOG_STDOUT_CAP_BYTES, LOG_STDERR_CAP_BYTES, PRE_SPAWN_TOKEN_MIN_LIFETIME_MS, SUPABASE_URL, SUPABASE_ANON_KEY, ARCHME_DAEMON_CLIENT_ID, ARCHME_MCP_BASE_URL, CLONE_BASE_DIR, DAEMON_ID, LEASE_SECONDS, inFlight, cancelled, killReasons, activeCleanups, cloneMutex, shuttingDown, daemonVersion, pauseUntilMs, resumeTimer, currentSched, MAX_CONCURRENT_JOBS, ctxByJob, deviceByJob, DEFAULT_CLONE_BASE_DIR, INLINE_PATCH_BYTE_CAP, GIT_SHA_RE, CURATOR_PREAMBLE, CORE_PRINCIPLES, STORY_COVERAGE_GATE, NEW_STORY_GUIDANCE, STORY_DESCRIPTION_EDIT_RULE, PHASE_GUIDANCE, BASE_RULES, DIFF_RULES, finite, channelSeq, MultipleAccountsError, __testDispatch;
|
|
18677
|
+
var HEARTBEAT_INTERVAL_MS, CLAUDE_TIMEOUT_MS, CLAUDE_LARGE_DIFF_TIMEOUT_MS, SAFETY_SWEEP_MS, LOG_STDOUT_CAP_BYTES, LOG_STDERR_CAP_BYTES, FAILURE_DETAIL_MAX, PRE_SPAWN_TOKEN_MIN_LIFETIME_MS, SUPABASE_URL, SUPABASE_ANON_KEY, ARCHME_DAEMON_CLIENT_ID, ARCHME_MCP_BASE_URL, CLONE_BASE_DIR, DAEMON_ID, LEASE_SECONDS, inFlight, cancelled, killReasons, activeCleanups, cloneMutex, shuttingDown, daemonVersion, pauseUntilMs, resumeTimer, currentSched, MAX_CONCURRENT_JOBS, ctxByJob, deviceByJob, DEFAULT_CLONE_BASE_DIR, INLINE_PATCH_BYTE_CAP, GIT_SHA_RE, CURATOR_PREAMBLE, CORE_PRINCIPLES, STORY_COVERAGE_GATE, NEW_STORY_GUIDANCE, STORY_DESCRIPTION_EDIT_RULE, PHASE_GUIDANCE, BASE_RULES, DIFF_RULES, finite, channelSeq, MultipleAccountsError, __testDispatch;
|
|
18561
18678
|
var init_run = __esm({
|
|
18562
18679
|
"src/daemon/run.ts"() {
|
|
18563
18680
|
"use strict";
|
|
@@ -18603,6 +18720,7 @@ var init_run = __esm({
|
|
|
18603
18720
|
SAFETY_SWEEP_MS = 3e4;
|
|
18604
18721
|
LOG_STDOUT_CAP_BYTES = 30 * 1024;
|
|
18605
18722
|
LOG_STDERR_CAP_BYTES = 30 * 1024;
|
|
18723
|
+
FAILURE_DETAIL_MAX = 400;
|
|
18606
18724
|
PRE_SPAWN_TOKEN_MIN_LIFETIME_MS = CLAUDE_LARGE_DIFF_TIMEOUT_MS + 5 * 60 * 1e3;
|
|
18607
18725
|
inFlight = /* @__PURE__ */ new Map();
|
|
18608
18726
|
cancelled = /* @__PURE__ */ new Set();
|
|
@@ -19983,7 +20101,7 @@ async function runScan(opts, deps = {}) {
|
|
|
19983
20101
|
...sourceRepo ? { source: await buildScanSource(opts.repoPath, sourceRepo, headSha) } : {}
|
|
19984
20102
|
});
|
|
19985
20103
|
try {
|
|
19986
|
-
const model = await
|
|
20104
|
+
const model = await resolveRunnableModel(supabase, { warn: log });
|
|
19987
20105
|
const interactive = opts.interactive !== false;
|
|
19988
20106
|
log(
|
|
19989
20107
|
interactive ? `starting claude (mcp config at ${configPath}, model ${model}) \u2014 this session is interactive; answer its questions as they come` : `spawning claude (mcp config at ${configPath}, model ${model}, timeout ${Math.round(SCAN_CLAUDE_TIMEOUT_MS / 6e4)} min)`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archme/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Map your codebase into a living architecture diagram: run `archme init` in a repo to scan it, `archme daemon start` to keep it current on every commit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|