agentgui 1.0.868 → 1.0.870
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/CHANGELOG.md +7 -0
- package/CLAUDE.md +12 -0
- package/lib/plugins/workflow-plugin.js +2 -6
- package/package.json +1 -1
- package/static/js/client-helpers.js +48 -13
- package/test.js +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [Unreleased] - GUI observability + workflow-plugin fix
|
|
2
|
+
|
|
3
|
+
- Fix regression from prior commit: workflow-plugin.js declared `dependencies: ['git','database']` but git plugin was deleted; plugin init failed with "Plugin git not found in registry". Removed unused git dep and stale binding.
|
|
4
|
+
- Consolidate client debug registry: `window.__debug` now exposes structured sub-keys (`machines.{conv,toolInstall,voice,convList,prompt,recording,terminal,ws}`, `ws`, `auth`, `perf`, `config`, `renderer`, `conv`) via live getters that snapshot scattered `window.__*` machines into a single queryable tree. Existing `getState`/`getSyncState`/`getMessageState` methods preserved.
|
|
5
|
+
- Null-safe snapshot helpers: uninitialized machines return `'uninitialized'` instead of crashing.
|
|
6
|
+
- test.js: add regression case for workflow-plugin deps (17/17 pass).
|
|
7
|
+
|
|
1
8
|
## [Unreleased] - observability + dead-code sweep + root test suite
|
|
2
9
|
|
|
3
10
|
- Expose acp-server-machine snapshots in /api/debug/machines (previously only tool-install + execution machines)
|
package/CLAUDE.md
CHANGED
|
@@ -368,3 +368,15 @@ The README.md uses shields.io badges with a consistent pattern:
|
|
|
368
368
|
- **`JsonlWatcher._read(fp)` override:** Captures `this._currentFp` before calling `super._read(fp)`, making the file path available to `_line()` callbacks for project-directory decoding in `_conv()`. JSONL project dirs are encoded (e.g., `-config-workspace-agentgui`) — decoded via `'/' + dirName.slice(1).replace(/-/g, '/')`.
|
|
369
369
|
- **`createHttpHandler` uses `getWss: () => wss` (lazy getter):** Passing `wss` directly would crash with TDZ since `wss` is declared after `createHttpHandler` is called. The function form defers access until request time when `wss` is initialized.
|
|
370
370
|
- **`_promptPushIfWeOwnRemote` fires after every `streaming_complete`:** `client-streaming4.js` calls `git.check` on the server after each agent turn. If `ownsRemote && (hasChanges || hasUnpushed)`, it auto-sends "Push the changes to the remote repository." to the current conversation. `ownsRemote` is true for non-github remotes, and for github.com remotes only when `GITHUB_USER` env var is set and appears in the URL. Without `GITHUB_USER`, github.com remotes return `ownsRemote=false` (safe default).
|
|
371
|
+
|
|
372
|
+
## Critical Knowledge for Future Sessions
|
|
373
|
+
|
|
374
|
+
**Codebase Insight Stale:** `.codeinsight` snapshot is outdated (v1.0.811 claimed server.js=3407L, db-queries.js=1412L, but actual as of 2026-04-17: server.js=201L, db-queries.js=94L). Heavy refactoring already done. Before acting on insight "issues" (SQL injection claims, hardcoded secrets, large files), always verify with grep/read against current state. Most reported issues are false positives or stale.
|
|
375
|
+
|
|
376
|
+
**Test Harness Pattern:** Use better-sqlite3 in-memory Database, call `initSchema()` → `migrateConversationColumns()` → `migrateACPSchema()` in order (conversations table needs agentType column from second migration). `createQueries` signature: `(db, prep, generateId)` where `prep=(sql)=>db.prepare(sql)`. Silence console during schema init to keep test output clean. Node ships with better-sqlite3 available (optional dep resolved).
|
|
377
|
+
|
|
378
|
+
**CI Auto-Rewrites History:** Every push to main triggers Auto-Declaudeify workflow that filters Claude coauthor commits and force-pushes filtered history. After a push, `git fetch origin` is needed — local SHA drifts from origin SHA.
|
|
379
|
+
|
|
380
|
+
**Debug Endpoints Scattered:** Routes at `/api/debug`, `/api/debug/machines`, `/api/debug/state`, `/api/ws-stats`, `/api/debug/ws-stats` (alias). `routes-debug.js` wires all five + backup/restore. DEBUG API in browser: `window.__debug.getSyncState()`.
|
|
381
|
+
|
|
382
|
+
**Plugin Files NOT Orphans:** lib/plugins/* are dynamically loaded via `lib/plugin-loader.js` (import with file:// URL + cache-busting `?v=` timestamp). Only truly dead plugin was `lib/plugins/git-plugin.js`. Static scan showing orphans is misleading.
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
// Workflow plugin - git push detection, workflow execution, status polling
|
|
2
|
-
|
|
3
1
|
import fs from 'fs';
|
|
4
2
|
import path from 'path';
|
|
5
3
|
|
|
6
4
|
export default {
|
|
7
5
|
name: 'workflow',
|
|
8
6
|
version: '1.0.0',
|
|
9
|
-
dependencies: ['
|
|
7
|
+
dependencies: ['database'],
|
|
10
8
|
|
|
11
9
|
async init(config, plugins) {
|
|
12
|
-
|
|
13
|
-
const db = plugins.get('database');
|
|
10
|
+
plugins.get('database');
|
|
14
11
|
const workflowPolls = new Map();
|
|
15
|
-
const runCache = new Map();
|
|
16
12
|
|
|
17
13
|
const getWorkflows = () => {
|
|
18
14
|
const repoRoot = process.cwd();
|
package/package.json
CHANGED
|
@@ -112,36 +112,71 @@ Object.assign(AgentGUIClient.prototype, {
|
|
|
112
112
|
_setupDebugHooks() {
|
|
113
113
|
if (typeof window === 'undefined') return;
|
|
114
114
|
const self = this;
|
|
115
|
-
|
|
115
|
+
const snap = (actor) => (actor && actor.getSnapshot) ? actor.getSnapshot().value : 'uninitialized';
|
|
116
|
+
const mapSnap = (m) => m ? Object.fromEntries([...m].map(([k, a]) => [k, snap(a)])) : {};
|
|
117
|
+
const registry = {
|
|
116
118
|
getState: () => ({
|
|
117
119
|
latencyEma: self.wsManager?._latencyEma || null,
|
|
118
120
|
serverProcessingEstimate: self._serverProcessingEstimate,
|
|
119
121
|
latencyTrend: self.wsManager?.latency?.trend || null
|
|
120
122
|
}),
|
|
121
|
-
|
|
122
123
|
getSyncState: () => ({
|
|
123
124
|
currentConversation: self.state.currentConversation,
|
|
124
125
|
isStreaming: self._convIsStreaming(self.state.currentConversation?.id),
|
|
125
126
|
streamingConversations: Array.from(self.state.streamingConversations),
|
|
126
|
-
convMachineStates:
|
|
127
|
-
toolInstallMachineStates:
|
|
128
|
-
voiceMachineState:
|
|
129
|
-
convListMachineState:
|
|
130
|
-
promptMachineState:
|
|
131
|
-
wsConnectionState: self.wsManager?._wsActor
|
|
127
|
+
convMachineStates: mapSnap(window.__convMachines),
|
|
128
|
+
toolInstallMachineStates: mapSnap(window.__toolInstallMachines),
|
|
129
|
+
voiceMachineState: snap(window.__voiceMachine),
|
|
130
|
+
convListMachineState: snap(window.__convListMachine),
|
|
131
|
+
promptMachineState: snap(window.__promptMachine),
|
|
132
|
+
wsConnectionState: snap(self.wsManager?._wsActor),
|
|
132
133
|
rendererEventQueueLength: self.renderer?.eventQueue?.length || 0,
|
|
133
134
|
rendererEventHistoryLength: self.renderer?.eventHistory?.length || 0,
|
|
134
135
|
}),
|
|
135
|
-
|
|
136
136
|
getMessageState: () => {
|
|
137
137
|
const output = document.querySelector('.conversation-messages');
|
|
138
138
|
if (!output) return { error: 'No conversation output found' };
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
return {
|
|
140
|
+
messageCount: output.querySelectorAll('.message').length,
|
|
141
|
+
queueItems: output.querySelectorAll('.queue-item').length,
|
|
142
|
+
pendingMessages: output.querySelectorAll('.message-sending').length,
|
|
143
|
+
};
|
|
143
144
|
}
|
|
144
145
|
};
|
|
146
|
+
const subkeys = {
|
|
147
|
+
machines: () => ({
|
|
148
|
+
conv: mapSnap(window.__convMachines),
|
|
149
|
+
toolInstall: mapSnap(window.__toolInstallMachines),
|
|
150
|
+
voice: snap(window.__voiceMachine),
|
|
151
|
+
convList: snap(window.__convListMachine),
|
|
152
|
+
prompt: snap(window.__promptMachine),
|
|
153
|
+
recording: snap(window.__recordingMachine),
|
|
154
|
+
terminal: snap(window.__terminalMachine),
|
|
155
|
+
ws: snap(self.wsManager?._wsActor),
|
|
156
|
+
}),
|
|
157
|
+
ws: () => ({
|
|
158
|
+
state: snap(self.wsManager?._wsActor),
|
|
159
|
+
latencyEma: self.wsManager?._latencyEma || null,
|
|
160
|
+
latencyTrend: self.wsManager?.latency?.trend || null,
|
|
161
|
+
url: window.__WS || null,
|
|
162
|
+
}),
|
|
163
|
+
auth: () => ({
|
|
164
|
+
state: window.__agentAuthState || null,
|
|
165
|
+
oauth: window.__agentAuthOAuth || null,
|
|
166
|
+
}),
|
|
167
|
+
perf: () => window.__convPerfMetrics || null,
|
|
168
|
+
config: () => ({ base: window.__BASE || null, server: window.__SERVER || null }),
|
|
169
|
+
renderer: () => ({
|
|
170
|
+
eventQueueLength: self.renderer?.eventQueue?.length || 0,
|
|
171
|
+
eventHistoryLength: self.renderer?.eventHistory?.length || 0,
|
|
172
|
+
}),
|
|
173
|
+
conv: () => ({
|
|
174
|
+
current: self.state.currentConversation,
|
|
175
|
+
streaming: Array.from(self.state.streamingConversations),
|
|
176
|
+
}),
|
|
177
|
+
};
|
|
178
|
+
for (const [k, fn] of Object.entries(subkeys)) Object.defineProperty(registry, k, { get: fn, enumerable: true });
|
|
179
|
+
window.__debug = registry;
|
|
145
180
|
},
|
|
146
181
|
|
|
147
182
|
|
package/test.js
CHANGED
|
@@ -161,5 +161,11 @@ section('acp-server-machine: getMachineActors returns Map', () => {
|
|
|
161
161
|
assert.ok(actors instanceof Map);
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
section('workflow-plugin: deps only list active plugins', async () => {
|
|
165
|
+
const wp = await import('./lib/plugins/workflow-plugin.js');
|
|
166
|
+
assert.deepEqual(wp.default.dependencies, ['database']);
|
|
167
|
+
assert.equal(typeof wp.default.init, 'function');
|
|
168
|
+
});
|
|
169
|
+
|
|
164
170
|
console.log(`\n${passed} passed, ${failed} failed`);
|
|
165
171
|
process.exit(failed === 0 ? 0 : 1);
|