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
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════
|
|
2
|
-
// SynaBun — Assistant
|
|
2
|
+
// SynaBun — Assistant budget (the one setting · list prices · Codex usage)
|
|
3
3
|
// ═══════════════════════════════════════════
|
|
4
4
|
//
|
|
5
|
-
//
|
|
5
|
+
// One setting for every Assistant session: { unlimited, amountUsd, version }.
|
|
6
|
+
// It lives in assistant-config.json under `budget` and is read live. Every new
|
|
7
|
+
// session starts with it; a change applies to the open sessions at once.
|
|
6
8
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
9
|
+
// unlimited false the session may spend `amountUsd` (brain + every run, at
|
|
10
|
+
// list price). The warning is fixed at 80 %; at 100 % the
|
|
11
|
+
// session stops. assistant-budget-split.js divides what is
|
|
12
|
+
// left across the providers (Jev or a fixed heuristic).
|
|
13
|
+
// unlimited true No limit: no caps, no shares, no Jev call. Spend is still
|
|
14
|
+
// metered.
|
|
12
15
|
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
16
|
+
// Older files kept five caps in `limits` (default/largest per run, session
|
|
17
|
+
// warning, session hard cap) and `brains.claude.maxBudgetUsd`. They are read
|
|
18
|
+
// once (migrateBudget): the session hard cap becomes the amount, the rest is
|
|
19
|
+
// dropped.
|
|
17
20
|
//
|
|
18
21
|
// Prices: Claude and OpenCode report what a turn cost. Codex reports tokens
|
|
19
22
|
// only, so its runs are priced from the list-price table (assistant-pricing.js,
|
|
@@ -28,17 +31,15 @@ import { homedir } from 'node:os';
|
|
|
28
31
|
import { join } from 'node:path';
|
|
29
32
|
import { PRICING_SOURCES, PRICING_VERIFIED, listPrice, pricingRows } from './assistant-pricing.js';
|
|
30
33
|
|
|
31
|
-
export const BUDGET_FIELDS = Object.freeze(['defaultRunUsd', 'maxRunUsd', 'sessionWarnUsd', 'sessionHardUsd', 'brainUsd']);
|
|
32
|
-
export const BUDGET_DEFAULTS = Object.freeze({ defaultRunUsd: 5, maxRunUsd: 25, sessionWarnUsd: 8, sessionHardUsd: 25, brainUsd: 10 });
|
|
33
34
|
export const BUDGET_MIN_USD = 0.1;
|
|
34
35
|
export const BUDGET_MAX_USD = 1000;
|
|
35
|
-
export const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
export const BUDGET_DEFAULT_USD = 25;
|
|
37
|
+
/** The one warning comes at this share of the budget. */
|
|
38
|
+
export const BUDGET_WARN_RATIO = 0.8;
|
|
39
|
+
export const BUDGET_FIELDS = Object.freeze(['unlimited', 'amountUsd']);
|
|
40
|
+
export const BUDGET_DEFAULTS = Object.freeze({ unlimited: false, amountUsd: BUDGET_DEFAULT_USD });
|
|
41
|
+
/** The keys of the old five-cap budget (`limits.*`, `brains.claude.maxBudgetUsd`), dropped by the migration. */
|
|
42
|
+
export const LEGACY_LIMIT_KEYS = Object.freeze(['defaultBudgetUsd', 'maxBudgetUsd', 'sessionWarnUsd', 'sessionSoftBudgetUsd', 'sessionHardBudgetUsd', 'budgetVersion', 'budgetUpdatedAt']);
|
|
42
43
|
|
|
43
44
|
function num(value) {
|
|
44
45
|
if (value === null || value === undefined || value === '' || typeof value === 'boolean') return null;
|
|
@@ -47,6 +48,8 @@ function num(value) {
|
|
|
47
48
|
}
|
|
48
49
|
function obj(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : {}; }
|
|
49
50
|
export function roundUsd(value) { return Math.round(Number(value) * 100) / 100; }
|
|
51
|
+
/** Whole cents, never more than `value` (a budget never rounds up). */
|
|
52
|
+
export function floorCents(value) { return Math.max(0, Math.floor(Number(value) * 100 + 1e-6)); }
|
|
50
53
|
|
|
51
54
|
function budgetError(field, message) {
|
|
52
55
|
const error = new Error(message);
|
|
@@ -55,109 +58,105 @@ function budgetError(field, message) {
|
|
|
55
58
|
error.status = 400;
|
|
56
59
|
return error;
|
|
57
60
|
}
|
|
61
|
+
const inRange = (n) => n !== null && n >= BUDGET_MIN_USD && n <= BUDGET_MAX_USD;
|
|
58
62
|
|
|
59
|
-
/**
|
|
60
|
-
export function
|
|
63
|
+
/** Whether a config file still carries the old five-cap budget and no `budget` of its own. */
|
|
64
|
+
export function needsBudgetMigration(raw = {}) {
|
|
65
|
+
if (raw?.budget && typeof raw.budget === 'object' && !Array.isArray(raw.budget)) return false;
|
|
61
66
|
const limits = obj(raw?.limits);
|
|
62
|
-
|
|
63
|
-
const warn = num(limits.sessionWarnUsd);
|
|
64
|
-
return {
|
|
65
|
-
defaultRunUsd: num(limits.defaultBudgetUsd),
|
|
66
|
-
maxRunUsd: num(limits.maxBudgetUsd),
|
|
67
|
-
sessionWarnUsd: warn ?? (soft !== null ? roundUsd(soft * 0.8) : null),
|
|
68
|
-
sessionHardUsd: num(limits.sessionHardBudgetUsd),
|
|
69
|
-
brainUsd: num(obj(obj(raw?.brains).claude).maxBudgetUsd),
|
|
70
|
-
};
|
|
67
|
+
return LEGACY_LIMIT_KEYS.some((key) => Object.hasOwn(limits, key)) || Object.hasOwn(obj(obj(raw?.brains).claude), 'maxBudgetUsd');
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
/**
|
|
74
|
-
* The
|
|
75
|
-
*
|
|
71
|
+
* The budget a config file holds: its `budget` when it has one, else what an
|
|
72
|
+
* older file says (the saved session hard cap, else the default).
|
|
73
|
+
* → { unlimited, amountUsd, version, updatedAt, source: 'saved' | 'migrated' | 'default' }
|
|
76
74
|
*/
|
|
77
|
-
export function
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
export function effectiveBudget(raw = {}) {
|
|
76
|
+
const stored = raw?.budget && typeof raw.budget === 'object' && !Array.isArray(raw.budget) ? raw.budget : null;
|
|
77
|
+
if (stored) {
|
|
78
|
+
const amount = num(stored.amountUsd);
|
|
79
|
+
return {
|
|
80
|
+
unlimited: stored.unlimited === true,
|
|
81
|
+
amountUsd: inRange(amount) ? roundUsd(amount) : BUDGET_DEFAULT_USD,
|
|
82
|
+
version: Math.max(0, Math.floor(num(stored.version) || 0)),
|
|
83
|
+
updatedAt: typeof stored.updatedAt === 'string' ? stored.updatedAt : null,
|
|
84
|
+
source: 'saved',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const limits = obj(raw?.limits);
|
|
88
|
+
const hard = num(limits.sessionHardBudgetUsd);
|
|
89
|
+
const migrated = needsBudgetMigration(raw);
|
|
90
|
+
return {
|
|
91
|
+
unlimited: false,
|
|
92
|
+
// The saved session hard cap is the amount (a hand edit outside the bounds is brought inside them).
|
|
93
|
+
amountUsd: hard !== null && hard > 0 ? roundUsd(Math.min(BUDGET_MAX_USD, Math.max(BUDGET_MIN_USD, hard))) : BUDGET_DEFAULT_USD,
|
|
94
|
+
version: Math.max(0, Math.floor(num(limits.budgetVersion) || 0)),
|
|
95
|
+
updatedAt: typeof limits.budgetUpdatedAt === 'string' ? limits.budgetUpdatedAt : null,
|
|
96
|
+
source: migrated ? 'migrated' : 'default',
|
|
97
|
+
};
|
|
83
98
|
}
|
|
84
99
|
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const sources = {};
|
|
93
|
-
for (const field of BUDGET_FIELDS) {
|
|
94
|
-
const value = stored[field];
|
|
95
|
-
const ok = value !== null && value >= BUDGET_MIN_USD && value <= BUDGET_MAX_USD;
|
|
96
|
-
out[field] = ok ? roundUsd(value) : BUDGET_DEFAULTS[field];
|
|
97
|
-
sources[field] = !ok ? 'default' : (field === 'sessionWarnUsd' && num(obj(raw?.limits).sessionWarnUsd) === null ? 'legacy' : 'saved');
|
|
100
|
+
/** A config object without the old five-cap keys (every other key kept). */
|
|
101
|
+
export function withoutLegacyBudget(raw = {}) {
|
|
102
|
+
const base = { ...obj(raw) };
|
|
103
|
+
if (base.limits && typeof base.limits === 'object') {
|
|
104
|
+
const limits = { ...base.limits };
|
|
105
|
+
for (const key of LEGACY_LIMIT_KEYS) delete limits[key];
|
|
106
|
+
base.limits = limits;
|
|
98
107
|
}
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
repairs.push(broken.field);
|
|
104
|
-
if (broken.field === 'maxRunUsd') out.maxRunUsd = out.sessionHardUsd;
|
|
105
|
-
else if (broken.field === 'defaultRunUsd') out.defaultRunUsd = out.maxRunUsd;
|
|
106
|
-
else if (broken.field === 'sessionWarnUsd') out.sessionWarnUsd = roundUsd(out.sessionHardUsd * 0.8);
|
|
107
|
-
else if (broken.field === 'brainUsd') out.brainUsd = out.sessionHardUsd;
|
|
108
|
+
const brains = obj(base.brains);
|
|
109
|
+
if (brains.claude && typeof brains.claude === 'object' && Object.hasOwn(brains.claude, 'maxBudgetUsd')) {
|
|
110
|
+
const { maxBudgetUsd: _cap, ...claude } = brains.claude;
|
|
111
|
+
base.brains = { ...brains, claude };
|
|
108
112
|
}
|
|
109
|
-
return
|
|
113
|
+
return base;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
/**
|
|
113
|
-
* Validate a patch
|
|
114
|
-
*
|
|
115
|
-
*
|
|
117
|
+
* Validate a patch ({ unlimited?, amountUsd? }) against the current budget and
|
|
118
|
+
* return the full next one. Throws BUDGET_INVALID (status 400, `field`) on an
|
|
119
|
+
* unknown field, a bad value or an empty patch. Amounts are kept in cents.
|
|
116
120
|
*/
|
|
117
121
|
export function validateBudgetPatch(patch = {}, current = BUDGET_DEFAULTS) {
|
|
118
122
|
if (!patch || typeof patch !== 'object' || Array.isArray(patch)) throw budgetError('budget', 'budget must be an object');
|
|
119
|
-
const next = {};
|
|
120
|
-
|
|
123
|
+
const next = { unlimited: current?.unlimited === true, amountUsd: inRange(num(current?.amountUsd)) ? roundUsd(current.amountUsd) : BUDGET_DEFAULT_USD };
|
|
124
|
+
let changed = 0;
|
|
121
125
|
for (const [field, value] of Object.entries(patch)) {
|
|
122
|
-
if (!BUDGET_FIELDS.includes(field)) throw budgetError(field, `Unknown budget field "${field}"
|
|
123
|
-
|
|
126
|
+
if (!BUDGET_FIELDS.includes(field)) throw budgetError(field, `Unknown budget field "${field}". Send unlimited and/or amountUsd.`);
|
|
127
|
+
changed += 1;
|
|
128
|
+
if (field === 'unlimited') {
|
|
129
|
+
if (typeof value !== 'boolean') throw budgetError('unlimited', 'unlimited must be true or false');
|
|
130
|
+
next.unlimited = value;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
124
133
|
const n = typeof value === 'number' || (typeof value === 'string' && value.trim() !== '') ? Number(value) : NaN;
|
|
125
|
-
if (!Number.isFinite(n)) throw budgetError(
|
|
126
|
-
if (n < BUDGET_MIN_USD || n > BUDGET_MAX_USD) throw budgetError(
|
|
127
|
-
next
|
|
134
|
+
if (!Number.isFinite(n)) throw budgetError('amountUsd', 'The budget must be an amount in US dollars');
|
|
135
|
+
if (n < BUDGET_MIN_USD || n > BUDGET_MAX_USD) throw budgetError('amountUsd', `The budget must be between $${BUDGET_MIN_USD.toFixed(2)} and $${BUDGET_MAX_USD}`);
|
|
136
|
+
next.amountUsd = roundUsd(n);
|
|
128
137
|
}
|
|
129
|
-
|
|
130
|
-
if (broken) throw budgetError(broken.field, broken.message);
|
|
138
|
+
if (!changed) throw budgetError('budget', 'Nothing to change: send unlimited and/or amountUsd');
|
|
131
139
|
return next;
|
|
132
140
|
}
|
|
133
141
|
|
|
134
|
-
/** A config object with `budget` written
|
|
142
|
+
/** A config object with `budget` written (the old caps dropped, every other key kept). */
|
|
135
143
|
export function writeBudgetInto(raw = {}, budget, { version = 0, at = new Date().toISOString() } = {}) {
|
|
136
|
-
const base = obj(raw);
|
|
137
|
-
const brains = obj(base.brains);
|
|
138
144
|
return {
|
|
139
|
-
...
|
|
140
|
-
|
|
141
|
-
...obj(base.limits),
|
|
142
|
-
defaultBudgetUsd: budget.defaultRunUsd,
|
|
143
|
-
maxBudgetUsd: budget.maxRunUsd,
|
|
144
|
-
sessionWarnUsd: budget.sessionWarnUsd,
|
|
145
|
-
sessionHardBudgetUsd: budget.sessionHardUsd,
|
|
146
|
-
budgetVersion: version,
|
|
147
|
-
budgetUpdatedAt: at,
|
|
148
|
-
},
|
|
149
|
-
brains: { ...brains, claude: { ...obj(brains.claude), maxBudgetUsd: budget.brainUsd } },
|
|
145
|
+
...withoutLegacyBudget(raw),
|
|
146
|
+
budget: { unlimited: budget.unlimited === true, amountUsd: roundUsd(budget.amountUsd), version, updatedAt: at },
|
|
150
147
|
};
|
|
151
148
|
}
|
|
152
149
|
|
|
153
|
-
/**
|
|
154
|
-
export function
|
|
150
|
+
/** What the Assistant's budget limits at `spentUsd` (null amounts under No limit). */
|
|
151
|
+
export function budgetLimitsAt(budget, spentUsd = 0) {
|
|
152
|
+
if (!budget || budget.unlimited) return { unlimited: true, amountUsd: null, warnAtUsd: null, leftUsd: null, warned: false, exceeded: false };
|
|
153
|
+
const amount = Number(budget.amountUsd) || 0;
|
|
154
|
+
const spent = Math.max(0, Number(spentUsd) || 0);
|
|
155
|
+
const warnAt = roundUsd(amount * BUDGET_WARN_RATIO);
|
|
155
156
|
return {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
sessionHardBudgetUsd: budget.sessionHardUsd,
|
|
160
|
-
brainBudgetUsd: budget.brainUsd,
|
|
157
|
+
unlimited: false, amountUsd: amount, warnAtUsd: warnAt,
|
|
158
|
+
leftUsd: Math.max(0, Number((amount - spent).toFixed(8))),
|
|
159
|
+
warned: spent >= warnAt, exceeded: spent >= amount,
|
|
161
160
|
};
|
|
162
161
|
}
|
|
163
162
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// The assistant's user-editable knobs live in one JSON file: `defaultBrain`,
|
|
6
6
|
// `persona`, `limits`, `memory` (read by the other assistant modules),
|
|
7
|
-
// `routing`,
|
|
7
|
+
// `routing`, `budget` (owned here; see assistant-budget.js) and
|
|
8
8
|
// `userContext` (the three layers of assistant-user-context.js). Knobs
|
|
9
9
|
// are data: the file is re-read when its mtime changes, so a PUT from the
|
|
10
10
|
// routes or budget editor, or a hand edit, applies without a restart. Writes
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
|
|
14
14
|
import { dirname } from 'node:path';
|
|
15
|
-
import { effectiveBudget, validateBudgetPatch, writeBudgetInto } from './assistant-budget.js';
|
|
15
|
+
import { effectiveBudget, needsBudgetMigration, validateBudgetPatch, writeBudgetInto } from './assistant-budget.js';
|
|
16
16
|
import { normalizeUserContext, USER_CONTEXT_DEFAULTS } from './assistant-user-context-budgets.js';
|
|
17
17
|
|
|
18
18
|
export const ROUTE_MODES = ['always-ask', 'ask-unsure', 'never'];
|
|
@@ -55,6 +55,10 @@ function cleanTarget(field, target) {
|
|
|
55
55
|
const provider = String(target.provider || '').trim();
|
|
56
56
|
if (!ROUTE_PROVIDERS.includes(provider)) throw routingError(`${field}.provider`, `routing.${field}.provider must be one of ${ROUTE_PROVIDERS.join(', ')}`);
|
|
57
57
|
const out = { kind, provider, model: target.model ? String(target.model).slice(0, 200) : null, effort: target.effort ? String(target.effort).slice(0, 40) : null };
|
|
58
|
+
if (target.accountId != null && target.accountId !== '') {
|
|
59
|
+
if (typeof target.accountId !== 'string' || !/^[a-z0-9-]{1,64}$/.test(target.accountId)) throw routingError(`${field}.accountId`, 'Invalid route account id');
|
|
60
|
+
if (provider !== 'opencode') out.accountId = target.accountId;
|
|
61
|
+
}
|
|
58
62
|
if (target.label) out.label = String(target.label).slice(0, 120);
|
|
59
63
|
if (target.at) out.at = String(target.at).slice(0, 40);
|
|
60
64
|
if (target.by) out.by = String(target.by).slice(0, 20);
|
|
@@ -210,30 +214,46 @@ export function createAssistantConfigStore({ path, log = () => {}, now = Date.no
|
|
|
210
214
|
return { routing: effectiveRouting(nextRouting), version: nextRouting.version };
|
|
211
215
|
}
|
|
212
216
|
|
|
213
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* The budget every session runs under (assistant-budget.js effectiveBudget):
|
|
219
|
+
* { unlimited, amountUsd, version, updatedAt, source }. A file that still
|
|
220
|
+
* holds the old five caps is migrated the first time it is read here: the
|
|
221
|
+
* session hard cap becomes the amount (else the default), the old keys go,
|
|
222
|
+
* and the version moves on so a client holding the old shape gets a 409.
|
|
223
|
+
* A file that cannot be written keeps working on the migrated values.
|
|
224
|
+
*/
|
|
214
225
|
function budget() {
|
|
215
226
|
const raw = read();
|
|
216
|
-
|
|
227
|
+
if (!needsBudgetMigration(raw)) return effectiveBudget(raw);
|
|
228
|
+
const migrated = effectiveBudget(raw);
|
|
229
|
+
try {
|
|
230
|
+
const version = migrated.version + 1;
|
|
231
|
+
write(writeBudgetInto(raw, migrated, { version, at: new Date(now()).toISOString() }));
|
|
232
|
+
log('config:budget-migrated', `amountUsd ${migrated.amountUsd} (from the session hard cap) · version ${version}`);
|
|
233
|
+
return { ...effectiveBudget(read()), source: 'migrated' };
|
|
234
|
+
} catch (error) {
|
|
235
|
+
log('config:budget-migration-failed', error?.message || String(error));
|
|
236
|
+
return migrated;
|
|
237
|
+
}
|
|
217
238
|
}
|
|
218
|
-
function budgetVersion() { return
|
|
239
|
+
function budgetVersion() { return budget().version; }
|
|
219
240
|
|
|
220
241
|
/**
|
|
221
|
-
* Validate and save budget
|
|
242
|
+
* Validate and save the budget (a partial patch: unlimited, amountUsd).
|
|
222
243
|
* `expectedVersion` (when given) must match. Readers pick it up on their next
|
|
223
|
-
* read: the dispatcher per dispatch / turn, the runtime per brain turn.
|
|
244
|
+
* read: the dispatcher per dispatch / turn / metered step, the runtime per brain turn.
|
|
224
245
|
*/
|
|
225
246
|
function patchBudget(patch = {}, { expectedVersion = null } = {}) {
|
|
226
|
-
const current =
|
|
227
|
-
|
|
228
|
-
if (expectedVersion !== null && expectedVersion !== undefined && Number(expectedVersion) !== currentVersion) {
|
|
247
|
+
const current = budget();
|
|
248
|
+
if (expectedVersion !== null && expectedVersion !== undefined && Number(expectedVersion) !== current.version) {
|
|
229
249
|
const error = new Error('Budget settings changed elsewhere; reload and try again.');
|
|
230
250
|
error.code = 'VERSION_CONFLICT';
|
|
231
251
|
error.status = 409;
|
|
232
|
-
error.version =
|
|
252
|
+
error.version = current.version;
|
|
233
253
|
throw error;
|
|
234
254
|
}
|
|
235
|
-
const next = validateBudgetPatch(patch,
|
|
236
|
-
write(writeBudgetInto(
|
|
255
|
+
const next = validateBudgetPatch(patch, current);
|
|
256
|
+
write(writeBudgetInto(read(), next, { version: current.version + 1, at: new Date(now()).toISOString() }));
|
|
237
257
|
return budget();
|
|
238
258
|
}
|
|
239
259
|
|
|
@@ -253,9 +273,37 @@ export function createAssistantConfigStore({ path, log = () => {}, now = Date.no
|
|
|
253
273
|
return userContext();
|
|
254
274
|
}
|
|
255
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Defaults for dispatched workers, read live. `claudeAccount` / `codexAccount`:
|
|
278
|
+
* the account a Claude Code / Codex worker runs under when its dispatch names
|
|
279
|
+
* none (null = Default).
|
|
280
|
+
*/
|
|
281
|
+
const WORKER_ACCOUNT_KEYS = { claudeAccount: 'Claude', codexAccount: 'Codex' };
|
|
282
|
+
const accountIdOf = (id) => (typeof id === 'string' && /^[a-z0-9-]{1,64}$/.test(id) && id !== 'default' ? id : null);
|
|
283
|
+
function workers() {
|
|
284
|
+
const raw = read().workers;
|
|
285
|
+
const stored = raw && typeof raw === 'object' ? raw : {};
|
|
286
|
+
return { claudeAccount: accountIdOf(stored.claudeAccount), codexAccount: accountIdOf(stored.codexAccount) };
|
|
287
|
+
}
|
|
288
|
+
/** Save worker defaults (a partial patch; null or 'default' for an account is Default). Unknown keys stay. */
|
|
289
|
+
function patchWorkers(patch = {}) {
|
|
290
|
+
const current = read();
|
|
291
|
+
const stored = current.workers && typeof current.workers === 'object' && !Array.isArray(current.workers) ? current.workers : {};
|
|
292
|
+
const next = { ...stored };
|
|
293
|
+
for (const [key, provider] of Object.entries(WORKER_ACCOUNT_KEYS)) {
|
|
294
|
+
if (!Object.prototype.hasOwnProperty.call(patch || {}, key)) continue;
|
|
295
|
+
const id = patch[key];
|
|
296
|
+
if (id === null || id === '' || id === 'default') delete next[key];
|
|
297
|
+
else if (typeof id === 'string' && /^[a-z0-9-]{1,64}$/.test(id)) next[key] = id;
|
|
298
|
+
else throw Object.assign(new Error(`That is not a ${provider} account id.`), { code: 'INVALID_ACCOUNT', status: 400 });
|
|
299
|
+
}
|
|
300
|
+
write({ ...current, workers: { ...next, updatedAt: new Date(now()).toISOString() } });
|
|
301
|
+
return workers();
|
|
302
|
+
}
|
|
303
|
+
|
|
256
304
|
function onChange(fn) { listeners.add(fn); return () => listeners.delete(fn); }
|
|
257
305
|
|
|
258
|
-
return { read, routing, version, patchRouting, setPreference, budget, budgetVersion, patchBudget, userContext, patchUserContext, onChange, path };
|
|
306
|
+
return { read, routing, version, patchRouting, setPreference, budget, budgetVersion, patchBudget, userContext, patchUserContext, workers, patchWorkers, onChange, path };
|
|
259
307
|
}
|
|
260
308
|
|
|
261
309
|
export function fileExists(path) { try { return existsSync(path); } catch { return false; } }
|