Skip to content

Commit da03ac1

Browse files
author
AgentGUI
committed
feat: consolidate client __debug registry + fix workflow-plugin regression
- window.__debug gains 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 - Null-safe snapshot helpers: uninitialized machines return 'uninitialized' instead of crashing - Existing getState/getSyncState/getMessageState methods preserved, internally simplified via shared snap/mapSnap helpers - workflow-plugin.js: remove stale 'git' dep (git plugin was deleted last commit; workflow-plugin only had unused binding). Eliminates 'Plugin git not found' startup warning. - test.js: add regression case for workflow-plugin deps shape
1 parent 3154e0a commit da03ac1

4 files changed

Lines changed: 63 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
18
## [Unreleased] - observability + dead-code sweep + root test suite
29

310
- Expose acp-server-machine snapshots in /api/debug/machines (previously only tool-install + execution machines)

lib/plugins/workflow-plugin.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
// Workflow plugin - git push detection, workflow execution, status polling
2-
31
import fs from 'fs';
42
import path from 'path';
53

64
export default {
75
name: 'workflow',
86
version: '1.0.0',
9-
dependencies: ['git', 'database'],
7+
dependencies: ['database'],
108

119
async init(config, plugins) {
12-
const git = plugins.get('git');
13-
const db = plugins.get('database');
10+
plugins.get('database');
1411
const workflowPolls = new Map();
15-
const runCache = new Map();
1612

1713
const getWorkflows = () => {
1814
const repoRoot = process.cwd();

static/js/client-helpers.js

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,36 +112,71 @@ Object.assign(AgentGUIClient.prototype, {
112112
_setupDebugHooks() {
113113
if (typeof window === 'undefined') return;
114114
const self = this;
115-
window.__debug = {
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 = {
116118
getState: () => ({
117119
latencyEma: self.wsManager?._latencyEma || null,
118120
serverProcessingEstimate: self._serverProcessingEstimate,
119121
latencyTrend: self.wsManager?.latency?.trend || null
120122
}),
121-
122123
getSyncState: () => ({
123124
currentConversation: self.state.currentConversation,
124125
isStreaming: self._convIsStreaming(self.state.currentConversation?.id),
125126
streamingConversations: Array.from(self.state.streamingConversations),
126-
convMachineStates: typeof convMachineAPI !== 'undefined' ? Object.fromEntries([...window.__convMachines].map(([k, a]) => [k, a.getSnapshot().value])) : {},
127-
toolInstallMachineStates: typeof window.__toolInstallMachines !== 'undefined' ? Object.fromEntries([...window.__toolInstallMachines].map(([k, a]) => [k, a.getSnapshot().value])) : {},
128-
voiceMachineState: typeof window.__voiceMachine !== 'undefined' ? window.__voiceMachine.getSnapshot().value : 'unknown',
129-
convListMachineState: typeof window.__convListMachine !== 'undefined' ? window.__convListMachine.getSnapshot().value : 'unknown',
130-
promptMachineState: typeof window.__promptMachine !== 'undefined' ? window.__promptMachine.getSnapshot().value : 'unknown',
131-
wsConnectionState: self.wsManager?._wsActor?.getSnapshot().value || 'unknown',
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),
132133
rendererEventQueueLength: self.renderer?.eventQueue?.length || 0,
133134
rendererEventHistoryLength: self.renderer?.eventHistory?.length || 0,
134135
}),
135-
136136
getMessageState: () => {
137137
const output = document.querySelector('.conversation-messages');
138138
if (!output) return { error: 'No conversation output found' };
139-
const messageCount = output.querySelectorAll('.message').length;
140-
const queueItems = output.querySelectorAll('.queue-item').length;
141-
const pendingMessages = output.querySelectorAll('.message-sending').length;
142-
return { messageCount, queueItems, pendingMessages };
139+
return {
140+
messageCount: output.querySelectorAll('.message').length,
141+
queueItems: output.querySelectorAll('.queue-item').length,
142+
pendingMessages: output.querySelectorAll('.message-sending').length,
143+
};
143144
}
144145
};
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;
145180
},
146181

147182

test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,11 @@ section('acp-server-machine: getMachineActors returns Map', () => {
161161
assert.ok(actors instanceof Map);
162162
});
163163

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+
164170
console.log(`\n${passed} passed, ${failed} failed`);
165171
process.exit(failed === 0 ? 0 : 1);

0 commit comments

Comments
 (0)