my-durable 0.0.24 → 0.0.25
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/apps/dpi-backend/src/git.ts +38 -4
- package/apps/dpi-backend/src/routes.ts +1 -1
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-CsBzwiFM.js +78 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-DM_ddsmz.css +1 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/index.html +2 -2
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/GitPanel.vue +258 -161
- package/apps/dpi-sdk/src/client.ts +8 -2
- package/docs/git-ui-checklist.md +194 -0
- package/package.json +1 -1
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-BLV50tg7.js +0 -78
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-CpVvdDil.css +0 -1
|
@@ -175,7 +175,13 @@ export type GitOp =
|
|
|
175
175
|
| "commit"
|
|
176
176
|
| "worktree-list"
|
|
177
177
|
| "worktree-add"
|
|
178
|
-
| "worktree-remove"
|
|
178
|
+
| "worktree-remove"
|
|
179
|
+
| "push"
|
|
180
|
+
| "stage"
|
|
181
|
+
| "discard"
|
|
182
|
+
| "diff-file"
|
|
183
|
+
| "stash-push"
|
|
184
|
+
| "stash-pop";
|
|
179
185
|
|
|
180
186
|
/** Plain string an arg may never contain — we build argv ourselves anyway. */
|
|
181
187
|
const safeRef = (s: string) => /^[\w./@+-]+$/.test(s) && !s.includes("..");
|
|
@@ -184,9 +190,17 @@ const safeRef = (s: string) => /^[\w./@+-]+$/.test(s) && !s.includes("..");
|
|
|
184
190
|
export async function gitOp(
|
|
185
191
|
path: string,
|
|
186
192
|
op: GitOp,
|
|
187
|
-
opts: {
|
|
193
|
+
opts: {
|
|
194
|
+
ref?: string;
|
|
195
|
+
message?: string;
|
|
196
|
+
target?: string;
|
|
197
|
+
branch?: string;
|
|
198
|
+
files?: string[];
|
|
199
|
+
create?: boolean;
|
|
200
|
+
staged?: boolean;
|
|
201
|
+
} = {},
|
|
188
202
|
): Promise<{ text: string; commits?: { hash: string; refs: string; author: string; date: string; subject: string }[] }> {
|
|
189
|
-
const { ref, message, target, branch, files } = opts;
|
|
203
|
+
const { ref, message, target, branch, files, create, staged } = opts;
|
|
190
204
|
switch (op) {
|
|
191
205
|
case "diff":
|
|
192
206
|
return { text: await git(path, ["--no-pager", "diff", ...(ref && safeRef(ref) ? [ref] : [])]) };
|
|
@@ -217,8 +231,28 @@ export async function gitOp(
|
|
|
217
231
|
return { text: (await git(path, ["--no-pager", "branch", "-vv"])).trimEnd() };
|
|
218
232
|
case "switch": {
|
|
219
233
|
if (!ref || !safeRef(ref)) throw Error("switch needs a branch name (letters, digits, ./-_)");
|
|
220
|
-
|
|
234
|
+
// create:true = git switch -c — IntelliJ's "new branch" action.
|
|
235
|
+
return { text: (await git(path, ["switch", ...(create ? ["-c"] : []), ref])).trim() };
|
|
221
236
|
}
|
|
237
|
+
case "push":
|
|
238
|
+
return { text: (await git(path, ["push"], GIT_SLOW_TIMEOUT)).trim() || "pushed (or nothing to push)" };
|
|
239
|
+
case "stage": {
|
|
240
|
+
if (!files?.length) throw Error("stage needs files");
|
|
241
|
+
return { text: (await git(path, ["add", "--", ...files])).trim() || `staged ${files.length} file(s)` };
|
|
242
|
+
}
|
|
243
|
+
case "discard": {
|
|
244
|
+
// IntelliJ's Rollback: index AND worktree back to HEAD for these paths.
|
|
245
|
+
if (!files?.length) throw Error("discard needs files");
|
|
246
|
+
return { text: (await git(path, ["checkout", "HEAD", "--", ...files])).trim() || `discarded ${files.length} file(s)` };
|
|
247
|
+
}
|
|
248
|
+
case "diff-file": {
|
|
249
|
+
if (!target) throw Error("diff-file needs a file path");
|
|
250
|
+
return { text: (await git(path, ["--no-pager", "diff", ...(staged ? ["--cached"] : []), "HEAD", "--", target])).trim() || "no diff" };
|
|
251
|
+
}
|
|
252
|
+
case "stash-push":
|
|
253
|
+
return { text: (await git(path, ["stash", "push", ...(message ? ["-m", message] : [])])).trim() || "stashed" };
|
|
254
|
+
case "stash-pop":
|
|
255
|
+
return { text: (await git(path, ["stash", "pop"])).trim() || "stash popped" };
|
|
222
256
|
case "commit": {
|
|
223
257
|
const msg = (message ?? "").trim();
|
|
224
258
|
if (!msg) throw Error("commit needs a message");
|
|
@@ -11,7 +11,7 @@ import type { DevicePairing } from "./pairing.js";
|
|
|
11
11
|
type Async = (req: Request, res: Response) => Promise<unknown>;
|
|
12
12
|
const route = (fn: Async) => (req: Request, res: Response, next: NextFunction) => fn(req, res).catch(next);
|
|
13
13
|
import { gitOp, gitStatus, gitStatusBatch, type GitOp } from "./git.ts";
|
|
14
|
-
const GIT_OPS: GitOp[] = ["diff", "log", "log-list", "fetch", "pull", "switch", "branch", "commit", "worktree-list", "worktree-add", "worktree-remove"];
|
|
14
|
+
const GIT_OPS: GitOp[] = ["diff", "log", "log-list", "fetch", "pull", "push", "switch", "branch", "commit", "stage", "discard", "diff-file", "stash-push", "stash-pop", "worktree-list", "worktree-add", "worktree-remove"];
|
|
15
15
|
|
|
16
16
|
interface Locals {
|
|
17
17
|
row: SessionRow;
|