@dotobokuri/fleet-console 1.15.0 → 1.16.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.
Files changed (68) hide show
  1. package/AGENTS.md +160 -23
  2. package/README.md +18 -16
  3. package/dist/cli.d.ts +1 -20
  4. package/dist/cli.mjs +14116 -22237
  5. package/dist/client/assets/{_baseUniq-cnqj2OOU.js → _baseUniq-Dl47hoBn.js} +1 -1
  6. package/dist/client/assets/{arc-DKvQCH7P.js → arc-gTL65oBG.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-iJqnsZ6O.js → architectureDiagram-Q4EWVU46-B4ysOekM.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-CkJhTJZi.js → blockDiagram-DXYQGD6D-Cn9GJTRY.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-DHkUfhoy.js → c4Diagram-AHTNJAMY-BIub3g5q.js} +1 -1
  10. package/dist/client/assets/channel-kIwNtTP-.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-CJmFkUz-.js → chunk-4BX2VUAB-DFHyuJK_.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-Dp00Zwg3.js → chunk-4TB4RGXK-CV_laQzm.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-DFBvwrH_.js → chunk-55IACEB6-Cs5LeHXe.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-Dik0hYho.js → chunk-EDXVE4YY-D_LyOot5.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-DYcmg67a.js → chunk-FMBD7UC4-B1dz5YRM.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-B9bhXkOc.js → chunk-OYMX7WX6-CT0D_NEN.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-CW_BXRdy.js → chunk-QZHKN3VN-CWNbvQat.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-uJM9wQJs.js → chunk-YZCP3GAM-C_fp6KvG.js} +1 -1
  19. package/dist/client/assets/classDiagram-6PBFFD2Q-DGNebVYt.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DGNebVYt.js +1 -0
  21. package/dist/client/assets/clone-DFRxH9FR.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-BpsaUYJS.js → cose-bilkent-S5V4N54A-B6xq1D1R.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-CLaMczco.js → dagre-KV5264BT-_leuW1pD.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-CFOnN2pM.js → diagram-5BDNPKRD-4wH1x31-.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-CkLTTvmR.js → diagram-G4DWMVQ6-nlP8pQsq.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-c8R_KOlQ.js → diagram-MMDJMWI5-CWgyNhRW.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-Cfz4vDC5.js → diagram-TYMM5635-DfGqjepr.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-BZFJRBcT.js → erDiagram-SMLLAGMA-CMpgXQfn.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-CSbwVNst.js → flowDiagram-DWJPFMVM-BaLRDaS7.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-Z3BPe1vZ.js → ganttDiagram-T4ZO3ILL-CAuXJ2xz.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-7Ka8NeSE.js → gitGraphDiagram-UUTBAWPF-KsfuOuTW.js} +1 -1
  32. package/dist/client/assets/{graph-DG6E-jsV.js → graph-3375lXck.js} +1 -1
  33. package/dist/client/assets/index-BRniWsxl.css +1 -0
  34. package/dist/client/assets/index-OEz1YKt3.js +361 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-CN7rF9WG.js → infoDiagram-42DDH7IO-GYhjUtOi.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-jus38Ki6.js → ishikawaDiagram-UXIWVN3A-DfjzfJ87.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-CCn-AdDe.js → journeyDiagram-VCZTEJTY-CjF_oAe2.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-BOfals_F.js → kanban-definition-6JOO6SKY-DkIK9azu.js} +1 -1
  39. package/dist/client/assets/{layout-B2qTAIS5.js → layout-g4DCAcmJ.js} +1 -1
  40. package/dist/client/assets/{linear-BmsYolMA.js → linear-BXtneTLA.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-D0OYO4L1.js → mermaid.core-CFCyolqU.js} +4 -4
  42. package/dist/client/assets/{min-jZihhkYo.js → min-BOlS-Kpi.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-35wK1xy9.js → mindmap-definition-QFDTVHPH-pM2WtK3x.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-BynWLFT0.js → pieDiagram-DEJITSTG-DDIwX7uR.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-w5UoFlnr.js → quadrantDiagram-34T5L4WZ-BXaToAll.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-BQ9zR_XY.js → requirementDiagram-MS252O5E-DcniSPVW.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-BL1Lj8dz.js → sankeyDiagram-XADWPNL6-BRSO8kbj.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-jC78BST4.js → sequenceDiagram-FGHM5R23-CUIcqpcf.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-iVYQ2VCC.js → stateDiagram-FHFEXIEX-DwQwUYPD.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-oBGjXrxd.js +1 -0
  51. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CYAlka_x.js → timeline-definition-GMOUNBTQ-DNrziHKp.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-BFcj10GU.js → vennDiagram-DHZGUBPP-BEVuQytw.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-CIUgshxb.js → wardley-RL74JXVD-Cwp-Pzm_.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-BEV516Os.js → wardleyDiagram-NUSXRM2D-Cd3w820H.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-D1DFk2ax.js → xychartDiagram-5P7HB3ND-CSVs_RZN.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/dist/fleet-plugins/diff/routes.mjs +304 -0
  58. package/dist/fleet-plugins/file-explorer/routes.mjs +446 -0
  59. package/dist/{cli-bin.mjs → fleet-plugins/terminal/routes.mjs} +17366 -21470
  60. package/package.json +7 -6
  61. package/dist/cli-bin.d.ts +0 -2
  62. package/dist/client/assets/channel-C3r_coHh.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-DmoF5itQ.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DmoF5itQ.js +0 -1
  65. package/dist/client/assets/clone-CJPQGOBM.js +0 -1
  66. package/dist/client/assets/index-B-bmeDQZ.js +0 -777
  67. package/dist/client/assets/index-BfTQyXzZ.css +0 -1
  68. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BEYzM5Cb.js +0 -1
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { spawn } from 'child_process';
5
+
6
+ // sdk/plugin/node.ts
7
+ function definePlugin(definition) {
8
+ return definition;
9
+ }
10
+ function registerRouter(ctx, path2, handler) {
11
+ ctx.registerRouter(normalizePath(path2), handler);
12
+ }
13
+ function normalizePath(path2) {
14
+ if (path2.length === 0 || path2 === "/") return "/";
15
+ return path2;
16
+ }
17
+ var GitExecutorError = class extends Error {
18
+ code;
19
+ exitCode;
20
+ stderr;
21
+ constructor(code, stderr = "", exitCode) {
22
+ super(code);
23
+ this.name = "GitExecutorError";
24
+ this.code = code;
25
+ this.stderr = stderr;
26
+ this.exitCode = exitCode;
27
+ }
28
+ };
29
+ var DEFAULT_TIMEOUT_MS = 3e4;
30
+ var DEFAULT_MAX_BUFFER = 8 * 1024 * 1024;
31
+ function runGit(args, opts) {
32
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
33
+ const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
34
+ return new Promise((resolve, reject) => {
35
+ let child;
36
+ try {
37
+ child = spawn("git", args, { cwd: opts.cwd, shell: false, windowsHide: true });
38
+ } catch (error) {
39
+ const code = error.code === "ENOENT" ? "git_unavailable" : "spawn_failed";
40
+ reject(new GitExecutorError(code, String(error)));
41
+ return;
42
+ }
43
+ const stdoutChunks = [];
44
+ const stderrChunks = [];
45
+ let stdoutLen = 0;
46
+ let truncated = false;
47
+ let timedOut = false;
48
+ const timer = setTimeout(() => {
49
+ timedOut = true;
50
+ child.kill("SIGTERM");
51
+ reject(new GitExecutorError("timeout"));
52
+ }, timeoutMs);
53
+ child.stdout.on("data", (chunk) => {
54
+ if (truncated) return;
55
+ const remaining = maxBuffer - stdoutLen;
56
+ if (chunk.length >= remaining) {
57
+ stdoutChunks.push(chunk.subarray(0, remaining));
58
+ stdoutLen += remaining;
59
+ truncated = true;
60
+ } else {
61
+ stdoutChunks.push(chunk);
62
+ stdoutLen += chunk.length;
63
+ }
64
+ });
65
+ child.stderr.on("data", (chunk) => {
66
+ stderrChunks.push(chunk);
67
+ });
68
+ child.on("error", (error) => {
69
+ clearTimeout(timer);
70
+ const code = error.code === "ENOENT" ? "git_unavailable" : "spawn_failed";
71
+ reject(new GitExecutorError(code, error.message));
72
+ });
73
+ child.on("close", (code) => {
74
+ clearTimeout(timer);
75
+ if (timedOut) return;
76
+ const stderr = Buffer.concat(stderrChunks).toString("utf8");
77
+ if (code !== 0) {
78
+ if (code !== null && (opts.allowExitCodes?.includes(code) ?? false)) {
79
+ const stdout2 = Buffer.concat(stdoutChunks).toString("utf8");
80
+ resolve({ stdout: stdout2, truncated });
81
+ return;
82
+ }
83
+ const isNoRepo = stderr.toLowerCase().includes("not a git repository");
84
+ reject(new GitExecutorError(isNoRepo ? "no_git_repo" : "non_zero_exit", stderr, code ?? void 0));
85
+ return;
86
+ }
87
+ const stdout = Buffer.concat(stdoutChunks).toString("utf8");
88
+ resolve({ stdout, truncated });
89
+ });
90
+ });
91
+ }
92
+
93
+ // ../fleet-plugins/diff/server/diff.ts
94
+ var REF_SAFE_RE = /^(?:[a-f0-9]{7,40}|[A-Za-z0-9][A-Za-z0-9/_.~^-]{0,250})$/;
95
+ function isSafeGitRef(ref) {
96
+ return REF_SAFE_RE.test(ref);
97
+ }
98
+ function buildDiffArgs(mode, ref) {
99
+ if (mode === "staged") return ["diff", "--cached"];
100
+ if (mode === "commit" && ref) return ["diff", `${ref}^`, ref];
101
+ return ["diff"];
102
+ }
103
+ function parseDiffFileList(nameStatusOutput, numstatOutput) {
104
+ const numstatMap = /* @__PURE__ */ new Map();
105
+ for (const line of numstatOutput.split("\n")) {
106
+ const parts = line.split(" ");
107
+ if (parts.length < 3) continue;
108
+ const [adds, dels, filePath] = parts;
109
+ if (!filePath) continue;
110
+ numstatMap.set(filePath, {
111
+ additions: parseInt(adds ?? "0", 10) || 0,
112
+ deletions: parseInt(dels ?? "0", 10) || 0
113
+ });
114
+ }
115
+ const files = [];
116
+ for (const line of nameStatusOutput.split("\n")) {
117
+ if (!line.trim()) continue;
118
+ const [rawStatus, ...pathParts] = line.split(" ");
119
+ if (!rawStatus || pathParts.length === 0) continue;
120
+ const statusChar = rawStatus.charAt(0).toUpperCase();
121
+ if (statusChar !== "M" && statusChar !== "A" && statusChar !== "D" && statusChar !== "R") continue;
122
+ const filePath = statusChar === "R" ? pathParts[1] ?? pathParts[0] ?? "" : pathParts[0] ?? "";
123
+ if (!filePath) continue;
124
+ const nums = numstatMap.get(filePath) ?? { additions: 0, deletions: 0 };
125
+ files.push({ path: filePath, status: statusChar, ...nums });
126
+ }
127
+ return files;
128
+ }
129
+ async function fetchUntrackedFiles(cwd) {
130
+ const result = await runGit(["ls-files", "--others", "--exclude-standard"], { cwd });
131
+ return result.stdout.split("\n").filter((p) => p.trim()).map((p) => ({
132
+ path: p,
133
+ status: "U",
134
+ additions: 0,
135
+ deletions: 0
136
+ }));
137
+ }
138
+ function isPlainObject(value) {
139
+ return typeof value === "object" && value !== null && !Array.isArray(value);
140
+ }
141
+ async function handleDiffChanged(req, res, ctx) {
142
+ if (req.method !== "POST") {
143
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
144
+ return;
145
+ }
146
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
147
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
148
+ return;
149
+ }
150
+ const body = await ctx.host.http.readJsonBody(req);
151
+ if (!isPlainObject(body)) {
152
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
153
+ return;
154
+ }
155
+ const mode = body.mode;
156
+ if (mode !== "workdir" && mode !== "staged" && mode !== "commit") {
157
+ ctx.host.http.writeJson(res, 400, { error: "invalid_mode" });
158
+ return;
159
+ }
160
+ const theaterId = body.theaterId;
161
+ if (typeof theaterId !== "string") {
162
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
163
+ return;
164
+ }
165
+ const rawRef = typeof body.ref === "string" ? body.ref : void 0;
166
+ if (rawRef !== void 0 && !isSafeGitRef(rawRef)) {
167
+ ctx.host.http.writeJson(res, 400, { error: "invalid_ref" });
168
+ return;
169
+ }
170
+ const theaterPath = ctx.host.paths.resolveTheaterPath(theaterId);
171
+ if (!theaterPath) {
172
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
173
+ return;
174
+ }
175
+ try {
176
+ const diffArgs = buildDiffArgs(mode, rawRef);
177
+ const nameStatusArgs = [...diffArgs, "--name-status", "--diff-filter=MADR"];
178
+ const numstatArgs = [...diffArgs, "--numstat", "--diff-filter=MADR"];
179
+ const [nameStatusResult, numstatResult] = await Promise.all([
180
+ runGit(nameStatusArgs, { cwd: theaterPath }),
181
+ runGit(numstatArgs, { cwd: theaterPath })
182
+ ]);
183
+ const files = parseDiffFileList(nameStatusResult.stdout, numstatResult.stdout);
184
+ if (mode === "workdir") {
185
+ try {
186
+ const untrackedFiles = await fetchUntrackedFiles(theaterPath);
187
+ files.push(...untrackedFiles);
188
+ } catch {
189
+ }
190
+ }
191
+ ctx.host.http.writeJson(res, 200, { files, truncated: nameStatusResult.truncated || numstatResult.truncated });
192
+ } catch (error) {
193
+ if (error instanceof GitExecutorError) {
194
+ if (error.code === "no_git_repo" || error.code === "git_unavailable") {
195
+ ctx.host.http.writeJson(res, 422, { error: error.code });
196
+ return;
197
+ }
198
+ ctx.host.http.writeJson(res, 500, { error: "git_failed" });
199
+ return;
200
+ }
201
+ throw error;
202
+ }
203
+ }
204
+ async function handleDiffFile(req, res, ctx) {
205
+ if (req.method !== "POST") {
206
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
207
+ return;
208
+ }
209
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
210
+ ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
211
+ return;
212
+ }
213
+ const body = await ctx.host.http.readJsonBody(req);
214
+ if (!isPlainObject(body) || typeof body.filePath !== "string") {
215
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
216
+ return;
217
+ }
218
+ const mode = body.mode;
219
+ if (mode !== "workdir" && mode !== "staged" && mode !== "commit" && mode !== "untracked") {
220
+ ctx.host.http.writeJson(res, 400, { error: "invalid_mode" });
221
+ return;
222
+ }
223
+ const theaterId = body.theaterId;
224
+ if (typeof theaterId !== "string") {
225
+ ctx.host.http.writeJson(res, 400, { error: "invalid_request" });
226
+ return;
227
+ }
228
+ const rawFilePath = body.filePath;
229
+ const theaterPath = ctx.host.paths.resolveTheaterPath(theaterId);
230
+ if (!theaterPath) {
231
+ ctx.host.http.writeJson(res, 404, { error: "theater_not_found" });
232
+ return;
233
+ }
234
+ const resolvedPath = path.resolve(theaterPath, rawFilePath);
235
+ if (!resolvedPath.startsWith(theaterPath + path.sep) && resolvedPath !== theaterPath) {
236
+ ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
237
+ return;
238
+ }
239
+ const relativePath = path.normalize(rawFilePath);
240
+ if (relativePath.startsWith("..")) {
241
+ ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
242
+ return;
243
+ }
244
+ const rawRef = typeof body.ref === "string" ? body.ref : void 0;
245
+ if (rawRef !== void 0 && !isSafeGitRef(rawRef)) {
246
+ ctx.host.http.writeJson(res, 400, { error: "invalid_ref" });
247
+ return;
248
+ }
249
+ try {
250
+ if (mode === "untracked") {
251
+ let realTheater;
252
+ let realFile;
253
+ try {
254
+ [realTheater, realFile] = await Promise.all([
255
+ fs.realpath(theaterPath),
256
+ fs.realpath(resolvedPath)
257
+ ]);
258
+ } catch {
259
+ ctx.host.http.writeJson(res, 404, { error: "file_not_found" });
260
+ return;
261
+ }
262
+ if (realFile !== realTheater && !realFile.startsWith(realTheater + path.sep)) {
263
+ ctx.host.http.writeJson(res, 403, { error: "path_outside_theater" });
264
+ return;
265
+ }
266
+ const result2 = await runGit(
267
+ ["diff", "--no-index", "--unified=3", "--", "/dev/null", relativePath],
268
+ { cwd: theaterPath, allowExitCodes: [1] }
269
+ );
270
+ ctx.host.http.writeJson(res, 200, { content: result2.stdout, truncated: result2.truncated });
271
+ return;
272
+ }
273
+ const diffArgs = [...buildDiffArgs(mode, rawRef), "--unified=3", "--", relativePath];
274
+ const result = await runGit(diffArgs, { cwd: theaterPath });
275
+ ctx.host.http.writeJson(res, 200, { content: result.stdout, truncated: result.truncated });
276
+ } catch (error) {
277
+ if (error instanceof GitExecutorError) {
278
+ if (error.code === "no_git_repo" || error.code === "git_unavailable") {
279
+ ctx.host.http.writeJson(res, 422, { error: error.code });
280
+ return;
281
+ }
282
+ ctx.host.http.writeJson(res, 500, { error: "git_failed" });
283
+ return;
284
+ }
285
+ throw error;
286
+ }
287
+ }
288
+
289
+ // ../fleet-plugins/diff/routes.ts
290
+ var routes_default = definePlugin({
291
+ id: "diff",
292
+ register(ctx) {
293
+ registerRouter(ctx, "changed", async ({ req, res }) => {
294
+ await handleDiffChanged(req, res, ctx);
295
+ return true;
296
+ });
297
+ registerRouter(ctx, "file", async ({ req, res }) => {
298
+ await handleDiffFile(req, res, ctx);
299
+ return true;
300
+ });
301
+ }
302
+ });
303
+
304
+ export { routes_default as default };