synabun 2.0.5 → 2.0.9
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 +78 -0
- package/README.md +2 -1
- package/THIRD-PARTY-LICENSES.md +13 -0
- package/docs/whatsapp.md +151 -16
- package/hooks/claude-code/post-plan.mjs +6 -30
- package/hooks/claude-code/session-start.mjs +1 -4
- package/hooks/claude-code/shared.mjs +112 -75
- package/lib/child-path.js +303 -0
- package/lib/claude-hooks.js +2 -1
- package/lib/data-home-migration.js +2 -0
- package/lib/desktop-app.js +265 -0
- package/lib/external-tools.js +7 -3
- package/lib/log-redact.js +102 -0
- package/lib/package-processes.js +670 -0
- package/lib/packaged-runtime.js +138 -11
- package/lib/runtime-dependencies.js +225 -0
- package/mcp-server/dist/http.d.ts +3 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +15 -4
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +9 -6
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/services/browser-bench.d.ts +1 -1
- package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/browser-bench.js +1 -1
- package/mcp-server/dist/services/browser-bench.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/budget-judgments.js +153 -0
- package/mcp-server/dist/services/budget-judgments.js.map +1 -0
- package/mcp-server/dist/services/categories.d.ts +35 -2
- package/mcp-server/dist/services/categories.d.ts.map +1 -1
- package/mcp-server/dist/services/categories.js +77 -33
- package/mcp-server/dist/services/categories.js.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +41 -4
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
- package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/desktop-bench.js +1 -1
- package/mcp-server/dist/services/desktop-bench.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +11 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -1
- package/mcp-server/dist/services/identity.js +24 -0
- package/mcp-server/dist/services/identity.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +13 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +34 -2
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
- package/mcp-server/dist/services/typesafe-config.js +4 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +11 -8
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +35 -14
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/bluesky.js +1 -1
- package/mcp-server/dist/tools/bluesky.js.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.js +1 -1
- package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-batch.js +1 -1
- package/mcp-server/dist/tools/browser-batch.js.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-interact.js +1 -1
- package/mcp-server/dist/tools/browser-interact.js.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.js +1 -1
- package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-observe.js +1 -1
- package/mcp-server/dist/tools/browser-observe.js.map +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/card-tools.js +1 -1
- package/mcp-server/dist/tools/card-tools.js.map +1 -1
- package/mcp-server/dist/tools/category.d.ts +1 -1
- package/mcp-server/dist/tools/category.d.ts.map +1 -1
- package/mcp-server/dist/tools/category.js +5 -1
- package/mcp-server/dist/tools/category.js.map +1 -1
- package/mcp-server/dist/tools/choice.d.ts +1 -1
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +1 -1
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/computer.d.ts +1 -1
- package/mcp-server/dist/tools/computer.d.ts.map +1 -1
- package/mcp-server/dist/tools/computer.js +1 -1
- package/mcp-server/dist/tools/computer.js.map +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-channel.js +1 -1
- package/mcp-server/dist/tools/discord-channel.js.map +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-guild.js +1 -1
- package/mcp-server/dist/tools/discord-guild.js.map +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-member.js +1 -1
- package/mcp-server/dist/tools/discord-member.js.map +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-message.js +1 -1
- package/mcp-server/dist/tools/discord-message.js.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-role.js +1 -1
- package/mcp-server/dist/tools/discord-role.js.map +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-thread.js +1 -1
- package/mcp-server/dist/tools/discord-thread.js.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.js +1 -1
- package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
- package/mcp-server/dist/tools/fb-groups.js +1 -1
- package/mcp-server/dist/tools/fb-groups.js.map +1 -1
- package/mcp-server/dist/tools/forget.d.ts +1 -1
- package/mcp-server/dist/tools/forget.d.ts.map +1 -1
- package/mcp-server/dist/tools/forget.js +1 -1
- package/mcp-server/dist/tools/forget.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +1 -1
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.js +1 -1
- package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.js +1 -1
- package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.js +1 -1
- package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/image-tools.js.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
- package/mcp-server/dist/tools/loop.d.ts +1 -1
- package/mcp-server/dist/tools/loop.d.ts.map +1 -1
- package/mcp-server/dist/tools/loop.js +1 -1
- package/mcp-server/dist/tools/loop.js.map +1 -1
- package/mcp-server/dist/tools/memories.d.ts +1 -1
- package/mcp-server/dist/tools/memories.d.ts.map +1 -1
- package/mcp-server/dist/tools/memories.js +1 -1
- package/mcp-server/dist/tools/memories.js.map +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +1 -1
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/profile.d.ts +1 -1
- package/mcp-server/dist/tools/profile.d.ts.map +1 -1
- package/mcp-server/dist/tools/profile.js +1 -1
- package/mcp-server/dist/tools/profile.js.map +1 -1
- package/mcp-server/dist/tools/recall.d.ts +1 -1
- package/mcp-server/dist/tools/recall.d.ts.map +1 -1
- package/mcp-server/dist/tools/recall.js +1 -1
- package/mcp-server/dist/tools/recall.js.map +1 -1
- package/mcp-server/dist/tools/reflect.d.ts +1 -1
- package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
- package/mcp-server/dist/tools/reflect.js +1 -1
- package/mcp-server/dist/tools/reflect.js.map +1 -1
- package/mcp-server/dist/tools/remember.d.ts +1 -1
- package/mcp-server/dist/tools/remember.d.ts.map +1 -1
- package/mcp-server/dist/tools/remember.js +13 -11
- package/mcp-server/dist/tools/remember.js.map +1 -1
- package/mcp-server/dist/tools/restore.d.ts +1 -1
- package/mcp-server/dist/tools/restore.d.ts.map +1 -1
- package/mcp-server/dist/tools/restore.js +1 -1
- package/mcp-server/dist/tools/restore.js.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
- package/mcp-server/dist/tools/sync.d.ts +1 -1
- package/mcp-server/dist/tools/sync.d.ts.map +1 -1
- package/mcp-server/dist/tools/sync.js +1 -1
- package/mcp-server/dist/tools/sync.js.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
- package/mcp-server/dist/tools/utils.d.ts +1 -1
- package/mcp-server/dist/tools/utils.d.ts.map +1 -1
- package/mcp-server/dist/tools/utils.js +1 -1
- package/mcp-server/dist/tools/utils.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/download.js +1 -1
- package/mcp-server/dist/tools/youtube/download.js.map +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/media.js +1 -1
- package/mcp-server/dist/tools/youtube/media.js.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/source.js +1 -1
- package/mcp-server/dist/tools/youtube/source.js.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.js +4 -9
- package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
- package/mcp-server/dist/tui.js +18 -5
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/dist/version.d.ts +5 -0
- package/mcp-server/dist/version.d.ts.map +1 -0
- package/mcp-server/dist/version.js +21 -0
- package/mcp-server/dist/version.js.map +1 -0
- package/mcp-server/package-lock.json +3 -3
- package/mcp-server/package.json +3 -3
- package/mcp-server/run.mjs +15 -9
- package/mcp-server/src/http.ts +18 -3
- package/mcp-server/src/index.ts +9 -6
- package/mcp-server/src/services/browser-bench.ts +1 -1
- package/mcp-server/src/services/budget-judgments.ts +183 -0
- package/mcp-server/src/services/categories.ts +77 -32
- package/mcp-server/src/services/codex-config-heal.ts +35 -4
- package/mcp-server/src/services/desktop-bench.ts +1 -1
- package/mcp-server/src/services/identity.ts +27 -0
- package/mcp-server/src/services/neural-interface.ts +34 -2
- package/mcp-server/src/services/typesafe-config.ts +4 -1
- package/mcp-server/src/tools/agents.ts +34 -15
- package/mcp-server/src/tools/bluesky.ts +1 -1
- package/mcp-server/src/tools/browser-advanced.ts +1 -1
- package/mcp-server/src/tools/browser-batch.ts +1 -1
- package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
- package/mcp-server/src/tools/browser-interact.ts +1 -1
- package/mcp-server/src/tools/browser-navigate.ts +1 -1
- package/mcp-server/src/tools/browser-observe.ts +1 -1
- package/mcp-server/src/tools/card-tools.ts +1 -1
- package/mcp-server/src/tools/category.ts +6 -1
- package/mcp-server/src/tools/choice.ts +1 -1
- package/mcp-server/src/tools/computer.ts +1 -1
- package/mcp-server/src/tools/discord-channel.ts +1 -1
- package/mcp-server/src/tools/discord-guild.ts +1 -1
- package/mcp-server/src/tools/discord-member.ts +1 -1
- package/mcp-server/src/tools/discord-message.ts +1 -1
- package/mcp-server/src/tools/discord-onboarding.ts +1 -1
- package/mcp-server/src/tools/discord-role.ts +1 -1
- package/mcp-server/src/tools/discord-thread.ts +1 -1
- package/mcp-server/src/tools/discord-webhook.ts +1 -1
- package/mcp-server/src/tools/fb-groups.ts +1 -1
- package/mcp-server/src/tools/forget.ts +1 -1
- package/mcp-server/src/tools/git-tools.ts +1 -1
- package/mcp-server/src/tools/gsc/experience.ts +1 -1
- package/mcp-server/src/tools/gsc/indexing.ts +1 -1
- package/mcp-server/src/tools/gsc/inspect.ts +1 -1
- package/mcp-server/src/tools/gsc/navigate.ts +1 -1
- package/mcp-server/src/tools/gsc/performance.ts +1 -1
- package/mcp-server/src/tools/gsc/settings.ts +1 -1
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
- package/mcp-server/src/tools/loop.ts +1 -1
- package/mcp-server/src/tools/memories.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +1 -1
- package/mcp-server/src/tools/profile.ts +1 -1
- package/mcp-server/src/tools/recall.ts +1 -1
- package/mcp-server/src/tools/reflect.ts +1 -1
- package/mcp-server/src/tools/remember.ts +13 -12
- package/mcp-server/src/tools/restore.ts +1 -1
- package/mcp-server/src/tools/style-guide-tools.ts +1 -1
- package/mcp-server/src/tools/sync.ts +1 -1
- package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
- package/mcp-server/src/tools/utils.ts +1 -1
- package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
- package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
- package/mcp-server/src/tools/youtube/analytics.ts +1 -1
- package/mcp-server/src/tools/youtube/download.ts +1 -1
- package/mcp-server/src/tools/youtube/media.ts +1 -1
- package/mcp-server/src/tools/youtube/metadata.ts +1 -1
- package/mcp-server/src/tools/youtube/navigate.ts +1 -1
- package/mcp-server/src/tools/youtube/playlist.ts +1 -1
- package/mcp-server/src/tools/youtube/schedule.ts +1 -1
- package/mcp-server/src/tools/youtube/source.ts +1 -1
- package/mcp-server/src/tools/youtube/upload.ts +4 -12
- package/mcp-server/src/tui.ts +24 -10
- package/mcp-server/src/version.ts +22 -0
- package/neural-interface/i18n/en.json +645 -57
- package/neural-interface/i18n/pt-BR.json +644 -56
- package/neural-interface/lib/account-usage.js +163 -0
- package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
- package/neural-interface/lib/agent-sandbox-setting.js +57 -0
- package/neural-interface/lib/assistant-api.js +274 -52
- package/neural-interface/lib/assistant-brains/claude.js +15 -2
- package/neural-interface/lib/assistant-brains/codex.js +3 -0
- package/neural-interface/lib/assistant-brains/opencode.js +17 -4
- package/neural-interface/lib/assistant-budget-planner.js +390 -0
- package/neural-interface/lib/assistant-budget-split.js +408 -0
- package/neural-interface/lib/assistant-budget.js +94 -95
- package/neural-interface/lib/assistant-config.js +62 -14
- package/neural-interface/lib/assistant-dispatch.js +432 -125
- package/neural-interface/lib/assistant-jev.js +26 -3
- package/neural-interface/lib/assistant-persona.js +68 -11
- package/neural-interface/lib/assistant-plan-permissions.js +8 -1
- package/neural-interface/lib/assistant-route-accounts.js +14 -0
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
- package/neural-interface/lib/assistant-route-gate.js +19 -3
- package/neural-interface/lib/assistant-router.js +373 -42
- package/neural-interface/lib/assistant-runtime.js +312 -48
- package/neural-interface/lib/assistant-user-writer.js +4 -2
- package/neural-interface/lib/augmented-path.js +317 -53
- package/neural-interface/lib/claude-accounts.js +342 -31
- package/neural-interface/lib/claude-agent-bridge.js +90 -3
- package/neural-interface/lib/claude-executable.js +6 -1
- package/neural-interface/lib/claude-model-catalog.js +3 -3
- package/neural-interface/lib/claude-panel-auth.js +221 -0
- package/neural-interface/lib/claude-profile-api-key.js +62 -0
- package/neural-interface/lib/cli-install-api.js +137 -0
- package/neural-interface/lib/cli-install.js +797 -0
- package/neural-interface/lib/cli-path.js +130 -0
- package/neural-interface/lib/cli-resolver.js +744 -0
- package/neural-interface/lib/cli-update-planner.js +143 -7
- package/neural-interface/lib/codex-account-auth.js +180 -0
- package/neural-interface/lib/codex-accounts.js +502 -0
- package/neural-interface/lib/codex-capabilities.js +2 -1
- package/neural-interface/lib/codex-compat-rpc.js +8 -2
- package/neural-interface/lib/codex-mcp-approvals.js +5 -1
- package/neural-interface/lib/codex-panel-auth.js +62 -0
- package/neural-interface/lib/codex-session-settings.js +1 -1
- package/neural-interface/lib/codex-settings-schema.js +122 -0
- package/neural-interface/lib/desktop/config.js +3 -0
- package/neural-interface/lib/exec-loop-command.js +3 -1
- package/neural-interface/lib/git-bash/bzip2.js +339 -0
- package/neural-interface/lib/git-bash/claude-settings.js +73 -0
- package/neural-interface/lib/git-bash/extract-worker.js +34 -0
- package/neural-interface/lib/git-bash/install.js +529 -0
- package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
- package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
- package/neural-interface/lib/git-bash/manager.js +268 -0
- package/neural-interface/lib/git-bash/pins.js +206 -0
- package/neural-interface/lib/git-bash/pins.json +34 -0
- package/neural-interface/lib/git-bash/resolver.js +194 -0
- package/neural-interface/lib/git-read.js +34 -2
- package/neural-interface/lib/install-details.js +163 -0
- package/neural-interface/lib/mcp-installer.js +14 -2
- package/neural-interface/lib/native-loop-providers.js +22 -4
- package/neural-interface/lib/native-loop-runtime.js +9 -4
- package/neural-interface/lib/os-path.js +319 -0
- package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +96 -0
- package/neural-interface/lib/pty-host/core.js +2 -1
- package/neural-interface/lib/pty-host/manager.js +27 -2
- package/neural-interface/lib/remote-policy.js +20 -11
- package/neural-interface/lib/session-indexer.js +3 -1
- package/neural-interface/lib/session-title-generator.js +6 -3
- package/neural-interface/lib/system-about.js +340 -0
- package/neural-interface/lib/system-activity.js +66 -0
- package/neural-interface/lib/terminal-env.js +11 -3
- package/neural-interface/lib/terminal-path.js +55 -0
- package/neural-interface/lib/virtual-socket.js +12 -1
- package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
- package/neural-interface/lib/whatsapp/bridge.js +78 -34
- package/neural-interface/lib/whatsapp/commands.js +13 -14
- package/neural-interface/lib/whatsapp/config.js +134 -20
- package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
- package/neural-interface/lib/whatsapp/host-core.js +168 -35
- package/neural-interface/lib/whatsapp/inbound.js +5 -3
- package/neural-interface/lib/whatsapp/local-file.js +524 -0
- package/neural-interface/lib/whatsapp/manager.js +92 -32
- package/neural-interface/lib/whatsapp/paths.js +11 -1
- package/neural-interface/lib/whatsapp/protocol.js +65 -5
- package/neural-interface/lib/whatsapp/redact.js +63 -0
- package/neural-interface/lib/whatsapp/service.js +343 -91
- package/neural-interface/lib/whatsapp/transcription.js +463 -0
- package/neural-interface/package-lock.json +2 -2
- package/neural-interface/package.json +1 -1
- package/neural-interface/public/index.html +2 -0
- package/neural-interface/public/index2d.html +2 -0
- package/neural-interface/public/offline.html +16 -1
- package/neural-interface/public/onboarding.html +96 -2
- package/neural-interface/public/shared/account-i18n.js +7 -0
- package/neural-interface/public/shared/account-menu.js +542 -0
- package/neural-interface/public/shared/account-usage.js +79 -0
- package/neural-interface/public/shared/account-view.js +336 -0
- package/neural-interface/public/shared/agent-runtime-options.js +28 -8
- package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
- package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
- package/neural-interface/public/shared/assistant/asst-api.js +39 -2
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +288 -32
- package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
- package/neural-interface/public/shared/assistant/asst-mascot.js +126 -7
- package/neural-interface/public/shared/assistant/asst-menu.js +219 -80
- package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
- package/neural-interface/public/shared/assistant/asst-panel.js +87 -16
- package/neural-interface/public/shared/assistant/asst-render.js +38 -7
- package/neural-interface/public/shared/assistant/asst-route.js +72 -14
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +45 -6
- package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
- package/neural-interface/public/shared/assistant/asst-state.js +1 -1
- package/neural-interface/public/shared/assistant/asst-styles.js +160 -29
- package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
- package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
- package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +49 -108
- package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +172 -111
- package/neural-interface/public/shared/cdx/cdx-tabs.js +264 -664
- package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
- package/neural-interface/public/shared/claude-account-view.js +3 -0
- package/neural-interface/public/shared/cli-install-view.js +392 -0
- package/neural-interface/public/shared/cli-status.js +282 -22
- package/neural-interface/public/shared/cp/cp-events.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +46 -0
- package/neural-interface/public/shared/desktop-bridge.js +39 -0
- package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
- package/neural-interface/public/shared/desktop-titlebar.js +153 -0
- package/neural-interface/public/shared/desktop-update-view.js +462 -0
- package/neural-interface/public/shared/editor/editor-panel.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +1 -1
- package/neural-interface/public/shared/git-bash-view.js +145 -0
- package/neural-interface/public/shared/html-shell.js +1 -0
- package/neural-interface/public/shared/i18n.js +19 -1
- package/neural-interface/public/shared/install-details-view.js +86 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +36 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +17 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +169 -2
- package/neural-interface/public/shared/pwa-install-page.js +3 -1
- package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
- package/neural-interface/public/shared/settings/settings-about.js +254 -0
- package/neural-interface/public/shared/settings/settings-ia.js +15 -0
- package/neural-interface/public/shared/showcase-privacy.js +490 -0
- package/neural-interface/public/shared/storage.js +30 -3
- package/neural-interface/public/shared/styles.css +281 -32
- package/neural-interface/public/shared/synabun-mascot.js +48 -2
- package/neural-interface/public/shared/ui-claude-panel.js +262 -217
- package/neural-interface/public/shared/ui-cli-banner.js +355 -0
- package/neural-interface/public/shared/ui-explorer.js +2 -0
- package/neural-interface/public/shared/ui-git-bash.js +124 -0
- package/neural-interface/public/shared/ui-judgments.js +10 -1
- package/neural-interface/public/shared/ui-loading.js +30 -6
- package/neural-interface/public/shared/ui-menubar.js +13 -3
- package/neural-interface/public/shared/ui-navbar.js +3 -1
- package/neural-interface/public/shared/ui-provider-auth.js +104 -0
- package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
- package/neural-interface/public/shared/ui-sessions.js +9 -3
- package/neural-interface/public/shared/ui-settings.js +55 -3
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
- package/neural-interface/public/shared/ui-sync.js +8 -0
- package/neural-interface/public/shared/ui-terminal.js +17 -0
- package/neural-interface/public/shared/ui-tool-updates.js +5 -0
- package/neural-interface/public/shared/ui-update.js +598 -7
- package/neural-interface/public/shared/ui-whatsapp.js +21 -6
- package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
- package/neural-interface/public/shared/worker-end.js +2 -0
- package/neural-interface/public/sw.js +1 -1
- package/neural-interface/public/variant/2d/main.js +10 -1
- package/neural-interface/public/variant/3d/main.js +10 -1
- package/neural-interface/scripts/rebuild-pty.js +14 -2
- package/neural-interface/server.js +1384 -679
- package/npm-shrinkwrap.json +4424 -0
- package/package.json +57 -2
- package/postinstall.js +61 -47
- package/preuninstall.js +8 -35
- package/setup.js +80 -47
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/schedule.md +1 -1
- package/updater.cmd +2 -2
- package/updater.mjs +97 -3
|
@@ -201,12 +201,14 @@ function handleSocketMessage(msg, tab, callbacks) {
|
|
|
201
201
|
case 'verification_canceled':
|
|
202
202
|
case 'account_info':
|
|
203
203
|
case 'account_login_started':
|
|
204
|
+
case 'account_login_state':
|
|
204
205
|
case 'account_logged_out':
|
|
205
206
|
case 'account_list':
|
|
206
207
|
case 'account_switched':
|
|
207
208
|
case 'account_add_started':
|
|
208
209
|
case 'account_removed':
|
|
209
210
|
case 'account_renamed':
|
|
211
|
+
case 'account_state':
|
|
210
212
|
case 'config_data':
|
|
211
213
|
case 'config_requirements':
|
|
212
214
|
case 'experimental_features':
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — the CLI banner of the side panels: what it says
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// What the Claude Code, Codex and OpenCode panels show above their transcript
|
|
6
|
+
// for one CLI: nothing while it is installed, "not installed" with a one-click
|
|
7
|
+
// Install (the vendor's own installer, run by the server: POST
|
|
8
|
+
// /api/cli/install/:tool) and the command to run by hand, the progress of an
|
|
9
|
+
// install, why an install failed, and "failed to start" with the error the CLI
|
|
10
|
+
// gave. One reading for all three panels, so they never disagree; the page
|
|
11
|
+
// side is ui-cli-banner.js, the data cli-status.js.
|
|
12
|
+
//
|
|
13
|
+
// No imports and no DOM: `node --test` loads this file as it is
|
|
14
|
+
// (tests/cli-install-view.test.mjs). CLI_INSTALL_COPY is the English of every
|
|
15
|
+
// sentence; `cliInstall.*` in i18n/en.json must equal it and i18n/pt-BR.json
|
|
16
|
+
// must have the same keys (the test checks both).
|
|
17
|
+
//
|
|
18
|
+
// A server from before the three states answers only `installed` (a version or
|
|
19
|
+
// null): null reads as "not installed", and no Install button is offered,
|
|
20
|
+
// because such a server has no install route.
|
|
21
|
+
|
|
22
|
+
export const CLI_INSTALL_COPY = Object.freeze({
|
|
23
|
+
titleMissing: '{label} is not installed',
|
|
24
|
+
titleBroken: '{label} failed to start',
|
|
25
|
+
titleInstalling: 'Installing {label}…',
|
|
26
|
+
titleFailed: '{label} could not be installed',
|
|
27
|
+
titleDone: '{label} is installed',
|
|
28
|
+
titlePath: 'Run {label} in your other terminals',
|
|
29
|
+
bodyPath: 'SynaBun terminals are ready. Add {dir} to your PATH for other terminals.',
|
|
30
|
+
addPath: 'Add to PATH',
|
|
31
|
+
addingPath: 'Adding…',
|
|
32
|
+
pathFailed: 'PATH could not be updated: {error}',
|
|
33
|
+
copyPathDiagnostics: 'Copy PATH diagnostics',
|
|
34
|
+
stepPath: 'Adding the CLI folder to your PATH…',
|
|
35
|
+
stepPathAdded: 'Added {dir} to your PATH',
|
|
36
|
+
bodyMissing: 'Install it with one click from {vendor}\'s official installer, or run:',
|
|
37
|
+
bodyMissingArchive: 'Install it with one click from {vendor}\'s official release, or run:',
|
|
38
|
+
bodyMissingManual: 'Install it with this command, then re-check:',
|
|
39
|
+
bodyBroken: '{label} was found at {path}, but it could not be started:',
|
|
40
|
+
bodyBrokenVersion: '{label} {version} was found at {path}, but it could not be started:',
|
|
41
|
+
bodyBrokenLatched: '{label} is installed, but it could not be started:',
|
|
42
|
+
bodyBrokenHint: 'Check the CLI path in Settings, then re-check.',
|
|
43
|
+
configuredFailed: 'The path set in Settings did not work: {error}',
|
|
44
|
+
bodyFailedManual: 'Run it yourself:',
|
|
45
|
+
doneNotOnPath: 'It is in {dir}. SynaBun finds it there; add that folder to your PATH to run it in a terminal.',
|
|
46
|
+
doneAddedToPath: 'Added {dir} to your PATH. New terminal windows and tabs pick it up.',
|
|
47
|
+
stepStart: 'Starting the official installer…',
|
|
48
|
+
stepDownload: 'Downloading…',
|
|
49
|
+
stepDownloadProgress: 'Downloading: {received} of {total} MB',
|
|
50
|
+
stepDownloadReceived: 'Downloading: {received} MB',
|
|
51
|
+
stepVerify: 'Checking the download…',
|
|
52
|
+
stepRun: 'Running the official installer…',
|
|
53
|
+
stepExtract: 'Unpacking…',
|
|
54
|
+
stepPlace: 'Putting it in place…',
|
|
55
|
+
stepCheck: 'Checking that it starts…',
|
|
56
|
+
errorOffline: 'The download server could not be reached. Check the connection and try again.',
|
|
57
|
+
errorHttp: 'The download server answered with an error. Try again in a moment.',
|
|
58
|
+
errorChecksum: 'The download did not match its published checksum, so it was removed and never run.',
|
|
59
|
+
errorInterrupted: 'The download stopped before it was complete. Nothing was kept. Try again.',
|
|
60
|
+
errorTimeout: 'The installer took too long and was stopped.',
|
|
61
|
+
errorInstallerFailed: 'The official installer stopped with an error.',
|
|
62
|
+
errorNotFound: 'The installer finished, but SynaBun does not find {label} afterwards.',
|
|
63
|
+
errorUnpack: 'The download could not be unpacked, so it was removed.',
|
|
64
|
+
errorDisk: 'The files could not be written. Check free space and permissions, then try again.',
|
|
65
|
+
errorCancelled: 'The installation was stopped.',
|
|
66
|
+
errorUnsupported: 'There is no one-click install for this system. Use the command below or the install guide.',
|
|
67
|
+
errorRefused: 'SynaBun refused the request. Install from SynaBun on this computer.',
|
|
68
|
+
errorConnection: 'The connection to SynaBun closed before the installation finished.',
|
|
69
|
+
errorUnknown: 'The installation did not finish.',
|
|
70
|
+
install: 'Install',
|
|
71
|
+
installing: 'Installing…',
|
|
72
|
+
retry: 'Try again',
|
|
73
|
+
guide: 'Install guide',
|
|
74
|
+
recheck: 'Re-check',
|
|
75
|
+
checking: 'Checking…',
|
|
76
|
+
copy: 'Copy',
|
|
77
|
+
copied: 'Copied',
|
|
78
|
+
dismiss: 'Dismiss',
|
|
79
|
+
logLabel: 'Installer output',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/** Who publishes each CLI: the {vendor} of "from {vendor}'s official installer". Names, not translated. */
|
|
83
|
+
export const CLI_VENDORS = Object.freeze({
|
|
84
|
+
'claude-code': 'Anthropic',
|
|
85
|
+
codex: 'OpenAI',
|
|
86
|
+
opencode: 'OpenCode',
|
|
87
|
+
gemini: 'Google',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/** The CLIs a server can install with one click (POST /api/cli/install/:tool). */
|
|
91
|
+
export const INSTALLABLE_CLIS = Object.freeze(['claude-code', 'codex', 'opencode']);
|
|
92
|
+
|
|
93
|
+
/** The steps an install reports (`{ type: 'step' }`), in the order they can come. */
|
|
94
|
+
export const INSTALL_STEPS = Object.freeze(['start', 'download', 'verify', 'run', 'extract', 'place', 'check', 'path']);
|
|
95
|
+
|
|
96
|
+
const STEP_COPY = Object.freeze({
|
|
97
|
+
start: 'stepStart', download: 'stepDownload', verify: 'stepVerify', run: 'stepRun',
|
|
98
|
+
extract: 'stepExtract', place: 'stepPlace', check: 'stepCheck', path: 'stepPath',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const ERROR_COPY = Object.freeze({
|
|
102
|
+
offline: 'errorOffline', http: 'errorHttp', checksum: 'errorChecksum', interrupted: 'errorInterrupted',
|
|
103
|
+
timeout: 'errorTimeout', 'installer-failed': 'errorInstallerFailed', 'not-found-after-install': 'errorNotFound',
|
|
104
|
+
unpack: 'errorUnpack', disk: 'errorDisk', cancelled: 'errorCancelled', unsupported: 'errorUnsupported',
|
|
105
|
+
refused: 'errorRefused', connection: 'errorConnection',
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
/** How many installer lines the banner keeps, and shows. */
|
|
109
|
+
export const INSTALL_LOG_KEEP = 200;
|
|
110
|
+
export const INSTALL_LOG_SHOWN = 6;
|
|
111
|
+
|
|
112
|
+
/** A CLI_INSTALL_COPY sentence with its `{params}` filled in: the translator when the page gives none. */
|
|
113
|
+
export function fillCliInstallCopy(key, params = {}) {
|
|
114
|
+
return String(CLI_INSTALL_COPY[key] ?? key).replace(/\{(\w+)\}/g, (whole, name) => (params[name] != null ? params[name] : whole));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let _translate = null;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The page's translator: `(key, params) => t('cliInstall.' + key, params)`. An answer that is empty, or the
|
|
121
|
+
* key itself (i18n's word for "no such string"), falls back to the English.
|
|
122
|
+
*/
|
|
123
|
+
export function setCliInstallTranslator(fn) {
|
|
124
|
+
_translate = typeof fn === 'function' ? fn : null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** A sentence in the page's language (the translator set above, else the English). */
|
|
128
|
+
export function cliInstallText(key, params = {}) {
|
|
129
|
+
if (_translate) {
|
|
130
|
+
try {
|
|
131
|
+
const text = _translate(key, params);
|
|
132
|
+
if (typeof text === 'string' && text && text !== key && text !== `cliInstall.${key}`) return text;
|
|
133
|
+
} catch { /* the English below */ }
|
|
134
|
+
}
|
|
135
|
+
return fillCliInstallCopy(key, params);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The state of one CLI in an answer of GET /api/system/tool-versions:
|
|
140
|
+
* 'installed' found, and it answered --version
|
|
141
|
+
* 'missing' nowhere to be found
|
|
142
|
+
* 'broken' found, but it would not start (info.error says why)
|
|
143
|
+
* 'unknown' no answer yet, or an answer that says nothing about this CLI
|
|
144
|
+
* An older server sends no `state`: its `installed` (a version or null) decides.
|
|
145
|
+
*/
|
|
146
|
+
export function cliStateOf(info) {
|
|
147
|
+
if (!info || typeof info !== 'object') return 'unknown';
|
|
148
|
+
if (info.state === 'installed' || info.state === 'missing' || info.state === 'broken' || info.state === 'unknown') return info.state;
|
|
149
|
+
return info.installed ? 'installed' : 'missing';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** The one-click install the server offers for this CLI on its system, or null. */
|
|
153
|
+
export function cliInstallOffer(info) {
|
|
154
|
+
const install = info && typeof info === 'object' && info.install && typeof info.install === 'object' ? info.install : null;
|
|
155
|
+
return install && install.available === true ? install : null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const line = (value, max = 400) => {
|
|
159
|
+
const text = String(value ?? '').replace(/\s+$/g, '');
|
|
160
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
161
|
+
};
|
|
162
|
+
const words = (value) => (typeof value === 'string' && value.trim() ? value.trim() : '');
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* One install as the page saw it, after one more event of the stream (or of the job list, when another window
|
|
166
|
+
* started it). Pure: a new object every time.
|
|
167
|
+
*
|
|
168
|
+
* @param {object | null} job the job so far (null: a new one)
|
|
169
|
+
* @param {object} event `{ type: 'start' | 'step' | 'progress' | 'log' | 'done', … }` as POST /api/cli/install/:tool sends
|
|
170
|
+
* @returns {{ phase: 'running' | 'failed' | 'done', step: string, received: number, total: number, log: string[],
|
|
171
|
+
* code: string | null, error: string | null, manualCommand: string | null, guideUrl: string | null,
|
|
172
|
+
* status: object | null, path: object | null, method: string | null, source: string | null }}
|
|
173
|
+
*/
|
|
174
|
+
export function reduceInstallJob(job, event) {
|
|
175
|
+
const next = job && typeof job === 'object'
|
|
176
|
+
? { ...job, log: Array.isArray(job.log) ? [...job.log] : [] }
|
|
177
|
+
: { phase: 'running', step: 'start', received: 0, total: 0, log: [], code: null, error: null, manualCommand: null, guideUrl: null, status: null, path: null, method: null, source: null };
|
|
178
|
+
const e = event && typeof event === 'object' ? event : {};
|
|
179
|
+
const push = (text) => {
|
|
180
|
+
for (const piece of String(text ?? '').split(/\r?\n/)) {
|
|
181
|
+
const kept = line(piece, 300);
|
|
182
|
+
if (kept.trim()) next.log.push(kept);
|
|
183
|
+
}
|
|
184
|
+
if (next.log.length > INSTALL_LOG_KEEP) next.log.splice(0, next.log.length - INSTALL_LOG_KEEP);
|
|
185
|
+
};
|
|
186
|
+
switch (e.type) {
|
|
187
|
+
case 'start':
|
|
188
|
+
next.phase = 'running';
|
|
189
|
+
next.step = 'start';
|
|
190
|
+
next.method = typeof e.method === 'string' ? e.method : next.method;
|
|
191
|
+
next.source = typeof e.source === 'string' ? e.source : next.source;
|
|
192
|
+
break;
|
|
193
|
+
case 'step':
|
|
194
|
+
if (INSTALL_STEPS.includes(e.step)) {
|
|
195
|
+
if (e.step !== next.step) { next.received = 0; next.total = 0; }
|
|
196
|
+
next.step = e.step;
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
case 'progress':
|
|
200
|
+
next.received = Math.max(0, Number(e.received) || 0);
|
|
201
|
+
next.total = Math.max(0, Number(e.total) || 0);
|
|
202
|
+
break;
|
|
203
|
+
case 'log':
|
|
204
|
+
push(e.line);
|
|
205
|
+
break;
|
|
206
|
+
case 'path':
|
|
207
|
+
if (e.added && words(e.dir)) push(cliInstallText('stepPathAdded', { dir: e.dir }));
|
|
208
|
+
break;
|
|
209
|
+
case 'done':
|
|
210
|
+
if (e.ok === true) {
|
|
211
|
+
next.phase = 'done';
|
|
212
|
+
next.status = e.status && typeof e.status === 'object' ? e.status : null;
|
|
213
|
+
next.path = e.path && typeof e.path === 'object' ? e.path : null;
|
|
214
|
+
next.code = null;
|
|
215
|
+
next.error = null;
|
|
216
|
+
} else {
|
|
217
|
+
next.phase = 'failed';
|
|
218
|
+
next.code = typeof e.code === 'string' && e.code ? e.code : 'internal';
|
|
219
|
+
next.error = words(e.error) || null;
|
|
220
|
+
next.manualCommand = words(e.manualCommand) || null;
|
|
221
|
+
next.guideUrl = words(e.guideUrl) || null;
|
|
222
|
+
if (Array.isArray(e.log) && !next.log.length) for (const entry of e.log) push(entry);
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
default:
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
return next;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const megabytes = (bytes) => (Math.max(0, Number(bytes) || 0) / (1024 * 1024)).toFixed(1);
|
|
232
|
+
|
|
233
|
+
/** The sentence for where an install is, and how far a download got (null when unknown). */
|
|
234
|
+
export function installStepView(job, { t = cliInstallText } = {}) {
|
|
235
|
+
const step = job?.step && STEP_COPY[job.step] ? job.step : 'start';
|
|
236
|
+
if (step === 'download') {
|
|
237
|
+
const total = Number(job?.total) || 0;
|
|
238
|
+
const received = Number(job?.received) || 0;
|
|
239
|
+
if (total > 0) {
|
|
240
|
+
const percent = Math.max(0, Math.min(100, Math.floor((Math.min(received, total) / total) * 100)));
|
|
241
|
+
return { step, text: t('stepDownloadProgress', { received: megabytes(Math.min(received, total)), total: megabytes(total) }), percent };
|
|
242
|
+
}
|
|
243
|
+
if (received > 0) return { step, text: t('stepDownloadReceived', { received: megabytes(received) }), percent: null };
|
|
244
|
+
}
|
|
245
|
+
return { step, text: t(STEP_COPY[step]), percent: null };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Why an install failed, as a sentence; the server's own words go in `detail` when they add something. */
|
|
249
|
+
export function installErrorView(job, { label = '', t = cliInstallText } = {}) {
|
|
250
|
+
const code = job?.code || 'internal';
|
|
251
|
+
const key = ERROR_COPY[code];
|
|
252
|
+
const raw = words(job?.error);
|
|
253
|
+
if (key) return { text: t(key, { label }), detail: raw || null };
|
|
254
|
+
return { text: t('errorUnknown'), detail: raw || null };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** The guide to link: the server's (an https address only), else the page's own. */
|
|
258
|
+
function safeUrl(...candidates) {
|
|
259
|
+
for (const value of candidates) {
|
|
260
|
+
if (typeof value === 'string' && /^https:\/\/[^\s"'<>]+$/i.test(value.trim())) return value.trim();
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* What the banner of one panel shows.
|
|
267
|
+
*
|
|
268
|
+
* @param {object} o
|
|
269
|
+
* @param {string} o.toolKey 'claude-code' | 'codex' | 'opencode'
|
|
270
|
+
* @param {string} [o.label] the CLI's name ("Claude Code")
|
|
271
|
+
* @param {object | null} [o.info] this CLI in the latest GET /api/system/tool-versions (null: no answer yet)
|
|
272
|
+
* @param {{ reason: string | null } | null} [o.forced] a start of the CLI failed in a session, before the
|
|
273
|
+
* server was asked again (the panels' latch): shown as "failed to start" until an answer says otherwise
|
|
274
|
+
* @param {object | null} [o.job] the install under way or just ended (reduceInstallJob)
|
|
275
|
+
* @param {string | null} [o.guideUrl] the page's install guide for this CLI
|
|
276
|
+
* @param {string} [o.installCommand] the command to install it by hand (cli-status getCliInstallCommand)
|
|
277
|
+
* @param {object} [options]
|
|
278
|
+
* @param {(key: string, params?: object) => string} [options.t] a key of CLI_INSTALL_COPY → its sentence
|
|
279
|
+
* @returns {{
|
|
280
|
+
* show: boolean, blocked: boolean,
|
|
281
|
+
* kind: 'hidden' | 'missing' | 'broken' | 'installing' | 'failed' | 'done',
|
|
282
|
+
* tone: 'warn' | 'err' | 'busy' | 'ok' | null, icon: string, live: 'polite' | 'assertive',
|
|
283
|
+
* title: string, text: string, command: string, error: string, note: string,
|
|
284
|
+
* progress: { step: string, text: string, percent: number | null } | null, log: string[],
|
|
285
|
+
* install: { label: string, disabled: boolean } | null, guide: string | null,
|
|
286
|
+
* recheck: boolean, dismiss: boolean,
|
|
287
|
+
* }}
|
|
288
|
+
* `blocked`: sending stays off (missing, broken, installing, failed). `install`: the Install button, when the
|
|
289
|
+
* server offers one for this system and the CLI really is missing.
|
|
290
|
+
*/
|
|
291
|
+
export function cliBannerView({ toolKey, label = '', info = null, forced = null, job = null, guideUrl = null, installCommand = '', addingPath = false, pathError = '' } = {}, { t = cliInstallText } = {}) {
|
|
292
|
+
const name = words(label) || String(toolKey || '');
|
|
293
|
+
const state = cliStateOf(info);
|
|
294
|
+
const guide = safeUrl(job?.guideUrl, info?.guideUrl, guideUrl);
|
|
295
|
+
const command = words(job?.manualCommand) || words(info?.installCommand) || words(installCommand);
|
|
296
|
+
const offer = cliInstallOffer(info);
|
|
297
|
+
const view = {
|
|
298
|
+
show: false, blocked: false, kind: 'hidden', tone: null, icon: '', live: 'polite',
|
|
299
|
+
title: '', text: '', command: '', error: '', note: '',
|
|
300
|
+
progress: null, log: [], install: null, guide, recheck: false, dismiss: false, addPath: null,
|
|
301
|
+
};
|
|
302
|
+
const lastLines = (log) => (Array.isArray(log) ? log.slice(-INSTALL_LOG_SHOWN) : []);
|
|
303
|
+
|
|
304
|
+
// An install under way: the banner stays, sending stays off, the steps and the installer's last lines show.
|
|
305
|
+
if (job?.phase === 'running') {
|
|
306
|
+
return Object.assign(view, {
|
|
307
|
+
show: true, blocked: true, kind: 'installing', tone: 'busy', icon: '…',
|
|
308
|
+
title: t('titleInstalling', { label: name }),
|
|
309
|
+
progress: installStepView(job, { t }),
|
|
310
|
+
log: lastLines(job.log),
|
|
311
|
+
install: { label: t('installing'), disabled: true },
|
|
312
|
+
recheck: false,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Installed: nothing to show, except, for a moment, where an install that just ended put it.
|
|
317
|
+
if (state === 'installed' && !forced) {
|
|
318
|
+
const where = job?.phase === 'done' && job.path && typeof job.path === 'object' ? job.path : null;
|
|
319
|
+
const dir = words(where?.dir);
|
|
320
|
+
const pathStatus = info?.pathStatus || where;
|
|
321
|
+
const missingPath = INSTALLABLE_CLIS.includes(toolKey) && pathStatus?.onPath === false && (pathStatus.canAdd !== false);
|
|
322
|
+
const addPath = missingPath ? { label: t(addingPath ? 'addingPath' : 'addPath'), disabled: addingPath } : null;
|
|
323
|
+
if (missingPath) return Object.assign(view, {
|
|
324
|
+
show: true, blocked: false, kind: 'path', tone: 'warn', icon: '!',
|
|
325
|
+
title: t('titlePath', { label: name }), text: t('bodyPath', { dir: pathStatus.dir }),
|
|
326
|
+
error: pathError ? t('pathFailed', { error: pathError }) : '',
|
|
327
|
+
addPath, recheck: true, guide: null,
|
|
328
|
+
});
|
|
329
|
+
if (where && dir && (where.onPath === false || where.added === true)) {
|
|
330
|
+
return Object.assign(view, {
|
|
331
|
+
show: true, blocked: false, kind: 'done', tone: 'ok', icon: '✓',
|
|
332
|
+
title: t('titleDone', { label: name }),
|
|
333
|
+
text: where.onPath === false ? t('doneNotOnPath', { label: name, dir }) : t('doneAddedToPath', { label: name, dir }),
|
|
334
|
+
note: words(where.warning), guide: null, dismiss: true,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return view;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Found, but it would not start: the error it gave, never an Install button (it is there already).
|
|
341
|
+
if (state === 'broken' || (forced && state !== 'missing')) {
|
|
342
|
+
const fromServer = state === 'broken';
|
|
343
|
+
const path = words(info?.binPath) || words(info?.realPath);
|
|
344
|
+
const version = words(info?.version) || words(info?.installed);
|
|
345
|
+
const error = fromServer ? words(info?.error) || words(forced?.reason) : words(forced?.reason) || words(info?.error);
|
|
346
|
+
let text;
|
|
347
|
+
if (path && version) text = t('bodyBrokenVersion', { label: name, version, path });
|
|
348
|
+
else if (path) text = t('bodyBroken', { label: name, path });
|
|
349
|
+
else text = t('bodyBrokenLatched', { label: name });
|
|
350
|
+
const configured = info?.configured && typeof info.configured === 'object' && info.configured.ok === false && words(info.configured.error)
|
|
351
|
+
? t('configuredFailed', { error: words(info.configured.error) })
|
|
352
|
+
: '';
|
|
353
|
+
return Object.assign(view, {
|
|
354
|
+
show: true, blocked: true, kind: 'broken', tone: 'err', icon: '!', live: 'assertive',
|
|
355
|
+
title: t('titleBroken', { label: name }),
|
|
356
|
+
text, error: line(error, 600),
|
|
357
|
+
note: configured || (error ? '' : t('bodyBrokenHint')),
|
|
358
|
+
recheck: true,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (state === 'missing') {
|
|
363
|
+
// The last install failed: why, what the installer said last, and the command to run by hand.
|
|
364
|
+
if (job?.phase === 'failed') {
|
|
365
|
+
const why = installErrorView(job, { label: name, t });
|
|
366
|
+
return Object.assign(view, {
|
|
367
|
+
show: true, blocked: true, kind: 'failed', tone: 'err', icon: '!', live: 'assertive',
|
|
368
|
+
title: t('titleFailed', { label: name }),
|
|
369
|
+
text: why.text,
|
|
370
|
+
error: why.detail ? line(why.detail, 600) : '',
|
|
371
|
+
note: command ? t('bodyFailedManual') : '',
|
|
372
|
+
command,
|
|
373
|
+
log: lastLines(job.log),
|
|
374
|
+
install: offer && job.code !== 'unsupported' ? { label: t('retry'), disabled: false } : null,
|
|
375
|
+
recheck: true,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
const text = offer
|
|
379
|
+
? t(offer.method === 'archive' ? 'bodyMissingArchive' : 'bodyMissing', { vendor: CLI_VENDORS[toolKey] || name, label: name })
|
|
380
|
+
: t('bodyMissingManual');
|
|
381
|
+
return Object.assign(view, {
|
|
382
|
+
show: true, blocked: true, kind: 'missing', tone: 'warn', icon: '!',
|
|
383
|
+
title: t('titleMissing', { label: name }),
|
|
384
|
+
text, command,
|
|
385
|
+
install: offer ? { label: t('install'), disabled: false } : null,
|
|
386
|
+
recheck: true,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// No answer yet: nothing to say, and nothing is held back (a start that fails says so itself).
|
|
391
|
+
return view;
|
|
392
|
+
}
|