kantban-cli 0.1.51 → 0.1.52
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/{chunk-X2CJ3ZAI.js → chunk-3A4B7CUH.js} +215 -25
- package/dist/chunk-3A4B7CUH.js.map +1 -0
- package/dist/{cron-OCKARAAM.js → cron-VZMNM2XT.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{pipeline-6J64Z7VH.js → pipeline-NRG2Q2TE.js} +56 -194
- package/dist/pipeline-NRG2Q2TE.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-X2CJ3ZAI.js.map +0 -1
- package/dist/pipeline-6J64Z7VH.js.map +0 -1
- /package/dist/{cron-OCKARAAM.js.map → cron-VZMNM2XT.js.map} +0 -0
|
@@ -7,14 +7,20 @@ import {
|
|
|
7
7
|
classifyTrajectory,
|
|
8
8
|
cleanupGateProxyConfigs,
|
|
9
9
|
cleanupMcpConfig,
|
|
10
|
+
cleanupWorktree,
|
|
10
11
|
composeStuckDetectionPrompt,
|
|
12
|
+
defaultWorktreeRoot,
|
|
11
13
|
detectBranchMerged,
|
|
14
|
+
ensureWorktreeRemote,
|
|
12
15
|
generateGateProxyMcpConfig,
|
|
13
16
|
generateMcpConfig,
|
|
17
|
+
generateWorktreeName,
|
|
18
|
+
mergeWorktreeBranch,
|
|
14
19
|
parseJsonFromLlmOutput,
|
|
15
20
|
parseStuckDetectionResponse,
|
|
16
|
-
reapOrphanedMcpConfigDirs
|
|
17
|
-
|
|
21
|
+
reapOrphanedMcpConfigDirs,
|
|
22
|
+
renderWorktreePath
|
|
23
|
+
} from "./chunk-3A4B7CUH.js";
|
|
18
24
|
import {
|
|
19
25
|
LoopCheckpointSchema,
|
|
20
26
|
VerdictSchema,
|
|
@@ -34,8 +40,8 @@ import {
|
|
|
34
40
|
// src/commands/pipeline.ts
|
|
35
41
|
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync3, unlinkSync as unlinkSync3, existsSync as existsSync3, appendFileSync as appendFileSync2, promises as fsPromises } from "fs";
|
|
36
42
|
import { execFile } from "child_process";
|
|
37
|
-
import { homedir as
|
|
38
|
-
import { join as
|
|
43
|
+
import { homedir as homedir2 } from "os";
|
|
44
|
+
import { join as join3, dirname as dirname2, resolve, sep } from "path";
|
|
39
45
|
import { promisify } from "util";
|
|
40
46
|
|
|
41
47
|
// src/lib/harness-signal.ts
|
|
@@ -58,150 +64,6 @@ function resolveToolRestrictions(builtinTools, allowedTools, disallowedTools) {
|
|
|
58
64
|
};
|
|
59
65
|
}
|
|
60
66
|
|
|
61
|
-
// src/lib/worktree.ts
|
|
62
|
-
import { execFile as defaultExecFile, execFileSync } from "child_process";
|
|
63
|
-
import { homedir } from "os";
|
|
64
|
-
import { join } from "path";
|
|
65
|
-
function generateWorktreeName(ticketNumber, columnName) {
|
|
66
|
-
const slug = columnSlug(columnName);
|
|
67
|
-
return `kantban-${ticketNumber}-${slug}`;
|
|
68
|
-
}
|
|
69
|
-
function columnSlug(columnName) {
|
|
70
|
-
return columnName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
71
|
-
}
|
|
72
|
-
function renderWorktreePath(ticketNumber, columnName, pathPattern, options) {
|
|
73
|
-
const slug = columnSlug(columnName);
|
|
74
|
-
const worktreeName = generateWorktreeName(ticketNumber, columnName);
|
|
75
|
-
if (pathPattern) {
|
|
76
|
-
return pathPattern.replace(/\{ticket_number\}/g, String(ticketNumber)).replace(/\{column_slug\}/g, slug).replace(/\{worktree_name\}/g, worktreeName);
|
|
77
|
-
}
|
|
78
|
-
return join(options.defaultRoot, options.boardId, slug, String(ticketNumber));
|
|
79
|
-
}
|
|
80
|
-
function defaultWorktreeRoot() {
|
|
81
|
-
return join(homedir(), ".kantban", "worktrees");
|
|
82
|
-
}
|
|
83
|
-
function isPlausibleRemoteUrl(url) {
|
|
84
|
-
return url.includes("/") || url.includes("@") || url.includes("://");
|
|
85
|
-
}
|
|
86
|
-
function ensureWorktreeRemote(worktreePath) {
|
|
87
|
-
try {
|
|
88
|
-
const remotes = normalizeEol(execFileSync("git", ["-C", worktreePath, "remote"], {
|
|
89
|
-
stdio: "pipe",
|
|
90
|
-
encoding: "utf-8"
|
|
91
|
-
})).trim();
|
|
92
|
-
if (remotes.split("\n").includes("origin")) {
|
|
93
|
-
const currentUrl = normalizeEol(execFileSync("git", ["-C", worktreePath, "remote", "get-url", "origin"], {
|
|
94
|
-
stdio: "pipe",
|
|
95
|
-
encoding: "utf-8"
|
|
96
|
-
})).trim();
|
|
97
|
-
if (isPlausibleRemoteUrl(currentUrl)) return;
|
|
98
|
-
console.error(`[worktree] Invalid origin URL in ${worktreePath}: "${currentUrl}" \u2014 fixing`);
|
|
99
|
-
execFileSync("git", ["-C", worktreePath, "remote", "remove", "origin"], {
|
|
100
|
-
stdio: "pipe"
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
const originUrl = normalizeEol(execFileSync("git", ["remote", "get-url", "origin"], {
|
|
104
|
-
stdio: "pipe",
|
|
105
|
-
encoding: "utf-8"
|
|
106
|
-
})).trim();
|
|
107
|
-
if (originUrl && isPlausibleRemoteUrl(originUrl)) {
|
|
108
|
-
execFileSync("git", ["-C", worktreePath, "remote", "add", "origin", originUrl], {
|
|
109
|
-
stdio: "pipe"
|
|
110
|
-
});
|
|
111
|
-
console.error(`[worktree] Added missing origin remote to ${worktreePath}: ${originUrl}`);
|
|
112
|
-
} else {
|
|
113
|
-
console.error(`[worktree] WARNING: main repo origin URL is also invalid: "${originUrl}"`);
|
|
114
|
-
}
|
|
115
|
-
} catch (err) {
|
|
116
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
117
|
-
console.error(`[worktree] Failed to ensure remote for ${worktreePath}: ${msg}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
async function cleanupWorktree(worktreeName, exec = defaultExecFile) {
|
|
121
|
-
let target = worktreeName;
|
|
122
|
-
try {
|
|
123
|
-
const path = await findWorktreeForBranch(exec, worktreeName);
|
|
124
|
-
if (!path) return true;
|
|
125
|
-
target = path;
|
|
126
|
-
} catch {
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
return new Promise((resolve2) => {
|
|
130
|
-
exec("git", ["worktree", "remove", "--force", target], (err) => {
|
|
131
|
-
if (err) {
|
|
132
|
-
console.error(`[worktree] cleanup failed for ${worktreeName} (${target}): ${err.message}`);
|
|
133
|
-
resolve2(false);
|
|
134
|
-
} else {
|
|
135
|
-
resolve2(true);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
function execPromise(exec, cmd, args) {
|
|
141
|
-
return new Promise((resolve2, reject) => {
|
|
142
|
-
exec(cmd, args, (err, stdout, stderr) => {
|
|
143
|
-
if (err) reject(Object.assign(err, { stdout, stderr }));
|
|
144
|
-
else resolve2({ stdout, stderr });
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
async function findWorktreeForBranch(exec, branch) {
|
|
149
|
-
try {
|
|
150
|
-
const { stdout } = await execPromise(exec, "git", ["worktree", "list", "--porcelain"]);
|
|
151
|
-
const targetRef = `refs/heads/${branch}`;
|
|
152
|
-
let currentPath = null;
|
|
153
|
-
for (const line of normalizeEol(stdout).split("\n")) {
|
|
154
|
-
if (line.startsWith("worktree ")) currentPath = line.slice("worktree ".length);
|
|
155
|
-
if (line.startsWith("branch ") && line.slice("branch ".length) === targetRef && currentPath) {
|
|
156
|
-
return currentPath;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return null;
|
|
160
|
-
} catch {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
async function mergeWorktreeBranch(worktreeName, integrationBranch, exec = defaultExecFile) {
|
|
165
|
-
try {
|
|
166
|
-
try {
|
|
167
|
-
await execPromise(exec, "git", ["rev-parse", "--verify", worktreeName]);
|
|
168
|
-
} catch {
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
await execPromise(exec, "git", ["branch", integrationBranch, "HEAD"]).catch(() => {
|
|
172
|
-
});
|
|
173
|
-
const checkedOutPath = await findWorktreeForBranch(exec, integrationBranch);
|
|
174
|
-
if (checkedOutPath) {
|
|
175
|
-
await execPromise(exec, "git", ["-C", checkedOutPath, "merge", "--no-edit", worktreeName]);
|
|
176
|
-
console.error(`[worktree] merged ${worktreeName} \u2192 ${integrationBranch}`);
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
|
-
const { stdout: baseOut } = await execPromise(exec, "git", ["merge-base", integrationBranch, worktreeName]);
|
|
180
|
-
const mergeBase = baseOut.trim();
|
|
181
|
-
const { stdout: integrationSha } = await execPromise(exec, "git", ["rev-parse", integrationBranch]);
|
|
182
|
-
if (integrationSha.trim() === mergeBase) {
|
|
183
|
-
const { stdout: worktreeSha } = await execPromise(exec, "git", ["rev-parse", worktreeName]);
|
|
184
|
-
await execPromise(exec, "git", ["update-ref", `refs/heads/${integrationBranch}`, worktreeSha.trim()]);
|
|
185
|
-
console.error(`[worktree] fast-forward merged ${worktreeName} \u2192 ${integrationBranch}`);
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
const tmpWorktree = `merge-tmp-${Date.now()}`;
|
|
189
|
-
try {
|
|
190
|
-
await execPromise(exec, "git", ["worktree", "add", tmpWorktree, integrationBranch]);
|
|
191
|
-
await execPromise(exec, "git", ["-C", tmpWorktree, "merge", "--no-edit", worktreeName]);
|
|
192
|
-
console.error(`[worktree] merged ${worktreeName} \u2192 ${integrationBranch}`);
|
|
193
|
-
} finally {
|
|
194
|
-
await execPromise(exec, "git", ["worktree", "remove", "--force", tmpWorktree]).catch(() => {
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
return true;
|
|
198
|
-
} catch (err) {
|
|
199
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
200
|
-
console.error(`[worktree] merge failed for ${worktreeName} \u2192 ${integrationBranch}: ${msg}`);
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
67
|
// src/lib/constraint-evaluator.ts
|
|
206
68
|
function resolveColumn(board, columnId, subjectRef) {
|
|
207
69
|
const ref = subjectRef ?? "self";
|
|
@@ -2780,7 +2642,7 @@ var PipelineWsClient = class _PipelineWsClient {
|
|
|
2780
2642
|
|
|
2781
2643
|
// src/lib/logger.ts
|
|
2782
2644
|
import { mkdirSync, writeFileSync, appendFileSync, readdirSync, rmSync, statSync, renameSync } from "fs";
|
|
2783
|
-
import { join
|
|
2645
|
+
import { join } from "path";
|
|
2784
2646
|
var MAX_LOG_BYTES = 5 * 1024 * 1024;
|
|
2785
2647
|
var MAX_ROTATED_FILES = 3;
|
|
2786
2648
|
var ROTATION_CHECK_INTERVAL = 100;
|
|
@@ -2788,11 +2650,11 @@ var PipelineLogger = class {
|
|
|
2788
2650
|
boardDir;
|
|
2789
2651
|
writeCount = 0;
|
|
2790
2652
|
constructor(baseDir, boardId) {
|
|
2791
|
-
this.boardDir =
|
|
2653
|
+
this.boardDir = join(baseDir, boardId);
|
|
2792
2654
|
mkdirSync(this.boardDir, { recursive: true });
|
|
2793
2655
|
}
|
|
2794
2656
|
orchestrator(message) {
|
|
2795
|
-
const logPath =
|
|
2657
|
+
const logPath = join(this.boardDir, "orchestrator.log");
|
|
2796
2658
|
const entry = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
2797
2659
|
`;
|
|
2798
2660
|
appendFileSync(logPath, entry);
|
|
@@ -2824,10 +2686,10 @@ var PipelineLogger = class {
|
|
|
2824
2686
|
}
|
|
2825
2687
|
}
|
|
2826
2688
|
iteration(ticketNumber, iterationNum, data) {
|
|
2827
|
-
const ticketDir =
|
|
2689
|
+
const ticketDir = join(this.boardDir, ticketNumber);
|
|
2828
2690
|
mkdirSync(ticketDir, { recursive: true });
|
|
2829
2691
|
const padded = String(iterationNum).padStart(3, "0");
|
|
2830
|
-
const logPath =
|
|
2692
|
+
const logPath = join(ticketDir, `iteration-${padded}.log`);
|
|
2831
2693
|
const entry = {
|
|
2832
2694
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2833
2695
|
iteration: iterationNum,
|
|
@@ -2846,7 +2708,7 @@ var PipelineLogger = class {
|
|
|
2846
2708
|
try {
|
|
2847
2709
|
const entries = readdirSync(this.boardDir, { withFileTypes: true });
|
|
2848
2710
|
for (const entry of entries) {
|
|
2849
|
-
const fullPath =
|
|
2711
|
+
const fullPath = join(this.boardDir, entry.name);
|
|
2850
2712
|
if (entry.isDirectory() && entry.name !== ".") {
|
|
2851
2713
|
try {
|
|
2852
2714
|
const stat = statSync(fullPath);
|
|
@@ -3483,7 +3345,7 @@ var ProviderRegistry = class {
|
|
|
3483
3345
|
};
|
|
3484
3346
|
|
|
3485
3347
|
// src/providers/codex-provider.ts
|
|
3486
|
-
import { spawn as spawn2, execFileSync
|
|
3348
|
+
import { spawn as spawn2, execFileSync } from "child_process";
|
|
3487
3349
|
import { existsSync, rmSync as rmSync2 } from "fs";
|
|
3488
3350
|
|
|
3489
3351
|
// src/providers/codex-jsonl-parser.ts
|
|
@@ -3624,12 +3486,12 @@ var CodexProvider = class {
|
|
|
3624
3486
|
const branch = request.branch ?? request.workingDirectory;
|
|
3625
3487
|
if (!existsSync(request.workingDirectory)) {
|
|
3626
3488
|
try {
|
|
3627
|
-
|
|
3489
|
+
execFileSync("git", ["worktree", "add", "-b", branch, request.workingDirectory, "HEAD"], {
|
|
3628
3490
|
stdio: "pipe"
|
|
3629
3491
|
});
|
|
3630
3492
|
} catch {
|
|
3631
3493
|
try {
|
|
3632
|
-
|
|
3494
|
+
execFileSync("git", ["worktree", "add", request.workingDirectory, branch], {
|
|
3633
3495
|
stdio: "pipe"
|
|
3634
3496
|
});
|
|
3635
3497
|
} catch (err) {
|
|
@@ -3639,18 +3501,18 @@ var CodexProvider = class {
|
|
|
3639
3501
|
}
|
|
3640
3502
|
} else {
|
|
3641
3503
|
try {
|
|
3642
|
-
|
|
3504
|
+
execFileSync("git", ["-C", request.workingDirectory, "rev-parse", "--git-dir"], {
|
|
3643
3505
|
stdio: "pipe"
|
|
3644
3506
|
});
|
|
3645
3507
|
} catch {
|
|
3646
3508
|
try {
|
|
3647
3509
|
rmSync2(request.workingDirectory, { recursive: true, force: true });
|
|
3648
|
-
|
|
3510
|
+
execFileSync("git", ["worktree", "add", "-b", branch, request.workingDirectory, "HEAD"], {
|
|
3649
3511
|
stdio: "pipe"
|
|
3650
3512
|
});
|
|
3651
3513
|
} catch {
|
|
3652
3514
|
try {
|
|
3653
|
-
|
|
3515
|
+
execFileSync("git", ["worktree", "add", request.workingDirectory, branch], {
|
|
3654
3516
|
stdio: "pipe"
|
|
3655
3517
|
});
|
|
3656
3518
|
} catch (err) {
|
|
@@ -3786,10 +3648,10 @@ var CodexProvider = class {
|
|
|
3786
3648
|
};
|
|
3787
3649
|
|
|
3788
3650
|
// src/providers/gemini-provider.ts
|
|
3789
|
-
import { spawn as spawn3, execFileSync as
|
|
3651
|
+
import { spawn as spawn3, execFileSync as execFileSync2 } from "child_process";
|
|
3790
3652
|
import { existsSync as existsSync2, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, rmSync as rmSync3 } from "fs";
|
|
3791
|
-
import { join as
|
|
3792
|
-
import { homedir
|
|
3653
|
+
import { join as join2, dirname } from "path";
|
|
3654
|
+
import { homedir } from "os";
|
|
3793
3655
|
import { fileURLToPath } from "url";
|
|
3794
3656
|
import { readFileSync as readFileSync2 } from "fs";
|
|
3795
3657
|
|
|
@@ -3952,13 +3814,13 @@ function resolveHookScriptPath() {
|
|
|
3952
3814
|
try {
|
|
3953
3815
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
3954
3816
|
const candidates = [
|
|
3955
|
-
|
|
3817
|
+
join2(thisDir, "lib", "gemini-hooks.mjs"),
|
|
3956
3818
|
// dist/lib/ (flat bundle)
|
|
3957
|
-
|
|
3819
|
+
join2(thisDir, "..", "lib", "gemini-hooks.mjs"),
|
|
3958
3820
|
// dist/../lib/ (nested)
|
|
3959
|
-
|
|
3821
|
+
join2(thisDir, "..", "src", "lib", "gemini-hooks.mjs"),
|
|
3960
3822
|
// source from dist/
|
|
3961
|
-
|
|
3823
|
+
join2(thisDir, "..", "..", "src", "lib", "gemini-hooks.mjs")
|
|
3962
3824
|
// source from dist/providers/
|
|
3963
3825
|
];
|
|
3964
3826
|
for (const p of candidates) {
|
|
@@ -3998,12 +3860,12 @@ var GeminiProvider = class _GeminiProvider {
|
|
|
3998
3860
|
if (request.workingDirectory) {
|
|
3999
3861
|
if (!existsSync2(request.workingDirectory)) {
|
|
4000
3862
|
try {
|
|
4001
|
-
|
|
3863
|
+
execFileSync2("git", ["worktree", "add", "-b", request.workingDirectory, request.workingDirectory, "HEAD"], {
|
|
4002
3864
|
stdio: "pipe"
|
|
4003
3865
|
});
|
|
4004
3866
|
} catch {
|
|
4005
3867
|
try {
|
|
4006
|
-
|
|
3868
|
+
execFileSync2("git", ["worktree", "add", request.workingDirectory, request.workingDirectory], {
|
|
4007
3869
|
stdio: "pipe"
|
|
4008
3870
|
});
|
|
4009
3871
|
} catch {
|
|
@@ -4012,18 +3874,18 @@ var GeminiProvider = class _GeminiProvider {
|
|
|
4012
3874
|
}
|
|
4013
3875
|
} else {
|
|
4014
3876
|
try {
|
|
4015
|
-
|
|
3877
|
+
execFileSync2("git", ["-C", request.workingDirectory, "rev-parse", "--git-dir"], {
|
|
4016
3878
|
stdio: "pipe"
|
|
4017
3879
|
});
|
|
4018
3880
|
} catch {
|
|
4019
3881
|
try {
|
|
4020
3882
|
rmSync3(request.workingDirectory, { recursive: true, force: true });
|
|
4021
|
-
|
|
3883
|
+
execFileSync2("git", ["worktree", "add", "-b", request.workingDirectory, request.workingDirectory, "HEAD"], {
|
|
4022
3884
|
stdio: "pipe"
|
|
4023
3885
|
});
|
|
4024
3886
|
} catch {
|
|
4025
3887
|
try {
|
|
4026
|
-
|
|
3888
|
+
execFileSync2("git", ["worktree", "add", request.workingDirectory, request.workingDirectory], {
|
|
4027
3889
|
stdio: "pipe"
|
|
4028
3890
|
});
|
|
4029
3891
|
} catch {
|
|
@@ -4152,9 +4014,9 @@ var GeminiProvider = class _GeminiProvider {
|
|
|
4152
4014
|
}
|
|
4153
4015
|
writeGeminiSettings(request, degraded) {
|
|
4154
4016
|
try {
|
|
4155
|
-
const baseDir =
|
|
4156
|
-
const dir =
|
|
4157
|
-
const geminiDir =
|
|
4017
|
+
const baseDir = join2(homedir(), ".kantban", "pipelines", "gemini-tmp");
|
|
4018
|
+
const dir = join2(baseDir, `session-${Date.now()}`);
|
|
4019
|
+
const geminiDir = join2(dir, ".gemini");
|
|
4158
4020
|
mkdirSync2(geminiDir, { recursive: true, mode: 448 });
|
|
4159
4021
|
const settings = {};
|
|
4160
4022
|
if (request.mcpConfig && Object.keys(request.mcpConfig.servers).length > 0) {
|
|
@@ -4178,20 +4040,20 @@ var GeminiProvider = class _GeminiProvider {
|
|
|
4178
4040
|
hookConfig.disallowedTools = tr.disallowedTools ? translateToolNames(tr.disallowedTools) : null;
|
|
4179
4041
|
if (tr.tools !== void 0) hookConfig.builtinToolsMode = tr.tools;
|
|
4180
4042
|
const ext = IS_WINDOWS ? ".cmd" : ".sh";
|
|
4181
|
-
const wrapperPath =
|
|
4182
|
-
writeFileSync3(wrapperPath, this.generateHookWrapper(hookPath, "BeforeToolSelection",
|
|
4043
|
+
const wrapperPath = join2(dir, `.kantban-hook-before-tool${ext}`);
|
|
4044
|
+
writeFileSync3(wrapperPath, this.generateHookWrapper(hookPath, "BeforeToolSelection", join2(dir, ".kantban-hook-config.json")), { mode: 493 });
|
|
4183
4045
|
hooks.BeforeToolSelection = [{ matcher: "*", hooks: [{ type: "command", command: wrapperPath, timeout: 3e4 }] }];
|
|
4184
4046
|
}
|
|
4185
4047
|
if (request.maxTurns && request.mcpConfig) {
|
|
4186
4048
|
hookConfig.maxTurns = request.maxTurns;
|
|
4187
|
-
hookConfig.turnFile =
|
|
4049
|
+
hookConfig.turnFile = join2(dir, ".kantban-turn-counter");
|
|
4188
4050
|
const ext = IS_WINDOWS ? ".cmd" : ".sh";
|
|
4189
|
-
const wrapperPath =
|
|
4190
|
-
writeFileSync3(wrapperPath, this.generateHookWrapper(hookPath, "AfterAgent",
|
|
4051
|
+
const wrapperPath = join2(dir, `.kantban-hook-after-agent${ext}`);
|
|
4052
|
+
writeFileSync3(wrapperPath, this.generateHookWrapper(hookPath, "AfterAgent", join2(dir, ".kantban-hook-config.json")), { mode: 493 });
|
|
4191
4053
|
hooks.AfterAgent = [{ matcher: "*", hooks: [{ type: "command", command: wrapperPath, timeout: 3e4 }] }];
|
|
4192
4054
|
}
|
|
4193
4055
|
if (Object.keys(hookConfig).length > 0) {
|
|
4194
|
-
writeFileSync3(
|
|
4056
|
+
writeFileSync3(join2(dir, ".kantban-hook-config.json"), JSON.stringify(hookConfig), { mode: 384 });
|
|
4195
4057
|
}
|
|
4196
4058
|
if (Object.keys(hooks).length > 0) {
|
|
4197
4059
|
settings.hooks = hooks;
|
|
@@ -4204,7 +4066,7 @@ var GeminiProvider = class _GeminiProvider {
|
|
|
4204
4066
|
process.stderr.write(`[gemini] Hook script not found \u2014 tool scoping and turn limits unavailable
|
|
4205
4067
|
`);
|
|
4206
4068
|
}
|
|
4207
|
-
writeFileSync3(
|
|
4069
|
+
writeFileSync3(join2(geminiDir, "settings.json"), JSON.stringify(settings, null, 2), { mode: 384 });
|
|
4208
4070
|
return dir;
|
|
4209
4071
|
} catch (err) {
|
|
4210
4072
|
process.stderr.write(`[gemini] Failed to write settings.json: ${err}
|
|
@@ -4270,11 +4132,11 @@ node "${hookScript}" "${event}" "${configFile}" < "$STDIN_FILE"
|
|
|
4270
4132
|
}
|
|
4271
4133
|
copySettingsToDir(settingsDir, targetDir) {
|
|
4272
4134
|
try {
|
|
4273
|
-
const sourceFile =
|
|
4274
|
-
const targetGeminiDir =
|
|
4135
|
+
const sourceFile = join2(settingsDir, ".gemini", "settings.json");
|
|
4136
|
+
const targetGeminiDir = join2(targetDir, ".gemini");
|
|
4275
4137
|
mkdirSync2(targetGeminiDir, { recursive: true, mode: 448 });
|
|
4276
4138
|
const content = readFileSync2(sourceFile, "utf-8");
|
|
4277
|
-
writeFileSync3(
|
|
4139
|
+
writeFileSync3(join2(targetGeminiDir, "settings.json"), content, { mode: 384 });
|
|
4278
4140
|
} catch {
|
|
4279
4141
|
}
|
|
4280
4142
|
}
|
|
@@ -4414,10 +4276,10 @@ Flags:
|
|
|
4414
4276
|
return { boardId, once, dryRun, columnFilter, maxIterations, maxBudget, model, provider, concurrency, logRetention, yes };
|
|
4415
4277
|
}
|
|
4416
4278
|
function pidDir(boardId) {
|
|
4417
|
-
return
|
|
4279
|
+
return join3(homedir2(), ".kantban", "pipelines", boardId);
|
|
4418
4280
|
}
|
|
4419
4281
|
function pidFilePath(boardId) {
|
|
4420
|
-
return
|
|
4282
|
+
return join3(pidDir(boardId), "orchestrator.pid");
|
|
4421
4283
|
}
|
|
4422
4284
|
function writePidFile(boardId) {
|
|
4423
4285
|
const dir = pidDir(boardId);
|
|
@@ -4431,7 +4293,7 @@ function removePidFile(boardId) {
|
|
|
4431
4293
|
}
|
|
4432
4294
|
}
|
|
4433
4295
|
function childManifestPath(boardId) {
|
|
4434
|
-
return
|
|
4296
|
+
return join3(pidDir(boardId), "children.pid");
|
|
4435
4297
|
}
|
|
4436
4298
|
function readChildManifest(boardId) {
|
|
4437
4299
|
try {
|
|
@@ -4476,7 +4338,7 @@ function cleanupOrphanedProcesses(boardId) {
|
|
|
4476
4338
|
console.log(`Killed ${String(manifestPids.length)} orphaned child process(es) from manifest`);
|
|
4477
4339
|
removeChildManifest(boardId);
|
|
4478
4340
|
}
|
|
4479
|
-
const staleReaperPath =
|
|
4341
|
+
const staleReaperPath = join3(pidDir(boardId), "reaper.pid");
|
|
4480
4342
|
try {
|
|
4481
4343
|
if (existsSync3(staleReaperPath)) {
|
|
4482
4344
|
const reaperPid = parseInt(readFileSync3(staleReaperPath, "utf-8").trim(), 10);
|
|
@@ -4535,7 +4397,7 @@ async function runPipeline(client, args) {
|
|
|
4535
4397
|
return;
|
|
4536
4398
|
}
|
|
4537
4399
|
}
|
|
4538
|
-
const gateFilePath =
|
|
4400
|
+
const gateFilePath = join3(process.cwd(), "pipeline.gates.yaml");
|
|
4539
4401
|
let gateConfig;
|
|
4540
4402
|
if (!existsSync3(gateFilePath)) {
|
|
4541
4403
|
console.error(`Error: pipeline.gates.yaml not found in ${process.cwd()}`);
|
|
@@ -4572,7 +4434,7 @@ async function runPipeline(client, args) {
|
|
|
4572
4434
|
...opts.provider ? { intelligence_provider: opts.provider } : {}
|
|
4573
4435
|
};
|
|
4574
4436
|
const intelligenceProvider = registry.resolveForIntelligence(boardProviderConfig);
|
|
4575
|
-
const logBaseDir =
|
|
4437
|
+
const logBaseDir = join3(homedir2(), ".kantban", "pipelines");
|
|
4576
4438
|
const logger = new PipelineLogger(logBaseDir, opts.boardId);
|
|
4577
4439
|
logger.pruneOldLogs(opts.logRetention);
|
|
4578
4440
|
let runMemory = null;
|
|
@@ -4636,7 +4498,7 @@ async function runPipeline(client, args) {
|
|
|
4636
4498
|
effectiveConfig.model = registry.resolveModel(columnProvider, effectiveConfig.model);
|
|
4637
4499
|
}
|
|
4638
4500
|
const { gates: columnGates } = resolveGatesForColumn(gateConfig, resolvedColumnName);
|
|
4639
|
-
const gateCwd = effectiveConfig.worktreePath ?? (effectiveConfig.worktreeName ?
|
|
4501
|
+
const gateCwd = effectiveConfig.worktreePath ?? (effectiveConfig.worktreeName ? join3(process.cwd(), effectiveConfig.worktreeName) : process.cwd());
|
|
4640
4502
|
const effectiveMcpConfigPath = columnGates.length > 0 ? generateGateProxyMcpConfig(
|
|
4641
4503
|
client.baseUrl,
|
|
4642
4504
|
client.token,
|
|
@@ -5145,7 +5007,7 @@ Received ${signal}. Shutting down gracefully...`);
|
|
|
5145
5007
|
cleanupOrphanedProcesses(opts.boardId);
|
|
5146
5008
|
writePidFile(opts.boardId);
|
|
5147
5009
|
logger.orchestrator(`PID file written: ${String(process.pid)}`);
|
|
5148
|
-
const reaperPidPath =
|
|
5010
|
+
const reaperPidPath = join3(pidDir(opts.boardId), "reaper.pid");
|
|
5149
5011
|
const reaperProcess = spawnReaper({
|
|
5150
5012
|
orchestratorPid: process.pid,
|
|
5151
5013
|
manifestPath: childManifestPath(opts.boardId),
|
|
@@ -5335,4 +5197,4 @@ export {
|
|
|
5335
5197
|
runPipeline,
|
|
5336
5198
|
stopPipeline
|
|
5337
5199
|
};
|
|
5338
|
-
//# sourceMappingURL=pipeline-
|
|
5200
|
+
//# sourceMappingURL=pipeline-NRG2Q2TE.js.map
|