@pixelbyte-software/pixcode 1.51.2 → 1.51.3
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/CODE_OF_CONDUCT.md +41 -41
- package/CONTRIBUTING.md +155 -155
- package/LICENSE +718 -718
- package/README.de.md +169 -169
- package/README.ja.md +167 -167
- package/README.ko.md +167 -167
- package/README.md +419 -419
- package/README.ru.md +169 -169
- package/README.tr.md +298 -298
- package/README.zh-CN.md +167 -167
- package/SECURITY.md +46 -46
- package/dist/api-automation.html +110 -110
- package/dist/api-docs.html +548 -548
- package/dist/assets/{index-EN9ngyxf.js → index-17CwxHSZ.js} +185 -185
- package/dist/assets/index-B9N-gfOQ.css +32 -0
- package/dist/clear-cache.html +85 -85
- package/dist/convert-icons.md +52 -52
- package/dist/docs.html +308 -308
- package/dist/favicon.svg +8 -8
- package/dist/features.html +133 -133
- package/dist/generate-icons.js +48 -48
- package/dist/humans.txt +15 -15
- package/dist/icons/codex-white.svg +3 -3
- package/dist/icons/codex.svg +3 -3
- package/dist/icons/cursor-white.svg +11 -11
- package/dist/icons/icon-128x128.svg +9 -9
- package/dist/icons/icon-144x144.svg +9 -9
- package/dist/icons/icon-152x152.svg +9 -9
- package/dist/icons/icon-192x192.svg +9 -9
- package/dist/icons/icon-384x384.svg +9 -9
- package/dist/icons/icon-512x512.svg +9 -9
- package/dist/icons/icon-72x72.svg +9 -9
- package/dist/icons/icon-96x96.svg +9 -9
- package/dist/icons/icon-template.svg +9 -9
- package/dist/icons/qwen-logo.svg +14 -14
- package/dist/index.html +59 -59
- package/dist/landing.html +268 -268
- package/dist/llms-full.txt +119 -119
- package/dist/llms.txt +53 -53
- package/dist/logo.svg +12 -12
- package/dist/manifest.json +60 -60
- package/dist/openapi.yaml +1696 -1696
- package/dist/orchestration.html +125 -125
- package/dist/robots.txt +4 -4
- package/dist/site.css +692 -692
- package/dist/sitemap.xml +51 -51
- package/dist/sw.js +132 -132
- package/dist-server/server/cli.js +96 -96
- package/dist-server/server/daemon/manager.js +33 -33
- package/dist-server/server/daemon-manager.js +64 -64
- package/dist-server/server/index.js +122 -3
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js +84 -0
- package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js.map +1 -0
- package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js +43 -0
- package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js.map +1 -0
- package/dist-server/server/modules/orchestration/hermes/hermes.routes.js +55 -1
- package/dist-server/server/modules/orchestration/hermes/hermes.routes.js.map +1 -1
- package/dist-server/server/modules/orchestration/index.js +1 -0
- package/dist-server/server/modules/orchestration/index.js.map +1 -1
- package/dist-server/server/routes/commands.js +25 -25
- package/dist-server/server/routes/git.js +17 -17
- package/dist-server/server/routes/live-view.js +46 -46
- package/dist-server/server/services/hermes-gateway.js +310 -0
- package/dist-server/server/services/hermes-gateway.js.map +1 -1
- package/dist-server/server/services/public-api-manifest.js +59 -51
- package/dist-server/server/services/public-api-manifest.js.map +1 -1
- package/package.json +222 -222
- package/scripts/fix-node-pty.js +67 -67
- package/scripts/github/create-v1.38-issues.mjs +351 -351
- package/scripts/github/create-vscode-workbench-issues.mjs +121 -121
- package/scripts/hermes/configure-pixcode-mcp.mjs +165 -163
- package/scripts/hermes/pixcode-mcp-server.mjs +1009 -958
- package/scripts/smoke/changes-panel-layout.mjs +48 -48
- package/scripts/smoke/chat-composer-fixed-layout.mjs +55 -55
- package/scripts/smoke/chat-message-timeline-order.mjs +41 -41
- package/scripts/smoke/chat-realtime-hydration.mjs +44 -44
- package/scripts/smoke/chat-session-provider-pools.mjs +35 -35
- package/scripts/smoke/chat-session-state.mjs +19 -19
- package/scripts/smoke/code-editor-theme.mjs +55 -55
- package/scripts/smoke/code-editor-vscode-engine.mjs +91 -91
- package/scripts/smoke/command-center-agent-writes.mjs +79 -79
- package/scripts/smoke/command-center-non-git.mjs +46 -46
- package/scripts/smoke/context-packet.mjs +43 -43
- package/scripts/smoke/control-room-ux-redesign.mjs +91 -91
- package/scripts/smoke/daemon-entrypoint.mjs +20 -20
- package/scripts/smoke/default-landing-routing.mjs +33 -33
- package/scripts/smoke/desktop-native-notifications.mjs +30 -30
- package/scripts/smoke/desktop-tray-icon.mjs +33 -33
- package/scripts/smoke/discord-release-workflow.mjs +24 -24
- package/scripts/smoke/git-install-update.mjs +255 -255
- package/scripts/smoke/handoff-artifact-protocol.mjs +50 -50
- package/scripts/smoke/hermes-api-install.mjs +56 -56
- package/scripts/smoke/hermes-gateway-persistence.mjs +104 -104
- package/scripts/smoke/hermes-mcp-pixcode-roundtrip.mjs +426 -367
- package/scripts/smoke/hermes-rest-chat-api.mjs +162 -162
- package/scripts/smoke/hermes-rest-chat-live.mjs +45 -45
- package/scripts/smoke/hermes-rest-codex-launch.mjs +209 -209
- package/scripts/smoke/hermes-rest-gateway.mjs +79 -70
- package/scripts/smoke/hermes-rest-live.mjs +42 -42
- package/scripts/smoke/hermes-roundtrip.mjs +167 -167
- package/scripts/smoke/hermes-settings-commands.mjs +349 -346
- package/scripts/smoke/hermes-smoke-launcher-guard.mjs +34 -34
- package/scripts/smoke/live-view-diagnostics.mjs +53 -53
- package/scripts/smoke/live-view-environment.mjs +92 -92
- package/scripts/smoke/live-view-integration.mjs +450 -450
- package/scripts/smoke/mac-desktop-runtime.mjs +37 -37
- package/scripts/smoke/mobile-tunnel-guidance.mjs +29 -29
- package/scripts/smoke/model-registry.mjs +36 -36
- package/scripts/smoke/multi-project-ui.mjs +45 -45
- package/scripts/smoke/multi-worker-slots.mjs +42 -42
- package/scripts/smoke/notification-center.mjs +87 -87
- package/scripts/smoke/notification-inapp-preference.mjs +23 -23
- package/scripts/smoke/notification-taxonomy.mjs +58 -58
- package/scripts/smoke/orchestration-api.mjs +172 -172
- package/scripts/smoke/orchestration-execution-dashboard.mjs +33 -33
- package/scripts/smoke/orchestration-live-run.mjs +176 -176
- package/scripts/smoke/orchestration-mobile-scroll.mjs +29 -29
- package/scripts/smoke/orchestration-model-sync.mjs +30 -30
- package/scripts/smoke/orchestration-permission-fallback.mjs +34 -34
- package/scripts/smoke/orchestration-runtime-guards.mjs +48 -48
- package/scripts/smoke/orchestration-user-facing-output.mjs +25 -25
- package/scripts/smoke/permission-policy.mjs +50 -50
- package/scripts/smoke/pixcode-workbench-1-48.mjs +167 -167
- package/scripts/smoke/provider-models-opencode-live.mjs +66 -66
- package/scripts/smoke/provider-rest-api.mjs +124 -124
- package/scripts/smoke/provider-selection-status.mjs +52 -52
- package/scripts/smoke/run-state-refresh.mjs +52 -52
- package/scripts/smoke/runtime-manager.mjs +99 -99
- package/scripts/smoke/shell-manual-disconnect.mjs +30 -30
- package/scripts/smoke/side-panel-editor-layout.mjs +34 -34
- package/scripts/smoke/static-root-routing.mjs +21 -21
- package/scripts/smoke/strict-handoff-compact.mjs +60 -60
- package/scripts/smoke/taskmaster-config.mjs +24 -24
- package/scripts/smoke/taskmaster-execution-telegram.mjs +3 -3
- package/scripts/smoke/taskmaster-onboarding.mjs +3 -3
- package/scripts/smoke/taskmaster-run-graph.mjs +3 -3
- package/scripts/smoke/telegram-control.mjs +242 -242
- package/scripts/smoke/tunnel-persistence.mjs +56 -56
- package/scripts/smoke/update-issue-progress.mjs +69 -69
- package/scripts/smoke/update-ux.mjs +55 -55
- package/scripts/smoke/v138-completion.mjs +132 -132
- package/scripts/smoke/v138-desktop-release-hardening.mjs +69 -69
- package/scripts/smoke/v138-diagnostics.mjs +63 -63
- package/scripts/smoke/v138-issue-planner.mjs +33 -33
- package/scripts/smoke/v143-remote-control.mjs +76 -76
- package/scripts/smoke/v144-production-loop.mjs +47 -47
- package/scripts/smoke/v145-platformization.mjs +46 -46
- package/scripts/smoke/v146-control-room-ui.mjs +150 -150
- package/scripts/smoke/version-modal-autoshow.mjs +29 -29
- package/scripts/smoke/vscode-workbench-layout.mjs +63 -63
- package/scripts/smoke/vscode-workbench-polish.mjs +461 -436
- package/scripts/smoke/workflow-fallback-replay.mjs +56 -56
- package/scripts/smoke/workflow-templates.mjs +43 -43
- package/scripts/smoke/workflow-trace-timeline.mjs +46 -46
- package/scripts/update-git-install.mjs +293 -293
- package/server/claude-sdk.js +920 -920
- package/server/cli.js +1039 -1039
- package/server/constants/config.js +4 -4
- package/server/cursor-cli.js +344 -344
- package/server/daemon/manager.js +563 -563
- package/server/daemon-manager.js +964 -964
- package/server/database/db.js +921 -921
- package/server/database/json-store.js +197 -197
- package/server/gemini-cli.js +550 -550
- package/server/gemini-response-handler.js +79 -79
- package/server/index.js +128 -2
- package/server/load-env.js +35 -35
- package/server/middleware/auth.js +175 -175
- package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
- package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +63 -63
- package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +286 -286
- package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
- package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
- package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/json-event.adapter.test.ts +60 -0
- package/server/modules/orchestration/a2a/adapters/json-event.adapter.ts +101 -0
- package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/agent-card.ts +55 -55
- package/server/modules/orchestration/a2a/routes.ts +590 -590
- package/server/modules/orchestration/a2a/task-store.ts +178 -178
- package/server/modules/orchestration/a2a/types.ts +126 -126
- package/server/modules/orchestration/a2a/validator.ts +113 -113
- package/server/modules/orchestration/hermes/hermes.routes.ts +642 -583
- package/server/modules/orchestration/index.ts +101 -100
- package/server/modules/orchestration/preview/port-watcher.ts +112 -112
- package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
- package/server/modules/orchestration/preview/types.ts +19 -19
- package/server/modules/orchestration/security/permission-policy.ts +401 -401
- package/server/modules/orchestration/tasks/orchestration-task-store.ts +41 -41
- package/server/modules/orchestration/tasks/orchestration-task.routes.ts +64 -64
- package/server/modules/orchestration/tasks/orchestration-task.service.ts +209 -209
- package/server/modules/orchestration/tasks/orchestration-task.types.ts +40 -40
- package/server/modules/orchestration/tasks/task-run-graph.ts +155 -155
- package/server/modules/orchestration/workflows/approval-queue.ts +106 -106
- package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
- package/server/modules/orchestration/workflows/context-packet.ts +186 -186
- package/server/modules/orchestration/workflows/handoff-artifact.ts +175 -175
- package/server/modules/orchestration/workflows/workflow-fallback-policy.ts +161 -161
- package/server/modules/orchestration/workflows/workflow-replay.ts +254 -254
- package/server/modules/orchestration/workflows/workflow-runner.ts +2070 -2070
- package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
- package/server/modules/orchestration/workflows/workflow-templates.ts +272 -272
- package/server/modules/orchestration/workflows/workflow-trace.ts +424 -424
- package/server/modules/orchestration/workflows/workflow.routes.ts +586 -586
- package/server/modules/orchestration/workflows/workflow.types.ts +111 -111
- package/server/modules/orchestration/workflows/workspace-target.ts +122 -122
- package/server/modules/orchestration/workspace/docker-workspace.ts +136 -136
- package/server/modules/orchestration/workspace/path-safety.ts +55 -55
- package/server/modules/orchestration/workspace/types.ts +52 -52
- package/server/modules/orchestration/workspace/workspace-manager.ts +102 -102
- package/server/modules/orchestration/workspace/worktree-workspace.ts +126 -126
- package/server/modules/providers/index.ts +2 -2
- package/server/modules/providers/list/claude/claude-auth.provider.ts +146 -146
- package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
- package/server/modules/providers/list/claude/claude.provider.ts +15 -15
- package/server/modules/providers/list/codex/codex-auth.provider.ts +117 -117
- package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
- package/server/modules/providers/list/codex/codex.provider.ts +15 -15
- package/server/modules/providers/list/cursor/cursor-auth.provider.ts +147 -147
- package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
- package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
- package/server/modules/providers/list/gemini/gemini-auth.provider.ts +173 -173
- package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
- package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
- package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
- package/server/modules/providers/list/opencode/opencode-auth.provider.ts +131 -131
- package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +126 -126
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +286 -286
- package/server/modules/providers/list/opencode/opencode.provider.ts +29 -29
- package/server/modules/providers/list/qwen/qwen-auth.provider.ts +146 -146
- package/server/modules/providers/list/qwen/qwen-mcp.provider.ts +114 -114
- package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
- package/server/modules/providers/list/qwen/qwen.provider.ts +21 -21
- package/server/modules/providers/provider.registry.ts +40 -40
- package/server/modules/providers/provider.routes.ts +944 -944
- package/server/modules/providers/services/mcp.service.ts +86 -86
- package/server/modules/providers/services/provider-auth.service.ts +26 -26
- package/server/modules/providers/services/sessions.service.ts +45 -45
- package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
- package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
- package/server/modules/providers/shared/provider-configs.ts +142 -142
- package/server/modules/providers/tests/mcp.test.ts +293 -293
- package/server/openai-codex.js +462 -462
- package/server/opencode-cli.js +491 -491
- package/server/opencode-response-handler.js +111 -111
- package/server/projects.js +3008 -3008
- package/server/qwen-code-cli.js +410 -410
- package/server/qwen-response-handler.js +73 -73
- package/server/routes/agent.js +1435 -1435
- package/server/routes/auth.js +159 -159
- package/server/routes/codex.js +20 -20
- package/server/routes/commands.js +570 -570
- package/server/routes/cursor.js +61 -61
- package/server/routes/diagnostics.js +41 -41
- package/server/routes/gemini.js +25 -25
- package/server/routes/git.js +1650 -1650
- package/server/routes/live-view.js +411 -411
- package/server/routes/mcp-utils.js +13 -13
- package/server/routes/messages.js +62 -62
- package/server/routes/network.js +125 -125
- package/server/routes/platformization.js +212 -212
- package/server/routes/plugins.js +320 -320
- package/server/routes/production-agent-loop.js +90 -90
- package/server/routes/projects.js +917 -917
- package/server/routes/public-api.js +34 -34
- package/server/routes/qwen.js +27 -27
- package/server/routes/remote.js +55 -55
- package/server/routes/settings.js +321 -321
- package/server/routes/telegram.js +140 -140
- package/server/routes/user.js +125 -125
- package/server/routes/webhooks.js +63 -63
- package/server/services/control-room.js +102 -102
- package/server/services/diagnostics.js +165 -165
- package/server/services/external-access.js +375 -375
- package/server/services/hermes-gateway.js +1562 -1247
- package/server/services/hermes-install-jobs.js +729 -729
- package/server/services/install-jobs.js +715 -715
- package/server/services/live-view.js +956 -956
- package/server/services/managed-runtimes.js +493 -493
- package/server/services/model-registry.js +144 -144
- package/server/services/notification-orchestrator.js +365 -365
- package/server/services/notification-taxonomy.js +204 -204
- package/server/services/platformization.js +815 -815
- package/server/services/production-agent-loop.js +248 -248
- package/server/services/provider-cli-versions.js +149 -149
- package/server/services/provider-credentials.js +189 -189
- package/server/services/provider-models.js +396 -396
- package/server/services/public-api-manifest.js +190 -182
- package/server/services/remote-connection.js +127 -127
- package/server/services/runtime-manager.js +323 -323
- package/server/services/startup-update.js +234 -234
- package/server/services/telegram/bot.js +331 -331
- package/server/services/telegram/control-center.js +979 -979
- package/server/services/telegram/telegram-http-client.js +151 -151
- package/server/services/telegram/translations.js +340 -340
- package/server/services/vapid-keys.js +36 -36
- package/server/services/webhooks.js +216 -216
- package/server/sessionManager.js +225 -225
- package/server/shared/interfaces.ts +54 -54
- package/server/shared/types.ts +172 -172
- package/server/shared/utils.ts +193 -193
- package/server/tsconfig.json +36 -36
- package/server/utils/colors.js +21 -21
- package/server/utils/commandParser.js +305 -305
- package/server/utils/frontmatter.js +18 -18
- package/server/utils/gitConfig.js +34 -34
- package/server/utils/plugin-loader.js +457 -457
- package/server/utils/plugin-process-manager.js +185 -185
- package/server/utils/port-access.js +209 -209
- package/server/utils/runtime-paths.js +37 -37
- package/server/utils/url-detection.js +71 -71
- package/server/vite-daemon.js +79 -79
- package/shared/modelConstants.js +161 -161
- package/shared/networkHosts.js +22 -22
- package/dist/assets/index-DMz0zv6T.css +0 -32
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
// Gemini Response Handler - JSON Stream processing
|
|
2
|
-
import { sessionsService } from './modules/providers/services/sessions.service.js';
|
|
3
|
-
|
|
4
|
-
class GeminiResponseHandler {
|
|
5
|
-
constructor(ws, options = {}) {
|
|
6
|
-
this.ws = ws;
|
|
7
|
-
this.buffer = '';
|
|
8
|
-
this.onContentFragment = options.onContentFragment || null;
|
|
9
|
-
this.onInit = options.onInit || null;
|
|
10
|
-
this.onToolUse = options.onToolUse || null;
|
|
11
|
-
this.onToolResult = options.onToolResult || null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Process incoming raw data from Gemini stream-json
|
|
15
|
-
processData(data) {
|
|
16
|
-
this.buffer += data;
|
|
17
|
-
|
|
18
|
-
// Split by newline
|
|
19
|
-
const lines = this.buffer.split('\n');
|
|
20
|
-
|
|
21
|
-
// Keep the last incomplete line in the buffer
|
|
22
|
-
this.buffer = lines.pop() || '';
|
|
23
|
-
|
|
24
|
-
for (const line of lines) {
|
|
25
|
-
if (!line.trim()) continue;
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const event = JSON.parse(line);
|
|
29
|
-
this.handleEvent(event);
|
|
30
|
-
} catch (err) {
|
|
31
|
-
// Not a JSON line, probably debug output or CLI warnings
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
handleEvent(event) {
|
|
37
|
-
const sid = typeof this.ws.getSessionId === 'function' ? this.ws.getSessionId() : null;
|
|
38
|
-
|
|
39
|
-
if (event.type === 'init') {
|
|
40
|
-
if (this.onInit) {
|
|
41
|
-
this.onInit(event);
|
|
42
|
-
}
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Invoke per-type callbacks for session tracking
|
|
47
|
-
if (event.type === 'message' && event.role === 'assistant') {
|
|
48
|
-
const content = event.content || '';
|
|
49
|
-
if (this.onContentFragment && content) {
|
|
50
|
-
this.onContentFragment(content);
|
|
51
|
-
}
|
|
52
|
-
} else if (event.type === 'tool_use' && this.onToolUse) {
|
|
53
|
-
this.onToolUse(event);
|
|
54
|
-
} else if (event.type === 'tool_result' && this.onToolResult) {
|
|
55
|
-
this.onToolResult(event);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Normalize via adapter and send all resulting messages
|
|
59
|
-
const normalized = sessionsService.normalizeMessage('gemini', event, sid);
|
|
60
|
-
for (const msg of normalized) {
|
|
61
|
-
this.ws.send(msg);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
forceFlush() {
|
|
66
|
-
if (this.buffer.trim()) {
|
|
67
|
-
try {
|
|
68
|
-
const event = JSON.parse(this.buffer);
|
|
69
|
-
this.handleEvent(event);
|
|
70
|
-
} catch (err) { }
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
destroy() {
|
|
75
|
-
this.buffer = '';
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default GeminiResponseHandler;
|
|
1
|
+
// Gemini Response Handler - JSON Stream processing
|
|
2
|
+
import { sessionsService } from './modules/providers/services/sessions.service.js';
|
|
3
|
+
|
|
4
|
+
class GeminiResponseHandler {
|
|
5
|
+
constructor(ws, options = {}) {
|
|
6
|
+
this.ws = ws;
|
|
7
|
+
this.buffer = '';
|
|
8
|
+
this.onContentFragment = options.onContentFragment || null;
|
|
9
|
+
this.onInit = options.onInit || null;
|
|
10
|
+
this.onToolUse = options.onToolUse || null;
|
|
11
|
+
this.onToolResult = options.onToolResult || null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Process incoming raw data from Gemini stream-json
|
|
15
|
+
processData(data) {
|
|
16
|
+
this.buffer += data;
|
|
17
|
+
|
|
18
|
+
// Split by newline
|
|
19
|
+
const lines = this.buffer.split('\n');
|
|
20
|
+
|
|
21
|
+
// Keep the last incomplete line in the buffer
|
|
22
|
+
this.buffer = lines.pop() || '';
|
|
23
|
+
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
if (!line.trim()) continue;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const event = JSON.parse(line);
|
|
29
|
+
this.handleEvent(event);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
// Not a JSON line, probably debug output or CLI warnings
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
handleEvent(event) {
|
|
37
|
+
const sid = typeof this.ws.getSessionId === 'function' ? this.ws.getSessionId() : null;
|
|
38
|
+
|
|
39
|
+
if (event.type === 'init') {
|
|
40
|
+
if (this.onInit) {
|
|
41
|
+
this.onInit(event);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Invoke per-type callbacks for session tracking
|
|
47
|
+
if (event.type === 'message' && event.role === 'assistant') {
|
|
48
|
+
const content = event.content || '';
|
|
49
|
+
if (this.onContentFragment && content) {
|
|
50
|
+
this.onContentFragment(content);
|
|
51
|
+
}
|
|
52
|
+
} else if (event.type === 'tool_use' && this.onToolUse) {
|
|
53
|
+
this.onToolUse(event);
|
|
54
|
+
} else if (event.type === 'tool_result' && this.onToolResult) {
|
|
55
|
+
this.onToolResult(event);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Normalize via adapter and send all resulting messages
|
|
59
|
+
const normalized = sessionsService.normalizeMessage('gemini', event, sid);
|
|
60
|
+
for (const msg of normalized) {
|
|
61
|
+
this.ws.send(msg);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
forceFlush() {
|
|
66
|
+
if (this.buffer.trim()) {
|
|
67
|
+
try {
|
|
68
|
+
const event = JSON.parse(this.buffer);
|
|
69
|
+
this.handleEvent(event);
|
|
70
|
+
} catch (err) { }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
destroy() {
|
|
75
|
+
this.buffer = '';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default GeminiResponseHandler;
|
package/server/index.js
CHANGED
|
@@ -111,6 +111,7 @@ import {
|
|
|
111
111
|
GeminiA2AAdapter,
|
|
112
112
|
OpenCodeA2AAdapter,
|
|
113
113
|
QwenA2AAdapter,
|
|
114
|
+
JsonEventA2AAdapter,
|
|
114
115
|
createPreviewProxyRouter,
|
|
115
116
|
createOrchestrationTaskRouter,
|
|
116
117
|
createHermesRouter,
|
|
@@ -302,6 +303,117 @@ async function setupProjectsWatcher() {
|
|
|
302
303
|
}
|
|
303
304
|
}
|
|
304
305
|
|
|
306
|
+
// ── Per-project workspace watchers (file explorer live refresh) ─────────────
|
|
307
|
+
// setupProjectsWatcher() above only watches provider metadata folders
|
|
308
|
+
// (~/.claude/projects etc.), so the file explorer never learned about changes
|
|
309
|
+
// inside the actual project working directory. These watchers are created on
|
|
310
|
+
// demand when a client sends `watch-project` over /ws and broadcast debounced
|
|
311
|
+
// `project_files_updated` events to subscribed clients only, letting the
|
|
312
|
+
// explorer refresh automatically without HTTP polling.
|
|
313
|
+
const WORKSPACE_WATCHER_DEBOUNCE_MS = 800;
|
|
314
|
+
const workspaceWatchers = new Map(); // projectName -> { watcher, subscribers, debounceTimer, pendingEvent, rootPath }
|
|
315
|
+
|
|
316
|
+
async function subscribeToWorkspace(ws, projectName) {
|
|
317
|
+
if (!projectName || typeof projectName !== 'string') return;
|
|
318
|
+
|
|
319
|
+
const existing = workspaceWatchers.get(projectName);
|
|
320
|
+
if (existing) {
|
|
321
|
+
existing.subscribers.add(ws);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
let rootPath;
|
|
326
|
+
try {
|
|
327
|
+
rootPath = await extractProjectDirectory(projectName);
|
|
328
|
+
await fsPromises.access(rootPath);
|
|
329
|
+
} catch (error) {
|
|
330
|
+
console.warn(`[watcher] Cannot watch workspace for ${projectName}:`, error.message);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const entry = {
|
|
335
|
+
watcher: null,
|
|
336
|
+
subscribers: new Set([ws]),
|
|
337
|
+
debounceTimer: null,
|
|
338
|
+
pendingEvent: null,
|
|
339
|
+
rootPath,
|
|
340
|
+
};
|
|
341
|
+
workspaceWatchers.set(projectName, entry);
|
|
342
|
+
|
|
343
|
+
const broadcastFileUpdate = (eventType, filePath) => {
|
|
344
|
+
entry.pendingEvent = { eventType, filePath };
|
|
345
|
+
if (entry.debounceTimer) {
|
|
346
|
+
clearTimeout(entry.debounceTimer);
|
|
347
|
+
}
|
|
348
|
+
entry.debounceTimer = setTimeout(() => {
|
|
349
|
+
entry.debounceTimer = null;
|
|
350
|
+
const pending = entry.pendingEvent || {};
|
|
351
|
+
entry.pendingEvent = null;
|
|
352
|
+
const message = JSON.stringify({
|
|
353
|
+
type: 'project_files_updated',
|
|
354
|
+
projectName,
|
|
355
|
+
changeType: pending.eventType || 'change',
|
|
356
|
+
changedFile: pending.filePath ? path.relative(rootPath, pending.filePath) : null,
|
|
357
|
+
timestamp: new Date().toISOString(),
|
|
358
|
+
});
|
|
359
|
+
entry.subscribers.forEach((client) => {
|
|
360
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
361
|
+
client.send(message);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}, WORKSPACE_WATCHER_DEBOUNCE_MS);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
try {
|
|
368
|
+
const chokidar = (await import('chokidar')).default;
|
|
369
|
+
const watcher = chokidar.watch(rootPath, {
|
|
370
|
+
ignored: WATCHER_IGNORED_PATTERNS,
|
|
371
|
+
persistent: true,
|
|
372
|
+
ignoreInitial: true,
|
|
373
|
+
followSymlinks: false,
|
|
374
|
+
depth: 10,
|
|
375
|
+
awaitWriteFinish: {
|
|
376
|
+
stabilityThreshold: 500,
|
|
377
|
+
pollInterval: 250
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
watcher
|
|
382
|
+
.on('add', (filePath) => broadcastFileUpdate('add', filePath))
|
|
383
|
+
.on('change', (filePath) => broadcastFileUpdate('change', filePath))
|
|
384
|
+
.on('unlink', (filePath) => broadcastFileUpdate('unlink', filePath))
|
|
385
|
+
.on('addDir', (dirPath) => broadcastFileUpdate('addDir', dirPath))
|
|
386
|
+
.on('unlinkDir', (dirPath) => broadcastFileUpdate('unlinkDir', dirPath))
|
|
387
|
+
.on('error', (error) => {
|
|
388
|
+
console.error(`[ERROR] Workspace watcher error for ${projectName}:`, error);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
entry.watcher = watcher;
|
|
392
|
+
} catch (error) {
|
|
393
|
+
workspaceWatchers.delete(projectName);
|
|
394
|
+
console.error(`[ERROR] Failed to watch workspace for ${projectName}:`, error);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function unsubscribeFromWorkspace(ws, projectName = null) {
|
|
399
|
+
const entries = projectName
|
|
400
|
+
? (workspaceWatchers.has(projectName) ? [[projectName, workspaceWatchers.get(projectName)]] : [])
|
|
401
|
+
: Array.from(workspaceWatchers.entries());
|
|
402
|
+
|
|
403
|
+
for (const [name, entry] of entries) {
|
|
404
|
+
entry.subscribers.delete(ws);
|
|
405
|
+
if (entry.subscribers.size === 0) {
|
|
406
|
+
if (entry.debounceTimer) {
|
|
407
|
+
clearTimeout(entry.debounceTimer);
|
|
408
|
+
}
|
|
409
|
+
workspaceWatchers.delete(name);
|
|
410
|
+
entry.watcher?.close().catch((error) => {
|
|
411
|
+
console.warn(`[watcher] Failed to close workspace watcher for ${name}:`, error?.message || error);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
305
417
|
|
|
306
418
|
const app = express();
|
|
307
419
|
const server = http.createServer(app);
|
|
@@ -986,6 +1098,7 @@ adapterRegistry.register(new CursorA2AAdapter());
|
|
|
986
1098
|
adapterRegistry.register(new GeminiA2AAdapter());
|
|
987
1099
|
adapterRegistry.register(new QwenA2AAdapter());
|
|
988
1100
|
adapterRegistry.register(new OpenCodeA2AAdapter());
|
|
1101
|
+
adapterRegistry.register(new JsonEventA2AAdapter());
|
|
989
1102
|
app.use('/hermes', createHermesTaskRouter());
|
|
990
1103
|
app.use('/preview', authenticateToken, createPreviewProxyRouter());
|
|
991
1104
|
app.use('/api/orchestration', authenticateToken, createOrchestrationTaskRouter());
|
|
@@ -1874,8 +1987,12 @@ app.get('/api/projects/:projectName/files', authenticateToken, async (req, res)
|
|
|
1874
1987
|
actualPath = await extractProjectDirectory(req.params.projectName);
|
|
1875
1988
|
} catch (error) {
|
|
1876
1989
|
console.error('Error extracting project directory:', error);
|
|
1877
|
-
//
|
|
1878
|
-
|
|
1990
|
+
// Do NOT fall back to projectName.replace(/-/g, '/') here: on Windows the
|
|
1991
|
+
// dash-encoded name ("C--Users-...") decodes to a garbage path ("C//Users/...")
|
|
1992
|
+
// that can never exist, so the old fallback just produced a confusing 404
|
|
1993
|
+
// with a fabricated path. extractProjectDirectory already handles the
|
|
1994
|
+
// POSIX-style decode internally; if it throws, the project is unknown.
|
|
1995
|
+
return res.status(404).json({ error: `Project not found: ${req.params.projectName}` });
|
|
1879
1996
|
}
|
|
1880
1997
|
|
|
1881
1998
|
// Check if path exists
|
|
@@ -2554,6 +2671,13 @@ function handleChatConnection(ws, request) {
|
|
|
2554
2671
|
data: pending
|
|
2555
2672
|
});
|
|
2556
2673
|
}
|
|
2674
|
+
} else if (data.type === 'watch-project') {
|
|
2675
|
+
// Subscribe this client to live file-tree updates for a project
|
|
2676
|
+
// workspace. The server pushes debounced `project_files_updated`
|
|
2677
|
+
// events so the explorer refreshes without HTTP polling.
|
|
2678
|
+
await subscribeToWorkspace(ws, data.projectName);
|
|
2679
|
+
} else if (data.type === 'unwatch-project') {
|
|
2680
|
+
unsubscribeFromWorkspace(ws, data.projectName || null);
|
|
2557
2681
|
} else if (data.type === 'get-active-sessions') {
|
|
2558
2682
|
// Get all currently active sessions
|
|
2559
2683
|
const activeSessions = {
|
|
@@ -2582,6 +2706,8 @@ function handleChatConnection(ws, request) {
|
|
|
2582
2706
|
console.log('🔌 Chat client disconnected');
|
|
2583
2707
|
// Remove from connected clients
|
|
2584
2708
|
connectedClients.delete(ws);
|
|
2709
|
+
// Drop any workspace watcher subscriptions held by this socket
|
|
2710
|
+
unsubscribeFromWorkspace(ws);
|
|
2585
2711
|
});
|
|
2586
2712
|
}
|
|
2587
2713
|
|
package/server/load-env.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
// Load environment variables from .env before other imports execute.
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
import { findAppRoot, getModuleDir } from './utils/runtime-paths.js';
|
|
7
|
-
|
|
8
|
-
const __dirname = getModuleDir(import.meta.url);
|
|
9
|
-
// Resolve the repo/app root via the nearest /server folder so this file keeps finding the
|
|
10
|
-
// same top-level .env file from both /server/load-env.js and /dist-server/server/load-env.js.
|
|
11
|
-
const APP_ROOT = findAppRoot(__dirname);
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
const envPath = path.join(APP_ROOT, '.env');
|
|
15
|
-
const envFile = fs.readFileSync(envPath, 'utf8');
|
|
16
|
-
envFile.split('\n').forEach(line => {
|
|
17
|
-
const trimmedLine = line.trim();
|
|
18
|
-
if (trimmedLine && !trimmedLine.startsWith('#')) {
|
|
19
|
-
const [key, ...valueParts] = trimmedLine.split('=');
|
|
20
|
-
if (key && valueParts.length > 0 && !process.env[key]) {
|
|
21
|
-
process.env[key] = valueParts.join('=').trim();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
} catch (e) {
|
|
26
|
-
console.log('No .env file found or error reading it:', e.message);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Keep the default database in a stable user-level location so rebuilding dist-server
|
|
30
|
-
// never changes where the backend stores auth.db when DATABASE_PATH is not set explicitly.
|
|
31
|
-
const DEFAULT_DATABASE_PATH = path.join(os.homedir(), '.pixcode', 'auth.db');
|
|
32
|
-
|
|
33
|
-
if (!process.env.DATABASE_PATH) {
|
|
34
|
-
process.env.DATABASE_PATH = DEFAULT_DATABASE_PATH;
|
|
35
|
-
}
|
|
1
|
+
// Load environment variables from .env before other imports execute.
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
|
|
6
|
+
import { findAppRoot, getModuleDir } from './utils/runtime-paths.js';
|
|
7
|
+
|
|
8
|
+
const __dirname = getModuleDir(import.meta.url);
|
|
9
|
+
// Resolve the repo/app root via the nearest /server folder so this file keeps finding the
|
|
10
|
+
// same top-level .env file from both /server/load-env.js and /dist-server/server/load-env.js.
|
|
11
|
+
const APP_ROOT = findAppRoot(__dirname);
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const envPath = path.join(APP_ROOT, '.env');
|
|
15
|
+
const envFile = fs.readFileSync(envPath, 'utf8');
|
|
16
|
+
envFile.split('\n').forEach(line => {
|
|
17
|
+
const trimmedLine = line.trim();
|
|
18
|
+
if (trimmedLine && !trimmedLine.startsWith('#')) {
|
|
19
|
+
const [key, ...valueParts] = trimmedLine.split('=');
|
|
20
|
+
if (key && valueParts.length > 0 && !process.env[key]) {
|
|
21
|
+
process.env[key] = valueParts.join('=').trim();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.log('No .env file found or error reading it:', e.message);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Keep the default database in a stable user-level location so rebuilding dist-server
|
|
30
|
+
// never changes where the backend stores auth.db when DATABASE_PATH is not set explicitly.
|
|
31
|
+
const DEFAULT_DATABASE_PATH = path.join(os.homedir(), '.pixcode', 'auth.db');
|
|
32
|
+
|
|
33
|
+
if (!process.env.DATABASE_PATH) {
|
|
34
|
+
process.env.DATABASE_PATH = DEFAULT_DATABASE_PATH;
|
|
35
|
+
}
|