ai-agent-router 0.2.0 → 0.2.2
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +14 -0
- package/.next/build-manifest.json +2 -2
- package/.next/fallback-build-manifest.json +2 -2
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +4 -4
- package/.next/required-server-files.json +4 -4
- package/.next/routes-manifest.json +84 -0
- package/.next/server/app/_global-error/page.js +1 -1
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +2 -2
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/models/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/available-models/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/save/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/status/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/test/route.js +1 -1
- package/.next/server/app/api/ide/claude/test/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/openclaw/apply/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/apply/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/apply/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/apply/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/apply/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/available-models/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/available-models/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/available-models/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/preview/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/preview/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/preview/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/preview/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/preview/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/restore/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/restore/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/restore/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js +6 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/restore/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/restore/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/save/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/save/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/save/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/save/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/save/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/save/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/save/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/status/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/status/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/status/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/status/route.js +7 -0
- package/.next/server/app/api/ide/openclaw/status/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/status/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/status/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/openclaw/test/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/openclaw/test/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/openclaw/test/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/openclaw/test/route.js +6 -0
- package/.next/server/app/api/ide/openclaw/test/route.js.map +5 -0
- package/.next/server/app/api/ide/openclaw/test/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/openclaw/test/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/apply/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/apply/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/apply/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/apply/route.js +7 -0
- package/.next/server/app/api/ide/opencode/apply/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/apply/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/apply/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/available-models/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/available-models/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/available-models/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js +7 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/available-models/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/available-models/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/preview/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/preview/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/preview/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/preview/route.js +7 -0
- package/.next/server/app/api/ide/opencode/preview/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/preview/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/preview/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/restore/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/restore/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/restore/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/restore/route.js +6 -0
- package/.next/server/app/api/ide/opencode/restore/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/restore/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/restore/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/save/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/save/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/save/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/save/route.js +7 -0
- package/.next/server/app/api/ide/opencode/save/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/save/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/save/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/status/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/status/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/status/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/status/route.js +7 -0
- package/.next/server/app/api/ide/opencode/status/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/status/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/status/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/ide/opencode/test/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/ide/opencode/test/route/build-manifest.json +11 -0
- package/.next/server/app/api/ide/opencode/test/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/ide/opencode/test/route.js +6 -0
- package/.next/server/app/api/ide/opencode/test/route.js.map +5 -0
- package/.next/server/app/api/ide/opencode/test/route.js.nft.json +1 -0
- package/.next/server/app/api/ide/opencode/test/route_client-reference-manifest.js +2 -0
- package/.next/server/app/api/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/test/route.js.nft.json +1 -1
- package/.next/server/app/api/service/force-stop/route.js.nft.json +1 -1
- package/.next/server/app/api/service/start/route.js.nft.json +1 -1
- package/.next/server/app/api/service/status/route.js.nft.json +1 -1
- package/.next/server/app/api/service/stop/route.js.nft.json +1 -1
- package/.next/server/app/ide/page.js +2 -2
- package/.next/server/app/ide/page.js.nft.json +1 -1
- package/.next/server/app/ide/page_client-reference-manifest.js +1 -1
- package/.next/server/app/ide.html +1 -1
- package/.next/server/app/ide.rsc +3 -3
- package/.next/server/app/ide.segments/_full.segment.rsc +3 -3
- package/.next/server/app/ide.segments/_head.segment.rsc +1 -1
- package/.next/server/app/ide.segments/_index.segment.rsc +2 -2
- package/.next/server/app/ide.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/ide.segments/ide/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/ide.segments/ide.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs/page.js +2 -2
- package/.next/server/app/logs/page.js.nft.json +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +1 -1
- package/.next/server/app/logs.rsc +3 -3
- package/.next/server/app/logs.segments/_full.segment.rsc +3 -3
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/models/page.js +2 -2
- package/.next/server/app/models/page.js.nft.json +1 -1
- package/.next/server/app/models/page_client-reference-manifest.js +1 -1
- package/.next/server/app/models.html +1 -1
- package/.next/server/app/models.rsc +2 -2
- package/.next/server/app/models.segments/_full.segment.rsc +2 -2
- package/.next/server/app/models.segments/_head.segment.rsc +1 -1
- package/.next/server/app/models.segments/_index.segment.rsc +2 -2
- package/.next/server/app/models.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/models.segments/models/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/models.segments/models.segment.rsc +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers/page.js +2 -2
- package/.next/server/app/providers/page.js.nft.json +1 -1
- package/.next/server/app/providers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers.html +1 -1
- package/.next/server/app/providers.rsc +2 -2
- package/.next/server/app/providers.segments/_full.segment.rsc +2 -2
- package/.next/server/app/providers.segments/_head.segment.rsc +1 -1
- package/.next/server/app/providers.segments/_index.segment.rsc +2 -2
- package/.next/server/app/providers.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/providers.segments/providers.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +14 -0
- package/.next/server/chunks/[root-of-the-server]__001d5756._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__001d5756._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__05f8578b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__05f8578b._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__3a204d25._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__3a204d25._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__43810962._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__43810962._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__4a8f9bc7._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__4a8f9bc7._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__55cd88b8._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__55cd88b8._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__5e8276bc._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__5e8276bc._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__760eaa16._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__760eaa16._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__7c298a19._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__7c298a19._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__85540228._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__85540228._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__94fe8d3c._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__94fe8d3c._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__97622908._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__97622908._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a02e6618._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a02e6618._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a32a20a7._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a32a20a7._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__af5b556a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__af5b556a._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js +16 -16
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__cafe113e._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__cafe113e._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__dc8b0bed._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__dc8b0bed._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__f0461b8d._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__f0461b8d._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__f8949f88._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__f8949f88._.js.map +1 -1
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_apply_route_actions_2cb9e4b4.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_apply_route_actions_2cb9e4b4.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_preview_route_actions_9814a8e4.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_preview_route_actions_9814a8e4.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_restore_route_actions_10ad8f9d.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_restore_route_actions_10ad8f9d.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_save_route_actions_044ad081.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_save_route_actions_044ad081.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_status_route_actions_ed9786d2.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_status_route_actions_ed9786d2.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_test_route_actions_ce2cb808.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_openclaw_test_route_actions_ce2cb808.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_apply_route_actions_6c422244.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_apply_route_actions_6c422244.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_preview_route_actions_256c82e0.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_preview_route_actions_256c82e0.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_restore_route_actions_371993d3.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_restore_route_actions_371993d3.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_save_route_actions_6e4c9c41.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_save_route_actions_6e4c9c41.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_status_route_actions_498ad77b.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_status_route_actions_498ad77b.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_test_route_actions_c71be510.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_ide_opencode_test_route_actions_c71be510.js.map +1 -0
- package/.next/server/chunks/ce889_server_app_api_ide_openclaw_available-models_route_actions_e568e70b.js +3 -0
- package/.next/server/chunks/ce889_server_app_api_ide_openclaw_available-models_route_actions_e568e70b.js.map +1 -0
- package/.next/server/chunks/ce889_server_app_api_ide_opencode_available-models_route_actions_95230db3.js +3 -0
- package/.next/server/chunks/ce889_server_app_api_ide_opencode_available-models_route_actions_95230db3.js.map +1 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__bec95712._.js → [root-of-the-server]__81937253._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__bec95712._.js.map → [root-of-the-server]__81937253._.js.map} +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__71c85955._.js → [root-of-the-server]__976ad963._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__71c85955._.js.map → [root-of-the-server]__976ad963._.js.map} +1 -1
- package/.next/server/chunks/ssr/_69468f4c._.js +3 -0
- package/.next/server/chunks/ssr/_69468f4c._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_ide_page_tsx_8962793b._.js +1 -1
- package/.next/server/chunks/ssr/src_app_ide_page_tsx_8962793b._.js.map +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js.map +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/64f547b3bcd3aef4.js +1 -0
- package/.next/static/chunks/6992685fe009e8fd.css +1 -0
- package/.next/static/chunks/{b6b258e8582e47c4.js → 7c8b7cbb3339f139.js} +1 -1
- package/.next/static/chunks/8ccc14e022ff6de3.js +1 -0
- package/.next/types/routes.d.ts +15 -1
- package/.next/types/validator.ts +126 -0
- package/README.md +31 -4
- package/dist/.next/dev/types/validator.js +56 -0
- package/dist/.next/types/validator.js +56 -0
- package/dist/package.json +55 -0
- package/dist/src/app/api/config/route.js +17 -0
- package/dist/src/app/api/ide/claude/apply/route.js +126 -31
- package/dist/src/app/api/ide/claude/restore/route.js +30 -0
- package/dist/src/app/api/ide/claude/save/route.js +79 -0
- package/dist/src/app/api/ide/claude/status/route.js +6 -1
- package/dist/src/app/api/ide/openclaw/apply/route.js +92 -0
- package/dist/src/app/api/ide/openclaw/available-models/route.js +46 -0
- package/dist/src/app/api/ide/openclaw/build-config.js +101 -0
- package/dist/src/app/api/ide/openclaw/preview/route.js +49 -0
- package/dist/src/app/api/ide/openclaw/restore/route.js +24 -0
- package/dist/src/app/api/ide/openclaw/save/route.js +54 -0
- package/dist/src/app/api/ide/openclaw/status/route.js +139 -0
- package/dist/src/app/api/ide/openclaw/test/route.js +158 -0
- package/dist/src/app/api/ide/opencode/apply/route.js +89 -0
- package/dist/src/app/api/ide/opencode/available-models/route.js +46 -0
- package/dist/src/app/api/ide/opencode/build-config.js +54 -0
- package/dist/src/app/api/ide/opencode/preview/route.js +36 -0
- package/dist/src/app/api/ide/opencode/restore/route.js +40 -0
- package/dist/src/app/api/ide/opencode/save/route.js +123 -0
- package/dist/src/app/api/ide/opencode/status/route.js +106 -0
- package/dist/src/app/api/ide/opencode/test/route.js +136 -0
- package/dist/src/app/components/Footer.js +11 -0
- package/dist/src/app/ide/page.js +651 -81
- package/dist/src/app/layout.js +5 -1
- package/dist/src/app/logs/page.js +4 -2
- package/dist/src/db/database.js +44 -8
- package/package.json +1 -1
- package/src/app/api/config/route.ts +17 -0
- package/src/app/api/ide/claude/apply/route.ts +140 -31
- package/src/app/api/ide/claude/restore/route.ts +36 -1
- package/src/app/api/ide/claude/save/route.ts +91 -1
- package/src/app/api/ide/claude/status/route.ts +12 -2
- package/src/app/api/ide/openclaw/apply/route.ts +103 -0
- package/src/app/api/ide/openclaw/available-models/route.ts +59 -0
- package/src/app/api/ide/openclaw/build-config.ts +152 -0
- package/src/app/api/ide/openclaw/preview/route.ts +57 -0
- package/src/app/api/ide/openclaw/restore/route.ts +27 -0
- package/src/app/api/ide/openclaw/save/route.ts +67 -0
- package/src/app/api/ide/openclaw/status/route.ts +178 -0
- package/src/app/api/ide/openclaw/test/route.ts +194 -0
- package/src/app/api/ide/opencode/apply/route.ts +92 -0
- package/src/app/api/ide/opencode/available-models/route.ts +59 -0
- package/src/app/api/ide/opencode/build-config.ts +69 -0
- package/src/app/api/ide/opencode/preview/route.ts +40 -0
- package/src/app/api/ide/opencode/restore/route.ts +52 -0
- package/src/app/api/ide/opencode/save/route.ts +131 -0
- package/src/app/api/ide/opencode/status/route.ts +128 -0
- package/src/app/api/ide/opencode/test/route.ts +145 -0
- package/src/app/components/Footer.tsx +9 -0
- package/src/app/globals.css +17 -0
- package/src/app/ide/page.tsx +1587 -118
- package/src/app/layout.tsx +3 -1
- package/src/app/logs/page.tsx +4 -2
- package/src/db/database.ts +55 -8
- package/.next/server/chunks/ssr/src_app_b2b1d928._.js +0 -3
- package/.next/server/chunks/ssr/src_app_b2b1d928._.js.map +0 -1
- package/.next/static/chunks/6418ca50028376b7.css +0 -1
- package/.next/static/chunks/9ec3b97741b6575e.js +0 -1
- /package/.next/static/{ryTeHAYUvjT1bYolc-x9Z → cf2SWIkI5HVbnDjLExI42}/_buildManifest.js +0 -0
- /package/.next/static/{ryTeHAYUvjT1bYolc-x9Z → cf2SWIkI5HVbnDjLExI42}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{ryTeHAYUvjT1bYolc-x9Z → cf2SWIkI5HVbnDjLExI42}/_ssgManifest.js +0 -0
package/dist/src/app/layout.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.metadata = void 0;
|
|
4
7
|
exports.default = RootLayout;
|
|
5
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
9
|
require("./globals.css");
|
|
7
10
|
const ToastProvider_1 = require("./components/ToastProvider");
|
|
11
|
+
const Footer_1 = __importDefault(require("./components/Footer"));
|
|
8
12
|
exports.metadata = {
|
|
9
13
|
title: 'AAR - AI Agent Router',
|
|
10
14
|
description: 'Unified API gateway for managing multiple AI model providers',
|
|
11
15
|
};
|
|
12
16
|
function RootLayout({ children, }) {
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)("html", { lang: "zh-CN", suppressHydrationWarning: true, children: (0, jsx_runtime_1.
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)("html", { lang: "zh-CN", suppressHydrationWarning: true, children: (0, jsx_runtime_1.jsxs)("body", { className: "pb-10", children: [(0, jsx_runtime_1.jsx)(ToastProvider_1.ToastProvider, { children: children }), (0, jsx_runtime_1.jsx)(Footer_1.default, {})] }) }));
|
|
14
18
|
}
|
|
@@ -10,15 +10,17 @@ const react_1 = require("react");
|
|
|
10
10
|
const Nav_1 = __importDefault(require("../components/Nav"));
|
|
11
11
|
const ToastProvider_1 = require("../components/ToastProvider");
|
|
12
12
|
const ConfirmDialog_1 = __importDefault(require("../components/ConfirmDialog"));
|
|
13
|
-
/** 将服务端返回的 created_at
|
|
13
|
+
/** 将服务端返回的 created_at 格式化为本地显示。数据库存储的是本地时间,无需追加 Z 后缀。 */
|
|
14
14
|
function formatCreatedAt(createdAt) {
|
|
15
15
|
if (!createdAt || typeof createdAt !== 'string')
|
|
16
16
|
return '';
|
|
17
17
|
const s = createdAt.trim();
|
|
18
18
|
if (!s)
|
|
19
19
|
return '';
|
|
20
|
+
// 数据库使用 datetime('now','localtime') 存储的已经是本地时间,
|
|
21
|
+
// 不带时区后缀时直接按本地时间解析,不要追加 'Z'(否则会多偏移 8 小时)
|
|
20
22
|
const hasTz = /[Z+-]\d{2}:?\d{2}$/.test(s);
|
|
21
|
-
const iso = hasTz ? s : s.replace(' ', 'T')
|
|
23
|
+
const iso = hasTz ? s : s.replace(' ', 'T');
|
|
22
24
|
const date = new Date(iso);
|
|
23
25
|
return Number.isNaN(date.getTime()) ? s : date.toLocaleString('zh-CN');
|
|
24
26
|
}
|
package/dist/src/db/database.js
CHANGED
|
@@ -14,12 +14,39 @@ const schema_1 = require("./schema");
|
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const os_1 = __importDefault(require("os"));
|
|
17
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
17
18
|
const DB_PATH = process.env.DB_PATH || path_1.default.join(os_1.default.homedir(), '.aar', 'gateway.db');
|
|
19
|
+
/**
|
|
20
|
+
* 生成随机的 API Key(用于网关密码默认值)
|
|
21
|
+
*/
|
|
22
|
+
function generateRandomApiKey() {
|
|
23
|
+
return `aar-${crypto_1.default.randomBytes(16).toString('hex')}`;
|
|
24
|
+
}
|
|
25
|
+
// Use hardcoded path for the built/distributed WASM file
|
|
26
|
+
// Next.js copies sql-wasm.wasm to its chunks directory
|
|
27
|
+
function findSqlJsWasmPath() {
|
|
28
|
+
// Try Next.js chunks directory first (works in dev and production)
|
|
29
|
+
const nextChunksPath = path_1.default.join(process.cwd(), '.next', 'dev', 'server', 'chunks', 'sql-wasm.wasm');
|
|
30
|
+
if (fs_1.default.existsSync(nextChunksPath)) {
|
|
31
|
+
return nextChunksPath;
|
|
32
|
+
}
|
|
33
|
+
// Try production .next directory
|
|
34
|
+
const prodChunksPath = path_1.default.join(process.cwd(), '.next', 'server', 'chunks', 'sql-wasm.wasm');
|
|
35
|
+
if (fs_1.default.existsSync(prodChunksPath)) {
|
|
36
|
+
return prodChunksPath;
|
|
37
|
+
}
|
|
38
|
+
// Try node_modules as fallback
|
|
39
|
+
const nodeModulesPath = path_1.default.join(process.cwd(), 'node_modules', 'sql.js', 'dist', 'sql-wasm.wasm');
|
|
40
|
+
if (fs_1.default.existsSync(nodeModulesPath)) {
|
|
41
|
+
return nodeModulesPath;
|
|
42
|
+
}
|
|
43
|
+
// Use the most likely location as default
|
|
44
|
+
return nodeModulesPath;
|
|
45
|
+
}
|
|
46
|
+
const SQLJS_WASM_PATH = findSqlJsWasmPath();
|
|
18
47
|
let dbInstance = null;
|
|
19
48
|
let sqlJsInstance = null;
|
|
20
|
-
/** 上次从磁盘加载 DB 的时间(用于多进程时发现磁盘被其他进程更新则重新加载) */
|
|
21
49
|
let lastLoadMtimeMs = 0;
|
|
22
|
-
/** 若磁盘上的 DB 被其他进程更新则重新加载,以便读到最新数据 */
|
|
23
50
|
function reloadFromFileIfNewer() {
|
|
24
51
|
if (!dbInstance || !fs_1.default.existsSync(DB_PATH))
|
|
25
52
|
return;
|
|
@@ -43,7 +70,7 @@ async function initSqlJsEngine() {
|
|
|
43
70
|
sqlJsInstance = await (0, sql_js_1.default)({
|
|
44
71
|
locateFile: (file) => {
|
|
45
72
|
if (file.endsWith('.wasm')) {
|
|
46
|
-
return
|
|
73
|
+
return SQLJS_WASM_PATH;
|
|
47
74
|
}
|
|
48
75
|
return `https://sql.js.org/dist/${file}`;
|
|
49
76
|
}
|
|
@@ -84,6 +111,7 @@ async function getDatabase() {
|
|
|
84
111
|
if (!dbInstance) {
|
|
85
112
|
const engine = await initSqlJsEngine();
|
|
86
113
|
const loaded = loadDatabase();
|
|
114
|
+
let isNewDatabase = false;
|
|
87
115
|
if (loaded) {
|
|
88
116
|
dbInstance = loaded;
|
|
89
117
|
if (fs_1.default.existsSync(DB_PATH))
|
|
@@ -92,7 +120,9 @@ async function getDatabase() {
|
|
|
92
120
|
else {
|
|
93
121
|
dbInstance = new engine.Database();
|
|
94
122
|
lastLoadMtimeMs = 0;
|
|
123
|
+
isNewDatabase = true; // 标记为新数据库
|
|
95
124
|
}
|
|
125
|
+
let migrationPerformed = false;
|
|
96
126
|
try {
|
|
97
127
|
dbInstance.run(schema_1.CREATE_TABLES_SQL);
|
|
98
128
|
// Migration: Allow NULL model_id in request_logs table
|
|
@@ -124,7 +154,7 @@ async function getDatabase() {
|
|
|
124
154
|
dbInstance.run(`INSERT INTO request_logs_new SELECT * FROM request_logs;`);
|
|
125
155
|
dbInstance.run(`DROP TABLE request_logs;`);
|
|
126
156
|
dbInstance.run(`ALTER TABLE request_logs_new RENAME TO request_logs;`);
|
|
127
|
-
|
|
157
|
+
migrationPerformed = true;
|
|
128
158
|
console.log('[Database] Migration completed successfully');
|
|
129
159
|
}
|
|
130
160
|
}
|
|
@@ -137,7 +167,16 @@ async function getDatabase() {
|
|
|
137
167
|
console.warn('[Database] Migration warning (non-critical):', migrationError.message);
|
|
138
168
|
}
|
|
139
169
|
}
|
|
140
|
-
|
|
170
|
+
// 只在新数据库创建或执行了 migration 时才保存,避免覆盖现有数据
|
|
171
|
+
if (isNewDatabase || migrationPerformed) {
|
|
172
|
+
// 为新数据库初始化默认的 api_key
|
|
173
|
+
if (isNewDatabase) {
|
|
174
|
+
const defaultApiKey = generateRandomApiKey();
|
|
175
|
+
dbInstance.run(`INSERT OR IGNORE INTO config (key, value, updated_at) VALUES ('api_key', ?, datetime('now'))`, [defaultApiKey]);
|
|
176
|
+
console.log('[Database] Generated default API key for new database');
|
|
177
|
+
}
|
|
178
|
+
saveDatabase(dbInstance);
|
|
179
|
+
}
|
|
141
180
|
}
|
|
142
181
|
catch (schemaError) {
|
|
143
182
|
if (!schemaError.message.includes('already exists') &&
|
|
@@ -159,7 +198,6 @@ async function closeDatabase() {
|
|
|
159
198
|
function getDbPath() {
|
|
160
199
|
return DB_PATH;
|
|
161
200
|
}
|
|
162
|
-
// Helper to run a query and get single result
|
|
163
201
|
async function queryOne(sql, params = []) {
|
|
164
202
|
const db = await getDatabase();
|
|
165
203
|
const stmt = db.prepare(sql);
|
|
@@ -172,7 +210,6 @@ async function queryOne(sql, params = []) {
|
|
|
172
210
|
stmt.free();
|
|
173
211
|
return null;
|
|
174
212
|
}
|
|
175
|
-
// Helper to run a query and get all results
|
|
176
213
|
async function queryAll(sql, params = []) {
|
|
177
214
|
const db = await getDatabase();
|
|
178
215
|
const results = [];
|
|
@@ -184,7 +221,6 @@ async function queryAll(sql, params = []) {
|
|
|
184
221
|
stmt.free();
|
|
185
222
|
return results;
|
|
186
223
|
}
|
|
187
|
-
// Helper to run INSERT/UPDATE/DELETE
|
|
188
224
|
async function run(sql, params = []) {
|
|
189
225
|
const db = await getDatabase();
|
|
190
226
|
db.run(sql, params);
|
package/package.json
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
import { getDatabase } from '@/db/database';
|
|
3
3
|
import { getConfig, setConfig, getAllConfig } from '@/db/queries';
|
|
4
|
+
import crypto from 'crypto';
|
|
4
5
|
|
|
5
6
|
// Ensure Node.js runtime (required for SQLite)
|
|
6
7
|
export const runtime = 'nodejs';
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* 生成随机的 API Key(用于网关密码默认值)
|
|
11
|
+
*/
|
|
12
|
+
function generateRandomApiKey(): string {
|
|
13
|
+
return `aar-${crypto.randomBytes(16).toString('hex')}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
export async function GET(request: NextRequest) {
|
|
9
17
|
try {
|
|
10
18
|
// Initialize database on request (safer than module load)
|
|
@@ -25,6 +33,15 @@ export async function GET(request: NextRequest) {
|
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
const configs = await getAllConfig();
|
|
36
|
+
|
|
37
|
+
// 如果 api_key 为空,生成一个随机默认值
|
|
38
|
+
if (!configs.api_key) {
|
|
39
|
+
const defaultApiKey = generateRandomApiKey();
|
|
40
|
+
await setConfig('api_key', defaultApiKey);
|
|
41
|
+
configs.api_key = defaultApiKey;
|
|
42
|
+
console.log('[Config API] Generated default API key');
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
return NextResponse.json(configs);
|
|
29
46
|
} catch (error: any) {
|
|
30
47
|
console.error('Config API error:', error);
|
|
@@ -10,6 +10,12 @@ const CLAUDE_DIR = join(homedir(), '.claude');
|
|
|
10
10
|
const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
|
|
11
11
|
const BACKUP_FILE = join(CLAUDE_DIR, 'settings.json.aar.bak');
|
|
12
12
|
|
|
13
|
+
// Claude 登录配置文件(用于 hasCompletedOnboarding)
|
|
14
|
+
const CLAUDE_JSON_FILE = join(homedir(), '.claude.json');
|
|
15
|
+
|
|
16
|
+
// AAR 备份目录
|
|
17
|
+
const AAR_BACKUP_DIR = join(homedir(), '.aar', 'backups');
|
|
18
|
+
|
|
13
19
|
// 默认模型映射
|
|
14
20
|
const DEFAULT_MODEL_MAPPING = {
|
|
15
21
|
haiku: 'GLM-4.5-air',
|
|
@@ -38,11 +44,20 @@ export async function POST(request: NextRequest) {
|
|
|
38
44
|
const gatewayAddress = await getGatewayAddress();
|
|
39
45
|
const gatewayApiKey = await getGatewayApiKey();
|
|
40
46
|
|
|
41
|
-
// 生成配置对象
|
|
42
47
|
const modelMapping = { haiku, sonnet, opus, default: defaultModel, reasoning: reasoningModel };
|
|
43
|
-
const
|
|
48
|
+
const aarEnv = buildAarEnv(gatewayAddress, gatewayApiKey, modelMapping);
|
|
49
|
+
|
|
50
|
+
// 在修改配置前,先备份到 ~/.aar/backups 目录
|
|
51
|
+
const settingsBackup = backupToAar(SETTINGS_FILE, 'settings');
|
|
52
|
+
const claudeJsonBackup = backupToAar(CLAUDE_JSON_FILE, 'claude');
|
|
53
|
+
|
|
54
|
+
if (!settingsBackup.success) {
|
|
55
|
+
console.warn('[Claude Apply] Settings backup warning:', settingsBackup.error);
|
|
56
|
+
}
|
|
57
|
+
if (!claudeJsonBackup.success) {
|
|
58
|
+
console.warn('[Claude Apply] Claude.json backup warning:', claudeJsonBackup.error);
|
|
59
|
+
}
|
|
44
60
|
|
|
45
|
-
// 备份原有配置
|
|
46
61
|
const backupResult = backupOriginalConfig();
|
|
47
62
|
if (!backupResult.success) {
|
|
48
63
|
return NextResponse.json(
|
|
@@ -51,13 +66,27 @@ export async function POST(request: NextRequest) {
|
|
|
51
66
|
);
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
// 确保目录存在
|
|
55
69
|
if (!existsSync(CLAUDE_DIR)) {
|
|
56
70
|
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
57
71
|
}
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
let configToWrite: any;
|
|
74
|
+
if (existsSync(SETTINGS_FILE)) {
|
|
75
|
+
try {
|
|
76
|
+
const existing = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
77
|
+
configToWrite = {
|
|
78
|
+
...existing,
|
|
79
|
+
env: { ...(existing.env || {}), ...aarEnv },
|
|
80
|
+
router_provider: 'aar',
|
|
81
|
+
};
|
|
82
|
+
} catch {
|
|
83
|
+
configToWrite = generateClaudeConfig(gatewayAddress, gatewayApiKey, modelMapping);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
configToWrite = generateClaudeConfig(gatewayAddress, gatewayApiKey, modelMapping);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const validationResult = validateAndWriteConfig(configToWrite);
|
|
61
90
|
if (!validationResult.success) {
|
|
62
91
|
return NextResponse.json(
|
|
63
92
|
{ error: validationResult.error },
|
|
@@ -65,12 +94,23 @@ export async function POST(request: NextRequest) {
|
|
|
65
94
|
);
|
|
66
95
|
}
|
|
67
96
|
|
|
97
|
+
// 处理 ~/.claude.json,确保包含 hasCompletedOnboarding: true
|
|
98
|
+
const onboardingResult = ensureClaudeOnboarding();
|
|
99
|
+
if (!onboardingResult.success) {
|
|
100
|
+
console.warn('[Claude Apply] Onboarding update warning:', onboardingResult.error);
|
|
101
|
+
}
|
|
102
|
+
|
|
68
103
|
return NextResponse.json({
|
|
69
104
|
success: true,
|
|
70
105
|
message: 'Configuration applied successfully',
|
|
71
|
-
config,
|
|
106
|
+
config: configToWrite,
|
|
72
107
|
backup: backupResult.existed ? 'Created backup' : 'No existing config to backup',
|
|
73
108
|
previousWasFromAar: backupResult.existed && backupResult.isFromAar,
|
|
109
|
+
onboarding: onboardingResult.created ? 'Created ~/.claude.json' : 'Updated ~/.claude.json',
|
|
110
|
+
aarBackups: {
|
|
111
|
+
settings: settingsBackup.backupPath,
|
|
112
|
+
claudeJson: claudeJsonBackup.backupPath,
|
|
113
|
+
},
|
|
74
114
|
});
|
|
75
115
|
} catch (error: any) {
|
|
76
116
|
console.error('IDE Apply API error:', error);
|
|
@@ -101,57 +141,60 @@ async function getGatewayApiKey(): Promise<string> {
|
|
|
101
141
|
return apiKeyConfig?.value || 'your-gateway-api-key';
|
|
102
142
|
}
|
|
103
143
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
144
|
+
/** 仅生成 AAR 相关的 env 字段,用于合并到现有配置 */
|
|
145
|
+
function buildAarEnv(
|
|
146
|
+
gatewayAddress: string,
|
|
147
|
+
gatewayApiKey: string,
|
|
148
|
+
modelMapping: { haiku: string; sonnet: string; opus: string; default: string; reasoning: string }
|
|
149
|
+
): Record<string, unknown> {
|
|
150
|
+
return {
|
|
151
|
+
ANTHROPIC_AUTH_TOKEN: gatewayApiKey,
|
|
152
|
+
ANTHROPIC_BASE_URL: gatewayAddress,
|
|
153
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: modelMapping.haiku,
|
|
154
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: modelMapping.opus,
|
|
155
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: modelMapping.sonnet,
|
|
156
|
+
ANTHROPIC_MODEL: modelMapping.default,
|
|
157
|
+
ANTHROPIC_REASONING_MODEL: modelMapping.reasoning,
|
|
158
|
+
API_TIMEOUT_MS: '3000000',
|
|
159
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
|
|
160
|
+
hasCompletedOnboarding: true,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** 生成完整 Claude 配置(仅在无现有文件时使用) */
|
|
107
165
|
function generateClaudeConfig(
|
|
108
166
|
gatewayAddress: string,
|
|
109
167
|
gatewayApiKey: string,
|
|
110
168
|
modelMapping: { haiku: string; sonnet: string; opus: string; default: string; reasoning: string }
|
|
111
169
|
): any {
|
|
112
170
|
return {
|
|
113
|
-
// 路由提供者标识,标识配置来自当前工具 aar
|
|
114
171
|
router_provider: 'aar',
|
|
115
|
-
env:
|
|
116
|
-
ANTHROPIC_AUTH_TOKEN: gatewayApiKey,
|
|
117
|
-
ANTHROPIC_BASE_URL: gatewayAddress,
|
|
118
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: modelMapping.haiku,
|
|
119
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: modelMapping.opus,
|
|
120
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: modelMapping.sonnet,
|
|
121
|
-
ANTHROPIC_MODEL: modelMapping.default,
|
|
122
|
-
ANTHROPIC_REASONING_MODEL: modelMapping.reasoning,
|
|
123
|
-
API_TIMEOUT_MS: '3000000',
|
|
124
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
|
|
125
|
-
hasCompletedOnboarding: true,
|
|
126
|
-
},
|
|
172
|
+
env: buildAarEnv(gatewayAddress, gatewayApiKey, modelMapping),
|
|
127
173
|
};
|
|
128
174
|
}
|
|
129
175
|
|
|
130
176
|
/**
|
|
131
177
|
* 备份原有配置
|
|
132
|
-
*
|
|
178
|
+
* 仅在当前配置不是 AAR 时写入备份,这样「还原」才能恢复到应用 AAR 前的状态
|
|
133
179
|
*/
|
|
134
180
|
function backupOriginalConfig(): { success: boolean; existed: boolean; isFromAar: boolean; error?: string } {
|
|
135
181
|
try {
|
|
136
|
-
// 检查原有配置是否存在
|
|
137
182
|
const existing = existsSync(SETTINGS_FILE);
|
|
138
183
|
|
|
139
184
|
if (existing) {
|
|
140
|
-
// 读取原有配置
|
|
141
185
|
const originalConfig = readFileSync(SETTINGS_FILE, 'utf-8');
|
|
142
186
|
|
|
143
|
-
// 解析配置检查 router_provider
|
|
144
187
|
let isFromAar = false;
|
|
145
188
|
try {
|
|
146
189
|
const parsedConfig = JSON.parse(originalConfig);
|
|
147
190
|
isFromAar = parsedConfig.router_provider === 'aar';
|
|
148
|
-
} catch
|
|
149
|
-
// 解析失败,不影响备份操作
|
|
191
|
+
} catch {
|
|
150
192
|
isFromAar = false;
|
|
151
193
|
}
|
|
152
194
|
|
|
153
|
-
|
|
154
|
-
|
|
195
|
+
if (!isFromAar) {
|
|
196
|
+
writeFileSync(BACKUP_FILE, originalConfig, 'utf-8');
|
|
197
|
+
}
|
|
155
198
|
|
|
156
199
|
return { success: true, existed: true, isFromAar };
|
|
157
200
|
}
|
|
@@ -189,3 +232,69 @@ function validateAndWriteConfig(config: any): { success: boolean; error?: string
|
|
|
189
232
|
};
|
|
190
233
|
}
|
|
191
234
|
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* 备份文件到 ~/.aar/backups 目录
|
|
238
|
+
*/
|
|
239
|
+
function backupToAar(filePath: string, backupName: string): { success: boolean; backupPath?: string; error?: string } {
|
|
240
|
+
try {
|
|
241
|
+
if (!existsSync(filePath)) {
|
|
242
|
+
return { success: true }; // 文件不存在,无需备份
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!existsSync(AAR_BACKUP_DIR)) {
|
|
246
|
+
mkdirSync(AAR_BACKUP_DIR, { recursive: true });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
250
|
+
const backupPath = join(AAR_BACKUP_DIR, `${backupName}-${timestamp}.json`);
|
|
251
|
+
copyFileSync(filePath, backupPath);
|
|
252
|
+
|
|
253
|
+
return { success: true, backupPath };
|
|
254
|
+
} catch (error: any) {
|
|
255
|
+
return {
|
|
256
|
+
success: false,
|
|
257
|
+
error: `Backup to AAR failed: ${error.message}`,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* 确保 ~/.claude.json 文件中包含 hasCompletedOnboarding: true
|
|
264
|
+
* 这允许用户跳过 Claude 登录使用自定义模型
|
|
265
|
+
*/
|
|
266
|
+
function ensureClaudeOnboarding(): { success: boolean; created: boolean; error?: string } {
|
|
267
|
+
try {
|
|
268
|
+
let config: any = {};
|
|
269
|
+
let created = false;
|
|
270
|
+
|
|
271
|
+
if (existsSync(CLAUDE_JSON_FILE)) {
|
|
272
|
+
try {
|
|
273
|
+
const content = readFileSync(CLAUDE_JSON_FILE, 'utf-8');
|
|
274
|
+
config = JSON.parse(content);
|
|
275
|
+
} catch {
|
|
276
|
+
// 文件存在但解析失败,使用空对象
|
|
277
|
+
config = {};
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
created = true;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// 检查是否已经有 hasCompletedOnboarding
|
|
284
|
+
if (config.hasCompletedOnboarding === true) {
|
|
285
|
+
return { success: true, created: false };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// 添加 hasCompletedOnboarding
|
|
289
|
+
config.hasCompletedOnboarding = true;
|
|
290
|
+
writeFileSync(CLAUDE_JSON_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
291
|
+
|
|
292
|
+
return { success: true, created };
|
|
293
|
+
} catch (error: any) {
|
|
294
|
+
return {
|
|
295
|
+
success: false,
|
|
296
|
+
created: false,
|
|
297
|
+
error: `Failed to update claude.json: ${error.message}`,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import { existsSync, readFileSync, copyFileSync, unlinkSync } from 'fs';
|
|
2
|
+
import { existsSync, readFileSync, copyFileSync, unlinkSync, mkdirSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
|
|
@@ -8,6 +8,9 @@ const CLAUDE_DIR = join(homedir(), '.claude');
|
|
|
8
8
|
const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
|
|
9
9
|
const BACKUP_FILE = join(CLAUDE_DIR, 'settings.json.aar.bak');
|
|
10
10
|
|
|
11
|
+
// AAR 备份目录
|
|
12
|
+
const AAR_BACKUP_DIR = join(homedir(), '.aar', 'backups');
|
|
13
|
+
|
|
11
14
|
/**
|
|
12
15
|
* 还原 Claude IDE 配置
|
|
13
16
|
*/
|
|
@@ -34,6 +37,12 @@ export async function POST(request: NextRequest) {
|
|
|
34
37
|
);
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
// 在还原前,先备份当前配置到 ~/.aar/backups 目录
|
|
41
|
+
const currentBackup = backupToAar(SETTINGS_FILE, 'settings-before-restore');
|
|
42
|
+
if (!currentBackup.success) {
|
|
43
|
+
console.warn('[IDE Restore] Current config backup warning:', currentBackup.error);
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
// 将备份内容复制到原配置文件
|
|
38
47
|
copyFileSync(BACKUP_FILE, SETTINGS_FILE);
|
|
39
48
|
|
|
@@ -93,3 +102,29 @@ export async function DELETE(request: NextRequest) {
|
|
|
93
102
|
);
|
|
94
103
|
}
|
|
95
104
|
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 备份文件到 ~/.aar/backups 目录
|
|
108
|
+
*/
|
|
109
|
+
function backupToAar(filePath: string, backupName: string): { success: boolean; backupPath?: string; error?: string } {
|
|
110
|
+
try {
|
|
111
|
+
if (!existsSync(filePath)) {
|
|
112
|
+
return { success: true }; // 文件不存在,无需备份
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!existsSync(AAR_BACKUP_DIR)) {
|
|
116
|
+
mkdirSync(AAR_BACKUP_DIR, { recursive: true });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
120
|
+
const backupPath = join(AAR_BACKUP_DIR, `${backupName}-${timestamp}.json`);
|
|
121
|
+
copyFileSync(filePath, backupPath);
|
|
122
|
+
|
|
123
|
+
return { success: true, backupPath };
|
|
124
|
+
} catch (error: any) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: `Backup to AAR failed: ${error.message}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
import { getDatabase } from '@/db/database';
|
|
@@ -9,10 +9,16 @@ import { getConfig } from '@/db/queries';
|
|
|
9
9
|
const CLAUDE_DIR = join(homedir(), '.claude');
|
|
10
10
|
const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
|
|
11
11
|
|
|
12
|
+
// Claude 登录配置文件(用于 hasCompletedOnboarding)
|
|
13
|
+
const CLAUDE_JSON_FILE = join(homedir(), '.claude.json');
|
|
14
|
+
|
|
12
15
|
// AAR 临时配置目录和文件
|
|
13
16
|
const AAR_DIR = join(homedir(), '.aar');
|
|
14
17
|
const TEMP_SETTINGS_FILE = join(AAR_DIR, 'settings.tmp.json');
|
|
15
18
|
|
|
19
|
+
// AAR 备份目录
|
|
20
|
+
const AAR_BACKUP_DIR = join(AAR_DIR, 'backups');
|
|
21
|
+
|
|
16
22
|
type SaveRequest = {
|
|
17
23
|
haiku?: string;
|
|
18
24
|
sonnet?: string;
|
|
@@ -64,6 +70,18 @@ export async function POST(request: NextRequest) {
|
|
|
64
70
|
// 已应用当前网关配置,更新 settings.json
|
|
65
71
|
savePath = SETTINGS_FILE;
|
|
66
72
|
saveType = 'applied';
|
|
73
|
+
|
|
74
|
+
// 备份到 ~/.aar/backups 目录
|
|
75
|
+
const settingsBackup = backupToAar(SETTINGS_FILE, 'settings');
|
|
76
|
+
const claudeJsonBackup = backupToAar(CLAUDE_JSON_FILE, 'claude');
|
|
77
|
+
|
|
78
|
+
if (!settingsBackup.success) {
|
|
79
|
+
console.warn('[IDE Save] Settings backup warning:', settingsBackup.error);
|
|
80
|
+
}
|
|
81
|
+
if (!claudeJsonBackup.success) {
|
|
82
|
+
console.warn('[IDE Save] Claude.json backup warning:', claudeJsonBackup.error);
|
|
83
|
+
}
|
|
84
|
+
|
|
67
85
|
mergedConfig = generateClaudeConfig(gatewayAddress, gatewayApiKey, {
|
|
68
86
|
haiku: haiku,
|
|
69
87
|
sonnet: sonnet,
|
|
@@ -71,6 +89,12 @@ export async function POST(request: NextRequest) {
|
|
|
71
89
|
default: defaultModel,
|
|
72
90
|
reasoning: reasoningModel
|
|
73
91
|
});
|
|
92
|
+
|
|
93
|
+
// 确保 ~/.claude.json 包含 hasCompletedOnboarding: true
|
|
94
|
+
const onboardingResult = ensureClaudeOnboarding();
|
|
95
|
+
if (!onboardingResult.success) {
|
|
96
|
+
console.warn('[IDE Save] Onboarding update warning:', onboardingResult.error);
|
|
97
|
+
}
|
|
74
98
|
} else {
|
|
75
99
|
// 未应用网络关配置,保存到临时文件 ~/.aar/settings.tmp.json
|
|
76
100
|
savePath = TEMP_SETTINGS_FILE;
|
|
@@ -179,3 +203,69 @@ function generateClaudeConfig(
|
|
|
179
203
|
},
|
|
180
204
|
};
|
|
181
205
|
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 备份文件到 ~/.aar/backups 目录
|
|
209
|
+
*/
|
|
210
|
+
function backupToAar(filePath: string, backupName: string): { success: boolean; backupPath?: string; error?: string } {
|
|
211
|
+
try {
|
|
212
|
+
if (!existsSync(filePath)) {
|
|
213
|
+
return { success: true }; // 文件不存在,无需备份
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!existsSync(AAR_BACKUP_DIR)) {
|
|
217
|
+
mkdirSync(AAR_BACKUP_DIR, { recursive: true });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
221
|
+
const backupPath = join(AAR_BACKUP_DIR, `${backupName}-${timestamp}.json`);
|
|
222
|
+
copyFileSync(filePath, backupPath);
|
|
223
|
+
|
|
224
|
+
return { success: true, backupPath };
|
|
225
|
+
} catch (error: any) {
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
error: `Backup to AAR failed: ${error.message}`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* 确保 ~/.claude.json 文件中包含 hasCompletedOnboarding: true
|
|
235
|
+
* 这允许用户跳过 Claude 登录使用自定义模型
|
|
236
|
+
*/
|
|
237
|
+
function ensureClaudeOnboarding(): { success: boolean; created: boolean; error?: string } {
|
|
238
|
+
try {
|
|
239
|
+
let config: any = {};
|
|
240
|
+
let created = false;
|
|
241
|
+
|
|
242
|
+
if (existsSync(CLAUDE_JSON_FILE)) {
|
|
243
|
+
try {
|
|
244
|
+
const content = readFileSync(CLAUDE_JSON_FILE, 'utf-8');
|
|
245
|
+
config = JSON.parse(content);
|
|
246
|
+
} catch {
|
|
247
|
+
// 文件存在但解析失败,使用空对象
|
|
248
|
+
config = {};
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
created = true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 检查是否已经有 hasCompletedOnboarding
|
|
255
|
+
if (config.hasCompletedOnboarding === true) {
|
|
256
|
+
return { success: true, created: false };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// 添加 hasCompletedOnboarding
|
|
260
|
+
config.hasCompletedOnboarding = true;
|
|
261
|
+
writeFileSync(CLAUDE_JSON_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
262
|
+
|
|
263
|
+
return { success: true, created };
|
|
264
|
+
} catch (error: any) {
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
created: false,
|
|
268
|
+
error: `Failed to update claude.json: ${error.message}`,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -29,9 +29,14 @@ type ConfigStatus = {
|
|
|
29
29
|
apiKey?: string;
|
|
30
30
|
lastUpdated?: string | null;
|
|
31
31
|
backupExists: boolean;
|
|
32
|
-
matchCurrentGateway?: boolean; //
|
|
32
|
+
matchCurrentGateway?: boolean; // 是否匹配当前网关配置(仅当 routerProvider === 'aar' 时有效)
|
|
33
33
|
routerProvider?: string; // 路由提供者标识,'aar' 表示配置来自当前工具
|
|
34
34
|
tempMapping?: { haiku?: string; sonnet?: string; opus?: string; default?: string; reasoning?: string }; // 临时配置模型映射
|
|
35
|
+
config?: Record<string, unknown>; // 当前配置文件完整内容,用于「生效中」展示
|
|
36
|
+
/** 当前网关地址(来自数据库),用于预览 */
|
|
37
|
+
currentGatewayAddress?: string;
|
|
38
|
+
/** 当前网关 API Key(来自数据库,脱敏),用于预览 */
|
|
39
|
+
currentGatewayApiKey?: string;
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -60,6 +65,8 @@ export async function GET(request: NextRequest) {
|
|
|
60
65
|
lastUpdated: undefined,
|
|
61
66
|
matchCurrentGateway: false,
|
|
62
67
|
routerProvider: undefined,
|
|
68
|
+
currentGatewayAddress: gatewayAddress,
|
|
69
|
+
currentGatewayApiKey: gatewayApiKey,
|
|
63
70
|
});
|
|
64
71
|
}
|
|
65
72
|
|
|
@@ -98,7 +105,7 @@ export async function GET(request: NextRequest) {
|
|
|
98
105
|
}
|
|
99
106
|
}
|
|
100
107
|
|
|
101
|
-
//
|
|
108
|
+
// 提取配置状态;返回完整 config 供前端在非 AAR 时展示原有配置文件
|
|
102
109
|
const status: ConfigStatus = {
|
|
103
110
|
applied: true,
|
|
104
111
|
modelMapping: extractModelMapping(config),
|
|
@@ -109,6 +116,9 @@ export async function GET(request: NextRequest) {
|
|
|
109
116
|
matchCurrentGateway,
|
|
110
117
|
routerProvider: config.router_provider,
|
|
111
118
|
tempMapping,
|
|
119
|
+
config,
|
|
120
|
+
currentGatewayAddress: gatewayAddress,
|
|
121
|
+
currentGatewayApiKey: gatewayApiKey,
|
|
112
122
|
};
|
|
113
123
|
|
|
114
124
|
return NextResponse.json(status);
|