hillclimb 0.1.2 → 0.1.3
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 +242 -26
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import fs16 from "fs";
|
|
5
|
+
import path19 from "path";
|
|
6
6
|
import * as p6 from "@clack/prompts";
|
|
7
7
|
|
|
8
8
|
// src/commands/init.ts
|
|
@@ -424,6 +424,27 @@ var TOOLS = [
|
|
|
424
424
|
// Events are wired inside the plugin itself; see OPENCODE_PLUGIN_CONTENT.
|
|
425
425
|
detect: () => isDir(path4.join(os2.homedir(), ".local", "share", "opencode")) || isDir(path4.join(os2.homedir(), ".config", "opencode"))
|
|
426
426
|
},
|
|
427
|
+
{
|
|
428
|
+
// VS Code Copilot Chat. Same "no SessionEnd" constraint as Codex (the
|
|
429
|
+
// event is documented but never fires — VS Code issue microsoft/vscode#300650).
|
|
430
|
+
// Stale-state cleanup happens on next SessionStart, like Codex.
|
|
431
|
+
// Hook config lives at .github/hooks/hooks.json — distinct from
|
|
432
|
+
// .claude/settings.local.json so Claude Code and Copilot Chat don't
|
|
433
|
+
// fire each other's hooks even though VS Code's docs claim they share.
|
|
434
|
+
tool: "copilot-chat",
|
|
435
|
+
label: "GitHub Copilot Chat",
|
|
436
|
+
settingsFile: ".github/hooks/hooks.json",
|
|
437
|
+
format: "copilot",
|
|
438
|
+
events: [
|
|
439
|
+
{ eventName: "SessionStart", command: GIT_TRACES_CMD("copilot-chat") },
|
|
440
|
+
{ eventName: "Stop", command: GIT_TRACES_CMD("copilot-chat") },
|
|
441
|
+
{
|
|
442
|
+
eventName: "Stop",
|
|
443
|
+
command: `${HOOK_CMD("upload")} --tool=copilot-chat`
|
|
444
|
+
}
|
|
445
|
+
],
|
|
446
|
+
detect: copilotChatDetect
|
|
447
|
+
},
|
|
427
448
|
{
|
|
428
449
|
// Codex has no SessionEnd hook (only SessionStart, PreToolUse, PostToolUse,
|
|
429
450
|
// UserPromptSubmit, Stop). We can't clean up refs/state at session end;
|
|
@@ -451,6 +472,20 @@ function isDir(p7) {
|
|
|
451
472
|
return false;
|
|
452
473
|
}
|
|
453
474
|
}
|
|
475
|
+
function copilotChatDetect() {
|
|
476
|
+
const home = os2.homedir();
|
|
477
|
+
const suffix = path4.join(
|
|
478
|
+
"User",
|
|
479
|
+
"globalStorage",
|
|
480
|
+
"github.copilot-chat"
|
|
481
|
+
);
|
|
482
|
+
const candidates = [
|
|
483
|
+
path4.join(home, "Library", "Application Support", "Code", suffix),
|
|
484
|
+
path4.join(home, ".config", "Code", suffix),
|
|
485
|
+
process.env.APPDATA ? path4.join(process.env.APPDATA, "Code", suffix) : null
|
|
486
|
+
].filter((p7) => p7 !== null);
|
|
487
|
+
return candidates.some(isDir);
|
|
488
|
+
}
|
|
454
489
|
function settingsPath(repoRoot, def) {
|
|
455
490
|
return path4.join(repoRoot, def.settingsFile);
|
|
456
491
|
}
|
|
@@ -545,6 +580,36 @@ function cursorUninstall(settings, eventName, command) {
|
|
|
545
580
|
}
|
|
546
581
|
return true;
|
|
547
582
|
}
|
|
583
|
+
function copilotHookPresent(entries, command) {
|
|
584
|
+
return entries.some((e) => e.type === "command" && e.command === command);
|
|
585
|
+
}
|
|
586
|
+
function copilotInstall(settings, eventName, command) {
|
|
587
|
+
if (!settings.hooks) settings.hooks = {};
|
|
588
|
+
if (!settings.hooks[eventName]) settings.hooks[eventName] = [];
|
|
589
|
+
const entries = settings.hooks[eventName];
|
|
590
|
+
if (copilotHookPresent(entries, command)) return false;
|
|
591
|
+
entries.push({ type: "command", command });
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
function copilotCheck(settings, eventName, command) {
|
|
595
|
+
const entries = settings.hooks?.[eventName] ?? [];
|
|
596
|
+
return copilotHookPresent(entries, command);
|
|
597
|
+
}
|
|
598
|
+
function copilotUninstall(settings, eventName, command) {
|
|
599
|
+
const entries = settings.hooks?.[eventName];
|
|
600
|
+
if (!entries || entries.length === 0) return false;
|
|
601
|
+
const next = entries.filter(
|
|
602
|
+
(e) => !(e.type === "command" && e.command === command)
|
|
603
|
+
);
|
|
604
|
+
if (next.length === entries.length) return false;
|
|
605
|
+
if (next.length > 0) {
|
|
606
|
+
settings.hooks[eventName] = next;
|
|
607
|
+
} else {
|
|
608
|
+
delete settings.hooks[eventName];
|
|
609
|
+
if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
|
|
610
|
+
}
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
548
613
|
var OPENCODE_PLUGIN_VERSION = 2;
|
|
549
614
|
var OPENCODE_PLUGIN_MARKER = `// HILLCLIMB_OPENCODE_PLUGIN_VERSION=${OPENCODE_PLUGIN_VERSION}`;
|
|
550
615
|
var OPENCODE_PLUGIN_CONTENT = `${OPENCODE_PLUGIN_MARKER}
|
|
@@ -714,13 +779,34 @@ async function opencodeCheck(file) {
|
|
|
714
779
|
}
|
|
715
780
|
}
|
|
716
781
|
function install(settings, format, eventName, command) {
|
|
717
|
-
|
|
782
|
+
switch (format) {
|
|
783
|
+
case "cursor":
|
|
784
|
+
return cursorInstall(settings, eventName, command);
|
|
785
|
+
case "copilot":
|
|
786
|
+
return copilotInstall(settings, eventName, command);
|
|
787
|
+
default:
|
|
788
|
+
return claudeInstall(settings, eventName, command);
|
|
789
|
+
}
|
|
718
790
|
}
|
|
719
791
|
function check(settings, format, eventName, command) {
|
|
720
|
-
|
|
792
|
+
switch (format) {
|
|
793
|
+
case "cursor":
|
|
794
|
+
return cursorCheck(settings, eventName, command);
|
|
795
|
+
case "copilot":
|
|
796
|
+
return copilotCheck(settings, eventName, command);
|
|
797
|
+
default:
|
|
798
|
+
return claudeCheck(settings, eventName, command);
|
|
799
|
+
}
|
|
721
800
|
}
|
|
722
801
|
function uninstall(settings, format, eventName, command) {
|
|
723
|
-
|
|
802
|
+
switch (format) {
|
|
803
|
+
case "cursor":
|
|
804
|
+
return cursorUninstall(settings, eventName, command);
|
|
805
|
+
case "copilot":
|
|
806
|
+
return copilotUninstall(settings, eventName, command);
|
|
807
|
+
default:
|
|
808
|
+
return claudeUninstall(settings, eventName, command);
|
|
809
|
+
}
|
|
724
810
|
}
|
|
725
811
|
function legacyCommandsFor(command) {
|
|
726
812
|
const prefix = "npx hillclimb ";
|
|
@@ -1277,7 +1363,7 @@ async function runInit(args = []) {
|
|
|
1277
1363
|
const hookResults = await installDetectedHooks(repoRoot);
|
|
1278
1364
|
if (hookResults.length === 0) {
|
|
1279
1365
|
p3.log.warn(
|
|
1280
|
-
"No supported tools detected (
|
|
1366
|
+
"No supported tools detected (Claude Code, Cursor, Codex, opencode, GitHub Copilot Chat). Hook not installed."
|
|
1281
1367
|
);
|
|
1282
1368
|
} else {
|
|
1283
1369
|
for (const r of hookResults) {
|
|
@@ -11464,6 +11550,9 @@ function formatTitleTimestamp(date) {
|
|
|
11464
11550
|
const pad = (n) => String(n).padStart(2, "0");
|
|
11465
11551
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
11466
11552
|
}
|
|
11553
|
+
function lineHasAssistant(line) {
|
|
11554
|
+
return line.includes('"type":"assistant"') || line.includes('"role":"assistant"') || line.includes('"type":"assistant.');
|
|
11555
|
+
}
|
|
11467
11556
|
async function hasAssistantMessage(transcriptPath) {
|
|
11468
11557
|
const stream = fs8.createReadStream(transcriptPath, { encoding: "utf-8" });
|
|
11469
11558
|
let buffer = "";
|
|
@@ -11474,15 +11563,14 @@ async function hasAssistantMessage(transcriptPath) {
|
|
|
11474
11563
|
while (newlineIdx !== -1) {
|
|
11475
11564
|
const line = buffer.slice(0, newlineIdx);
|
|
11476
11565
|
buffer = buffer.slice(newlineIdx + 1);
|
|
11477
|
-
if (
|
|
11566
|
+
if (lineHasAssistant(line)) {
|
|
11478
11567
|
stream.destroy();
|
|
11479
11568
|
return true;
|
|
11480
11569
|
}
|
|
11481
11570
|
newlineIdx = buffer.indexOf("\n");
|
|
11482
11571
|
}
|
|
11483
11572
|
}
|
|
11484
|
-
if (buffer
|
|
11485
|
-
return true;
|
|
11573
|
+
if (lineHasAssistant(buffer)) return true;
|
|
11486
11574
|
} catch {
|
|
11487
11575
|
return true;
|
|
11488
11576
|
}
|
|
@@ -11600,7 +11688,13 @@ async function uploadSession(args) {
|
|
|
11600
11688
|
}
|
|
11601
11689
|
const client = new PlatformClient(config.apiBaseUrl, identity.sessionCookie);
|
|
11602
11690
|
const shortId = sessionId.slice(0, 12);
|
|
11603
|
-
const toolLabels = {
|
|
11691
|
+
const toolLabels = {
|
|
11692
|
+
cursor: "Cursor",
|
|
11693
|
+
codex: "Codex",
|
|
11694
|
+
claude: "Claude",
|
|
11695
|
+
"copilot-chat": "GitHub Copilot Chat",
|
|
11696
|
+
opencode: "opencode"
|
|
11697
|
+
};
|
|
11604
11698
|
const toolLabel = toolLabels[sourceTool] ?? "Claude";
|
|
11605
11699
|
const title = `${toolLabel} session ${shortId} \u2014 ${formatTitleTimestamp(now)}`;
|
|
11606
11700
|
const body = `Session ID: ${sessionId}
|
|
@@ -11641,6 +11735,15 @@ Uploaded: ${now.toISOString()}`;
|
|
|
11641
11735
|
}
|
|
11642
11736
|
}
|
|
11643
11737
|
var WORKER_ENV_FLAG = "HILLCLIMB_UPLOAD_WORKER";
|
|
11738
|
+
var TOOL_ENV_FLAG = "HILLCLIMB_UPLOAD_TOOL";
|
|
11739
|
+
function parseToolArg(argv) {
|
|
11740
|
+
for (let i = 0; i < argv.length; i++) {
|
|
11741
|
+
const a = argv[i];
|
|
11742
|
+
if (a.startsWith("--tool=")) return a.slice("--tool=".length);
|
|
11743
|
+
if (a === "--tool" && i + 1 < argv.length) return argv[i + 1];
|
|
11744
|
+
}
|
|
11745
|
+
return null;
|
|
11746
|
+
}
|
|
11644
11747
|
async function runUpload() {
|
|
11645
11748
|
if (process.env[WORKER_ENV_FLAG] === "1") {
|
|
11646
11749
|
await runUploadWorker();
|
|
@@ -11669,11 +11772,17 @@ async function runUpload() {
|
|
|
11669
11772
|
appendLog("error", "Cannot detach worker: process.argv[1] is empty");
|
|
11670
11773
|
return;
|
|
11671
11774
|
}
|
|
11775
|
+
const toolArg = parseToolArg(process.argv.slice(2));
|
|
11776
|
+
const workerEnv = {
|
|
11777
|
+
...process.env,
|
|
11778
|
+
[WORKER_ENV_FLAG]: "1"
|
|
11779
|
+
};
|
|
11780
|
+
if (toolArg) workerEnv[TOOL_ENV_FLAG] = toolArg;
|
|
11672
11781
|
try {
|
|
11673
11782
|
const child = spawn2(process.execPath, [entrypoint, "upload"], {
|
|
11674
11783
|
detached: true,
|
|
11675
11784
|
stdio: ["pipe", "ignore", "ignore"],
|
|
11676
|
-
env:
|
|
11785
|
+
env: workerEnv
|
|
11677
11786
|
});
|
|
11678
11787
|
child.on("error", (err) => {
|
|
11679
11788
|
appendLog("error", `Failed to spawn worker: ${err.message}`);
|
|
@@ -11719,6 +11828,8 @@ async function runUploadWorker() {
|
|
|
11719
11828
|
);
|
|
11720
11829
|
return;
|
|
11721
11830
|
}
|
|
11831
|
+
const toolOverride = process.env[TOOL_ENV_FLAG];
|
|
11832
|
+
if (toolOverride) payload.tool = toolOverride;
|
|
11722
11833
|
try {
|
|
11723
11834
|
await runUploadInner(payload);
|
|
11724
11835
|
} catch (err) {
|
|
@@ -12058,9 +12169,9 @@ function parseCommitFiles(repoRoot, sha) {
|
|
|
12058
12169
|
oldPath
|
|
12059
12170
|
});
|
|
12060
12171
|
} else {
|
|
12061
|
-
const
|
|
12062
|
-
indexByPath.set(
|
|
12063
|
-
files.push({ path:
|
|
12172
|
+
const path20 = parts[parts.length - 1];
|
|
12173
|
+
indexByPath.set(path20, files.length);
|
|
12174
|
+
files.push({ path: path20, status, additions: 0, deletions: 0 });
|
|
12064
12175
|
}
|
|
12065
12176
|
}
|
|
12066
12177
|
for (const line of numstat.split("\n")) {
|
|
@@ -12188,6 +12299,7 @@ var TOOL_LABELS = {
|
|
|
12188
12299
|
cursor: "Cursor",
|
|
12189
12300
|
codex: "Codex",
|
|
12190
12301
|
claude: "Claude",
|
|
12302
|
+
"copilot-chat": "GitHub Copilot Chat",
|
|
12191
12303
|
opencode: "opencode"
|
|
12192
12304
|
};
|
|
12193
12305
|
function resolveCwd(payload) {
|
|
@@ -12542,9 +12654,15 @@ async function handleSessionEnd(payload, tool) {
|
|
|
12542
12654
|
|
|
12543
12655
|
// src/git-traces/index.ts
|
|
12544
12656
|
var WORKER_ENV_FLAG2 = "HILLCLIMB_GIT_TRACES_WORKER";
|
|
12545
|
-
var
|
|
12546
|
-
var KNOWN_TOOLS = /* @__PURE__ */ new Set([
|
|
12547
|
-
|
|
12657
|
+
var TOOL_ENV_FLAG2 = "HILLCLIMB_GIT_TRACES_TOOL";
|
|
12658
|
+
var KNOWN_TOOLS = /* @__PURE__ */ new Set([
|
|
12659
|
+
"claude",
|
|
12660
|
+
"codex",
|
|
12661
|
+
"copilot-chat",
|
|
12662
|
+
"cursor",
|
|
12663
|
+
"opencode"
|
|
12664
|
+
]);
|
|
12665
|
+
function parseToolArg2(argv) {
|
|
12548
12666
|
for (let i = 0; i < argv.length; i++) {
|
|
12549
12667
|
const a = argv[i];
|
|
12550
12668
|
if (a.startsWith("--tool=")) return a.slice("--tool=".length);
|
|
@@ -12565,7 +12683,7 @@ async function runGitTraces() {
|
|
|
12565
12683
|
await runGitTracesWorker();
|
|
12566
12684
|
return;
|
|
12567
12685
|
}
|
|
12568
|
-
const toolArg =
|
|
12686
|
+
const toolArg = parseToolArg2(process.argv.slice(2));
|
|
12569
12687
|
appendLog(
|
|
12570
12688
|
"info",
|
|
12571
12689
|
`git-traces hook invoked (pid ${process.pid}, tool=${toolArg ?? "<none>"})`
|
|
@@ -12606,7 +12724,7 @@ async function runGitTraces() {
|
|
|
12606
12724
|
env: {
|
|
12607
12725
|
...process.env,
|
|
12608
12726
|
[WORKER_ENV_FLAG2]: "1",
|
|
12609
|
-
[
|
|
12727
|
+
[TOOL_ENV_FLAG2]: toolArg
|
|
12610
12728
|
}
|
|
12611
12729
|
}
|
|
12612
12730
|
);
|
|
@@ -12628,7 +12746,7 @@ async function runGitTraces() {
|
|
|
12628
12746
|
}
|
|
12629
12747
|
}
|
|
12630
12748
|
async function runGitTracesWorker() {
|
|
12631
|
-
const tool = process.env[
|
|
12749
|
+
const tool = process.env[TOOL_ENV_FLAG2] ?? parseToolArg2(process.argv.slice(2)) ?? null;
|
|
12632
12750
|
appendLog(
|
|
12633
12751
|
"info",
|
|
12634
12752
|
`git-traces worker started (pid ${process.pid}, tool=${tool ?? "<none>"})`
|
|
@@ -13202,8 +13320,106 @@ var CodexSource = class {
|
|
|
13202
13320
|
}
|
|
13203
13321
|
};
|
|
13204
13322
|
|
|
13323
|
+
// src/sources/copilotChat.ts
|
|
13324
|
+
import fs15 from "fs";
|
|
13325
|
+
import os11 from "os";
|
|
13326
|
+
import path18 from "path";
|
|
13327
|
+
import { fileURLToPath } from "url";
|
|
13328
|
+
function vsCodeUserDirs() {
|
|
13329
|
+
const home = os11.homedir();
|
|
13330
|
+
const dirs = [
|
|
13331
|
+
path18.join(home, "Library", "Application Support", "Code", "User"),
|
|
13332
|
+
path18.join(home, ".config", "Code", "User")
|
|
13333
|
+
];
|
|
13334
|
+
if (process.env.APPDATA) {
|
|
13335
|
+
dirs.push(path18.join(process.env.APPDATA, "Code", "User"));
|
|
13336
|
+
}
|
|
13337
|
+
return dirs;
|
|
13338
|
+
}
|
|
13339
|
+
function uriToFsPath(uri) {
|
|
13340
|
+
if (!uri.startsWith("file://")) return null;
|
|
13341
|
+
try {
|
|
13342
|
+
return fileURLToPath(uri);
|
|
13343
|
+
} catch {
|
|
13344
|
+
return null;
|
|
13345
|
+
}
|
|
13346
|
+
}
|
|
13347
|
+
async function readWorkspaceFolder(workspaceJsonPath) {
|
|
13348
|
+
let raw;
|
|
13349
|
+
try {
|
|
13350
|
+
raw = await fs15.promises.readFile(workspaceJsonPath, "utf-8");
|
|
13351
|
+
} catch {
|
|
13352
|
+
return null;
|
|
13353
|
+
}
|
|
13354
|
+
let data;
|
|
13355
|
+
try {
|
|
13356
|
+
data = JSON.parse(raw);
|
|
13357
|
+
} catch {
|
|
13358
|
+
return null;
|
|
13359
|
+
}
|
|
13360
|
+
if (!data || typeof data !== "object") return null;
|
|
13361
|
+
const obj = data;
|
|
13362
|
+
if (typeof obj.folder === "string") {
|
|
13363
|
+
return uriToFsPath(obj.folder) ?? obj.folder;
|
|
13364
|
+
}
|
|
13365
|
+
return null;
|
|
13366
|
+
}
|
|
13367
|
+
var CopilotChatSource = class {
|
|
13368
|
+
name = "copilot-chat";
|
|
13369
|
+
async scan() {
|
|
13370
|
+
const results = [];
|
|
13371
|
+
for (const userDir of vsCodeUserDirs()) {
|
|
13372
|
+
const workspaceStorage = path18.join(userDir, "workspaceStorage");
|
|
13373
|
+
let hashDirs;
|
|
13374
|
+
try {
|
|
13375
|
+
hashDirs = await fs15.promises.readdir(workspaceStorage, {
|
|
13376
|
+
withFileTypes: true
|
|
13377
|
+
});
|
|
13378
|
+
} catch {
|
|
13379
|
+
continue;
|
|
13380
|
+
}
|
|
13381
|
+
for (const hash of hashDirs) {
|
|
13382
|
+
if (!hash.isDirectory()) continue;
|
|
13383
|
+
const wsRoot = path18.join(workspaceStorage, hash.name);
|
|
13384
|
+
const transcriptsDir = path18.join(
|
|
13385
|
+
wsRoot,
|
|
13386
|
+
"GitHub.copilot-chat",
|
|
13387
|
+
"transcripts"
|
|
13388
|
+
);
|
|
13389
|
+
let transcriptEntries;
|
|
13390
|
+
try {
|
|
13391
|
+
transcriptEntries = await fs15.promises.readdir(transcriptsDir, {
|
|
13392
|
+
withFileTypes: true
|
|
13393
|
+
});
|
|
13394
|
+
} catch {
|
|
13395
|
+
continue;
|
|
13396
|
+
}
|
|
13397
|
+
const repoPath = await readWorkspaceFolder(
|
|
13398
|
+
path18.join(wsRoot, "workspace.json")
|
|
13399
|
+
);
|
|
13400
|
+
if (!repoPath) continue;
|
|
13401
|
+
for (const entry of transcriptEntries) {
|
|
13402
|
+
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
|
|
13403
|
+
const sessionId = entry.name.slice(0, -".jsonl".length);
|
|
13404
|
+
results.push({
|
|
13405
|
+
sourceName: this.name,
|
|
13406
|
+
absolutePath: path18.join(transcriptsDir, entry.name),
|
|
13407
|
+
repoPath,
|
|
13408
|
+
metadata: { sessionId }
|
|
13409
|
+
});
|
|
13410
|
+
}
|
|
13411
|
+
}
|
|
13412
|
+
}
|
|
13413
|
+
return results;
|
|
13414
|
+
}
|
|
13415
|
+
};
|
|
13416
|
+
|
|
13205
13417
|
// src/sources/index.ts
|
|
13206
|
-
var sources = [
|
|
13418
|
+
var sources = [
|
|
13419
|
+
new ClaudeSource(),
|
|
13420
|
+
new CodexSource(),
|
|
13421
|
+
new CopilotChatSource()
|
|
13422
|
+
];
|
|
13207
13423
|
|
|
13208
13424
|
// src/cli.ts
|
|
13209
13425
|
function reportRedactionStats(noun, stats) {
|
|
@@ -13227,7 +13443,7 @@ function reportRedactionStats(noun, stats) {
|
|
|
13227
13443
|
async function filterByTimeRange(group, range) {
|
|
13228
13444
|
const results = await Promise.all(
|
|
13229
13445
|
group.files.map(
|
|
13230
|
-
(f) =>
|
|
13446
|
+
(f) => fs16.promises.stat(f.absolutePath).then((s) => ({ file: f, stat: s })).catch(() => null)
|
|
13231
13447
|
)
|
|
13232
13448
|
);
|
|
13233
13449
|
const filtered = [];
|
|
@@ -13254,10 +13470,10 @@ async function runInteractive() {
|
|
|
13254
13470
|
s.start(`Scanning ${source.name} logs...`);
|
|
13255
13471
|
const allFiles = await source.scan();
|
|
13256
13472
|
const allGroups = await mergeByRepo(allFiles);
|
|
13257
|
-
const repoRoot =
|
|
13473
|
+
const repoRoot = path19.resolve(repo.root);
|
|
13258
13474
|
const matching = allGroups.filter((g) => {
|
|
13259
|
-
const resolved =
|
|
13260
|
-
return resolved === repoRoot || resolved.startsWith(repoRoot +
|
|
13475
|
+
const resolved = path19.resolve(g.repoPath);
|
|
13476
|
+
return resolved === repoRoot || resolved.startsWith(repoRoot + path19.sep);
|
|
13261
13477
|
});
|
|
13262
13478
|
if (matching.length === 0) {
|
|
13263
13479
|
s.stop(`No ${source.name} logs found for ${repo.name}.`);
|
|
@@ -13288,7 +13504,7 @@ async function runInteractive() {
|
|
|
13288
13504
|
}
|
|
13289
13505
|
}
|
|
13290
13506
|
const envFileNames = await discoverEnvFiles(repoRoot);
|
|
13291
|
-
const envFilePaths = envFileNames.map((n) =>
|
|
13507
|
+
const envFilePaths = envFileNames.map((n) => path19.join(repoRoot, n));
|
|
13292
13508
|
const additionalFiles = await promptSecretFiles(envFileNames);
|
|
13293
13509
|
const secretResult = await collectSecrets(
|
|
13294
13510
|
repoRoot,
|