@dotobokuri/fleet-console 1.40.0 → 1.41.0
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/README.md +2 -3
- package/dist/cli.d.ts +2 -1
- package/dist/cli.mjs +151 -134
- package/dist/client/assets/{_baseUniq-Bao5GOIa.js → _baseUniq-CImzMrtU.js} +1 -1
- package/dist/client/assets/{arc-DnhHMLy9.js → arc-CKb0rHjN.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-DAbURr0a.js → architectureDiagram-Q4EWVU46-BaZipXSe.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-DE1raZQ6.js → blockDiagram-DXYQGD6D-D4sS9TjR.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-beLZlUB3.js → c4Diagram-AHTNJAMY-DvjpMsKx.js} +1 -1
- package/dist/client/assets/channel-dSuGhtYS.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DEqdunZS.js → chunk-4BX2VUAB-B47BryhY.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-D8i5nx4L.js → chunk-4TB4RGXK-DKIhSC52.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-eM3-fH_e.js → chunk-55IACEB6-B3Gvpef7.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-nQoyt_Pd.js → chunk-EDXVE4YY-C4gFtvU8.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-D8Wq8CYj.js → chunk-FMBD7UC4-BADPieOa.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-Cx4Wr2ZT.js → chunk-OYMX7WX6-BUdtWGUY.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BM2v7Krr.js → chunk-QZHKN3VN-CMxkeGnM.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-zTniPxm7.js → chunk-YZCP3GAM-Br6N7t8d.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DEN4mh7x.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DEN4mh7x.js +1 -0
- package/dist/client/assets/clone-BbTnmCoq.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-B5pl2A_p.js → cose-bilkent-S5V4N54A-D1Uw7i5_.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-KHPgW9C2.js → dagre-KV5264BT-kop0bHkM.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DCv28c7S.js → diagram-5BDNPKRD-B9e41qNA.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-mT5WQ415.js → diagram-G4DWMVQ6-Wew8X03k.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-iKYfjiRC.js → diagram-MMDJMWI5-DGBb5Oqa.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-_uqBP7vH.js → diagram-TYMM5635-CiVNsAz6.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-DxNN1WhN.js → erDiagram-SMLLAGMA-BdemYTgC.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-DGTsrBvM.js → flowDiagram-DWJPFMVM-CXC6yxhU.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-C17hg4lr.js → ganttDiagram-T4ZO3ILL-SMUpaiUg.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CeJ25hAd.js → gitGraphDiagram-UUTBAWPF-UaFgTHEh.js} +1 -1
- package/dist/client/assets/{graph-BQvb-BfT.js → graph-Ch8F0gMI.js} +1 -1
- package/dist/client/assets/index-D38r12i5.css +1 -0
- package/dist/client/assets/index-DkTcJcbj.js +452 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-BctsofOZ.js → infoDiagram-42DDH7IO-BHBzw0bu.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-PiPmxcg9.js → ishikawaDiagram-UXIWVN3A-CnDea8bw.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BwkjYq3n.js → journeyDiagram-VCZTEJTY-CI91m8BP.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-CSV4dYfF.js → kanban-definition-6JOO6SKY-D-rn-rG2.js} +1 -1
- package/dist/client/assets/{layout-DdReLJnP.js → layout-Cd9zpG94.js} +1 -1
- package/dist/client/assets/{linear-B54euy_k.js → linear-Cucr1ojd.js} +1 -1
- package/dist/client/assets/{mermaid.core-CF92I5mT.js → mermaid.core-G36P12JZ.js} +4 -4
- package/dist/client/assets/{min-BcETQ2qJ.js → min-CzfCLG7v.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-CrmVPycO.js → mindmap-definition-QFDTVHPH-4e1VjBV7.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B5d4jR0H.js → pieDiagram-DEJITSTG-m2CGbU51.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-DlgCNExa.js → quadrantDiagram-34T5L4WZ-BKNPGqMc.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-CeuVib_X.js → requirementDiagram-MS252O5E-D2BMwnpz.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-Bzxv73ik.js → sankeyDiagram-XADWPNL6-Bm6hTqEh.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-B0Ondg0u.js → sequenceDiagram-FGHM5R23-Ds2FEGPj.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-CuNHg5DJ.js → stateDiagram-FHFEXIEX-CrXn2Tb7.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BbzpXIlW.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-DXcye6z7.js → timeline-definition-GMOUNBTQ-mw053fb5.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CL4rbpzL.js → vennDiagram-DHZGUBPP-CAws0Vt2.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-rVZBTA_R.js → wardley-RL74JXVD-DGad2cmz.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-Cb8Arj1F.js → wardleyDiagram-NUSXRM2D-BlIyft8I.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-C-qp4Say.js → xychartDiagram-5P7HB3ND-DHmSULAI.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/file-explorer/routes.mjs +484 -56
- package/dist/fleet-plugins/ledger/routes.mjs +56 -47
- package/dist/fleet-plugins/quota/routes.mjs +19252 -118
- package/dist/fleet-plugins/repository/routes.mjs +274 -17
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +6 -81
- package/dist/fleet-plugins/skills/routes.mjs +1 -46
- package/dist/fleet-plugins/terminal/routes.mjs +12090 -1060
- package/package.json +1 -1
- package/dist/client/assets/channel-Bn1wyUhs.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DBE3Ix3c.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DBE3Ix3c.js +0 -1
- package/dist/client/assets/clone-COL47Wy_.js +0 -1
- package/dist/client/assets/index-Ca6HkGPQ.css +0 -1
- package/dist/client/assets/index-Cr3Xq85X.js +0 -452
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BVPbUfrG.js +0 -1
|
@@ -8,12 +8,12 @@ import fs2 from 'fs/promises';
|
|
|
8
8
|
function definePlugin(definition) {
|
|
9
9
|
return definition;
|
|
10
10
|
}
|
|
11
|
-
function registerRouter(ctx,
|
|
12
|
-
ctx.registerRouter(normalizePath(
|
|
11
|
+
function registerRouter(ctx, path10, handler) {
|
|
12
|
+
ctx.registerRouter(normalizePath(path10), handler);
|
|
13
13
|
}
|
|
14
|
-
function normalizePath(
|
|
15
|
-
if (
|
|
16
|
-
return
|
|
14
|
+
function normalizePath(path10) {
|
|
15
|
+
if (path10.length === 0 || path10 === "/") return "/";
|
|
16
|
+
return path10;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// ../../packages/core-process/src/hidden.ts
|
|
@@ -36,9 +36,25 @@ var GitExecutorError = class extends Error {
|
|
|
36
36
|
};
|
|
37
37
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
38
38
|
var DEFAULT_MAX_BUFFER = 8 * 1024 * 1024;
|
|
39
|
+
var STDERR_MAX_BUFFER = 1024 * 1024;
|
|
40
|
+
var GIT_HARDENING_PREFIX = ["-c", "core.fsmonitor=false", "--no-optional-locks"];
|
|
41
|
+
function sanitizeGitEnvironment(environment) {
|
|
42
|
+
const sanitized = {};
|
|
43
|
+
for (const [key, value] of Object.entries(environment)) {
|
|
44
|
+
const normalizedKey = key.toUpperCase();
|
|
45
|
+
if (normalizedKey.startsWith("GIT_") || normalizedKey === "LC_ALL" || normalizedKey === "SSH_ASKPASS" || normalizedKey === "SSH_ASKPASS_REQUIRE") continue;
|
|
46
|
+
if (value !== void 0) sanitized[key] = value;
|
|
47
|
+
}
|
|
48
|
+
sanitized.GIT_OPTIONAL_LOCKS = "0";
|
|
49
|
+
sanitized.GIT_TERMINAL_PROMPT = "0";
|
|
50
|
+
sanitized.GIT_ALLOW_PROTOCOL = "ssh:git:http:https:file";
|
|
51
|
+
sanitized.LC_ALL = "C";
|
|
52
|
+
return sanitized;
|
|
53
|
+
}
|
|
39
54
|
function runGit(args, opts) {
|
|
40
55
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
41
56
|
const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
57
|
+
const hardenedArgs = [...GIT_HARDENING_PREFIX, ...args];
|
|
42
58
|
return new Promise((resolve, reject) => {
|
|
43
59
|
if (opts.signal?.aborted) {
|
|
44
60
|
reject(new GitExecutorError("timeout"));
|
|
@@ -46,7 +62,11 @@ function runGit(args, opts) {
|
|
|
46
62
|
}
|
|
47
63
|
let child;
|
|
48
64
|
try {
|
|
49
|
-
child = spawn("git",
|
|
65
|
+
child = spawn("git", hardenedArgs, withHidden({
|
|
66
|
+
cwd: opts.cwd,
|
|
67
|
+
env: sanitizeGitEnvironment(process.env),
|
|
68
|
+
shell: false
|
|
69
|
+
}));
|
|
50
70
|
} catch (error) {
|
|
51
71
|
const code = error.code === "ENOENT" ? "git_unavailable" : "spawn_failed";
|
|
52
72
|
reject(new GitExecutorError(code, String(error)));
|
|
@@ -55,7 +75,9 @@ function runGit(args, opts) {
|
|
|
55
75
|
const stdoutChunks = [];
|
|
56
76
|
const stderrChunks = [];
|
|
57
77
|
let stdoutLen = 0;
|
|
78
|
+
let stderrLen = 0;
|
|
58
79
|
let truncated = false;
|
|
80
|
+
let stderrTruncated = false;
|
|
59
81
|
let timedOut = false;
|
|
60
82
|
const abort = () => {
|
|
61
83
|
timedOut = true;
|
|
@@ -83,7 +105,16 @@ function runGit(args, opts) {
|
|
|
83
105
|
}
|
|
84
106
|
});
|
|
85
107
|
child.stderr.on("data", (chunk) => {
|
|
86
|
-
|
|
108
|
+
if (stderrTruncated) return;
|
|
109
|
+
const remaining = STDERR_MAX_BUFFER - stderrLen;
|
|
110
|
+
if (chunk.length >= remaining) {
|
|
111
|
+
stderrChunks.push(chunk.subarray(0, remaining));
|
|
112
|
+
stderrLen += remaining;
|
|
113
|
+
stderrTruncated = true;
|
|
114
|
+
} else {
|
|
115
|
+
stderrChunks.push(chunk);
|
|
116
|
+
stderrLen += chunk.length;
|
|
117
|
+
}
|
|
87
118
|
});
|
|
88
119
|
child.on("error", (error) => {
|
|
89
120
|
cleanup();
|
|
@@ -97,7 +128,7 @@ function runGit(args, opts) {
|
|
|
97
128
|
if (code !== 0) {
|
|
98
129
|
if (code !== null && (opts.allowExitCodes?.includes(code) ?? false)) {
|
|
99
130
|
const stdout2 = Buffer.concat(stdoutChunks).toString("utf8");
|
|
100
|
-
resolve({ stdout: stdout2, truncated });
|
|
131
|
+
resolve({ stdout: stdout2, stderr, truncated, stderrTruncated });
|
|
101
132
|
return;
|
|
102
133
|
}
|
|
103
134
|
const isNoRepo = stderr.toLowerCase().includes("not a git repository");
|
|
@@ -105,7 +136,7 @@ function runGit(args, opts) {
|
|
|
105
136
|
return;
|
|
106
137
|
}
|
|
107
138
|
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
108
|
-
resolve({ stdout, truncated });
|
|
139
|
+
resolve({ stdout, stderr, truncated, stderrTruncated });
|
|
109
140
|
});
|
|
110
141
|
});
|
|
111
142
|
}
|
|
@@ -796,10 +827,232 @@ async function handleRepositoryCompareFile(req, res, ctx) {
|
|
|
796
827
|
throw error;
|
|
797
828
|
}
|
|
798
829
|
}
|
|
830
|
+
var AUTO_FETCH_THROTTLE_MS = 3e5;
|
|
831
|
+
var autoFetchInFlight = /* @__PURE__ */ new Map();
|
|
832
|
+
var lastSuccessfulFetchAt = /* @__PURE__ */ new Map();
|
|
833
|
+
function isPlainObject6(value) {
|
|
834
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
835
|
+
}
|
|
836
|
+
function classifyFetchError(stderr) {
|
|
837
|
+
if (/permission denied|authentication failed|could not read username|terminal prompts disabled|repository not found/i.test(stderr)) {
|
|
838
|
+
return "auth_failed";
|
|
839
|
+
}
|
|
840
|
+
if (/could not resolve host|failed to connect|connection (refused|reset)|operation timed out|network is unreachable/i.test(stderr)) {
|
|
841
|
+
return "network";
|
|
842
|
+
}
|
|
843
|
+
if (/no remote repository specified|does not appear to be a git repository/i.test(stderr)) {
|
|
844
|
+
return "no_remote";
|
|
845
|
+
}
|
|
846
|
+
return null;
|
|
847
|
+
}
|
|
848
|
+
async function resolveGitIdentity(gitCwd) {
|
|
849
|
+
const [gitDirResult, commonDirResult] = await Promise.all([
|
|
850
|
+
runGit(["rev-parse", "--absolute-git-dir"], { cwd: gitCwd }),
|
|
851
|
+
runGit(["rev-parse", "--git-common-dir"], { cwd: gitCwd })
|
|
852
|
+
]);
|
|
853
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
854
|
+
fs2.realpath(path4.resolve(gitCwd, gitDirResult.stdout.trim())),
|
|
855
|
+
fs2.realpath(path4.resolve(gitCwd, commonDirResult.stdout.trim()))
|
|
856
|
+
]);
|
|
857
|
+
return { gitDir, commonDir };
|
|
858
|
+
}
|
|
859
|
+
async function readLastFetchAt(gitDirs) {
|
|
860
|
+
let newest = null;
|
|
861
|
+
for (const gitDir of gitDirs) {
|
|
862
|
+
try {
|
|
863
|
+
const stats = await fs2.stat(path4.join(gitDir, "FETCH_HEAD"));
|
|
864
|
+
if (stats.size === 0) continue;
|
|
865
|
+
if (!newest || stats.mtime.getTime() > newest.getTime()) newest = stats.mtime;
|
|
866
|
+
} catch (error) {
|
|
867
|
+
if (error.code !== "ENOENT") throw error;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return newest;
|
|
871
|
+
}
|
|
872
|
+
function countFetchProgress(stderr, marker) {
|
|
873
|
+
return stderr.split(/\r?\n/).filter((line) => line.includes(marker)).length;
|
|
874
|
+
}
|
|
875
|
+
function countFetchUpdatedRefs(stderr) {
|
|
876
|
+
return stderr.split(/\r?\n/).filter(
|
|
877
|
+
(line) => line.includes(" -> ") && /\S+\.\.\S+/.test(line) && !line.includes("[deleted]") && !line.includes("[new ")
|
|
878
|
+
).length;
|
|
879
|
+
}
|
|
880
|
+
var NoRemoteError = class extends Error {
|
|
881
|
+
};
|
|
882
|
+
var SAFE_CREDENTIAL_HELPERS = /* @__PURE__ */ new Set([
|
|
883
|
+
"cache",
|
|
884
|
+
"store",
|
|
885
|
+
"osxkeychain",
|
|
886
|
+
"wincred",
|
|
887
|
+
"libsecret",
|
|
888
|
+
"gnome-libsecret",
|
|
889
|
+
"manager",
|
|
890
|
+
"manager-core"
|
|
891
|
+
]);
|
|
892
|
+
async function resolveCredentialHelperArgs(gitCwd) {
|
|
893
|
+
const raw = (await runGit(["config", "--get-all", "credential.helper"], { cwd: gitCwd, allowExitCodes: [1] })).stdout;
|
|
894
|
+
const helpers = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
895
|
+
const kept = helpers.filter((helper) => {
|
|
896
|
+
if (!/^[A-Za-z0-9-]+$/.test(helper)) return false;
|
|
897
|
+
return SAFE_CREDENTIAL_HELPERS.has(helper) || SAFE_CREDENTIAL_HELPERS.has(helper.replace(/^git-credential-/, ""));
|
|
898
|
+
});
|
|
899
|
+
return ["-c", "credential.helper=", ...kept.flatMap((helper) => ["-c", `credential.helper=${helper}`]), "-c", "core.askPass="];
|
|
900
|
+
}
|
|
901
|
+
async function resolveDefaultRemote(gitCwd) {
|
|
902
|
+
const branch = (await runGit(["rev-parse", "--abbrev-ref", "HEAD"], { cwd: gitCwd })).stdout.trim();
|
|
903
|
+
if (branch && branch !== "HEAD") {
|
|
904
|
+
const upstream = (await runGit(["config", "--get", `branch.${branch}.remote`], { cwd: gitCwd, allowExitCodes: [1] })).stdout.trim();
|
|
905
|
+
if (upstream && upstream !== ".") return upstream;
|
|
906
|
+
}
|
|
907
|
+
const remotes = (await runGit(["remote"], { cwd: gitCwd })).stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
908
|
+
if (remotes.includes("origin")) return "origin";
|
|
909
|
+
return remotes[0] ?? null;
|
|
910
|
+
}
|
|
911
|
+
async function readThrottleResult(gitDirs, commonDir) {
|
|
912
|
+
const fsNewest = await readLastFetchAt(gitDirs);
|
|
913
|
+
const recorded = lastSuccessfulFetchAt.get(commonDir);
|
|
914
|
+
let newest = fsNewest;
|
|
915
|
+
if (recorded !== void 0 && (!newest || recorded > newest.getTime())) newest = new Date(recorded);
|
|
916
|
+
if (!newest || Date.now() - newest.getTime() >= AUTO_FETCH_THROTTLE_MS) return null;
|
|
917
|
+
return { ok: true, skipped: "throttled", lastFetchAt: newest.toISOString() };
|
|
918
|
+
}
|
|
919
|
+
async function fetchRepository(gitCwd) {
|
|
920
|
+
const remote = await resolveDefaultRemote(gitCwd);
|
|
921
|
+
if (!remote) throw new NoRemoteError();
|
|
922
|
+
const credentialArgs = await resolveCredentialHelperArgs(gitCwd);
|
|
923
|
+
const result = await runGit([
|
|
924
|
+
"-c",
|
|
925
|
+
"core.sshCommand=ssh",
|
|
926
|
+
"-c",
|
|
927
|
+
// git 예약어 none만 프록시 우회다 — 다른 값은 프록시 "명령"으로 실행된다.
|
|
928
|
+
"core.gitProxy=none",
|
|
929
|
+
"-c",
|
|
930
|
+
// protocol.allow=user는 ext를 never에서 허용으로 뒤집는다(GIT_PROTOCOL_FROM_USER unset) —
|
|
931
|
+
// 기본 정책을 유지한 채 실행형 transport만 명시 차단한다.
|
|
932
|
+
"protocol.ext.allow=never",
|
|
933
|
+
"-c",
|
|
934
|
+
// ref transaction 훅(reference-transaction 등)의 zero-click 실행을 플랫폼 널 장치로 차단한다.
|
|
935
|
+
`core.hooksPath=${process.platform === "win32" ? "NUL" : "/dev/null"}`,
|
|
936
|
+
...credentialArgs,
|
|
937
|
+
"fetch",
|
|
938
|
+
remote,
|
|
939
|
+
// 명시 refspec이 configured refspec을 대체한다 — prune의 파괴 범위를
|
|
940
|
+
// refs/remotes/<remote>/ 아래로 고정해 로컬 refs를 보호한다.
|
|
941
|
+
`+refs/heads/*:refs/remotes/${remote}/*`,
|
|
942
|
+
// repo config의 remote.<name>.uploadpack이 로컬 transport에서 명령 실행되므로 표준 명령을 강제한다.
|
|
943
|
+
"--upload-pack=git-upload-pack",
|
|
944
|
+
// 하드닝된 상위 fetch를 빠져나가는 재귀(중첩 네트워크+하위 upload-pack)를 끊는다.
|
|
945
|
+
"--no-recurse-submodules",
|
|
946
|
+
"--prune",
|
|
947
|
+
"--no-tags",
|
|
948
|
+
// fetch.pruneTags=true인 저장소가 --prune과 결합해 로컬 전용 태그를 지우는 것을 막는다.
|
|
949
|
+
"--no-prune-tags"
|
|
950
|
+
], { cwd: gitCwd });
|
|
951
|
+
const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
952
|
+
return {
|
|
953
|
+
ok: true,
|
|
954
|
+
fetchedAt,
|
|
955
|
+
lastFetchAt: fetchedAt,
|
|
956
|
+
pruned: countFetchProgress(result.stderr, " - [deleted] "),
|
|
957
|
+
newRefs: countFetchProgress(result.stderr, " * [new branch] "),
|
|
958
|
+
updatedRefs: countFetchUpdatedRefs(result.stderr)
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
async function fetchHeadCandidates(identity) {
|
|
962
|
+
const candidates = /* @__PURE__ */ new Set([identity.gitDir, identity.commonDir]);
|
|
963
|
+
try {
|
|
964
|
+
const worktreesDir = path4.join(identity.commonDir, "worktrees");
|
|
965
|
+
for (const entry of await fs2.readdir(worktreesDir, { withFileTypes: true })) {
|
|
966
|
+
if (entry.isDirectory()) candidates.add(path4.join(worktreesDir, entry.name));
|
|
967
|
+
}
|
|
968
|
+
} catch (error) {
|
|
969
|
+
if (error.code !== "ENOENT") throw error;
|
|
970
|
+
}
|
|
971
|
+
return [...candidates];
|
|
972
|
+
}
|
|
973
|
+
async function runAutoFetch(gitCwd, identity) {
|
|
974
|
+
const throttled = await readThrottleResult(await fetchHeadCandidates(identity), identity.commonDir);
|
|
975
|
+
return throttled ?? fetchRepository(gitCwd);
|
|
976
|
+
}
|
|
977
|
+
async function fetchAutoSingleFlight(gitCwd, identity) {
|
|
978
|
+
const key = identity.commonDir;
|
|
979
|
+
const existing = autoFetchInFlight.get(key);
|
|
980
|
+
if (existing) {
|
|
981
|
+
await existing;
|
|
982
|
+
const throttled = await readThrottleResult(await fetchHeadCandidates(identity), identity.commonDir);
|
|
983
|
+
if (throttled) return throttled;
|
|
984
|
+
}
|
|
985
|
+
const operation = runAutoFetch(gitCwd, identity);
|
|
986
|
+
autoFetchInFlight.set(key, operation);
|
|
987
|
+
try {
|
|
988
|
+
return await operation;
|
|
989
|
+
} finally {
|
|
990
|
+
if (autoFetchInFlight.get(key) === operation) autoFetchInFlight.delete(key);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
async function handleRepositoryFetch(req, res, ctx) {
|
|
994
|
+
if (req.method !== "POST") {
|
|
995
|
+
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (!ctx.host.security.isTerminalAuthorized(req)) {
|
|
999
|
+
ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
const body = await ctx.host.http.readJsonBody(req);
|
|
1003
|
+
if (!isPlainObject6(body) || "subPath" in body || typeof body.theaterId !== "string" || body.mode !== void 0 && body.mode !== "auto") {
|
|
1004
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
const theaterPath = ctx.host.paths.resolveTheaterPath(body.theaterId);
|
|
1008
|
+
if (!theaterPath) {
|
|
1009
|
+
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
let gitCwd;
|
|
1013
|
+
try {
|
|
1014
|
+
({ gitCwd } = await resolveGitCwd(theaterPath, body.repoRel));
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
if (error instanceof InvalidRepoError) {
|
|
1017
|
+
ctx.host.http.writeJson(res, 400, { error: error.code });
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
throw error;
|
|
1021
|
+
}
|
|
1022
|
+
try {
|
|
1023
|
+
const identity = await resolveGitIdentity(gitCwd);
|
|
1024
|
+
const result = body.mode === "auto" ? await fetchAutoSingleFlight(gitCwd, identity) : await (autoFetchInFlight.get(identity.commonDir) ?? fetchRepository(gitCwd));
|
|
1025
|
+
if ("fetchedAt" in result) lastSuccessfulFetchAt.set(identity.commonDir, Date.parse(result.fetchedAt));
|
|
1026
|
+
ctx.host.http.writeJson(res, 200, result);
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
if (error instanceof NoRemoteError) {
|
|
1029
|
+
ctx.host.http.writeJson(res, 422, { error: "no_remote" });
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
if (error instanceof GitExecutorError) {
|
|
1033
|
+
if (error.code === "timeout") {
|
|
1034
|
+
ctx.host.http.writeJson(res, 422, { error: "timeout" });
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const classified = classifyFetchError(error.stderr);
|
|
1038
|
+
if (classified) {
|
|
1039
|
+
ctx.host.http.writeJson(res, 422, { error: classified });
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
if (error.code === "no_git_repo" || error.code === "git_unavailable") {
|
|
1043
|
+
ctx.host.http.writeJson(res, 422, { error: error.code });
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
ctx.host.http.writeJson(res, 500, { error: "git_failed" });
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
throw error;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
799
1052
|
var WORKTREE_SHA_RE = /^[0-9a-f]{40}$/;
|
|
800
1053
|
var CANONICAL_REF_RE = /^refs\/(?:heads|remotes|tags)\//;
|
|
801
1054
|
var REF_METACHAR_RE = /[~^:?*\[\\\s\x00-\x1f\x7f]/;
|
|
802
|
-
function
|
|
1055
|
+
function isPlainObject7(value) {
|
|
803
1056
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
804
1057
|
}
|
|
805
1058
|
function isCanonicalRepositoryRef(ref) {
|
|
@@ -924,7 +1177,7 @@ async function handleRepositoryLog(req, res, ctx) {
|
|
|
924
1177
|
return;
|
|
925
1178
|
}
|
|
926
1179
|
const body = await ctx.host.http.readJsonBody(req);
|
|
927
|
-
if (!
|
|
1180
|
+
if (!isPlainObject7(body) || "subPath" in body) {
|
|
928
1181
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
929
1182
|
return;
|
|
930
1183
|
}
|
|
@@ -1092,7 +1345,7 @@ var HARD_CAP_DEPTH = 8;
|
|
|
1092
1345
|
var NESTED_BRANCH_CAP = 64;
|
|
1093
1346
|
var SCAN_VISIT_BUDGET = 1e4;
|
|
1094
1347
|
var DEFAULT_DEPTH = 3;
|
|
1095
|
-
function
|
|
1348
|
+
function isPlainObject8(value) {
|
|
1096
1349
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1097
1350
|
}
|
|
1098
1351
|
async function resolveRepoBranch(repoDir) {
|
|
@@ -1181,7 +1434,7 @@ async function handleRepositoryRepos(req, res, ctx) {
|
|
|
1181
1434
|
return;
|
|
1182
1435
|
}
|
|
1183
1436
|
const body = await ctx.host.http.readJsonBody(req);
|
|
1184
|
-
if (!
|
|
1437
|
+
if (!isPlainObject8(body) || typeof body.theaterId !== "string") {
|
|
1185
1438
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
1186
1439
|
return;
|
|
1187
1440
|
}
|
|
@@ -1260,7 +1513,7 @@ async function handleRepositorySearch(req, res, ctx) {
|
|
|
1260
1513
|
return;
|
|
1261
1514
|
}
|
|
1262
1515
|
const body = await ctx.host.http.readJsonBody(req);
|
|
1263
|
-
if (!
|
|
1516
|
+
if (!isPlainObject9(body) || typeof body.theaterId !== "string" || typeof body.query !== "string" || body.query.trim() === "" || !Number.isInteger(body.limit) || body.limit < 1 || body.limit > 8 || "subPath" in body || "ref" in body) {
|
|
1264
1517
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
1265
1518
|
return;
|
|
1266
1519
|
}
|
|
@@ -1314,10 +1567,10 @@ async function handleRepositorySearch(req, res, ctx) {
|
|
|
1314
1567
|
throw error;
|
|
1315
1568
|
}
|
|
1316
1569
|
}
|
|
1317
|
-
function
|
|
1570
|
+
function isPlainObject9(value) {
|
|
1318
1571
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1319
1572
|
}
|
|
1320
|
-
function
|
|
1573
|
+
function isPlainObject10(value) {
|
|
1321
1574
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1322
1575
|
}
|
|
1323
1576
|
async function handleRepositoryWorktrees(req, res, ctx) {
|
|
@@ -1330,7 +1583,7 @@ async function handleRepositoryWorktrees(req, res, ctx) {
|
|
|
1330
1583
|
return;
|
|
1331
1584
|
}
|
|
1332
1585
|
const body = await ctx.host.http.readJsonBody(req);
|
|
1333
|
-
if (!
|
|
1586
|
+
if (!isPlainObject10(body) || "subPath" in body || typeof body.theaterId !== "string") {
|
|
1334
1587
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
1335
1588
|
return;
|
|
1336
1589
|
}
|
|
@@ -1411,6 +1664,10 @@ var routes_default = definePlugin({
|
|
|
1411
1664
|
await handleRepositoryChanged(req, res, ctx);
|
|
1412
1665
|
return true;
|
|
1413
1666
|
});
|
|
1667
|
+
registerRouter(ctx, "fetch", async ({ req, res }) => {
|
|
1668
|
+
await handleRepositoryFetch(req, res, ctx);
|
|
1669
|
+
return true;
|
|
1670
|
+
});
|
|
1414
1671
|
registerRouter(ctx, "file", async ({ req, res }) => {
|
|
1415
1672
|
await handleRepositoryFile(req, res, ctx);
|
|
1416
1673
|
return true;
|
|
@@ -18913,7 +18913,7 @@ var AcpConnection = class extends BaseConnection {
|
|
|
18913
18913
|
}
|
|
18914
18914
|
/** Claude 계열 브릿지인지 여부를 단일 판별 지점으로 유지합니다. */
|
|
18915
18915
|
isClaudeBackend() {
|
|
18916
|
-
return this.cliType === "claude"
|
|
18916
|
+
return this.cliType === "claude";
|
|
18917
18917
|
}
|
|
18918
18918
|
/** Claude bridge 전용 system prompt replacement, strict-MCP와 effort `_meta`를 조립합니다. */
|
|
18919
18919
|
buildClaudeSessionMeta(systemPrompt, strictMcp, effort) {
|
|
@@ -19379,22 +19379,6 @@ var models_default = {
|
|
|
19379
19379
|
{ modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
|
|
19380
19380
|
]
|
|
19381
19381
|
},
|
|
19382
|
-
"claude-kimi": {
|
|
19383
|
-
name: "Kimi via Claude Code",
|
|
19384
|
-
defaultModel: "kimi-for-coding",
|
|
19385
|
-
models: [
|
|
19386
|
-
{ modelId: "kimi-for-coding", name: "Kimi for Coding", description: "Available on every Kimi Code membership tier (262K context)", effort: { supported: false }, contextWindow: 262144 },
|
|
19387
|
-
{ modelId: "k3", name: "Kimi K3", description: "Available on Moderato and higher tiers (262K context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 262144 },
|
|
19388
|
-
{ modelId: "k3[1m]", name: "Kimi K3 [1M]", description: "Available on Allegretto and higher tiers (1M context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 1048576 },
|
|
19389
|
-
{ modelId: "kimi-for-coding-highspeed", name: "Kimi for Coding Highspeed", description: "Available on Allegretto and higher tiers (262K context)", effort: { supported: false }, contextWindow: 262144 }
|
|
19390
|
-
],
|
|
19391
|
-
modelsMapping: {
|
|
19392
|
-
haiku: "kimi-for-coding",
|
|
19393
|
-
sonnet: "kimi-for-coding",
|
|
19394
|
-
opus: "kimi-for-coding",
|
|
19395
|
-
fable: "kimi-for-coding"
|
|
19396
|
-
}
|
|
19397
|
-
},
|
|
19398
19382
|
codex: {
|
|
19399
19383
|
name: "Codex",
|
|
19400
19384
|
defaultModel: "gpt-5.6-sol",
|
|
@@ -19510,16 +19494,13 @@ var ModelEntrySchema = external_exports.object({
|
|
|
19510
19494
|
});
|
|
19511
19495
|
}
|
|
19512
19496
|
});
|
|
19513
|
-
var ModelsMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
|
|
19514
19497
|
var ProviderSchema = external_exports.object({
|
|
19515
19498
|
/** 프로바이더 표시 이름 */
|
|
19516
19499
|
name: external_exports.string(),
|
|
19517
19500
|
/** 기본 모델 ID */
|
|
19518
19501
|
defaultModel: external_exports.string(),
|
|
19519
19502
|
/** 사용 가능한 모델 목록 */
|
|
19520
|
-
models: external_exports.array(ModelEntrySchema).min(1)
|
|
19521
|
-
/** modelId와 연관된 매핑 모델 (선택) */
|
|
19522
|
-
modelsMapping: ModelsMappingSchema.optional()
|
|
19503
|
+
models: external_exports.array(ModelEntrySchema).min(1)
|
|
19523
19504
|
}).check((ctx) => {
|
|
19524
19505
|
const ids = new Set(ctx.value.models.map((m) => m.modelId));
|
|
19525
19506
|
if (!ids.has(ctx.value.defaultModel)) {
|
|
@@ -19585,13 +19566,6 @@ function resolveCursorSpawnModel(modelId, effort) {
|
|
|
19585
19566
|
}
|
|
19586
19567
|
return model.spawnModelTemplate.replace("{effort}", resolvedLevel);
|
|
19587
19568
|
}
|
|
19588
|
-
function getProviderModelsMapping(cli) {
|
|
19589
|
-
const provider = registry2.providers[cli];
|
|
19590
|
-
if (!provider) {
|
|
19591
|
-
throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
|
|
19592
|
-
}
|
|
19593
|
-
return provider.modelsMapping ? structuredClone(provider.modelsMapping) : null;
|
|
19594
|
-
}
|
|
19595
19569
|
function findProviderModel(cli, modelId) {
|
|
19596
19570
|
const provider = registry2.providers[cli];
|
|
19597
19571
|
if (!provider) {
|
|
@@ -19623,32 +19597,6 @@ var CLI_BACKENDS = {
|
|
|
19623
19597
|
usesNpxBridge: true,
|
|
19624
19598
|
defaultMaxTokens: 16384
|
|
19625
19599
|
},
|
|
19626
|
-
"claude-kimi": {
|
|
19627
|
-
id: "claude-kimi",
|
|
19628
|
-
cliCommand: "claude",
|
|
19629
|
-
protocol: "acp",
|
|
19630
|
-
authRequired: true,
|
|
19631
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
19632
|
-
modes: [
|
|
19633
|
-
{ id: "default", label: "Default" },
|
|
19634
|
-
{ id: "plan", label: "Plan" },
|
|
19635
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
19636
|
-
],
|
|
19637
|
-
supportsSessionClose: true,
|
|
19638
|
-
supportsSessionLoad: true,
|
|
19639
|
-
requiresModelAtSpawn: false,
|
|
19640
|
-
usesNpxBridge: true,
|
|
19641
|
-
defaultMaxTokens: 262144,
|
|
19642
|
-
defaultEnv: {
|
|
19643
|
-
ANTHROPIC_BASE_URL: "https://api.kimi.com/coding/",
|
|
19644
|
-
ANTHROPIC_MODEL: "kimi-for-coding",
|
|
19645
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "kimi-for-coding",
|
|
19646
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "kimi-for-coding",
|
|
19647
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "kimi-for-coding",
|
|
19648
|
-
CLAUDE_CODE_SUBAGENT_MODEL: "kimi-for-coding",
|
|
19649
|
-
API_TIMEOUT_MS: "3000000"
|
|
19650
|
-
}
|
|
19651
|
-
},
|
|
19652
19600
|
codex: {
|
|
19653
19601
|
id: "codex",
|
|
19654
19602
|
cliCommand: "codex",
|
|
@@ -19725,7 +19673,6 @@ function getBackendConfig(cli) {
|
|
|
19725
19673
|
function getYoloModeId(cli) {
|
|
19726
19674
|
switch (cli) {
|
|
19727
19675
|
case "claude":
|
|
19728
|
-
case "claude-kimi":
|
|
19729
19676
|
return "bypassPermissions";
|
|
19730
19677
|
case "cursor":
|
|
19731
19678
|
return "agent";
|
|
@@ -19937,11 +19884,7 @@ var UnifiedClaudeAgentClient = class extends EventEmitter {
|
|
|
19937
19884
|
firstPromptPending = null;
|
|
19938
19885
|
currentEffort = null;
|
|
19939
19886
|
detector = new CliDetector();
|
|
19940
|
-
cliType;
|
|
19941
|
-
constructor(cliType = "claude") {
|
|
19942
|
-
super();
|
|
19943
|
-
this.cliType = cliType;
|
|
19944
|
-
}
|
|
19887
|
+
cliType = "claude";
|
|
19945
19888
|
on(event, listener) {
|
|
19946
19889
|
return super.on(event, listener);
|
|
19947
19890
|
}
|
|
@@ -19957,31 +19900,14 @@ var UnifiedClaudeAgentClient = class extends EventEmitter {
|
|
|
19957
19900
|
async connect(options) {
|
|
19958
19901
|
await this.disconnect();
|
|
19959
19902
|
const systemPromptMode = options.systemPromptMode ?? "prepend";
|
|
19960
|
-
const requestedCli = options.cli ?? this.cliType;
|
|
19961
|
-
if (systemPromptMode === "replace" && requestedCli !== "claude" && requestedCli !== "claude-kimi") {
|
|
19962
|
-
throw new Error(
|
|
19963
|
-
`system prompt replacement is not supported by the "${requestedCli}" backend`
|
|
19964
|
-
);
|
|
19965
|
-
}
|
|
19966
19903
|
if (options.cli && options.cli !== this.cliType) {
|
|
19967
19904
|
throw new Error(`UnifiedClaudeAgentClient\uB294 ${this.cliType} CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.`);
|
|
19968
19905
|
}
|
|
19969
19906
|
const acpMcpServers = this.resolveMcpServers(options.mcpServers);
|
|
19970
19907
|
const spawnConfig = createSpawnConfig(this.cliType, options);
|
|
19971
|
-
const modelsMapping = getProviderModelsMapping(this.cliType);
|
|
19972
|
-
const mappingEnv = {};
|
|
19973
|
-
if (modelsMapping) {
|
|
19974
|
-
for (const [modelId, mappedModel] of Object.entries(modelsMapping)) {
|
|
19975
|
-
const envKey = `ANTHROPIC_DEFAULT_${modelId.toUpperCase()}_MODEL`;
|
|
19976
|
-
mappingEnv[envKey] = mappedModel;
|
|
19977
|
-
}
|
|
19978
|
-
}
|
|
19979
19908
|
const backendConfig = getBackendConfig(this.cliType);
|
|
19980
19909
|
const defaultEnv = backendConfig.defaultEnv ?? {};
|
|
19981
|
-
const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...
|
|
19982
|
-
if (this.cliType === "claude-kimi") {
|
|
19983
|
-
delete cleanEnv.ANTHROPIC_AUTH_TOKEN;
|
|
19984
|
-
}
|
|
19910
|
+
const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...options.env });
|
|
19985
19911
|
if (defaultEnv.ANTHROPIC_BASE_URL && !cleanEnv.ANTHROPIC_API_KEY && !cleanEnv.ANTHROPIC_AUTH_TOKEN) {
|
|
19986
19912
|
throw new Error(
|
|
19987
19913
|
`[${this.cliType}] ANTHROPIC_API_KEY \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${getProviderModels(this.cliType).name} API \uD0A4\uB97C \uC124\uC815\uD574\uC8FC\uC138\uC694.`
|
|
@@ -22132,8 +22058,7 @@ var UnifiedAgent = {
|
|
|
22132
22058
|
createClient(cli) {
|
|
22133
22059
|
switch (cli) {
|
|
22134
22060
|
case "claude":
|
|
22135
|
-
|
|
22136
|
-
return new UnifiedClaudeAgentClient(cli);
|
|
22061
|
+
return new UnifiedClaudeAgentClient();
|
|
22137
22062
|
case "codex":
|
|
22138
22063
|
return new UnifiedCodexAgentClient();
|
|
22139
22064
|
case "cursor":
|
|
@@ -22150,7 +22075,7 @@ var UnifiedAgent = {
|
|
|
22150
22075
|
const preferred = await new CliDetector().getPreferred();
|
|
22151
22076
|
if (!preferred) {
|
|
22152
22077
|
throw new Error(
|
|
22153
|
-
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude,
|
|
22078
|
+
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
|
|
22154
22079
|
);
|
|
22155
22080
|
}
|
|
22156
22081
|
return this.createClient(preferred.cli);
|
|
@@ -16402,22 +16402,6 @@ var models_default = {
|
|
|
16402
16402
|
{ modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
|
|
16403
16403
|
]
|
|
16404
16404
|
},
|
|
16405
|
-
"claude-kimi": {
|
|
16406
|
-
name: "Kimi via Claude Code",
|
|
16407
|
-
defaultModel: "kimi-for-coding",
|
|
16408
|
-
models: [
|
|
16409
|
-
{ modelId: "kimi-for-coding", name: "Kimi for Coding", description: "Available on every Kimi Code membership tier (262K context)", effort: { supported: false }, contextWindow: 262144 },
|
|
16410
|
-
{ modelId: "k3", name: "Kimi K3", description: "Available on Moderato and higher tiers (262K context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 262144 },
|
|
16411
|
-
{ modelId: "k3[1m]", name: "Kimi K3 [1M]", description: "Available on Allegretto and higher tiers (1M context)", effort: { supported: true, levels: ["low", "high", "max"], default: "high" }, contextWindow: 1048576 },
|
|
16412
|
-
{ modelId: "kimi-for-coding-highspeed", name: "Kimi for Coding Highspeed", description: "Available on Allegretto and higher tiers (262K context)", effort: { supported: false }, contextWindow: 262144 }
|
|
16413
|
-
],
|
|
16414
|
-
modelsMapping: {
|
|
16415
|
-
haiku: "kimi-for-coding",
|
|
16416
|
-
sonnet: "kimi-for-coding",
|
|
16417
|
-
opus: "kimi-for-coding",
|
|
16418
|
-
fable: "kimi-for-coding"
|
|
16419
|
-
}
|
|
16420
|
-
},
|
|
16421
16405
|
codex: {
|
|
16422
16406
|
name: "Codex",
|
|
16423
16407
|
defaultModel: "gpt-5.6-sol",
|
|
@@ -16533,16 +16517,13 @@ var ModelEntrySchema = external_exports.object({
|
|
|
16533
16517
|
});
|
|
16534
16518
|
}
|
|
16535
16519
|
});
|
|
16536
|
-
var ModelsMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
|
|
16537
16520
|
var ProviderSchema = external_exports.object({
|
|
16538
16521
|
/** 프로바이더 표시 이름 */
|
|
16539
16522
|
name: external_exports.string(),
|
|
16540
16523
|
/** 기본 모델 ID */
|
|
16541
16524
|
defaultModel: external_exports.string(),
|
|
16542
16525
|
/** 사용 가능한 모델 목록 */
|
|
16543
|
-
models: external_exports.array(ModelEntrySchema).min(1)
|
|
16544
|
-
/** modelId와 연관된 매핑 모델 (선택) */
|
|
16545
|
-
modelsMapping: ModelsMappingSchema.optional()
|
|
16526
|
+
models: external_exports.array(ModelEntrySchema).min(1)
|
|
16546
16527
|
}).check((ctx) => {
|
|
16547
16528
|
const ids = new Set(ctx.value.models.map((m) => m.modelId));
|
|
16548
16529
|
if (!ids.has(ctx.value.defaultModel)) {
|
|
@@ -16593,32 +16574,6 @@ var CLI_BACKENDS = {
|
|
|
16593
16574
|
usesNpxBridge: true,
|
|
16594
16575
|
defaultMaxTokens: 16384
|
|
16595
16576
|
},
|
|
16596
|
-
"claude-kimi": {
|
|
16597
|
-
id: "claude-kimi",
|
|
16598
|
-
cliCommand: "claude",
|
|
16599
|
-
protocol: "acp",
|
|
16600
|
-
authRequired: true,
|
|
16601
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
16602
|
-
modes: [
|
|
16603
|
-
{ id: "default", label: "Default" },
|
|
16604
|
-
{ id: "plan", label: "Plan" },
|
|
16605
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
16606
|
-
],
|
|
16607
|
-
supportsSessionClose: true,
|
|
16608
|
-
supportsSessionLoad: true,
|
|
16609
|
-
requiresModelAtSpawn: false,
|
|
16610
|
-
usesNpxBridge: true,
|
|
16611
|
-
defaultMaxTokens: 262144,
|
|
16612
|
-
defaultEnv: {
|
|
16613
|
-
ANTHROPIC_BASE_URL: "https://api.kimi.com/coding/",
|
|
16614
|
-
ANTHROPIC_MODEL: "kimi-for-coding",
|
|
16615
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "kimi-for-coding",
|
|
16616
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "kimi-for-coding",
|
|
16617
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "kimi-for-coding",
|
|
16618
|
-
CLAUDE_CODE_SUBAGENT_MODEL: "kimi-for-coding",
|
|
16619
|
-
API_TIMEOUT_MS: "3000000"
|
|
16620
|
-
}
|
|
16621
|
-
},
|
|
16622
16577
|
codex: {
|
|
16623
16578
|
id: "codex",
|
|
16624
16579
|
cliCommand: "codex",
|