claudekit-cli 3.42.2-dev.6 → 3.42.2-dev.8
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/cli-manifest.json +2 -2
- package/dist/index.js +405 -53
- package/package.json +1 -1
package/cli-manifest.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -62389,7 +62389,7 @@ var package_default;
|
|
|
62389
62389
|
var init_package = __esm(() => {
|
|
62390
62390
|
package_default = {
|
|
62391
62391
|
name: "claudekit-cli",
|
|
62392
|
-
version: "3.42.2-dev.
|
|
62392
|
+
version: "3.42.2-dev.8",
|
|
62393
62393
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
62394
62394
|
type: "module",
|
|
62395
62395
|
repository: {
|
|
@@ -63356,6 +63356,9 @@ async function invalidateAuth() {
|
|
|
63356
63356
|
cachedOctokit = null;
|
|
63357
63357
|
logger.debug("Invalidated cached authentication due to 401 error");
|
|
63358
63358
|
}
|
|
63359
|
+
function resetClient() {
|
|
63360
|
+
cachedOctokit = null;
|
|
63361
|
+
}
|
|
63359
63362
|
var cachedOctokit = null;
|
|
63360
63363
|
var init_auth_api = __esm(() => {
|
|
63361
63364
|
init_claudekit_constants();
|
|
@@ -64268,6 +64271,16 @@ var init_asset_utils = __esm(() => {
|
|
|
64268
64271
|
});
|
|
64269
64272
|
|
|
64270
64273
|
// src/domains/github/client/index.ts
|
|
64274
|
+
var exports_client = {};
|
|
64275
|
+
__export(exports_client, {
|
|
64276
|
+
resetClient: () => resetClient,
|
|
64277
|
+
invalidateAuth: () => invalidateAuth,
|
|
64278
|
+
handleHttpError: () => handleHttpError,
|
|
64279
|
+
getDownloadableAsset: () => getDownloadableAsset,
|
|
64280
|
+
getAuthenticatedClient: () => getAuthenticatedClient,
|
|
64281
|
+
RepoApi: () => RepoApi,
|
|
64282
|
+
ReleasesApi: () => ReleasesApi
|
|
64283
|
+
});
|
|
64271
64284
|
var init_client = __esm(() => {
|
|
64272
64285
|
init_auth_api();
|
|
64273
64286
|
init_error_handler2();
|
|
@@ -73512,7 +73525,7 @@ async function restoreOriginalBranch(branchName, cwd2, issueNumber) {
|
|
|
73512
73525
|
}
|
|
73513
73526
|
}
|
|
73514
73527
|
function spawnAndCollect(command, args, cwd2) {
|
|
73515
|
-
return new Promise((
|
|
73528
|
+
return new Promise((resolve44, reject) => {
|
|
73516
73529
|
const child = spawn6(command, args, { ...cwd2 && { cwd: cwd2 }, stdio: ["ignore", "pipe", "pipe"] });
|
|
73517
73530
|
const chunks = [];
|
|
73518
73531
|
const stderrChunks = [];
|
|
@@ -73525,7 +73538,7 @@ function spawnAndCollect(command, args, cwd2) {
|
|
|
73525
73538
|
reject(new Error(`${command} ${args[0] ?? ""} exited with code ${code2}: ${stderr}`));
|
|
73526
73539
|
return;
|
|
73527
73540
|
}
|
|
73528
|
-
|
|
73541
|
+
resolve44(Buffer.concat(chunks).toString("utf-8"));
|
|
73529
73542
|
});
|
|
73530
73543
|
});
|
|
73531
73544
|
}
|
|
@@ -76327,8 +76340,8 @@ function shouldRunCleanup(lastAt) {
|
|
|
76327
76340
|
return Date.now() - new Date(lastAt).getTime() >= 86400000;
|
|
76328
76341
|
}
|
|
76329
76342
|
function sleep2(ms) {
|
|
76330
|
-
return new Promise((
|
|
76331
|
-
setTimeout(
|
|
76343
|
+
return new Promise((resolve44) => {
|
|
76344
|
+
setTimeout(resolve44, ms);
|
|
76332
76345
|
});
|
|
76333
76346
|
}
|
|
76334
76347
|
var LOCK_DIR2, LOCK_FILE, MAX_CREATION_RETRIES = 3, MAX_PUBLISH_RETRIES_PER_CYCLE = 3, PUBLISH_RETRY_WINDOW_HOURS = 24;
|
|
@@ -78611,7 +78624,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
78611
78624
|
return [];
|
|
78612
78625
|
}
|
|
78613
78626
|
async function trySystemPager(content) {
|
|
78614
|
-
return new Promise((
|
|
78627
|
+
return new Promise((resolve44) => {
|
|
78615
78628
|
const pagerCmd = process.env.PAGER || "less";
|
|
78616
78629
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
78617
78630
|
try {
|
|
@@ -78621,20 +78634,20 @@ async function trySystemPager(content) {
|
|
|
78621
78634
|
});
|
|
78622
78635
|
const timeout2 = setTimeout(() => {
|
|
78623
78636
|
pager.kill();
|
|
78624
|
-
|
|
78637
|
+
resolve44(false);
|
|
78625
78638
|
}, 30000);
|
|
78626
78639
|
pager.stdin.write(content);
|
|
78627
78640
|
pager.stdin.end();
|
|
78628
78641
|
pager.on("close", (code2) => {
|
|
78629
78642
|
clearTimeout(timeout2);
|
|
78630
|
-
|
|
78643
|
+
resolve44(code2 === 0);
|
|
78631
78644
|
});
|
|
78632
78645
|
pager.on("error", () => {
|
|
78633
78646
|
clearTimeout(timeout2);
|
|
78634
|
-
|
|
78647
|
+
resolve44(false);
|
|
78635
78648
|
});
|
|
78636
78649
|
} catch {
|
|
78637
|
-
|
|
78650
|
+
resolve44(false);
|
|
78638
78651
|
}
|
|
78639
78652
|
});
|
|
78640
78653
|
}
|
|
@@ -78661,16 +78674,16 @@ async function basicPager(content) {
|
|
|
78661
78674
|
break;
|
|
78662
78675
|
}
|
|
78663
78676
|
const remaining = lines.length - currentLine;
|
|
78664
|
-
await new Promise((
|
|
78677
|
+
await new Promise((resolve44) => {
|
|
78665
78678
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
78666
78679
|
if (answer.toLowerCase() === "q") {
|
|
78667
78680
|
rl.close();
|
|
78668
78681
|
process.exitCode = 0;
|
|
78669
|
-
|
|
78682
|
+
resolve44();
|
|
78670
78683
|
return;
|
|
78671
78684
|
}
|
|
78672
78685
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
78673
|
-
|
|
78686
|
+
resolve44();
|
|
78674
78687
|
});
|
|
78675
78688
|
});
|
|
78676
78689
|
}
|
|
@@ -86223,6 +86236,20 @@ import { join as join86, resolve as resolve31 } from "node:path";
|
|
|
86223
86236
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
86224
86237
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
86225
86238
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
86239
|
+
|
|
86240
|
+
class FixerDidNotConvergeError extends Error {
|
|
86241
|
+
unresolved;
|
|
86242
|
+
constructor(unresolved) {
|
|
86243
|
+
const lines = unresolved.map((f3) => ` ${f3.label} :: ${f3.eventName} :: ${f3.command}`).join(`
|
|
86244
|
+
`);
|
|
86245
|
+
super(`ck doctor --fix: fixer did not converge — ${unresolved.length} stale hook command path(s) remain after repair:
|
|
86246
|
+
${lines}
|
|
86247
|
+
|
|
86248
|
+
This is a bug. Please open an issue at https://github.com/mrgoonie/claudekit-cli`);
|
|
86249
|
+
this.name = "FixerDidNotConvergeError";
|
|
86250
|
+
this.unresolved = unresolved;
|
|
86251
|
+
}
|
|
86252
|
+
}
|
|
86226
86253
|
function getHooksDir(projectDir) {
|
|
86227
86254
|
const projectHooksDir = resolve31(projectDir, ".claude", "hooks");
|
|
86228
86255
|
const globalHooksDir = resolve31(PathResolver.getGlobalKitDir(), "hooks");
|
|
@@ -86316,13 +86343,18 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
|
|
|
86316
86343
|
if (!settings?.hooks) {
|
|
86317
86344
|
return 0;
|
|
86318
86345
|
}
|
|
86346
|
+
const findings = collectHookCommandFindings(settings, settingsFile);
|
|
86347
|
+
if (findings.length === 0) {
|
|
86348
|
+
return 0;
|
|
86349
|
+
}
|
|
86350
|
+
const repairMap = new Map(findings.map((f3) => [f3.command, f3.expected]));
|
|
86319
86351
|
let repaired = 0;
|
|
86320
86352
|
for (const entries of Object.values(settings.hooks)) {
|
|
86321
86353
|
for (const entry of entries) {
|
|
86322
86354
|
if ("command" in entry && typeof entry.command === "string") {
|
|
86323
|
-
const
|
|
86324
|
-
if (
|
|
86325
|
-
entry.command =
|
|
86355
|
+
const fixed = repairMap.get(entry.command);
|
|
86356
|
+
if (fixed !== undefined) {
|
|
86357
|
+
entry.command = fixed;
|
|
86326
86358
|
repaired++;
|
|
86327
86359
|
}
|
|
86328
86360
|
}
|
|
@@ -86333,9 +86365,9 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
|
|
|
86333
86365
|
if (!hook.command) {
|
|
86334
86366
|
continue;
|
|
86335
86367
|
}
|
|
86336
|
-
const
|
|
86337
|
-
if (
|
|
86338
|
-
hook.command =
|
|
86368
|
+
const fixed = repairMap.get(hook.command);
|
|
86369
|
+
if (fixed !== undefined) {
|
|
86370
|
+
hook.command = fixed;
|
|
86339
86371
|
repaired++;
|
|
86340
86372
|
}
|
|
86341
86373
|
}
|
|
@@ -86344,6 +86376,10 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
|
|
|
86344
86376
|
if (repaired > 0) {
|
|
86345
86377
|
await SettingsMerger.writeSettingsFile(settingsFile.path, settings);
|
|
86346
86378
|
}
|
|
86379
|
+
const remaining = collectHookCommandFindings(settings, settingsFile);
|
|
86380
|
+
if (remaining.length > 0) {
|
|
86381
|
+
throw new FixerDidNotConvergeError(remaining);
|
|
86382
|
+
}
|
|
86347
86383
|
return repaired;
|
|
86348
86384
|
}
|
|
86349
86385
|
async function checkHookSyntax(projectDir) {
|
|
@@ -88231,6 +88267,313 @@ class NetworkChecker {
|
|
|
88231
88267
|
}
|
|
88232
88268
|
}
|
|
88233
88269
|
}
|
|
88270
|
+
// src/domains/health-checks/checkers/github-reachability-checker.ts
|
|
88271
|
+
init_environment();
|
|
88272
|
+
init_logger();
|
|
88273
|
+
init_types3();
|
|
88274
|
+
import * as dnsPromises from "node:dns/promises";
|
|
88275
|
+
import * as https from "node:https";
|
|
88276
|
+
import * as net2 from "node:net";
|
|
88277
|
+
var DNS_TIMEOUT_MS = (() => {
|
|
88278
|
+
const envVal = Number.parseInt(process.env.CLAUDEKIT_DNS_TIMEOUT ?? "", 10);
|
|
88279
|
+
return Number.isFinite(envVal) && envVal > 0 ? envVal : 500;
|
|
88280
|
+
})();
|
|
88281
|
+
var TCP_TIMEOUT_MS = 1000;
|
|
88282
|
+
var TLS_TIMEOUT_MS = 3000;
|
|
88283
|
+
var AUTH_TIMEOUT_MS = 5000;
|
|
88284
|
+
var API_HOST = "api.github.com";
|
|
88285
|
+
var ZEN_URL = `https://${API_HOST}/zen`;
|
|
88286
|
+
var PROBE_KIT = "engineer";
|
|
88287
|
+
function createDefaultDeps() {
|
|
88288
|
+
return {
|
|
88289
|
+
dns: createDefaultDns(),
|
|
88290
|
+
tcp: createDefaultTcp(),
|
|
88291
|
+
tls: createDefaultTls(),
|
|
88292
|
+
auth: createDefaultAuth()
|
|
88293
|
+
};
|
|
88294
|
+
}
|
|
88295
|
+
function createDefaultDns() {
|
|
88296
|
+
return {
|
|
88297
|
+
resolve4: (host) => dnsPromises.resolve4(host),
|
|
88298
|
+
resolve6: (host) => dnsPromises.resolve6(host)
|
|
88299
|
+
};
|
|
88300
|
+
}
|
|
88301
|
+
function createDefaultTcp() {
|
|
88302
|
+
return {
|
|
88303
|
+
connect: ({ host, port, timeoutMs }) => new Promise((resolve32) => {
|
|
88304
|
+
const start = Date.now();
|
|
88305
|
+
const socket = net2.createConnection({ host, port });
|
|
88306
|
+
const timer = setTimeout(() => {
|
|
88307
|
+
socket.destroy();
|
|
88308
|
+
resolve32({ ok: false, layer: "tcp", detail: "timeout", latencyMs: Date.now() - start });
|
|
88309
|
+
}, timeoutMs);
|
|
88310
|
+
socket.on("connect", () => {
|
|
88311
|
+
clearTimeout(timer);
|
|
88312
|
+
socket.destroy();
|
|
88313
|
+
resolve32({
|
|
88314
|
+
ok: true,
|
|
88315
|
+
layer: "tcp",
|
|
88316
|
+
detail: "connected",
|
|
88317
|
+
latencyMs: Date.now() - start
|
|
88318
|
+
});
|
|
88319
|
+
});
|
|
88320
|
+
socket.on("error", (err) => {
|
|
88321
|
+
clearTimeout(timer);
|
|
88322
|
+
resolve32({
|
|
88323
|
+
ok: false,
|
|
88324
|
+
layer: "tcp",
|
|
88325
|
+
detail: err.message,
|
|
88326
|
+
latencyMs: Date.now() - start
|
|
88327
|
+
});
|
|
88328
|
+
});
|
|
88329
|
+
})
|
|
88330
|
+
};
|
|
88331
|
+
}
|
|
88332
|
+
function createDefaultTls() {
|
|
88333
|
+
return {
|
|
88334
|
+
get: (url, timeoutMs) => new Promise((resolve32) => {
|
|
88335
|
+
const start = Date.now();
|
|
88336
|
+
const timer = setTimeout(() => {
|
|
88337
|
+
req.destroy();
|
|
88338
|
+
resolve32({ ok: false, layer: "tls", detail: "timeout", latencyMs: Date.now() - start });
|
|
88339
|
+
}, timeoutMs);
|
|
88340
|
+
const req = https.get(url, {
|
|
88341
|
+
headers: {
|
|
88342
|
+
"User-Agent": "claudekit-cli-doctor/1.0"
|
|
88343
|
+
}
|
|
88344
|
+
}, (res) => {
|
|
88345
|
+
res.resume();
|
|
88346
|
+
clearTimeout(timer);
|
|
88347
|
+
const status = res.statusCode ?? 0;
|
|
88348
|
+
const latencyMs = Date.now() - start;
|
|
88349
|
+
if (status === 200) {
|
|
88350
|
+
resolve32({ ok: true, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
88351
|
+
} else {
|
|
88352
|
+
resolve32({ ok: false, layer: "tls", detail: `HTTP ${status}`, latencyMs });
|
|
88353
|
+
}
|
|
88354
|
+
});
|
|
88355
|
+
req.on("error", (err) => {
|
|
88356
|
+
clearTimeout(timer);
|
|
88357
|
+
resolve32({
|
|
88358
|
+
ok: false,
|
|
88359
|
+
layer: "tls",
|
|
88360
|
+
detail: err.message,
|
|
88361
|
+
latencyMs: Date.now() - start
|
|
88362
|
+
});
|
|
88363
|
+
});
|
|
88364
|
+
})
|
|
88365
|
+
};
|
|
88366
|
+
}
|
|
88367
|
+
function createDefaultAuth() {
|
|
88368
|
+
return {
|
|
88369
|
+
checkKitAccess: async () => {
|
|
88370
|
+
const start = Date.now();
|
|
88371
|
+
const { getAuthenticatedClient: getAuthenticatedClient2 } = await Promise.resolve().then(() => (init_client(), exports_client));
|
|
88372
|
+
const kit = AVAILABLE_KITS[PROBE_KIT];
|
|
88373
|
+
try {
|
|
88374
|
+
const client = await getAuthenticatedClient2();
|
|
88375
|
+
await client.repos.get({ owner: kit.owner, repo: kit.repo });
|
|
88376
|
+
return {
|
|
88377
|
+
ok: true,
|
|
88378
|
+
layer: "auth",
|
|
88379
|
+
detail: "200 OK",
|
|
88380
|
+
latencyMs: Date.now() - start,
|
|
88381
|
+
statusCode: 200
|
|
88382
|
+
};
|
|
88383
|
+
} catch (err) {
|
|
88384
|
+
const latencyMs = Date.now() - start;
|
|
88385
|
+
const status = err?.status ?? err?.statusCode;
|
|
88386
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
88387
|
+
if (status === 401) {
|
|
88388
|
+
return {
|
|
88389
|
+
ok: false,
|
|
88390
|
+
layer: "auth",
|
|
88391
|
+
detail: `401 Unauthorized — token invalid or missing. ${message}`,
|
|
88392
|
+
latencyMs,
|
|
88393
|
+
statusCode: 401
|
|
88394
|
+
};
|
|
88395
|
+
}
|
|
88396
|
+
if (status === 404) {
|
|
88397
|
+
return {
|
|
88398
|
+
ok: false,
|
|
88399
|
+
layer: "auth",
|
|
88400
|
+
detail: `404 — no repository access (invitation pending). ${message}`,
|
|
88401
|
+
latencyMs,
|
|
88402
|
+
statusCode: 404
|
|
88403
|
+
};
|
|
88404
|
+
}
|
|
88405
|
+
return {
|
|
88406
|
+
ok: false,
|
|
88407
|
+
layer: "auth",
|
|
88408
|
+
detail: `${status ?? "?"} — ${message}`,
|
|
88409
|
+
latencyMs,
|
|
88410
|
+
statusCode: status
|
|
88411
|
+
};
|
|
88412
|
+
}
|
|
88413
|
+
}
|
|
88414
|
+
};
|
|
88415
|
+
}
|
|
88416
|
+
async function checkGitHubReachability(deps) {
|
|
88417
|
+
const dnsStart = Date.now();
|
|
88418
|
+
let dnsResult;
|
|
88419
|
+
try {
|
|
88420
|
+
const [r4, r6] = await Promise.allSettled([
|
|
88421
|
+
raceTimeout(deps.dns.resolve4(API_HOST), DNS_TIMEOUT_MS),
|
|
88422
|
+
raceTimeout(deps.dns.resolve6(API_HOST), DNS_TIMEOUT_MS)
|
|
88423
|
+
]);
|
|
88424
|
+
const ok = r4.status === "fulfilled" || r6.status === "fulfilled";
|
|
88425
|
+
let detail;
|
|
88426
|
+
if (ok) {
|
|
88427
|
+
if (r4.status === "fulfilled") {
|
|
88428
|
+
detail = `resolved: ${r4.value[0]}`;
|
|
88429
|
+
} else {
|
|
88430
|
+
const r6Value = r6.value;
|
|
88431
|
+
detail = `resolved (IPv6): ${r6Value[0]}`;
|
|
88432
|
+
}
|
|
88433
|
+
} else {
|
|
88434
|
+
detail = "NXDOMAIN / timeout";
|
|
88435
|
+
}
|
|
88436
|
+
dnsResult = { ok, layer: "dns", detail, latencyMs: Date.now() - dnsStart };
|
|
88437
|
+
} catch {
|
|
88438
|
+
dnsResult = {
|
|
88439
|
+
ok: false,
|
|
88440
|
+
layer: "dns",
|
|
88441
|
+
detail: "DNS resolution failed",
|
|
88442
|
+
latencyMs: Date.now() - dnsStart
|
|
88443
|
+
};
|
|
88444
|
+
}
|
|
88445
|
+
if (!dnsResult.ok) {
|
|
88446
|
+
return { ok: false, failedLayer: "dns", layers: { dns: dnsResult } };
|
|
88447
|
+
}
|
|
88448
|
+
const tcpResult = await deps.tcp.connect({
|
|
88449
|
+
host: API_HOST,
|
|
88450
|
+
port: 443,
|
|
88451
|
+
timeoutMs: TCP_TIMEOUT_MS
|
|
88452
|
+
});
|
|
88453
|
+
if (!tcpResult.ok) {
|
|
88454
|
+
return { ok: false, failedLayer: "tcp", layers: { dns: dnsResult, tcp: tcpResult } };
|
|
88455
|
+
}
|
|
88456
|
+
const tlsResult = await deps.tls.get(ZEN_URL, TLS_TIMEOUT_MS);
|
|
88457
|
+
if (!tlsResult.ok) {
|
|
88458
|
+
return {
|
|
88459
|
+
ok: false,
|
|
88460
|
+
failedLayer: "tls",
|
|
88461
|
+
layers: { dns: dnsResult, tcp: tcpResult, tls: tlsResult }
|
|
88462
|
+
};
|
|
88463
|
+
}
|
|
88464
|
+
const authResult = await deps.auth.checkKitAccess();
|
|
88465
|
+
if (!authResult.ok) {
|
|
88466
|
+
return {
|
|
88467
|
+
ok: false,
|
|
88468
|
+
failedLayer: "auth",
|
|
88469
|
+
layers: { dns: dnsResult, tcp: tcpResult, tls: tlsResult, auth: authResult }
|
|
88470
|
+
};
|
|
88471
|
+
}
|
|
88472
|
+
return {
|
|
88473
|
+
ok: true,
|
|
88474
|
+
layers: { dns: dnsResult, tcp: tcpResult, tls: tlsResult, auth: authResult }
|
|
88475
|
+
};
|
|
88476
|
+
}
|
|
88477
|
+
function raceTimeout(promise, ms) {
|
|
88478
|
+
return new Promise((resolve32, reject) => {
|
|
88479
|
+
const timer = setTimeout(() => reject(new Error(`timeout after ${ms}ms`)), ms);
|
|
88480
|
+
promise.then((v2) => {
|
|
88481
|
+
clearTimeout(timer);
|
|
88482
|
+
resolve32(v2);
|
|
88483
|
+
}, (e2) => {
|
|
88484
|
+
clearTimeout(timer);
|
|
88485
|
+
reject(e2);
|
|
88486
|
+
});
|
|
88487
|
+
});
|
|
88488
|
+
}
|
|
88489
|
+
|
|
88490
|
+
class GitHubReachabilityChecker {
|
|
88491
|
+
group = "network";
|
|
88492
|
+
deps;
|
|
88493
|
+
usingRealDeps;
|
|
88494
|
+
constructor(options2 = {}) {
|
|
88495
|
+
this.usingRealDeps = options2.deps === undefined;
|
|
88496
|
+
this.deps = options2.deps ?? createDefaultDeps();
|
|
88497
|
+
}
|
|
88498
|
+
async run() {
|
|
88499
|
+
if (this.usingRealDeps && (isCIEnvironment() || isTestEnvironment())) {
|
|
88500
|
+
return [
|
|
88501
|
+
{
|
|
88502
|
+
id: "github-reachability",
|
|
88503
|
+
name: "GitHub Reachability",
|
|
88504
|
+
group: "network",
|
|
88505
|
+
priority: "standard",
|
|
88506
|
+
status: "info",
|
|
88507
|
+
message: "Skipped in CI/test environment",
|
|
88508
|
+
autoFixable: false
|
|
88509
|
+
}
|
|
88510
|
+
];
|
|
88511
|
+
}
|
|
88512
|
+
logger.verbose("GitHubReachabilityChecker: running layered probe");
|
|
88513
|
+
let result;
|
|
88514
|
+
try {
|
|
88515
|
+
result = await raceTimeout(checkGitHubReachability(this.deps), AUTH_TIMEOUT_MS + TLS_TIMEOUT_MS + TCP_TIMEOUT_MS + DNS_TIMEOUT_MS + 500);
|
|
88516
|
+
} catch (err) {
|
|
88517
|
+
return [
|
|
88518
|
+
{
|
|
88519
|
+
id: "github-reachability",
|
|
88520
|
+
name: "GitHub Reachability",
|
|
88521
|
+
group: "network",
|
|
88522
|
+
priority: "standard",
|
|
88523
|
+
status: "fail",
|
|
88524
|
+
message: "Probe timed out",
|
|
88525
|
+
details: err instanceof Error ? err.message : String(err),
|
|
88526
|
+
suggestion: "Check internet connection and proxy settings",
|
|
88527
|
+
autoFixable: false
|
|
88528
|
+
}
|
|
88529
|
+
];
|
|
88530
|
+
}
|
|
88531
|
+
logger.verbose("GitHubReachabilityChecker: probe complete", { result });
|
|
88532
|
+
return [buildCheckResult(result)];
|
|
88533
|
+
}
|
|
88534
|
+
}
|
|
88535
|
+
function buildCheckResult(result) {
|
|
88536
|
+
if (result.ok) {
|
|
88537
|
+
const { dns, tcp, tls, auth } = result.layers;
|
|
88538
|
+
const details = [
|
|
88539
|
+
`DNS: ${dns.latencyMs}ms`,
|
|
88540
|
+
tcp ? `TCP: ${tcp.latencyMs}ms` : null,
|
|
88541
|
+
tls ? `TLS/GET: ${tls.latencyMs}ms` : null,
|
|
88542
|
+
auth ? `Auth: ${auth.latencyMs}ms` : null
|
|
88543
|
+
].filter(Boolean).join(", ");
|
|
88544
|
+
return {
|
|
88545
|
+
id: "github-reachability",
|
|
88546
|
+
name: "GitHub Reachability",
|
|
88547
|
+
group: "network",
|
|
88548
|
+
priority: "standard",
|
|
88549
|
+
status: "pass",
|
|
88550
|
+
message: "All layers reachable",
|
|
88551
|
+
details,
|
|
88552
|
+
autoFixable: false
|
|
88553
|
+
};
|
|
88554
|
+
}
|
|
88555
|
+
const { failedLayer, layers } = result;
|
|
88556
|
+
const failedProbe = layers[failedLayer];
|
|
88557
|
+
const detail = failedProbe?.detail ?? "unknown";
|
|
88558
|
+
const authSuggestion = failedProbe?.statusCode === 401 ? "GitHub token invalid or missing — run: gh auth login" : "No repository access — check GitHub invitation email or purchase at https://claudekit.cc";
|
|
88559
|
+
const suggestions = {
|
|
88560
|
+
dns: "DNS resolution failed — check /etc/resolv.conf or system DNS settings",
|
|
88561
|
+
tcp: "TCP connect to api.github.com:443 failed — check firewall or proxy blocking port 443",
|
|
88562
|
+
tls: "HTTPS GET /zen returned unexpected status — possible TLS interception or GitHub outage. Check https://githubstatus.com",
|
|
88563
|
+
auth: authSuggestion
|
|
88564
|
+
};
|
|
88565
|
+
return {
|
|
88566
|
+
id: "github-reachability",
|
|
88567
|
+
name: "GitHub Reachability",
|
|
88568
|
+
group: "network",
|
|
88569
|
+
priority: "standard",
|
|
88570
|
+
status: "fail",
|
|
88571
|
+
message: `GitHub unreachable at ${failedLayer?.toUpperCase()} layer`,
|
|
88572
|
+
details: detail,
|
|
88573
|
+
suggestion: suggestions[failedLayer ?? ""] ?? "Run: ck doctor for full diagnostics",
|
|
88574
|
+
autoFixable: false
|
|
88575
|
+
};
|
|
88576
|
+
}
|
|
88234
88577
|
// src/domains/health-checks/auto-healer.ts
|
|
88235
88578
|
class AutoHealer {
|
|
88236
88579
|
timeout;
|
|
@@ -88657,6 +89000,7 @@ async function doctorCommand(options2 = {}) {
|
|
|
88657
89000
|
runner.registerChecker(new AuthChecker);
|
|
88658
89001
|
runner.registerChecker(new PlatformChecker);
|
|
88659
89002
|
runner.registerChecker(new NetworkChecker);
|
|
89003
|
+
runner.registerChecker(new GitHubReachabilityChecker);
|
|
88660
89004
|
const summary = await runner.run();
|
|
88661
89005
|
if (json) {
|
|
88662
89006
|
const generator = new ReportGenerator;
|
|
@@ -105359,7 +105703,15 @@ async function handleSelection(ctx) {
|
|
|
105359
105703
|
logger.info("Full diagnostics: ck doctor");
|
|
105360
105704
|
return { ...ctx, cancelled: true };
|
|
105361
105705
|
}
|
|
105362
|
-
|
|
105706
|
+
try {
|
|
105707
|
+
accessibleKits = await detectAccessibleKits();
|
|
105708
|
+
} catch (err) {
|
|
105709
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
105710
|
+
logger.error(`Failed to check repository access: ${message}`);
|
|
105711
|
+
logger.info("");
|
|
105712
|
+
logger.info("Run: ck doctor");
|
|
105713
|
+
return { ...ctx, cancelled: true };
|
|
105714
|
+
}
|
|
105363
105715
|
if (accessibleKits.length === 0) {
|
|
105364
105716
|
logger.error("No ClaudeKit repository access found.");
|
|
105365
105717
|
logger.info("Check email for GitHub invitation, or purchase at https://claudekit.cc");
|
|
@@ -108812,7 +109164,7 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
108812
109164
|
|
|
108813
109165
|
// src/commands/new/phases/directory-setup.ts
|
|
108814
109166
|
init_config_manager();
|
|
108815
|
-
import { resolve as
|
|
109167
|
+
import { resolve as resolve43 } from "node:path";
|
|
108816
109168
|
init_logger();
|
|
108817
109169
|
init_path_resolver();
|
|
108818
109170
|
init_types3();
|
|
@@ -108897,7 +109249,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
108897
109249
|
targetDir = await prompts.getDirectory(targetDir);
|
|
108898
109250
|
}
|
|
108899
109251
|
}
|
|
108900
|
-
const resolvedDir =
|
|
109252
|
+
const resolvedDir = resolve43(targetDir);
|
|
108901
109253
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
108902
109254
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
108903
109255
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -109231,7 +109583,7 @@ Please use only one download method.`);
|
|
|
109231
109583
|
// src/commands/plan/plan-command.ts
|
|
109232
109584
|
init_output_manager();
|
|
109233
109585
|
import { existsSync as existsSync67, statSync as statSync12 } from "node:fs";
|
|
109234
|
-
import { dirname as dirname46, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as
|
|
109586
|
+
import { dirname as dirname46, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as resolve48 } from "node:path";
|
|
109235
109587
|
|
|
109236
109588
|
// src/commands/plan/plan-read-handlers.ts
|
|
109237
109589
|
init_config();
|
|
@@ -109241,7 +109593,7 @@ init_logger();
|
|
|
109241
109593
|
init_output_manager();
|
|
109242
109594
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
109243
109595
|
import { existsSync as existsSync66, statSync as statSync11 } from "node:fs";
|
|
109244
|
-
import { basename as basename28, dirname as dirname44, join as join146, relative as relative27, resolve as
|
|
109596
|
+
import { basename as basename28, dirname as dirname44, join as join146, relative as relative27, resolve as resolve46 } from "node:path";
|
|
109245
109597
|
|
|
109246
109598
|
// src/commands/plan/plan-dependencies.ts
|
|
109247
109599
|
init_config();
|
|
@@ -109299,14 +109651,14 @@ init_config();
|
|
|
109299
109651
|
init_plan_parser();
|
|
109300
109652
|
init_plan_scope();
|
|
109301
109653
|
init_plans_registry();
|
|
109302
|
-
import { isAbsolute as isAbsolute10, resolve as
|
|
109654
|
+
import { isAbsolute as isAbsolute10, resolve as resolve45 } from "node:path";
|
|
109303
109655
|
async function getGlobalPlansDirFromCwd() {
|
|
109304
109656
|
const projectRoot = findProjectRoot(process.cwd());
|
|
109305
109657
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
109306
109658
|
return resolveGlobalPlansDir(config);
|
|
109307
109659
|
}
|
|
109308
109660
|
function resolveTargetFromBase(target, baseDir) {
|
|
109309
|
-
const resolvedTarget = isAbsolute10(target) ?
|
|
109661
|
+
const resolvedTarget = isAbsolute10(target) ? resolve45(target) : resolve45(baseDir, target);
|
|
109310
109662
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
109311
109663
|
}
|
|
109312
109664
|
|
|
@@ -109409,7 +109761,7 @@ async function handleStatus(target, options2) {
|
|
|
109409
109761
|
return;
|
|
109410
109762
|
}
|
|
109411
109763
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
109412
|
-
const t = effectiveTarget ?
|
|
109764
|
+
const t = effectiveTarget ? resolve46(effectiveTarget) : null;
|
|
109413
109765
|
const plansDir = t && existsSync66(t) && statSync11(t).isDirectory() && !existsSync66(join146(t, "plan.md")) ? t : null;
|
|
109414
109766
|
if (plansDir) {
|
|
109415
109767
|
const planFiles = scanPlanDir(plansDir);
|
|
@@ -109594,7 +109946,7 @@ init_plan_parser();
|
|
|
109594
109946
|
init_plans_registry();
|
|
109595
109947
|
init_output_manager();
|
|
109596
109948
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
109597
|
-
import { basename as basename29, dirname as dirname45, relative as relative28, resolve as
|
|
109949
|
+
import { basename as basename29, dirname as dirname45, relative as relative28, resolve as resolve47 } from "node:path";
|
|
109598
109950
|
async function handleCreate(target, options2) {
|
|
109599
109951
|
if (!options2.title) {
|
|
109600
109952
|
output.error("[X] --title is required for create");
|
|
@@ -109626,13 +109978,13 @@ async function handleCreate(target, options2) {
|
|
|
109626
109978
|
return;
|
|
109627
109979
|
}
|
|
109628
109980
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
109629
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
109981
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve47(dir);
|
|
109630
109982
|
if (globalBaseDir && !resolvedDir) {
|
|
109631
109983
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
109632
109984
|
process.exitCode = 1;
|
|
109633
109985
|
return;
|
|
109634
109986
|
}
|
|
109635
|
-
const safeResolvedDir = resolvedDir ??
|
|
109987
|
+
const safeResolvedDir = resolvedDir ?? resolve47(dir);
|
|
109636
109988
|
const result = scaffoldPlan({
|
|
109637
109989
|
title: options2.title,
|
|
109638
109990
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -109808,19 +110160,19 @@ async function handleAddPhase(target, options2) {
|
|
|
109808
110160
|
// src/commands/plan/plan-command.ts
|
|
109809
110161
|
function resolveTargetPath(target, baseDir) {
|
|
109810
110162
|
if (!baseDir) {
|
|
109811
|
-
return
|
|
110163
|
+
return resolve48(target);
|
|
109812
110164
|
}
|
|
109813
110165
|
if (isAbsolute11(target)) {
|
|
109814
|
-
return
|
|
110166
|
+
return resolve48(target);
|
|
109815
110167
|
}
|
|
109816
|
-
const cwdCandidate =
|
|
110168
|
+
const cwdCandidate = resolve48(target);
|
|
109817
110169
|
if (existsSync67(cwdCandidate)) {
|
|
109818
110170
|
return cwdCandidate;
|
|
109819
110171
|
}
|
|
109820
|
-
return
|
|
110172
|
+
return resolve48(baseDir, target);
|
|
109821
110173
|
}
|
|
109822
110174
|
function resolvePlanFile(target, baseDir) {
|
|
109823
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
110175
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve48(baseDir) : process.cwd();
|
|
109824
110176
|
if (existsSync67(t)) {
|
|
109825
110177
|
const stat24 = statSync12(t);
|
|
109826
110178
|
if (stat24.isFile())
|
|
@@ -109884,7 +110236,7 @@ async function planCommand(action, target, options2) {
|
|
|
109884
110236
|
let resolvedTarget = target;
|
|
109885
110237
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
109886
110238
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
109887
|
-
const existsOnDisk = !looksLikePath && existsSync67(
|
|
110239
|
+
const existsOnDisk = !looksLikePath && existsSync67(resolve48(resolvedAction));
|
|
109888
110240
|
if (looksLikePath || existsOnDisk) {
|
|
109889
110241
|
resolvedTarget = resolvedAction;
|
|
109890
110242
|
resolvedAction = undefined;
|
|
@@ -109927,11 +110279,11 @@ init_logger();
|
|
|
109927
110279
|
init_safe_prompts();
|
|
109928
110280
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
109929
110281
|
import { existsSync as existsSync68 } from "node:fs";
|
|
109930
|
-
import { resolve as
|
|
110282
|
+
import { resolve as resolve49 } from "node:path";
|
|
109931
110283
|
async function handleAdd(projectPath, options2) {
|
|
109932
110284
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
109933
110285
|
intro("Add Project");
|
|
109934
|
-
const absolutePath =
|
|
110286
|
+
const absolutePath = resolve49(projectPath);
|
|
109935
110287
|
if (!existsSync68(absolutePath)) {
|
|
109936
110288
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
109937
110289
|
process.exitCode = 1;
|
|
@@ -111036,7 +111388,7 @@ async function detectInstallations() {
|
|
|
111036
111388
|
|
|
111037
111389
|
// src/commands/uninstall/removal-handler.ts
|
|
111038
111390
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
111039
|
-
import { basename as basename30, join as join150, resolve as
|
|
111391
|
+
import { basename as basename30, join as join150, resolve as resolve50, sep as sep12 } from "node:path";
|
|
111040
111392
|
init_logger();
|
|
111041
111393
|
init_safe_prompts();
|
|
111042
111394
|
init_safe_spinner();
|
|
@@ -111217,8 +111569,8 @@ async function restoreUninstallBackup(backup) {
|
|
|
111217
111569
|
}
|
|
111218
111570
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
111219
111571
|
try {
|
|
111220
|
-
const resolvedPath =
|
|
111221
|
-
const resolvedBase =
|
|
111572
|
+
const resolvedPath = resolve50(filePath);
|
|
111573
|
+
const resolvedBase = resolve50(baseDir);
|
|
111222
111574
|
if (!resolvedPath.startsWith(resolvedBase + sep12) && resolvedPath !== resolvedBase) {
|
|
111223
111575
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
111224
111576
|
return false;
|
|
@@ -111226,7 +111578,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
111226
111578
|
const stats = await import_fs_extra44.lstat(filePath);
|
|
111227
111579
|
if (stats.isSymbolicLink()) {
|
|
111228
111580
|
const realPath = await import_fs_extra44.realpath(filePath);
|
|
111229
|
-
const resolvedReal =
|
|
111581
|
+
const resolvedReal = resolve50(realPath);
|
|
111230
111582
|
if (!resolvedReal.startsWith(resolvedBase + sep12) && resolvedReal !== resolvedBase) {
|
|
111231
111583
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
111232
111584
|
return false;
|
|
@@ -111689,7 +112041,7 @@ function getDisclaimerMarker() {
|
|
|
111689
112041
|
return AI_DISCLAIMER;
|
|
111690
112042
|
}
|
|
111691
112043
|
function spawnAndCollect2(command, args) {
|
|
111692
|
-
return new Promise((
|
|
112044
|
+
return new Promise((resolve44, reject) => {
|
|
111693
112045
|
const child = spawn7(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
111694
112046
|
const chunks = [];
|
|
111695
112047
|
const stderrChunks = [];
|
|
@@ -111702,7 +112054,7 @@ function spawnAndCollect2(command, args) {
|
|
|
111702
112054
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
111703
112055
|
return;
|
|
111704
112056
|
}
|
|
111705
|
-
|
|
112057
|
+
resolve44(Buffer.concat(chunks).toString("utf-8"));
|
|
111706
112058
|
});
|
|
111707
112059
|
});
|
|
111708
112060
|
}
|
|
@@ -111810,7 +112162,7 @@ function formatResponse(content, showBranding) {
|
|
|
111810
112162
|
return disclaimer + formatted + branding;
|
|
111811
112163
|
}
|
|
111812
112164
|
async function postViaGh(owner, repo, issueNumber, body) {
|
|
111813
|
-
return new Promise((
|
|
112165
|
+
return new Promise((resolve44, reject) => {
|
|
111814
112166
|
const args = [
|
|
111815
112167
|
"issue",
|
|
111816
112168
|
"comment",
|
|
@@ -111832,7 +112184,7 @@ async function postViaGh(owner, repo, issueNumber, body) {
|
|
|
111832
112184
|
reject(new Error(`gh exited with code ${code2}: ${stderr}`));
|
|
111833
112185
|
return;
|
|
111834
112186
|
}
|
|
111835
|
-
|
|
112187
|
+
resolve44();
|
|
111836
112188
|
});
|
|
111837
112189
|
});
|
|
111838
112190
|
}
|
|
@@ -111950,7 +112302,7 @@ After completing the implementation:
|
|
|
111950
112302
|
"--allowedTools",
|
|
111951
112303
|
tools
|
|
111952
112304
|
];
|
|
111953
|
-
await new Promise((
|
|
112305
|
+
await new Promise((resolve44, reject) => {
|
|
111954
112306
|
const child = spawn9("claude", args, { cwd: cwd2, stdio: ["pipe", "pipe", "pipe"], detached: false });
|
|
111955
112307
|
child.stdin.write(prompt);
|
|
111956
112308
|
child.stdin.end();
|
|
@@ -111975,7 +112327,7 @@ After completing the implementation:
|
|
|
111975
112327
|
reject(new Error(`Claude exited ${code2}: ${stderr.slice(0, 500)}`));
|
|
111976
112328
|
return;
|
|
111977
112329
|
}
|
|
111978
|
-
|
|
112330
|
+
resolve44();
|
|
111979
112331
|
});
|
|
111980
112332
|
});
|
|
111981
112333
|
}
|
|
@@ -112119,7 +112471,7 @@ function checkRateLimit2(processedThisHour, maxPerHour) {
|
|
|
112119
112471
|
return processedThisHour < maxPerHour;
|
|
112120
112472
|
}
|
|
112121
112473
|
function spawnAndCollect3(command, args) {
|
|
112122
|
-
return new Promise((
|
|
112474
|
+
return new Promise((resolve44, reject) => {
|
|
112123
112475
|
const child = spawn10(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
112124
112476
|
const chunks = [];
|
|
112125
112477
|
const stderrChunks = [];
|
|
@@ -112132,7 +112484,7 @@ function spawnAndCollect3(command, args) {
|
|
|
112132
112484
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
112133
112485
|
return;
|
|
112134
112486
|
}
|
|
112135
|
-
|
|
112487
|
+
resolve44(Buffer.concat(chunks).toString("utf-8"));
|
|
112136
112488
|
});
|
|
112137
112489
|
});
|
|
112138
112490
|
}
|
|
@@ -112184,7 +112536,7 @@ async function invokeClaude(options2) {
|
|
|
112184
112536
|
return collectClaudeOutput(child, options2.timeoutSec, verbose);
|
|
112185
112537
|
}
|
|
112186
112538
|
function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
112187
|
-
return new Promise((
|
|
112539
|
+
return new Promise((resolve44, reject) => {
|
|
112188
112540
|
const chunks = [];
|
|
112189
112541
|
const stderrChunks = [];
|
|
112190
112542
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -112214,7 +112566,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
|
112214
112566
|
reject(new Error(`Claude exited with code ${code2}: ${stderr}`));
|
|
112215
112567
|
return;
|
|
112216
112568
|
}
|
|
112217
|
-
|
|
112569
|
+
resolve44(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
|
|
112218
112570
|
});
|
|
112219
112571
|
});
|
|
112220
112572
|
}
|
|
@@ -113478,7 +113830,7 @@ function formatQueueInfo(state) {
|
|
|
113478
113830
|
return "idle";
|
|
113479
113831
|
}
|
|
113480
113832
|
function sleep(ms) {
|
|
113481
|
-
return new Promise((
|
|
113833
|
+
return new Promise((resolve44) => setTimeout(resolve44, ms));
|
|
113482
113834
|
}
|
|
113483
113835
|
// src/cli/command-registry.ts
|
|
113484
113836
|
init_logger();
|