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
|
@@ -33,7 +33,7 @@ import { execSync } from 'node:child_process';
|
|
|
33
33
|
import { dirname, join } from 'node:path';
|
|
34
34
|
import { fileURLToPath } from 'node:url';
|
|
35
35
|
import { homedir } from 'node:os';
|
|
36
|
-
import { getHookFeatures, detectProject,
|
|
36
|
+
import { getHookFeatures, detectProject, cleanupStaleLoops, cleanupStalePendingRemember, cleanupStaleFiles, appendCapped, DATA_DIR, isTemporaryChat, niUrl, greetingSurface, greetingOff, GREETING_NOTE_DIR } from './shared.mjs';
|
|
37
37
|
|
|
38
38
|
// CC updates (especially when installer runs as root) can wipe ~/.claude.json
|
|
39
39
|
// or strip mcpServers.SynaBun, leaving the side panel/CLI with MCP disabled
|
|
@@ -228,9 +228,6 @@ async function main() {
|
|
|
228
228
|
} catch { /* ok */ }
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
// Ensure all registered projects have their default category trees
|
|
232
|
-
try { withStateLock(() => ensureProjectCategories()); } catch { /* non-critical */ }
|
|
233
|
-
|
|
234
231
|
// Self-heal SynaBun MCP registration (CC updates can strip it)
|
|
235
232
|
healSynaBunMcp();
|
|
236
233
|
|
|
@@ -1031,15 +1031,21 @@ export function buildCategoryTree(categories) {
|
|
|
1031
1031
|
}
|
|
1032
1032
|
|
|
1033
1033
|
// --- Auto-category creation ---
|
|
1034
|
+
// A fresh install has no categories. The only ones made without being asked are a
|
|
1035
|
+
// project's defaults (when the project is added) and a feature's own category (the
|
|
1036
|
+
// first time that feature saves into it).
|
|
1034
1037
|
|
|
1035
1038
|
/**
|
|
1036
|
-
*
|
|
1039
|
+
* Categories features save into by name, created on first save, never earlier.
|
|
1040
|
+
* The hooks' and the Neural Interface's share of mcp-server/src/services/categories.ts
|
|
1041
|
+
* FEATURE_CATEGORIES: keep the descriptions the same.
|
|
1037
1042
|
*/
|
|
1038
|
-
const
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
+
export const FEATURE_CATEGORIES = {
|
|
1044
|
+
conversations: { description: 'Indexed conversation sessions with compacted summaries for cross-session recall: session metadata (date, branch, session id) and topic summaries, so past conversations can be found by asking for them.' },
|
|
1045
|
+
'communication-style': { description: 'How the user communicates and works: patterns in how they give instructions, correct, decide and signal frustration, and their stated preferences.' },
|
|
1046
|
+
plans: { description: 'Implementation plans stored after plan mode approval, one child category per project.', is_parent: true },
|
|
1047
|
+
uncategorized: { description: 'Fallback for memories stored without a category.' },
|
|
1048
|
+
};
|
|
1043
1049
|
|
|
1044
1050
|
/**
|
|
1045
1051
|
* Default child categories for every registered project.
|
|
@@ -1052,90 +1058,118 @@ const PROJECT_CHILDREN = [
|
|
|
1052
1058
|
{ suffix: 'config', description: 'Configuration, deployment, environment, and infrastructure' },
|
|
1053
1059
|
];
|
|
1054
1060
|
|
|
1061
|
+
/** A project's parent category name: the label normalized, cut to 16 so children stay within 30 chars (16 + 1 + 12 = 29). */
|
|
1062
|
+
export function projectCategoryLabel(label) {
|
|
1063
|
+
let name = normalizeLabel(String(label || ''));
|
|
1064
|
+
if (name.length > 16) name = name.slice(0, 16).replace(/-$/, '');
|
|
1065
|
+
return name;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1055
1068
|
/**
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1069
|
+
* Add the categories in `defs` that are missing, in order (parents first), to the
|
|
1070
|
+
* MCP server's categories file (no connection suffix), whose watcher refreshes the
|
|
1071
|
+
* tool schemas. A missing file is an empty list; an unreadable one is left alone.
|
|
1072
|
+
* `mutate(categories, now)` may push more entries and return the names it created.
|
|
1058
1073
|
*
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
1061
|
-
*
|
|
1062
|
-
* Idempotent: only adds missing categories, never modifies or removes existing ones.
|
|
1074
|
+
* Idempotent: only adds missing categories, never modifies or removes existing ones
|
|
1075
|
+
* (a project parent that exists without the flag is marked `is_parent` so its
|
|
1076
|
+
* children can sit under it).
|
|
1063
1077
|
*
|
|
1064
1078
|
* @returns {{ created: string[], total: number }}
|
|
1065
1079
|
*/
|
|
1066
|
-
|
|
1067
|
-
const projects = loadRegisteredProjects();
|
|
1080
|
+
function addMissingCategories(mutate) {
|
|
1068
1081
|
const catPath = getMcpCategoriesPath();
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
data
|
|
1073
|
-
} catch {
|
|
1074
|
-
data = { version: 1, categories: [] };
|
|
1082
|
+
let data = { version: 1, categories: [] };
|
|
1083
|
+
if (existsSync(catPath)) {
|
|
1084
|
+
try { data = JSON.parse(readFileSync(catPath, 'utf-8')); } catch { return { created: [], total: 0 }; }
|
|
1085
|
+
if (!data || !Array.isArray(data.categories)) return { created: [], total: 0 };
|
|
1075
1086
|
}
|
|
1087
|
+
const categories = data.categories;
|
|
1088
|
+
const created = mutate(categories, new Date().toISOString());
|
|
1089
|
+
if (created.length > 0) {
|
|
1090
|
+
data.version = data.version || 1;
|
|
1091
|
+
mkdirSync(dirname(catPath), { recursive: true });
|
|
1092
|
+
writeFileSync(catPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
1093
|
+
}
|
|
1094
|
+
return { created, total: categories.length };
|
|
1095
|
+
}
|
|
1076
1096
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1097
|
+
/**
|
|
1098
|
+
* Create categories the first time something saves into them.
|
|
1099
|
+
* `defs`: [{ name, description, parent?, is_parent?, color? }], parents first. A
|
|
1100
|
+
* parent is attached only when it exists (or is created by an earlier def).
|
|
1101
|
+
*
|
|
1102
|
+
* @returns {{ created: string[], total: number }}
|
|
1103
|
+
*/
|
|
1104
|
+
export function ensureCategories(defs) {
|
|
1105
|
+
return addMissingCategories((categories, now) => {
|
|
1106
|
+
const names = new Set(categories.map((c) => c.name));
|
|
1107
|
+
const created = [];
|
|
1108
|
+
for (const def of defs || []) {
|
|
1109
|
+
if (!def?.name || names.has(def.name)) continue;
|
|
1110
|
+
const cat = { name: def.name, description: def.description || def.name, created_at: now };
|
|
1111
|
+
if (def.parent && names.has(def.parent)) cat.parent = def.parent;
|
|
1112
|
+
else if (def.is_parent) cat.is_parent = true;
|
|
1087
1113
|
if (def.color) cat.color = def.color;
|
|
1088
1114
|
categories.push(cat);
|
|
1089
|
-
|
|
1115
|
+
names.add(def.name);
|
|
1090
1116
|
created.push(def.name);
|
|
1091
1117
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
for (const proj of projects) {
|
|
1096
|
-
let label = normalizeLabel(proj.label);
|
|
1097
|
-
// Truncate to 16 chars so children stay within 30-char limit (16 + 1 + 12 = 29)
|
|
1098
|
-
if (label.length > 16) label = label.slice(0, 16).replace(/-$/, '');
|
|
1099
|
-
|
|
1100
|
-
// Ensure parent exists
|
|
1101
|
-
if (!existingNames.has(label)) {
|
|
1102
|
-
categories.push({
|
|
1103
|
-
name: label,
|
|
1104
|
-
description: `Knowledge and context for the ${proj.label} project`,
|
|
1105
|
-
is_parent: true,
|
|
1106
|
-
created_at: now,
|
|
1107
|
-
});
|
|
1108
|
-
existingNames.add(label);
|
|
1109
|
-
created.push(label);
|
|
1110
|
-
} else {
|
|
1111
|
-
// Parent exists — ensure it has is_parent flag
|
|
1112
|
-
const existing = categories.find((c) => c.name === label);
|
|
1113
|
-
if (existing && !existing.is_parent) existing.is_parent = true;
|
|
1114
|
-
}
|
|
1118
|
+
return created;
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1115
1121
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1122
|
+
/**
|
|
1123
|
+
* Create a project's parent category with the default children, once: at the moment
|
|
1124
|
+
* the project is registered (the Neural Interface's add-project route, the only
|
|
1125
|
+
* writer of the registry). Never called for a project that was already registered,
|
|
1126
|
+
* so a default category the user deleted stays deleted.
|
|
1127
|
+
*
|
|
1128
|
+
* @param {Array<{ label: string }>} projects — the project(s) just registered
|
|
1129
|
+
* @returns {{ created: string[], total: number }}
|
|
1130
|
+
*/
|
|
1131
|
+
export function ensureProjectCategories(projects) {
|
|
1132
|
+
return addMissingCategories((categories, now) => {
|
|
1133
|
+
const existingNames = new Set(categories.map((c) => c.name));
|
|
1134
|
+
const created = [];
|
|
1135
|
+
for (const proj of projects || []) {
|
|
1136
|
+
if (!proj?.label) continue;
|
|
1137
|
+
const label = projectCategoryLabel(proj.label);
|
|
1138
|
+
if (!label) continue;
|
|
1139
|
+
|
|
1140
|
+
// Ensure parent exists
|
|
1141
|
+
if (!existingNames.has(label)) {
|
|
1120
1142
|
categories.push({
|
|
1121
|
-
name:
|
|
1122
|
-
description:
|
|
1123
|
-
|
|
1143
|
+
name: label,
|
|
1144
|
+
description: `Knowledge and context for the ${proj.label} project`,
|
|
1145
|
+
is_parent: true,
|
|
1124
1146
|
created_at: now,
|
|
1125
1147
|
});
|
|
1126
|
-
existingNames.add(
|
|
1127
|
-
created.push(
|
|
1148
|
+
existingNames.add(label);
|
|
1149
|
+
created.push(label);
|
|
1150
|
+
} else {
|
|
1151
|
+
// Parent exists — ensure it has is_parent flag
|
|
1152
|
+
const existing = categories.find((c) => c.name === label);
|
|
1153
|
+
if (existing && !existing.is_parent && !existing.parent) existing.is_parent = true;
|
|
1128
1154
|
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
1155
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1156
|
+
// Ensure each default child exists
|
|
1157
|
+
for (const child of PROJECT_CHILDREN) {
|
|
1158
|
+
const childName = `${label}-${child.suffix}`;
|
|
1159
|
+
if (!existingNames.has(childName)) {
|
|
1160
|
+
categories.push({
|
|
1161
|
+
name: childName,
|
|
1162
|
+
description: `${child.description} for ${proj.label}`,
|
|
1163
|
+
parent: label,
|
|
1164
|
+
created_at: now,
|
|
1165
|
+
});
|
|
1166
|
+
existingNames.add(childName);
|
|
1167
|
+
created.push(childName);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
return created;
|
|
1172
|
+
});
|
|
1139
1173
|
}
|
|
1140
1174
|
|
|
1141
1175
|
/**
|
|
@@ -1180,9 +1214,11 @@ const LOOP_STALE_INACTIVITY_MS = 45 * 60 * 1000; // 45 min — browser iteration
|
|
|
1180
1214
|
* Scan loop directory and delete stale/inactive loop files.
|
|
1181
1215
|
* No history keeping — ended loops are removed immediately.
|
|
1182
1216
|
*
|
|
1183
|
-
* A loop is stale if
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1217
|
+
* A loop is stale if it is active with no iteration activity for 45 minutes
|
|
1218
|
+
* (session died). A dispatched worker's file (runMode 'task') is never swept
|
|
1219
|
+
* here: its one iteration lasts the whole run, which idles warm between turns
|
|
1220
|
+
* for far longer, and the server ends it (work-time cap, idle timeout, and
|
|
1221
|
+
* marks it inactive after a restart).
|
|
1186
1222
|
*
|
|
1187
1223
|
* @param {string} loopDir - path to data/loop/
|
|
1188
1224
|
* @returns {{ deactivated: string[], deleted: string[] }}
|
|
@@ -1201,6 +1237,7 @@ export function cleanupStaleLoops(loopDir) {
|
|
|
1201
1237
|
const loop = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
1202
1238
|
|
|
1203
1239
|
if (loop.active) {
|
|
1240
|
+
if (loop.runMode === 'task') continue;
|
|
1204
1241
|
const lastActivity = new Date(loop.lastIterationAt || loop.startedAt || 0).getTime();
|
|
1205
1242
|
const noRecentActivity = (now - lastActivity) >= LOOP_STALE_INACTIVITY_MS;
|
|
1206
1243
|
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SynaBun — the PATH of everything SynaBun starts, and where npm puts global commands
|
|
3
|
+
*
|
|
4
|
+
* A packaged application (packaging/) brings its own Node runtime, npm and npx.
|
|
5
|
+
* They are a fallback: on the PATH of every process the application starts,
|
|
6
|
+
* the order is
|
|
7
|
+
*
|
|
8
|
+
* 1. the user's own PATH, as it came
|
|
9
|
+
* 2. the bin folder of npm's global prefix, when the PATH lacks it (where
|
|
10
|
+
* `npm i -g` through SynaBun's npm puts commands: the user's own prefix
|
|
11
|
+
* when they set one, else a per-user folder of SynaBun's, never the app)
|
|
12
|
+
* 3. the packaged runtime, last
|
|
13
|
+
*
|
|
14
|
+
* packagedPathLast() is that order, and the one implementation of it: the
|
|
15
|
+
* entry points of a packaged build (lib/packaged-runtime.js packagedChildEnv:
|
|
16
|
+
* the bootstrap, the hook handler, the headless MCP server) and every PATH the
|
|
17
|
+
* Neural Interface builds (neural-interface/lib/augmented-path.js) use it.
|
|
18
|
+
*
|
|
19
|
+
* npm's global prefix is read here the way npm 10 (@npmcli/config) settles it,
|
|
20
|
+
* from plain files, without starting npm:
|
|
21
|
+
*
|
|
22
|
+
* 1. the environment: npm_config_prefix, in any letter case, when not empty
|
|
23
|
+
* 2. the user's config file: npm_config_userconfig, else ~/.npmrc
|
|
24
|
+
* 3. the global config file: npm_config_globalconfig, else `globalconfig=` in
|
|
25
|
+
* the user's (or the builtin) file, else <the prefix so far>/etc/npmrc
|
|
26
|
+
* 4. the builtin config of that npm (<npm>/npmrc: a packaged build writes one)
|
|
27
|
+
* 5. the default: $PREFIX, else the folder of the node running npm (Windows)
|
|
28
|
+
* or the folder above it
|
|
29
|
+
*
|
|
30
|
+
* (The command line comes first for npm and is never known here; a project's
|
|
31
|
+
* .npmrc is ignored by npm for a global install.) Every value goes through
|
|
32
|
+
* npm's ${VAR} substitution; a path then has a leading `~/` (on Windows also
|
|
33
|
+
* `~\`) replaced by the home folder (HOME, else the account's) and is made
|
|
34
|
+
* absolute. Files are read as npm's ini reader reads them: `;` and `#`
|
|
35
|
+
* comments, quotes, inline comments; a `prefix` inside a [section] is not the
|
|
36
|
+
* prefix. One difference: an empty `prefix=` counts as not set (npm would use
|
|
37
|
+
* the folder it happens to run in, which is no folder to put on a PATH).
|
|
38
|
+
*
|
|
39
|
+
* Only node: modules here: neural-interface/lib/augmented-path.js imports this
|
|
40
|
+
* file, and tests copy both into scratch trees.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { readFileSync } from 'node:fs';
|
|
44
|
+
import { homedir } from 'node:os';
|
|
45
|
+
import path from 'node:path';
|
|
46
|
+
|
|
47
|
+
const MEMO_MS = 5_000;
|
|
48
|
+
let _memo = null; // { key, at, value }
|
|
49
|
+
|
|
50
|
+
const implFor = (platform) => (platform === 'win32' ? path.win32 : path.posix);
|
|
51
|
+
|
|
52
|
+
/** The value of an env's PATH, whatever its spelling (Windows: Path). */
|
|
53
|
+
export function pathEnvValue(env = process.env) {
|
|
54
|
+
return env[Object.keys(env).find(key => key.toUpperCase() === 'PATH')] || '';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `env` with PATH set to `value`. Windows environment names are
|
|
59
|
+
* case-insensitive and JS object keys are not: the base's spelling is kept and
|
|
60
|
+
* every alias removed before an env reaches Node or ConPTY.
|
|
61
|
+
*/
|
|
62
|
+
export function withPathEnv(env = process.env, value = pathEnvValue(env), platform = process.platform) {
|
|
63
|
+
if (platform !== 'win32') return { ...env, PATH: value };
|
|
64
|
+
const keys = Object.keys(env).filter(key => key.toUpperCase() === 'PATH');
|
|
65
|
+
const key = keys[0] || 'Path';
|
|
66
|
+
const out = { ...env };
|
|
67
|
+
for (const alias of keys) delete out[alias];
|
|
68
|
+
out[key] = value;
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* PATH `value` with a packaged application's folders after the user's: each
|
|
74
|
+
* `extra` folder (npm's global bin) appended when the PATH does not have it
|
|
75
|
+
* yet, then every `last` folder (the runtime) moved to the very end. Nothing
|
|
76
|
+
* else moves; each folder stays once (Windows compares without case and
|
|
77
|
+
* trailing separators).
|
|
78
|
+
*/
|
|
79
|
+
export function packagedPathLast(value, { platform = process.platform, last = [], extra = [] } = {}) {
|
|
80
|
+
const delimiter = platform === 'win32' ? ';' : ':';
|
|
81
|
+
const id = (entry) => (platform === 'win32' ? entry.toLowerCase().replace(/[\\/]+$/, '') : entry.replace(/\/+$/, '') || '/');
|
|
82
|
+
const lastIds = new Set(last.filter(Boolean).map(id));
|
|
83
|
+
const seen = new Set();
|
|
84
|
+
const out = [];
|
|
85
|
+
const add = (entry) => {
|
|
86
|
+
if (!entry) return;
|
|
87
|
+
const key = id(entry);
|
|
88
|
+
if (seen.has(key)) return;
|
|
89
|
+
seen.add(key);
|
|
90
|
+
out.push(entry);
|
|
91
|
+
};
|
|
92
|
+
for (const entry of String(value || '').split(delimiter)) if (entry && !lastIds.has(id(entry))) add(entry);
|
|
93
|
+
for (const entry of extra) if (entry && !lastIds.has(id(entry))) add(entry);
|
|
94
|
+
for (const entry of last) add(entry);
|
|
95
|
+
return out.join(delimiter);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Where npm puts the commands of global packages under `prefix`: the prefix itself on Windows, its bin/ elsewhere. */
|
|
99
|
+
export function npmGlobalBinFor(prefix, platform = process.platform) {
|
|
100
|
+
if (!prefix) return null;
|
|
101
|
+
return platform === 'win32' ? prefix : implFor(platform).join(prefix, 'bin');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The builtin npmrc of the npm in a packaged runtime whose executables are in `runtimeBin`. */
|
|
105
|
+
export function bundledNpmrcPath(runtimeBin, platform = process.platform) {
|
|
106
|
+
if (!runtimeBin) return null;
|
|
107
|
+
const impl = implFor(platform);
|
|
108
|
+
return platform === 'win32'
|
|
109
|
+
? impl.join(runtimeBin, 'node_modules', 'npm', 'npmrc')
|
|
110
|
+
: impl.join(runtimeBin, '..', 'lib', 'node_modules', 'npm', 'npmrc');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function envLookup(env, name, platform) {
|
|
114
|
+
if (env[name] !== undefined) return env[name];
|
|
115
|
+
if (platform !== 'win32') return undefined;
|
|
116
|
+
const key = Object.keys(env).find(candidate => candidate.toUpperCase() === name.toUpperCase());
|
|
117
|
+
return key === undefined ? undefined : env[key];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* npm's ${VAR} substitution (@npmcli/config env-replace.js): `${NAME}` is the
|
|
122
|
+
* variable's value, a name that is not set stays as written, and a backslash
|
|
123
|
+
* before `${` escapes it (an even number of them is that many halved, then the value).
|
|
124
|
+
*/
|
|
125
|
+
export function npmEnvReplace(text, env = process.env, platform = process.platform) {
|
|
126
|
+
return String(text).replace(/(?<!\\)(\\*)\$\{([^${}]+)\}/g, (orig, esc, name) => {
|
|
127
|
+
const found = envLookup(env, name, platform);
|
|
128
|
+
const value = found !== undefined ? found : `\${${name}}`;
|
|
129
|
+
if (esc.length % 2) return orig.slice((esc.length + 1) / 2);
|
|
130
|
+
return esc.slice(esc.length / 2) + value;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// The ini reader npm uses (ini 4.x unsafe()): quotes, then `;` / `#` ending the value unless escaped.
|
|
135
|
+
function iniValue(raw) {
|
|
136
|
+
let value = String(raw || '').trim();
|
|
137
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
138
|
+
if (value.charAt(0) === "'") value = value.slice(1, -1);
|
|
139
|
+
try { value = JSON.parse(value); } catch { /* kept as it is */ }
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
let escaped = false;
|
|
143
|
+
let out = '';
|
|
144
|
+
for (const char of value) {
|
|
145
|
+
if (escaped) {
|
|
146
|
+
out += '\\;#'.includes(char) ? char : `\\${char}`;
|
|
147
|
+
escaped = false;
|
|
148
|
+
} else if (char === ';' || char === '#') {
|
|
149
|
+
break;
|
|
150
|
+
} else if (char === '\\') {
|
|
151
|
+
escaped = true;
|
|
152
|
+
} else {
|
|
153
|
+
out += char;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (escaped) out += '\\';
|
|
157
|
+
return out.trim();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The top-level settings of an .npmrc, as npm's ini reader gives them (a key
|
|
162
|
+
* inside a [section] is the section's; `true` / `false` / `null` are those
|
|
163
|
+
* values; `key[]` makes a list; the last of a repeated key wins).
|
|
164
|
+
*/
|
|
165
|
+
export function parseNpmrc(text) {
|
|
166
|
+
const out = Object.create(null);
|
|
167
|
+
for (const line of String(text || '').split(/[\r\n]+/g)) {
|
|
168
|
+
if (!line || /^\s*[;#]/.test(line) || /^\s*$/.test(line)) continue;
|
|
169
|
+
if (/^\[([^\]]*)\]\s*$/.test(line)) break;
|
|
170
|
+
const match = line.match(/^([^=]+)(=(.*))?$/);
|
|
171
|
+
if (!match) continue;
|
|
172
|
+
const rawKey = iniValue(match[1]);
|
|
173
|
+
const isList = rawKey.length > 2 && rawKey.endsWith('[]');
|
|
174
|
+
const key = isList ? rawKey.slice(0, -2) : rawKey;
|
|
175
|
+
if (!key || key === '__proto__') continue;
|
|
176
|
+
const raw = match[2] ? iniValue(match[3]) : true;
|
|
177
|
+
const value = raw === 'true' || raw === 'false' || raw === 'null' ? JSON.parse(raw) : raw;
|
|
178
|
+
if (isList) {
|
|
179
|
+
if (!Array.isArray(out[key])) out[key] = out[key] === undefined ? [] : [out[key]];
|
|
180
|
+
}
|
|
181
|
+
if (Array.isArray(out[key])) out[key].push(value);
|
|
182
|
+
else out[key] = value;
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** The npm_config_* settings of an environment, as npm reads them (any letter case, `_` as `-`, empty ones skipped; the last spelling wins). */
|
|
188
|
+
export function npmEnvConfig(env = process.env) {
|
|
189
|
+
const out = Object.create(null);
|
|
190
|
+
for (const [name, value] of Object.entries(env)) {
|
|
191
|
+
if (!/^npm_config_/i.test(name) || value === '' || value === undefined) continue;
|
|
192
|
+
let key = name.slice('npm_config_'.length);
|
|
193
|
+
if (!key.startsWith('//')) key = key.replace(/(?!^)_/g, '-').toLowerCase();
|
|
194
|
+
out[key] = value;
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** A path setting as npm parses it: ${VAR}, then `~/`, then absolute. null for one that is not a usable string. */
|
|
200
|
+
export function npmPathValue(value, { env = process.env, platform = process.platform, home, cwd = process.cwd() } = {}) {
|
|
201
|
+
if (typeof value !== 'string') return null;
|
|
202
|
+
const text = npmEnvReplace(value.trim(), env, platform);
|
|
203
|
+
if (!text) return null;
|
|
204
|
+
const impl = implFor(platform);
|
|
205
|
+
const homePattern = platform === 'win32' ? /^~(\/|\\)/ : /^~\//;
|
|
206
|
+
if (homePattern.test(text) && home) return impl.resolve(home, text.slice(2));
|
|
207
|
+
return impl.resolve(cwd, text);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** The home folder npm uses: HOME, else the account's (os.homedir(); on Windows USERPROFILE). */
|
|
211
|
+
export function npmHome(env = process.env, platform = process.platform) {
|
|
212
|
+
if (env.HOME) return env.HOME;
|
|
213
|
+
if (env === process.env) return homedir();
|
|
214
|
+
if (platform === 'win32') return envLookup(env, 'USERPROFILE', platform) || homedir();
|
|
215
|
+
return homedir();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* npm's global prefix, as described at the top. `builtin` is the builtin npmrc
|
|
220
|
+
* of the npm that will run (lib/packaged-runtime.js names the packaged one),
|
|
221
|
+
* `execPath` the node it runs on (for the default); leave both out to get only
|
|
222
|
+
* what the user set (`source` then never says 'builtin' or 'default').
|
|
223
|
+
*
|
|
224
|
+
* Returns { prefix, bin, source, from, userconfig, globalconfig }: `prefix` an
|
|
225
|
+
* absolute folder or null, `source` 'env' | 'userconfig' | 'globalconfig' |
|
|
226
|
+
* 'builtin' | 'default' | null, `from` what set it (the variable or the file).
|
|
227
|
+
*/
|
|
228
|
+
export function resolveNpmPrefix({
|
|
229
|
+
env = process.env,
|
|
230
|
+
platform = process.platform,
|
|
231
|
+
home = npmHome(env, platform),
|
|
232
|
+
cwd = process.cwd(),
|
|
233
|
+
readFile = readFileSync,
|
|
234
|
+
builtin = null,
|
|
235
|
+
execPath = null,
|
|
236
|
+
} = {}) {
|
|
237
|
+
const impl = implFor(platform);
|
|
238
|
+
const parse = { env, platform, home, cwd };
|
|
239
|
+
const read = (file) => {
|
|
240
|
+
if (!file) return Object.create(null);
|
|
241
|
+
try { return parseNpmrc(readFile(file, 'utf8')); } catch { return Object.create(null); }
|
|
242
|
+
};
|
|
243
|
+
const fromEnv = npmEnvConfig(env);
|
|
244
|
+
const envPrefix = npmPathValue(fromEnv.prefix, parse);
|
|
245
|
+
const userconfig = npmPathValue(fromEnv.userconfig, parse) || (home ? impl.resolve(home, '.npmrc') : null);
|
|
246
|
+
const user = read(userconfig);
|
|
247
|
+
const userPrefix = npmPathValue(user.prefix, parse);
|
|
248
|
+
const builtinConfig = read(builtin);
|
|
249
|
+
const builtinPrefix = npmPathValue(builtinConfig.prefix, parse);
|
|
250
|
+
let defaultPrefix = null;
|
|
251
|
+
if (execPath) {
|
|
252
|
+
if (env.PREFIX) defaultPrefix = npmPathValue(env.PREFIX, parse);
|
|
253
|
+
else if (platform === 'win32') defaultPrefix = impl.dirname(execPath);
|
|
254
|
+
else defaultPrefix = env.DESTDIR ? impl.join(env.DESTDIR, impl.dirname(impl.dirname(execPath))) : impl.dirname(impl.dirname(execPath));
|
|
255
|
+
}
|
|
256
|
+
const soFar = envPrefix || userPrefix || builtinPrefix || defaultPrefix;
|
|
257
|
+
const globalconfig = npmPathValue(fromEnv.globalconfig, parse)
|
|
258
|
+
|| npmPathValue(user.globalconfig, parse)
|
|
259
|
+
|| npmPathValue(builtinConfig.globalconfig, parse)
|
|
260
|
+
|| (soFar ? impl.resolve(soFar, 'etc', 'npmrc') : null);
|
|
261
|
+
const globalPrefix = npmPathValue(read(globalconfig).prefix, parse);
|
|
262
|
+
const levels = [
|
|
263
|
+
['env', envPrefix, 'npm_config_prefix'],
|
|
264
|
+
['userconfig', userPrefix, userconfig],
|
|
265
|
+
['globalconfig', globalPrefix, globalconfig],
|
|
266
|
+
['builtin', builtinPrefix, builtin],
|
|
267
|
+
['default', defaultPrefix, execPath],
|
|
268
|
+
];
|
|
269
|
+
const found = levels.find(([, value]) => value);
|
|
270
|
+
const prefix = found ? found[1] : null;
|
|
271
|
+
return {
|
|
272
|
+
prefix,
|
|
273
|
+
bin: npmGlobalBinFor(prefix, platform),
|
|
274
|
+
source: found ? found[0] : null,
|
|
275
|
+
from: found ? found[2] : null,
|
|
276
|
+
userconfig,
|
|
277
|
+
globalconfig,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* resolveNpmPrefix() for this process, kept for a few seconds: every PATH
|
|
283
|
+
* SynaBun builds asks, and a changed ~/.npmrc counts within seconds. Options
|
|
284
|
+
* other than `builtin` and `execPath` (an env that is not process.env, a
|
|
285
|
+
* readFile) are not cached.
|
|
286
|
+
*/
|
|
287
|
+
export function effectiveNpmPrefix(options = {}) {
|
|
288
|
+
const { builtin = null, execPath = null, ...rest } = options;
|
|
289
|
+
const live = Object.keys(rest).every(key => (key === 'env' ? rest.env === process.env : key === 'platform' ? rest.platform === process.platform : false));
|
|
290
|
+
if (!live) return resolveNpmPrefix(options);
|
|
291
|
+
const env = process.env;
|
|
292
|
+
const relevant = Object.entries(env).filter(([name]) => /^npm_config_/i.test(name) || ['HOME', 'USERPROFILE', 'APPDATA', 'PREFIX', 'DESTDIR'].includes(name.toUpperCase()));
|
|
293
|
+
const key = JSON.stringify([builtin, execPath, process.cwd(), relevant]);
|
|
294
|
+
if (_memo && _memo.key === key && Date.now() - _memo.at < MEMO_MS) return _memo.value;
|
|
295
|
+
const value = resolveNpmPrefix({ builtin, execPath });
|
|
296
|
+
_memo = { key, at: Date.now(), value };
|
|
297
|
+
return value;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Forget what effectiveNpmPrefix() keeps (a test, or a settings change that must count at once). */
|
|
301
|
+
export function forgetNpmPrefix() {
|
|
302
|
+
_memo = null;
|
|
303
|
+
}
|
package/lib/claude-hooks.js
CHANGED
|
@@ -78,7 +78,8 @@ export function isSynaBunHookCommand(command, scriptName) {
|
|
|
78
78
|
/**
|
|
79
79
|
* Why this run must not write hook commands, or null when it may. A packaged
|
|
80
80
|
* application with no path that outlives the run (macOS started it from a
|
|
81
|
-
* temporary copy) would leave every handler
|
|
81
|
+
* temporary copy, or from the disk image it came in) would leave every handler
|
|
82
|
+
* pointing at nothing.
|
|
82
83
|
*/
|
|
83
84
|
export function hookInstallBlocker(runtime = packagedRuntime()) {
|
|
84
85
|
if (!runtime || durableEntry(runtime)) return null;
|
|
@@ -52,6 +52,8 @@ function isRuntimeOnlyMigrationFile(relativePath) {
|
|
|
52
52
|
return name === '.DS_Store'
|
|
53
53
|
|| MIGRATION_RUNTIME_ONLY_FILES.has(normalized)
|
|
54
54
|
|| /(?:^|\/)server-(?:stdout|stderr)\.log(?:\.1)?$/i.test(normalized)
|
|
55
|
+
// The desktop app's own log (packaging/desktop) and the launcher's rotated one, written from the first start on.
|
|
56
|
+
|| /^data\/(?:desktop\.log(?:\.1)?|launcher\.log\.1)$/i.test(normalized)
|
|
55
57
|
|| /(?:^|\/)(?:restart-requested|opencode-managed\.pid)$/i.test(normalized);
|
|
56
58
|
}
|
|
57
59
|
|