agentgui 1.0.1094 → 1.0.1095
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/.gm/gm.db +0 -0
- package/.gm/prd.yml +4 -0
- package/lib/ws-handlers-util.js +20 -0
- package/package.json +1 -1
- package/site/app/js/app.js +53 -23
- package/site/app/js/backend.js +5 -0
- package/site/app/vendor/anentrypoint-design/247420.js +27 -27
package/.gm/gm.db
CHANGED
|
Binary file
|
package/.gm/prd.yml
CHANGED
|
@@ -3142,3 +3142,7 @@
|
|
|
3142
3142
|
notes: docstudio utils/dom-busy.js:5-20 withButtonBusy disables the triggering button + aria-busy + label swap + guaranteed restore via try/finally, dropping re-entry while busy. agentgui had zero button.disabled guards anywhere in app.js. Ported as withBusy() in overlay-primitives.js (raw-DOM utility alongside trapTab/useLongPress), wired onto ACP restart, agent re-check, and both agent-list retry buttons.
|
|
3143
3143
|
status: completed
|
|
3144
3144
|
witness: 'Kit built+tested (bun test.js all pass, all lints pass, docs regenerated 0 drift), rebased onto v0.0.354/v0.0.355 cleanly, pushed c7da8c0->bee6ab7, kit CI (Publish/Deploy-GH-Pages/ci) all green. agentgui: browser-witnessed via agent-browser CLI (independent of the broken gm-plugkit spool) - withBusy() live-executed against a real button showed calls:1 for two concurrent invocations (second correctly dropped), disabled:true/aria-busy:true/label swap mid-flight, full restore after; all 4 call-site wirings confirmed present via regex against the live-served /gm/js/app.js source. agentgui pushed 6c8c6bc->ea402c1, all 4 CI checks green.'
|
|
3145
|
+
- id: confirming-pass-agents-md-embedding
|
|
3146
|
+
subject: 'Confirming pass: independently re-verify AGENTS.md compression and embedding fix durability'
|
|
3147
|
+
status: completed
|
|
3148
|
+
witness: 'AGENTS.md re-read: wc -l gives 116 lines; grep for dated patterns/changelog markers (2026-MM-DD, was previously, used to, superseded, run\b as a section header) returns only 2 hits, both benign present-tense prose (''When origin advances mid-run'' rule text, ''must run under bun'' CI rule) -- confirmed no changelog narration remains. Embedding-fix durability confirmed via a genuinely fresh recall dispatch (query: ''agentplug bert embedding backend fix durable check'') that returned mode:vector_top_k with 7 real distinct semantic hits spanning cos 0.55-0.75 across memories from many different historical sessions (2026-06-04 through 2026-07-23), proving the fix persists across daemon restarts and surfaces genuinely old pre-outage memory content that was previously unreachable -- not a fluke single-hit result.'
|
package/lib/ws-handlers-util.js
CHANGED
|
@@ -324,6 +324,26 @@ 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
|
+
|
|
327
347
|
// --- git.diff: unified diff for a single file or the whole working tree.
|
|
328
348
|
// p.cwd (optional) is confined via confineToRoots/fsAllowRoots, same as
|
|
329
349
|
// 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 } = C;
|
|
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, GitStatusPanel, GitDiffView, WorktreeSwitcher } = 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,10 +43,7 @@ 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
|
-
|
|
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: '' },
|
|
46
|
+
git: { loading: false, error: null, diff: '', commits: [], worktrees: [], files: [], file: '', worktreeBusy: false },
|
|
50
47
|
};
|
|
51
48
|
|
|
52
49
|
// Two-step arm controls auto-reset after this delay so an accidental first click
|
|
@@ -939,20 +936,19 @@ function mainContent() {
|
|
|
939
936
|
return settingsMain();
|
|
940
937
|
}
|
|
941
938
|
|
|
942
|
-
// --- git (diff/log + worktree list) ---
|
|
943
|
-
//
|
|
944
|
-
//
|
|
945
|
-
//
|
|
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).
|
|
939
|
+
// --- git (status/diff/log + worktree list) ---
|
|
940
|
+
// Uses anentrypoint-design's GitStatusPanel/GitDiffView/WorktreeSwitcher
|
|
941
|
+
// (ported from pi-web's BranchNavigator concept) once the vendored SDK
|
|
942
|
+
// bundle carries them - see components.js barrel export.
|
|
949
943
|
async function loadGitPanel() {
|
|
950
944
|
state.git.loading = true; state.git.error = null; render();
|
|
951
945
|
try {
|
|
952
|
-
const [commits, worktrees] = await Promise.all([
|
|
946
|
+
const [files, commits, worktrees] = await Promise.all([
|
|
947
|
+
B.gitStatus(state.backend, {}),
|
|
953
948
|
B.gitLog(state.backend, { limit: 20 }),
|
|
954
949
|
B.worktreeList(state.backend, {}),
|
|
955
950
|
]);
|
|
951
|
+
state.git.files = files;
|
|
956
952
|
state.git.commits = commits;
|
|
957
953
|
state.git.worktrees = worktrees;
|
|
958
954
|
} catch (e) {
|
|
@@ -973,19 +969,59 @@ async function loadGitDiff(file) {
|
|
|
973
969
|
state.git.diffLoading = false; render();
|
|
974
970
|
}
|
|
975
971
|
|
|
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
|
+
|
|
976
1004
|
function gitMain() {
|
|
977
|
-
if (!state.git.loading && !state.git.commits.length && !state.git.worktrees.length && !state.git.error) loadGitPanel();
|
|
1005
|
+
if (!state.git.loading && !state.git.files.length && !state.git.commits.length && !state.git.worktrees.length && !state.git.error) loadGitPanel();
|
|
978
1006
|
const g = state.git;
|
|
979
1007
|
return [
|
|
980
1008
|
PageHeader({ compact: true, dense: true, title: 'Git', lede: 'Working-tree diff, recent commits, and worktrees.' }),
|
|
981
1009
|
g.error ? Alert({ key: 'git-err', kind: 'error', title: 'Git error', children: g.error }) : null,
|
|
982
1010
|
Row({ key: 'git-actions', children: [
|
|
983
1011
|
Btn({ key: 'refresh', onClick: () => loadGitPanel(), children: g.loading ? 'loading…' : 'refresh' }),
|
|
984
|
-
|
|
1012
|
+
WorktreeSwitcher({
|
|
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
|
+
}),
|
|
985
1019
|
] }),
|
|
1020
|
+
Panel({ id: 'git-status', title: 'changed files', children:
|
|
1021
|
+
GitStatusPanel({ files: g.files, active: g.file, onFileClick: (f) => loadGitDiff(f.path) }) }),
|
|
986
1022
|
Panel({ id: 'git-diff', title: g.file ? ('diff: ' + g.file) : 'diff', children:
|
|
987
1023
|
g.diffError ? h('p', { key: 'de', class: 't-meta field-error' }, g.diffError)
|
|
988
|
-
:
|
|
1024
|
+
: GitDiffView({ diff: g.diff || '', filename: g.file }) }),
|
|
989
1025
|
Panel({ id: 'git-log', title: 'recent commits', children:
|
|
990
1026
|
!g.commits.length ? h('p', { key: 'nc', class: 't-meta' }, g.loading ? 'loading…' : 'no commits')
|
|
991
1027
|
: h('ul', { key: 'cl', class: 'git-commit-list' }, g.commits.map(c =>
|
|
@@ -995,13 +1031,7 @@ function gitMain() {
|
|
|
995
1031
|
h('span', { key: 'm', class: 't-meta' }, ' — ' + (c.author || '') + ' · ' + (c.date || '')),
|
|
996
1032
|
Btn({ key: 'view', small: true, onClick: () => loadGitDiff(''), children: 'view' }),
|
|
997
1033
|
]))) }),
|
|
998
|
-
|
|
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
|
-
]))) }),
|
|
1034
|
+
gitWorktreeDialog(),
|
|
1005
1035
|
];
|
|
1006
1036
|
}
|
|
1007
1037
|
|
package/site/app/js/backend.js
CHANGED
|
@@ -430,6 +430,11 @@ 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
|
+
|
|
433
438
|
export async function gitDiff(base, { cwd, file, staged } = {}) {
|
|
434
439
|
return wsCall(base, 'git.diff', { cwd, file, staged });
|
|
435
440
|
}
|