@dotobokuri/fleet-console 1.27.0 → 1.29.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/AGENTS.md +6 -0
- package/README.md +1 -0
- package/dist/cli.mjs +24956 -8793
- package/dist/client/assets/{_baseUniq-FPn1UwMX.js → _baseUniq-DEvADUqz.js} +1 -1
- package/dist/client/assets/{arc-Dbkm3o2R.js → arc-pB9oYw5d.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-DGXd_rAH.js → architectureDiagram-Q4EWVU46-D0gUBsh1.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-B1TfqDXH.js → blockDiagram-DXYQGD6D-9NSt9xrC.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DkgjfzU2.js → c4Diagram-AHTNJAMY-BS1EhMAN.js} +1 -1
- package/dist/client/assets/channel-BSgCfWXO.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-D82651yi.js → chunk-4BX2VUAB-BKkeF7mF.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-3v1J62DG.js → chunk-4TB4RGXK-DRp3Dsap.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-BrEuCB92.js → chunk-55IACEB6-De-sLT-H.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-QZ3Tkj6o.js → chunk-EDXVE4YY-ByYWvw6c.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-C0zm-jqg.js → chunk-FMBD7UC4-BDpIWnNm.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-BLWP9U3k.js → chunk-OYMX7WX6-qxbtvneQ.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-61zanhRL.js → chunk-QZHKN3VN-BnkLN840.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-DtQ3mOc9.js → chunk-YZCP3GAM-HfizEXdz.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-C3WhxxfZ.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-C3WhxxfZ.js +1 -0
- package/dist/client/assets/clone-DjOK69th.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-Zg6I9Teh.js → cose-bilkent-S5V4N54A-B4U_tiL9.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-DGHWYQzp.js → dagre-KV5264BT-De3dSv-R.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-sJLUf_Mf.js → diagram-5BDNPKRD-CZAF0Kro.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-BlyVweUa.js → diagram-G4DWMVQ6-BHyDlHAq.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-TN0odItE.js → diagram-MMDJMWI5-CV93x0hu.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-DMg-H_H9.js → diagram-TYMM5635-CTRzVEQp.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-q52C6AV0.js → erDiagram-SMLLAGMA-xW-UvBlm.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-DNTSODrD.js → flowDiagram-DWJPFMVM-C21IECUy.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-B8lDyFkt.js → ganttDiagram-T4ZO3ILL-DVzOf8Xv.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CMPu2f37.js → gitGraphDiagram-UUTBAWPF-B-NQC3Ae.js} +1 -1
- package/dist/client/assets/{graph-B4pb3uGP.js → graph-BDzdWbuy.js} +1 -1
- package/dist/client/assets/index-BDJVPQd1.css +1 -0
- package/dist/client/assets/index-CjBu8lNT.js +451 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-V3RHqQRb.js → infoDiagram-42DDH7IO-2KCXFMZg.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-R7Tyr7yI.js → ishikawaDiagram-UXIWVN3A-D4Fvy3ms.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-ChcMOmKn.js → journeyDiagram-VCZTEJTY-DkXZkeED.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-B37w6pAA.js → kanban-definition-6JOO6SKY-CTrIp4rv.js} +1 -1
- package/dist/client/assets/{layout-osi6dy0A.js → layout-DKdT-A2u.js} +1 -1
- package/dist/client/assets/{linear-Dq0-nOx7.js → linear-Dn21C3ab.js} +1 -1
- package/dist/client/assets/{mermaid.core-C5QhuJDM.js → mermaid.core-ho7gOyUr.js} +4 -4
- package/dist/client/assets/{min-xvvoUYjd.js → min-DV-zxfLU.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-CAgbfylQ.js → mindmap-definition-QFDTVHPH-By8nfvJ0.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-CkYJac9b.js → pieDiagram-DEJITSTG-B4ndzH1J.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-B_ylk-UV.js → quadrantDiagram-34T5L4WZ-CiDb6b3-.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-CaI3fMhb.js → requirementDiagram-MS252O5E-TTr1SzvX.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-Bc-gJOJq.js → sankeyDiagram-XADWPNL6-CUyxk-WA.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-Cp36qrrt.js → sequenceDiagram-FGHM5R23-CyBxBNAZ.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-7DLhFomz.js → stateDiagram-FHFEXIEX-Cj4j5FFK.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CWhJmDZj.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-ePpcuK5O.js → timeline-definition-GMOUNBTQ-MQzKGbxg.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-Cm2Die3B.js → vennDiagram-DHZGUBPP-sG3K7NAZ.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-ni10OklI.js → wardley-RL74JXVD-ID5rQjqH.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CjIa7qSE.js → wardleyDiagram-NUSXRM2D-AMajCCI5.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-B7aOvrmt.js → xychartDiagram-5P7HB3ND-DUb36W9E.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/{diff → repository}/routes.mjs +119 -68
- package/dist/fleet-plugins/skills/routes.mjs +51 -73
- package/dist/fleet-plugins/terminal/routes.mjs +2243 -463
- package/package.json +1 -1
- package/dist/client/assets/channel-CozojXwb.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DfJLxwIy.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DfJLxwIy.js +0 -1
- package/dist/client/assets/clone-hpL84gNz.js +0 -1
- package/dist/client/assets/index-BsO9uzdN.css +0 -1
- package/dist/client/assets/index-rJKd0Wfd.js +0 -395
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CRYMSSnC.js +0 -1
|
@@ -21,7 +21,7 @@ function withHidden(options) {
|
|
|
21
21
|
return { ...options ?? {}, windowsHide: true };
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// ../fleet-plugins/
|
|
24
|
+
// ../fleet-plugins/repository/server/git-executor.ts
|
|
25
25
|
var GitExecutorError = class extends Error {
|
|
26
26
|
code;
|
|
27
27
|
exitCode;
|
|
@@ -154,26 +154,10 @@ function isNoHeadError(error) {
|
|
|
154
154
|
if (error.code !== "non_zero_exit") return false;
|
|
155
155
|
return error.stderr.includes("unknown revision") || error.stderr.includes("bad revision");
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const resolvedSub = path2.resolve(theaterPath, rawSubPath);
|
|
160
|
-
if (!resolvedSub.startsWith(theaterPath + path2.sep) && resolvedSub !== theaterPath) return null;
|
|
161
|
-
if (path2.normalize(rawSubPath).startsWith("..")) return null;
|
|
162
|
-
let realTheater;
|
|
163
|
-
let realSub;
|
|
164
|
-
try {
|
|
165
|
-
[realTheater, realSub] = await Promise.all([
|
|
166
|
-
fs.realpath(theaterPath),
|
|
167
|
-
fs.realpath(resolvedSub)
|
|
168
|
-
]);
|
|
169
|
-
} catch {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
const norm = realTheater.endsWith(path2.sep) ? realTheater : realTheater + path2.sep;
|
|
173
|
-
if (realSub !== realTheater && !realSub.startsWith(norm)) return null;
|
|
174
|
-
return { gitCwd: resolvedSub };
|
|
157
|
+
function resolveGitCwd(theaterPath) {
|
|
158
|
+
return { gitCwd: theaterPath };
|
|
175
159
|
}
|
|
176
|
-
async function
|
|
160
|
+
async function handleRepositoryChanged(req, res, ctx) {
|
|
177
161
|
if (req.method !== "POST") {
|
|
178
162
|
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
179
163
|
return;
|
|
@@ -183,7 +167,7 @@ async function handleDiffChanged(req, res, ctx) {
|
|
|
183
167
|
return;
|
|
184
168
|
}
|
|
185
169
|
const body = await ctx.host.http.readJsonBody(req);
|
|
186
|
-
if (!isPlainObject(body)) {
|
|
170
|
+
if (!isPlainObject(body) || "subPath" in body) {
|
|
187
171
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
188
172
|
return;
|
|
189
173
|
}
|
|
@@ -197,12 +181,7 @@ async function handleDiffChanged(req, res, ctx) {
|
|
|
197
181
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
198
182
|
return;
|
|
199
183
|
}
|
|
200
|
-
const
|
|
201
|
-
const cwdResult = await resolveGitCwd(theaterPath, rawSubPath);
|
|
202
|
-
if (!cwdResult) {
|
|
203
|
-
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
184
|
+
const cwdResult = resolveGitCwd(theaterPath);
|
|
206
185
|
const { gitCwd } = cwdResult;
|
|
207
186
|
try {
|
|
208
187
|
await ensureGitRepository(gitCwd);
|
|
@@ -242,7 +221,7 @@ async function handleDiffChanged(req, res, ctx) {
|
|
|
242
221
|
throw error;
|
|
243
222
|
}
|
|
244
223
|
}
|
|
245
|
-
async function
|
|
224
|
+
async function handleRepositoryFile(req, res, ctx) {
|
|
246
225
|
if (req.method !== "POST") {
|
|
247
226
|
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
248
227
|
return;
|
|
@@ -252,7 +231,7 @@ async function handleDiffFile(req, res, ctx) {
|
|
|
252
231
|
return;
|
|
253
232
|
}
|
|
254
233
|
const body = await ctx.host.http.readJsonBody(req);
|
|
255
|
-
if (!isPlainObject(body) || typeof body.filePath !== "string") {
|
|
234
|
+
if (!isPlainObject(body) || "subPath" in body || typeof body.filePath !== "string") {
|
|
256
235
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
257
236
|
return;
|
|
258
237
|
}
|
|
@@ -271,12 +250,7 @@ async function handleDiffFile(req, res, ctx) {
|
|
|
271
250
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
272
251
|
return;
|
|
273
252
|
}
|
|
274
|
-
const
|
|
275
|
-
const cwdResult = await resolveGitCwd(theaterPath, rawSubPath);
|
|
276
|
-
if (!cwdResult) {
|
|
277
|
-
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
253
|
+
const cwdResult = resolveGitCwd(theaterPath);
|
|
280
254
|
const { gitCwd } = cwdResult;
|
|
281
255
|
const rawFilePath = body.filePath;
|
|
282
256
|
const resolvedFilePath = path2.resolve(gitCwd, rawFilePath);
|
|
@@ -345,7 +319,7 @@ async function handleDiffFile(req, res, ctx) {
|
|
|
345
319
|
}
|
|
346
320
|
}
|
|
347
321
|
|
|
348
|
-
// ../fleet-plugins/
|
|
322
|
+
// ../fleet-plugins/repository/server/commit.ts
|
|
349
323
|
var REF_RE = /^[0-9a-f]{7,40}$/i;
|
|
350
324
|
function isPlainObject2(value) {
|
|
351
325
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -366,7 +340,7 @@ function parseCommitMeta(output) {
|
|
|
366
340
|
parents: rawParents.split(" ").filter(Boolean).map((full) => ({ full, short: full.slice(0, 9) }))
|
|
367
341
|
};
|
|
368
342
|
}
|
|
369
|
-
async function
|
|
343
|
+
async function handleRepositoryCommit(req, res, ctx) {
|
|
370
344
|
if (req.method !== "POST") {
|
|
371
345
|
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
372
346
|
return;
|
|
@@ -376,7 +350,7 @@ async function handleDiffCommit(req, res, ctx) {
|
|
|
376
350
|
return;
|
|
377
351
|
}
|
|
378
352
|
const body = await ctx.host.http.readJsonBody(req);
|
|
379
|
-
if (!isPlainObject2(body)) {
|
|
353
|
+
if (!isPlainObject2(body) || "subPath" in body) {
|
|
380
354
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
381
355
|
return;
|
|
382
356
|
}
|
|
@@ -395,12 +369,7 @@ async function handleDiffCommit(req, res, ctx) {
|
|
|
395
369
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
396
370
|
return;
|
|
397
371
|
}
|
|
398
|
-
const
|
|
399
|
-
const cwdResult = await resolveGitCwd(theaterPath, rawSubPath);
|
|
400
|
-
if (!cwdResult) {
|
|
401
|
-
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
372
|
+
const cwdResult = resolveGitCwd(theaterPath);
|
|
404
373
|
const { gitCwd } = cwdResult;
|
|
405
374
|
try {
|
|
406
375
|
const [metaResult, nameStatusResult, numstatResult] = await Promise.all([
|
|
@@ -442,7 +411,7 @@ function resolveLiteralFilePath(gitCwd, rawPath) {
|
|
|
442
411
|
function literalPathspec2(relativePath) {
|
|
443
412
|
return `:(literal)${relativePath}`;
|
|
444
413
|
}
|
|
445
|
-
async function
|
|
414
|
+
async function handleRepositoryCommitFile(req, res, ctx) {
|
|
446
415
|
if (req.method !== "POST") {
|
|
447
416
|
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
448
417
|
return;
|
|
@@ -452,7 +421,7 @@ async function handleDiffCommitFile(req, res, ctx) {
|
|
|
452
421
|
return;
|
|
453
422
|
}
|
|
454
423
|
const body = await ctx.host.http.readJsonBody(req);
|
|
455
|
-
if (!isPlainObject3(body) || typeof body.theaterId !== "string" || typeof body.ref !== "string" || typeof body.filePath !== "string") {
|
|
424
|
+
if (!isPlainObject3(body) || "subPath" in body || typeof body.theaterId !== "string" || typeof body.ref !== "string" || typeof body.filePath !== "string") {
|
|
456
425
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
457
426
|
return;
|
|
458
427
|
}
|
|
@@ -473,11 +442,7 @@ async function handleDiffCommitFile(req, res, ctx) {
|
|
|
473
442
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
474
443
|
return;
|
|
475
444
|
}
|
|
476
|
-
const cwdResult =
|
|
477
|
-
if (!cwdResult) {
|
|
478
|
-
ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
445
|
+
const cwdResult = resolveGitCwd(theaterPath);
|
|
481
446
|
const relativePath = resolveLiteralFilePath(cwdResult.gitCwd, body.filePath);
|
|
482
447
|
const oldPath = typeof body.oldPath === "string" ? resolveLiteralFilePath(cwdResult.gitCwd, body.oldPath) : void 0;
|
|
483
448
|
if (!relativePath || body.oldPath !== void 0 && !oldPath) {
|
|
@@ -500,17 +465,22 @@ async function handleDiffCommitFile(req, res, ctx) {
|
|
|
500
465
|
}
|
|
501
466
|
}
|
|
502
467
|
var WORKTREE_SHA_RE = /^[0-9a-f]{40}$/;
|
|
468
|
+
var CANONICAL_REF_RE = /^refs\/(?:heads|remotes|tags)\//;
|
|
469
|
+
var REF_METACHAR_RE = /[~^:?*\[\\\s\x00-\x1f\x7f]/;
|
|
503
470
|
function isPlainObject4(value) {
|
|
504
471
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
505
472
|
}
|
|
473
|
+
function isCanonicalRepositoryRef(ref) {
|
|
474
|
+
return CANONICAL_REF_RE.test(ref) && !ref.startsWith("-") && !ref.includes("..") && !ref.includes("//") && !REF_METACHAR_RE.test(ref) && !ref.includes("@{") && !ref.endsWith("/") && !ref.endsWith(".") && !ref.split("/").some((part) => part.startsWith(".") || part.endsWith(".lock"));
|
|
475
|
+
}
|
|
506
476
|
function parseLogOutput(stdout) {
|
|
507
477
|
if (!stdout.trim()) return [];
|
|
508
478
|
const commits = [];
|
|
509
479
|
for (const chunk of stdout.split("")) {
|
|
510
480
|
const trimmed = chunk.trimStart();
|
|
511
481
|
if (!trimmed) continue;
|
|
512
|
-
const
|
|
513
|
-
const firstLine =
|
|
482
|
+
const lines2 = trimmed.split("\n");
|
|
483
|
+
const firstLine = lines2[0] ?? "";
|
|
514
484
|
const fields = firstLine.split("\0");
|
|
515
485
|
const fullHash = fields[0] ?? "";
|
|
516
486
|
const shortHash = fields[1] ?? "";
|
|
@@ -608,7 +578,7 @@ async function readCurrentWorktreePath(gitCwd) {
|
|
|
608
578
|
throw error;
|
|
609
579
|
}
|
|
610
580
|
}
|
|
611
|
-
async function
|
|
581
|
+
async function handleRepositoryLog(req, res, ctx) {
|
|
612
582
|
if (req.method !== "POST") {
|
|
613
583
|
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
614
584
|
return;
|
|
@@ -618,7 +588,7 @@ async function handleDiffLog(req, res, ctx) {
|
|
|
618
588
|
return;
|
|
619
589
|
}
|
|
620
590
|
const body = await ctx.host.http.readJsonBody(req);
|
|
621
|
-
if (!isPlainObject4(body)) {
|
|
591
|
+
if (!isPlainObject4(body) || "subPath" in body) {
|
|
622
592
|
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
623
593
|
return;
|
|
624
594
|
}
|
|
@@ -632,14 +602,15 @@ async function handleDiffLog(req, res, ctx) {
|
|
|
632
602
|
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
633
603
|
return;
|
|
634
604
|
}
|
|
635
|
-
const
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
605
|
+
const cwdResult = resolveGitCwd(theaterPath);
|
|
606
|
+
const { gitCwd } = cwdResult;
|
|
607
|
+
const requestedRef = body.ref;
|
|
608
|
+
if (requestedRef !== void 0 && (typeof requestedRef !== "string" || !isCanonicalRepositoryRef(requestedRef))) {
|
|
609
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_ref" });
|
|
639
610
|
return;
|
|
640
611
|
}
|
|
641
|
-
const { gitCwd } = cwdResult;
|
|
642
612
|
try {
|
|
613
|
+
const resolvedRef = typeof requestedRef === "string" ? (await runGit(["rev-parse", "--verify", "--end-of-options", `${requestedRef}^{commit}`], { cwd: gitCwd })).stdout.trim() : null;
|
|
643
614
|
const [worktrees, currentWorktreePath, headRevList] = await Promise.all([
|
|
644
615
|
runGit(["worktree", "list", "--porcelain"], { cwd: gitCwd }),
|
|
645
616
|
readCurrentWorktreePath(gitCwd),
|
|
@@ -648,7 +619,7 @@ async function handleDiffLog(req, res, ctx) {
|
|
|
648
619
|
const checkouts = await parseWorktreePorcelain(worktrees.stdout, currentWorktreePath);
|
|
649
620
|
const worktreeRevs = [...new Set(checkouts.map((checkout) => checkout.sha))].filter((sha) => WORKTREE_SHA_RE.test(sha) && !/^0+$/.test(sha));
|
|
650
621
|
const headRevs = headRevList ? ["HEAD"] : [];
|
|
651
|
-
const result = await runGit(
|
|
622
|
+
const result = resolvedRef ? await runGit(["log", resolvedRef, "--date-order", "-n", "200", "--relative", "--decorate=full", "--pretty=format:%x1e%H%x00%h%x00%s%x00%an%x00%ar%x00%at%x00%D%x00%P", "--", "."], { cwd: gitCwd }) : await runGit(
|
|
652
623
|
// --all은 refs/stash·refs/notes까지 그래프에 유입시키므로 브랜치/태그/원격 + 현재 HEAD + 워크트리 HEAD로 한정한다
|
|
653
624
|
["log", "--branches", "--tags", "--remotes", "--date-order", "-n", "200", "--relative", "--decorate=full", "--pretty=format:%x1e%H%x00%h%x00%s%x00%an%x00%ar%x00%at%x00%D%x00%P", ...headRevs, ...worktreeRevs, "--", "."],
|
|
654
625
|
{ cwd: gitCwd }
|
|
@@ -657,6 +628,10 @@ async function handleDiffLog(req, res, ctx) {
|
|
|
657
628
|
ctx.host.http.writeJson(res, 200, { commits, checkouts, ...result.truncated ? { truncated: true } : {} });
|
|
658
629
|
} catch (error) {
|
|
659
630
|
if (error instanceof GitExecutorError) {
|
|
631
|
+
if (requestedRef !== void 0 && error.code === "non_zero_exit") {
|
|
632
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_ref" });
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
660
635
|
if (error.code === "no_git_repo") {
|
|
661
636
|
ctx.host.http.writeJson(res, 200, { commits: [], checkouts: [] });
|
|
662
637
|
return;
|
|
@@ -676,28 +651,104 @@ async function handleDiffLog(req, res, ctx) {
|
|
|
676
651
|
}
|
|
677
652
|
}
|
|
678
653
|
|
|
679
|
-
// ../fleet-plugins/
|
|
654
|
+
// ../fleet-plugins/repository/server/refs.ts
|
|
655
|
+
function isObject(value) {
|
|
656
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
657
|
+
}
|
|
658
|
+
function lines(stdout) {
|
|
659
|
+
return stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
660
|
+
}
|
|
661
|
+
function parseRefItems(stdout, current) {
|
|
662
|
+
return lines(stdout).flatMap((line) => {
|
|
663
|
+
const [ref, label] = line.split("\0");
|
|
664
|
+
return ref && label ? [{ ref, label, current: ref === current }] : [];
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
async function readStashes(gitCwd) {
|
|
668
|
+
try {
|
|
669
|
+
return (await runGit(["stash", "list", "--format=%gd%x00%s"], { cwd: gitCwd })).stdout;
|
|
670
|
+
} catch (error) {
|
|
671
|
+
if (error instanceof GitExecutorError) return "";
|
|
672
|
+
throw error;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
async function handleRepositoryRefs(req, res, ctx) {
|
|
676
|
+
if (req.method !== "POST") {
|
|
677
|
+
ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
if (!ctx.host.security.isTerminalAuthorized(req)) {
|
|
681
|
+
ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
const body = await ctx.host.http.readJsonBody(req);
|
|
685
|
+
if (!isObject(body) || "subPath" in body || typeof body.theaterId !== "string") {
|
|
686
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
const theaterPath = ctx.host.paths.resolveTheaterPath(body.theaterId);
|
|
690
|
+
if (!theaterPath) {
|
|
691
|
+
ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
const resolved = resolveGitCwd(theaterPath);
|
|
695
|
+
try {
|
|
696
|
+
const [head, local, remote, tags, stashes] = await Promise.all([
|
|
697
|
+
runGit(["symbolic-ref", "--quiet", "HEAD"], { cwd: resolved.gitCwd, allowExitCodes: [1] }),
|
|
698
|
+
runGit(["for-each-ref", "--format=%(refname)%00%(refname:short)", "refs/heads"], { cwd: resolved.gitCwd }),
|
|
699
|
+
runGit(["for-each-ref", "--format=%(refname)%00%(refname:short)", "refs/remotes"], { cwd: resolved.gitCwd }),
|
|
700
|
+
runGit(["for-each-ref", "--format=%(refname)%00%(refname:short)", "refs/tags"], { cwd: resolved.gitCwd }),
|
|
701
|
+
readStashes(resolved.gitCwd)
|
|
702
|
+
]);
|
|
703
|
+
const current = head.stdout.trim();
|
|
704
|
+
ctx.host.http.writeJson(res, 200, {
|
|
705
|
+
branches: parseRefItems(local.stdout, current),
|
|
706
|
+
remotes: parseRefItems(remote.stdout, current),
|
|
707
|
+
tags: parseRefItems(tags.stdout, current),
|
|
708
|
+
stashes: lines(stashes).map((line) => {
|
|
709
|
+
const [name, subject = ""] = line.split("\0");
|
|
710
|
+
return { name, subject };
|
|
711
|
+
})
|
|
712
|
+
});
|
|
713
|
+
} catch (error) {
|
|
714
|
+
if (error instanceof GitExecutorError && error.code === "no_git_repo") {
|
|
715
|
+
ctx.host.http.writeJson(res, 200, { branches: [], remotes: [], tags: [], stashes: [] });
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if (error instanceof GitExecutorError && error.code === "git_unavailable") {
|
|
719
|
+
ctx.host.http.writeJson(res, 422, { error: error.code });
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
ctx.host.http.writeJson(res, 500, { error: "git_failed" });
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// ../fleet-plugins/repository/routes.ts
|
|
680
727
|
var routes_default = definePlugin({
|
|
681
|
-
id: "
|
|
728
|
+
id: "repository",
|
|
682
729
|
register(ctx) {
|
|
683
730
|
registerRouter(ctx, "changed", async ({ req, res }) => {
|
|
684
|
-
await
|
|
731
|
+
await handleRepositoryChanged(req, res, ctx);
|
|
685
732
|
return true;
|
|
686
733
|
});
|
|
687
734
|
registerRouter(ctx, "file", async ({ req, res }) => {
|
|
688
|
-
await
|
|
735
|
+
await handleRepositoryFile(req, res, ctx);
|
|
689
736
|
return true;
|
|
690
737
|
});
|
|
691
738
|
registerRouter(ctx, "log", async ({ req, res }) => {
|
|
692
|
-
await
|
|
739
|
+
await handleRepositoryLog(req, res, ctx);
|
|
740
|
+
return true;
|
|
741
|
+
});
|
|
742
|
+
registerRouter(ctx, "refs", async ({ req, res }) => {
|
|
743
|
+
await handleRepositoryRefs(req, res, ctx);
|
|
693
744
|
return true;
|
|
694
745
|
});
|
|
695
746
|
registerRouter(ctx, "commit", async ({ req, res }) => {
|
|
696
|
-
await
|
|
747
|
+
await handleRepositoryCommit(req, res, ctx);
|
|
697
748
|
return true;
|
|
698
749
|
});
|
|
699
750
|
registerRouter(ctx, "commit-file", async ({ req, res }) => {
|
|
700
|
-
await
|
|
751
|
+
await handleRepositoryCommitFile(req, res, ctx);
|
|
701
752
|
return true;
|
|
702
753
|
});
|
|
703
754
|
}
|