my-durable 0.0.23 → 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 +57 -5
- 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 +269 -119
- package/apps/dpi-sdk/src/client.ts +14 -3
- package/docs/git-ui-checklist.md +194 -0
- package/package.json +1 -1
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-BT2MDDdt.css +0 -1
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-CclVXMo8.js +0 -78
|
@@ -167,6 +167,7 @@ export async function gitStatus(path: string): Promise<GitStatus> {
|
|
|
167
167
|
export type GitOp =
|
|
168
168
|
| "diff"
|
|
169
169
|
| "log"
|
|
170
|
+
| "log-list"
|
|
170
171
|
| "fetch"
|
|
171
172
|
| "pull"
|
|
172
173
|
| "switch"
|
|
@@ -174,7 +175,13 @@ export type GitOp =
|
|
|
174
175
|
| "commit"
|
|
175
176
|
| "worktree-list"
|
|
176
177
|
| "worktree-add"
|
|
177
|
-
| "worktree-remove"
|
|
178
|
+
| "worktree-remove"
|
|
179
|
+
| "push"
|
|
180
|
+
| "stage"
|
|
181
|
+
| "discard"
|
|
182
|
+
| "diff-file"
|
|
183
|
+
| "stash-push"
|
|
184
|
+
| "stash-pop";
|
|
178
185
|
|
|
179
186
|
/** Plain string an arg may never contain — we build argv ourselves anyway. */
|
|
180
187
|
const safeRef = (s: string) => /^[\w./@+-]+$/.test(s) && !s.includes("..");
|
|
@@ -183,14 +190,39 @@ const safeRef = (s: string) => /^[\w./@+-]+$/.test(s) && !s.includes("..");
|
|
|
183
190
|
export async function gitOp(
|
|
184
191
|
path: string,
|
|
185
192
|
op: GitOp,
|
|
186
|
-
opts: {
|
|
187
|
-
|
|
188
|
-
|
|
193
|
+
opts: {
|
|
194
|
+
ref?: string;
|
|
195
|
+
message?: string;
|
|
196
|
+
target?: string;
|
|
197
|
+
branch?: string;
|
|
198
|
+
files?: string[];
|
|
199
|
+
create?: boolean;
|
|
200
|
+
staged?: boolean;
|
|
201
|
+
} = {},
|
|
202
|
+
): Promise<{ text: string; commits?: { hash: string; refs: string; author: string; date: string; subject: string }[] }> {
|
|
203
|
+
const { ref, message, target, branch, files, create, staged } = opts;
|
|
189
204
|
switch (op) {
|
|
190
205
|
case "diff":
|
|
191
206
|
return { text: await git(path, ["--no-pager", "diff", ...(ref && safeRef(ref) ? [ref] : [])]) };
|
|
192
207
|
case "log":
|
|
193
208
|
return { text: (await git(path, ["--no-pager", "log", "--oneline", "-n", "30", ...(ref && safeRef(ref) ? [ref] : [])])).trimEnd() };
|
|
209
|
+
case "log-list": {
|
|
210
|
+
// IntelliJ's log window: hash, refs, author, date, subject — structured.
|
|
211
|
+
const raw = await git(
|
|
212
|
+
path,
|
|
213
|
+
["--no-pager", "log", "-n", "50", "--date=short", "--pretty=format:%h%x1f%D%x1f%an%x1f%ad%x1f%s"],
|
|
214
|
+
);
|
|
215
|
+
return {
|
|
216
|
+
text: "",
|
|
217
|
+
commits: raw
|
|
218
|
+
.split("\n")
|
|
219
|
+
.filter(Boolean)
|
|
220
|
+
.map((l) => {
|
|
221
|
+
const [hash, refs, author, date, subject] = l.split("\x1f");
|
|
222
|
+
return { hash: hash ?? "", refs: refs ?? "", author: author ?? "", date: date ?? "", subject: subject ?? "" };
|
|
223
|
+
}),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
194
226
|
case "fetch":
|
|
195
227
|
return { text: (await git(path, ["fetch", "--all", "--prune"])).trim() || "fetched" };
|
|
196
228
|
case "pull":
|
|
@@ -199,8 +231,28 @@ export async function gitOp(
|
|
|
199
231
|
return { text: (await git(path, ["--no-pager", "branch", "-vv"])).trimEnd() };
|
|
200
232
|
case "switch": {
|
|
201
233
|
if (!ref || !safeRef(ref)) throw Error("switch needs a branch name (letters, digits, ./-_)");
|
|
202
|
-
|
|
234
|
+
// create:true = git switch -c — IntelliJ's "new branch" action.
|
|
235
|
+
return { text: (await git(path, ["switch", ...(create ? ["-c"] : []), ref])).trim() };
|
|
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" };
|
|
203
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" };
|
|
204
256
|
case "commit": {
|
|
205
257
|
const msg = (message ?? "").trim();
|
|
206
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", "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;
|