agentgui 1.0.1095 → 1.0.1096
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/lib/ws-handlers-util.js
CHANGED
|
@@ -324,26 +324,6 @@ export function register(router, deps) {
|
|
|
324
324
|
} catch (e) { err(500, e.message); }
|
|
325
325
|
});
|
|
326
326
|
|
|
327
|
-
// --- git.status: changed-file list (staged/unstaged/untracked) for
|
|
328
|
-
// GitStatusPanel. Porcelain=v1 line format "XY PATH" (rename: "XY OLD -> NEW"),
|
|
329
|
-
// X = index state, Y = worktree state, '?'/' ' = untouched/untracked.
|
|
330
|
-
router.handle('git.status', async (p) => {
|
|
331
|
-
const cwd = resolveGitCwd(p, STARTUP_CWD);
|
|
332
|
-
try {
|
|
333
|
-
const { stdout } = await execFileP('git', ['status', '--porcelain=v1'], { cwd });
|
|
334
|
-
const files = [];
|
|
335
|
-
for (const line of stdout.split('\n')) {
|
|
336
|
-
if (!line) continue;
|
|
337
|
-
const x = line[0], y = line[1];
|
|
338
|
-
const path = line.slice(3);
|
|
339
|
-
if (x === '?' && y === '?') { files.push({ path, status: '?' }); continue; }
|
|
340
|
-
if (x !== ' ' && x !== '?') files.push({ path, status: x, staged: true });
|
|
341
|
-
else if (y !== ' ' && y !== '?') files.push({ path, status: y, staged: false });
|
|
342
|
-
}
|
|
343
|
-
return { files };
|
|
344
|
-
} catch (e) { err(500, (e.stderr || e.message || 'git status failed').trim()); }
|
|
345
|
-
});
|
|
346
|
-
|
|
347
327
|
// --- git.diff: unified diff for a single file or the whole working tree.
|
|
348
328
|
// p.cwd (optional) is confined via confineToRoots/fsAllowRoots, same as
|
|
349
329
|
// chat.sendMessage; p.file (optional) is validated to reject flags/shell
|
package/package.json
CHANGED
package/site/app/js/app.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as B from './backend.js';
|
|
|
3
3
|
|
|
4
4
|
installStyles().catch(() => {});
|
|
5
5
|
|
|
6
|
-
const { AppShell, WorkspaceShell, WorkspaceRail, Topbar, Crumb, Side, Status, Chat, ChatComposer, AgentChat, ConversationList, SessionDashboard, Row, Panel, PageHeader, TextField, Select, Btn, Icon, IconButton, EventList, Spinner, Alert, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker, BreadcrumbPath, EmptyState, FileViewer, FilePreviewPane, FilePreviewCode, FilePreviewText, FilePreviewMedia, ThemeToggle, ContextPane, PromptDialog, ConfirmDialog, DropZone, UploadProgress, FilterPills, SessionMeta, BulkBar, Checkbox, ShortcutList, FocusTrap, AgentListSkeleton, flashComposerNote, toast, withBusy
|
|
6
|
+
const { AppShell, WorkspaceShell, WorkspaceRail, Topbar, Crumb, Side, Status, Chat, ChatComposer, AgentChat, ConversationList, SessionDashboard, Row, Panel, PageHeader, TextField, Select, Btn, Icon, IconButton, EventList, Spinner, Alert, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker, BreadcrumbPath, EmptyState, FileViewer, FilePreviewPane, FilePreviewCode, FilePreviewText, FilePreviewMedia, ThemeToggle, ContextPane, PromptDialog, ConfirmDialog, DropZone, UploadProgress, FilterPills, SessionMeta, BulkBar, Checkbox, ShortcutList, FocusTrap, AgentListSkeleton, flashComposerNote, toast, withBusy } = C;
|
|
7
7
|
|
|
8
8
|
// One duration/bytes vocabulary across every surface: prefer the kit's shared
|
|
9
9
|
// formatters (exported alongside the components), fall back to the local
|
|
@@ -43,7 +43,10 @@ const state = {
|
|
|
43
43
|
activeTimer: null,
|
|
44
44
|
eventsLimit: 300, // how many of the most-recent events to render; grows via "load older"
|
|
45
45
|
files: { path: '', segments: [], entries: [], roots: [], loading: false, error: null, preview: null, sort: 'name', sortDir: 'asc', filter: '' },
|
|
46
|
-
|
|
46
|
+
// Minimal git/worktree panel state. The richer visual component
|
|
47
|
+
// (GitDiffView/WorktreeSwitcher) lives in anentrypoint-design; this is a
|
|
48
|
+
// plain list/text render until the vendored SDK bundle picks those up.
|
|
49
|
+
git: { loading: false, error: null, diff: '', commits: [], worktrees: [], file: '' },
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
// Two-step arm controls auto-reset after this delay so an accidental first click
|
|
@@ -936,19 +939,20 @@ function mainContent() {
|
|
|
936
939
|
return settingsMain();
|
|
937
940
|
}
|
|
938
941
|
|
|
939
|
-
// --- git (
|
|
940
|
-
//
|
|
941
|
-
//
|
|
942
|
-
//
|
|
942
|
+
// --- git (diff/log + worktree list) ---
|
|
943
|
+
// Minimal panel: loads git.log + worktree.list on entry, git.diff on demand.
|
|
944
|
+
// A richer visual component (GitDiffView/WorktreeSwitcher) is being built in
|
|
945
|
+
// anentrypoint-design in parallel; swap this for those exports once the
|
|
946
|
+
// vendored SDK bundle (site/app/vendor/anentrypoint-design) is rebuilt to
|
|
947
|
+
// include them - it does not yet (checked: no GitDiffView/WorktreeSwitcher
|
|
948
|
+
// in the vendored 247420.js as of this change).
|
|
943
949
|
async function loadGitPanel() {
|
|
944
950
|
state.git.loading = true; state.git.error = null; render();
|
|
945
951
|
try {
|
|
946
|
-
const [
|
|
947
|
-
B.gitStatus(state.backend, {}),
|
|
952
|
+
const [commits, worktrees] = await Promise.all([
|
|
948
953
|
B.gitLog(state.backend, { limit: 20 }),
|
|
949
954
|
B.worktreeList(state.backend, {}),
|
|
950
955
|
]);
|
|
951
|
-
state.git.files = files;
|
|
952
956
|
state.git.commits = commits;
|
|
953
957
|
state.git.worktrees = worktrees;
|
|
954
958
|
} catch (e) {
|
|
@@ -969,59 +973,19 @@ async function loadGitDiff(file) {
|
|
|
969
973
|
state.git.diffLoading = false; render();
|
|
970
974
|
}
|
|
971
975
|
|
|
972
|
-
async function createWorktree(path, branch, newBranch) {
|
|
973
|
-
state.git.worktreeBusy = true; render();
|
|
974
|
-
try {
|
|
975
|
-
await B.worktreeCreate(state.backend, { path, branch, newBranch });
|
|
976
|
-
state.git.wtDialog = null;
|
|
977
|
-
await loadGitPanel();
|
|
978
|
-
} catch (e) {
|
|
979
|
-
if (state.git.wtDialog) { state.git.wtDialog.error = e.message || 'Could not create worktree.'; }
|
|
980
|
-
else state.git.error = e.message || 'Could not create worktree.';
|
|
981
|
-
}
|
|
982
|
-
state.git.worktreeBusy = false; render();
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
function gitWorktreeDialog() {
|
|
986
|
-
const d = state.git.wtDialog;
|
|
987
|
-
if (!d) return null;
|
|
988
|
-
return PromptDialog({
|
|
989
|
-
title: 'New worktree', value: d.value ?? '', placeholder: 'relative path, e.g. ../myrepo-feature',
|
|
990
|
-
error: d.error || null, busy: !!state.git.worktreeBusy,
|
|
991
|
-
confirmLabel: state.git.worktreeBusy ? 'creating…' : 'create', cancelLabel: 'cancel',
|
|
992
|
-
onCancel: () => { state.git.wtDialog = null; render(); },
|
|
993
|
-
onInput: (v) => { d.value = v; },
|
|
994
|
-
onConfirm: (v) => {
|
|
995
|
-
if (!v) { d.error = 'enter a worktree path'; render(); return; }
|
|
996
|
-
// New worktree checks out a branch named after the path's basename -
|
|
997
|
-
// matches WorktreeSwitcher's "new worktree" action, which collects no
|
|
998
|
-
// separate branch field (host owns the create flow per its own docs).
|
|
999
|
-
createWorktree(v, undefined, v.split('/').filter(Boolean).pop());
|
|
1000
|
-
},
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
976
|
function gitMain() {
|
|
1005
|
-
if (!state.git.loading && !state.git.
|
|
977
|
+
if (!state.git.loading && !state.git.commits.length && !state.git.worktrees.length && !state.git.error) loadGitPanel();
|
|
1006
978
|
const g = state.git;
|
|
1007
979
|
return [
|
|
1008
980
|
PageHeader({ compact: true, dense: true, title: 'Git', lede: 'Working-tree diff, recent commits, and worktrees.' }),
|
|
1009
981
|
g.error ? Alert({ key: 'git-err', kind: 'error', title: 'Git error', children: g.error }) : null,
|
|
1010
982
|
Row({ key: 'git-actions', children: [
|
|
1011
983
|
Btn({ key: 'refresh', onClick: () => loadGitPanel(), children: g.loading ? 'loading…' : 'refresh' }),
|
|
1012
|
-
|
|
1013
|
-
key: 'wts',
|
|
1014
|
-
worktrees: g.worktrees,
|
|
1015
|
-
current: (g.worktrees.find(w => w.branch) || {}).branch,
|
|
1016
|
-
onSwitch: (w) => loadGitDiff(''),
|
|
1017
|
-
onCreate: () => { state.git.wtDialog = { value: '', error: null }; render(); },
|
|
1018
|
-
}),
|
|
984
|
+
Btn({ key: 'diff-all', onClick: () => loadGitDiff(''), children: g.diffLoading ? 'loading diff…' : 'load full diff' }),
|
|
1019
985
|
] }),
|
|
1020
|
-
Panel({ id: 'git-status', title: 'changed files', children:
|
|
1021
|
-
GitStatusPanel({ files: g.files, active: g.file, onFileClick: (f) => loadGitDiff(f.path) }) }),
|
|
1022
986
|
Panel({ id: 'git-diff', title: g.file ? ('diff: ' + g.file) : 'diff', children:
|
|
1023
987
|
g.diffError ? h('p', { key: 'de', class: 't-meta field-error' }, g.diffError)
|
|
1024
|
-
:
|
|
988
|
+
: h('pre', { key: 'dp', class: 'git-diff-pre' }, g.diff || '(no diff loaded)') }),
|
|
1025
989
|
Panel({ id: 'git-log', title: 'recent commits', children:
|
|
1026
990
|
!g.commits.length ? h('p', { key: 'nc', class: 't-meta' }, g.loading ? 'loading…' : 'no commits')
|
|
1027
991
|
: h('ul', { key: 'cl', class: 'git-commit-list' }, g.commits.map(c =>
|
|
@@ -1031,7 +995,13 @@ function gitMain() {
|
|
|
1031
995
|
h('span', { key: 'm', class: 't-meta' }, ' — ' + (c.author || '') + ' · ' + (c.date || '')),
|
|
1032
996
|
Btn({ key: 'view', small: true, onClick: () => loadGitDiff(''), children: 'view' }),
|
|
1033
997
|
]))) }),
|
|
1034
|
-
|
|
998
|
+
Panel({ id: 'git-worktrees', title: 'worktrees', children:
|
|
999
|
+
!g.worktrees.length ? h('p', { key: 'nw', class: 't-meta' }, g.loading ? 'loading…' : 'no worktrees')
|
|
1000
|
+
: h('ul', { key: 'wl', class: 'git-worktree-list' }, g.worktrees.map((w, i) =>
|
|
1001
|
+
h('li', { key: w.path || i }, [
|
|
1002
|
+
h('code', { key: 'p' }, w.path || ''),
|
|
1003
|
+
' ' + (w.branch || (w.detached ? '(detached)' : '')),
|
|
1004
|
+
]))) }),
|
|
1035
1005
|
];
|
|
1036
1006
|
}
|
|
1037
1007
|
|
package/site/app/js/backend.js
CHANGED
|
@@ -430,11 +430,6 @@ export async function listAgentModels(base, agentId) {
|
|
|
430
430
|
|
|
431
431
|
// ---------- Git / worktrees (WS) ----------
|
|
432
432
|
|
|
433
|
-
export async function gitStatus(base, { cwd } = {}) {
|
|
434
|
-
const { files } = await wsCall(base, 'git.status', { cwd });
|
|
435
|
-
return files || [];
|
|
436
|
-
}
|
|
437
|
-
|
|
438
433
|
export async function gitDiff(base, { cwd, file, staged } = {}) {
|
|
439
434
|
return wsCall(base, 'git.diff', { cwd, file, staged });
|
|
440
435
|
}
|