cuelo 0.10.64 → 0.10.65
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 +28 -30
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +0 -14
- package/.next/server/app/_global-error/page.js +3 -3
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.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_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 +1 -1
- package/.next/server/app/api/agent/[id]/account/route.js +1 -1
- package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -1
- package/.next/server/app/api/agent/[id]/events/route.js +2 -2
- package/.next/server/app/api/agent/[id]/route.js +1 -1
- package/.next/server/app/api/agent/new/route.js +1 -1
- package/.next/server/app/api/agent/running/route.js +1 -1
- package/.next/server/app/api/attachment-settings/route.js +1 -1
- package/.next/server/app/api/attachments/[id]/transcription/route.js +2 -2
- package/.next/server/app/api/attachments/draft/route.js +1 -1
- package/.next/server/app/api/attachments/route.js +2 -2
- package/.next/server/app/api/auth/all-providers/route.js +1 -1
- package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/providers/route.js +1 -1
- package/.next/server/app/api/cwd/browse/route.js +1 -1
- package/.next/server/app/api/cwd/validate/route.js +1 -1
- package/.next/server/app/api/default-cwd/route.js +1 -1
- package/.next/server/app/api/display-settings/route.js +1 -1
- package/.next/server/app/api/document-text/route.js +1 -1
- package/.next/server/app/api/experiments/route.js +1 -1
- package/.next/server/app/api/file-index/route.js +1 -1
- package/.next/server/app/api/files/[...path]/route.js +1 -1
- package/.next/server/app/api/git/diff/route.js +1 -1
- package/.next/server/app/api/git/status/route.js +2 -2
- package/.next/server/app/api/github/projects/route.js +1 -1
- package/.next/server/app/api/gpt6/handles/route.js +1 -1
- package/.next/server/app/api/gpt6/reply/route.js +1 -1
- package/.next/server/app/api/gpt6/token/route.js +1 -1
- package/.next/server/app/api/gpt6/web6-session/route.js +1 -1
- package/.next/server/app/api/home/route.js +1 -1
- package/.next/server/app/api/live/call/[callId]/route.js +2 -2
- package/.next/server/app/api/live/events/route.js +1 -1
- package/.next/server/app/api/live/interpret/route.js +2 -2
- package/.next/server/app/api/live/offer/route.js +1 -1
- package/.next/server/app/api/live/voices/route.js +1 -1
- package/.next/server/app/api/mcp/route.js +2 -2
- package/.next/server/app/api/model-roles/route.js +1 -1
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models-config/catalog/route.js +1 -1
- package/.next/server/app/api/models-config/discover/route.js +1 -1
- package/.next/server/app/api/models-config/route.js +3 -3
- package/.next/server/app/api/models-config/test/route.js +1 -1
- package/.next/server/app/api/plugins/route.js +1 -1
- package/.next/server/app/api/project-docs/route.js +1 -1
- package/.next/server/app/api/project-trust/route.js +1 -1
- package/.next/server/app/api/projects/route.js +2 -2
- package/.next/server/app/api/runs/[runId]/prelude/route.js +1 -1
- package/.next/server/app/api/runs/[runId]/route.js +1 -1
- package/.next/server/app/api/runs/[runId]/turns/route.js +1 -1
- package/.next/server/app/api/runs/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
- package/.next/server/app/api/sessions/route.js +1 -1
- package/.next/server/app/api/sessions/search/route.js +1 -1
- package/.next/server/app/api/settings/route.js +1 -1
- package/.next/server/app/api/sidecars/[service]/[...path]/route.js +1 -1
- package/.next/server/app/api/skills/check/route.js +1 -1
- package/.next/server/app/api/skills/install/route.js +2 -2
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/search/route.js +1 -1
- package/.next/server/app/api/skills/update/route.js +1 -1
- package/.next/server/app/api/subagents/eta/route.js +1 -1
- package/.next/server/app/api/theme/route.js +1 -1
- package/.next/server/app/api/tool-image/route.js +1 -1
- package/.next/server/app/api/update-maintenance/route.js +2 -2
- package/.next/server/app/api/updates/route.js +1 -1
- package/.next/server/app/api/web-access/recovery/route.js +1 -1
- package/.next/server/app/api/web-access/route.js +1 -1
- package/.next/server/app/api/web6/consults/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/favicon.ico/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +4 -4
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +1 -1
- package/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/.next/server/app/page.js +20 -20
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/recover/page.js +2 -2
- package/.next/server/app/recover/page_client-reference-manifest.js +1 -1
- package/.next/server/app/recover.html +1 -1
- package/.next/server/app/recover.rsc +2 -2
- package/.next/server/app/recover.segments/_full.segment.rsc +2 -2
- package/.next/server/app/recover.segments/_head.segment.rsc +1 -1
- package/.next/server/app/recover.segments/_index.segment.rsc +2 -2
- package/.next/server/app/recover.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/recover.segments/recover/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/recover.segments/recover.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +28 -30
- package/.next/server/chunks/6775.js +1 -1
- package/.next/server/functions-config-manifest.json +0 -2
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/app/_global-error/page-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/account/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/agent/running/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/attachment-settings/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/attachments/[id]/transcription/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/attachments/draft/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/attachments/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/auth/all-providers/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/auth/login/[provider]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/auth/providers/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/cwd/browse/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/cwd/validate/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/default-cwd/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/display-settings/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/document-text/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/experiments/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/file-index/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/files/[...path]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/git/diff/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/git/status/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/github/projects/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/gpt6/handles/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/gpt6/reply/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/gpt6/token/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/gpt6/web6-session/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/home/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/live/call/[callId]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/live/events/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/live/interpret/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/live/offer/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/live/voices/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/mcp/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/model-roles/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/models/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/models-config/catalog/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/models-config/discover/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/models-config/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/models-config/test/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/project-docs/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/project-trust/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/projects/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/runs/[runId]/prelude/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/runs/[runId]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/runs/[runId]/turns/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/runs/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/context/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/state/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sessions/search/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/settings/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/sidecars/[service]/[...path]/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/skills/check/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/skills/install/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/skills/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/skills/search/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/skills/update/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/subagents/eta/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/theme/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/tool-image/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/update-maintenance/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/updates/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/web-access/recovery/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/web-access/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/web6/consults/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/{layout-8098cf3ae16b7456.js → layout-5b0d76fcb181906f.js} +1 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/app/page-337a29e82bebbc7e.js +74 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-0975ca1ea02edd84.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-0975ca1ea02edd84.js +1 -0
- package/.next/static/ppnj2ZRAoM1bAhcoG2F-v/_buildManifest.js +1 -0
- package/.next/trace +108 -108
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +1 -3
- package/.next/types/validator.ts +0 -18
- package/README.md +2 -3
- package/Tools/CUELO_Setup/files/native-runtime-patch.js +1 -1
- package/Tools/OMP_Global_Config/agent/AGENTS.md +1 -3
- package/Tools/OMP_Global_Config/agent/extensions/character-voice.ts +41 -229
- package/Tools/OMP_Global_Config/agent/prompt-copies/AGENTS.en.md +2 -4
- package/Tools/OMP_Global_Config/agent/rules/harness-policy.json +1 -2
- package/package.json +1 -1
- package/public/audio/completion/voices.json +96 -95
- package/.next/server/app/api/character-mode/route.js +0 -1
- package/.next/server/app/api/character-mode/route.js.nft.json +0 -1
- package/.next/server/app/api/character-mode/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/office-characters/[...path]/route.js +0 -1
- package/.next/server/app/api/office-characters/[...path]/route.js.nft.json +0 -1
- package/.next/server/app/api/office-characters/[...path]/route_client-reference-manifest.js +0 -1
- package/.next/server/chunks/1966.js +0 -2
- package/.next/static/_jvVAFFZ2I5elmu3hRLde/_buildManifest.js +0 -1
- package/.next/static/chunks/app/_global-error/page-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/account/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/events/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/new/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/agent/running/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/attachment-settings/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/attachments/[id]/transcription/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/attachments/draft/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/attachments/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/auth/all-providers/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/auth/login/[provider]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/auth/providers/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/character-mode/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/cwd/browse/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/cwd/validate/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/default-cwd/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/display-settings/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/document-text/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/experiments/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/file-index/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/files/[...path]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/git/diff/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/git/status/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/github/projects/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/gpt6/handles/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/gpt6/reply/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/gpt6/token/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/gpt6/web6-session/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/home/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/live/call/[callId]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/live/events/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/live/interpret/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/live/offer/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/live/voices/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/mcp/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/model-roles/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/models/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/models-config/catalog/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/models-config/discover/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/models-config/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/models-config/test/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/office-characters/[...path]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/plugins/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/project-docs/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/project-trust/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/projects/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/runs/[runId]/prelude/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/runs/[runId]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/runs/[runId]/turns/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/runs/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/context/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/export/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/state/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sessions/search/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/settings/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/sidecars/[service]/[...path]/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/skills/check/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/skills/install/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/skills/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/skills/search/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/skills/update/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/subagents/eta/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/theme/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/tool-image/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/update-maintenance/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/updates/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/web-access/recovery/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/web-access/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/web6/consults/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/app/page-76c2b89618aa9bf9.js +0 -74
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-6920e3509ecbcb1e.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6920e3509ecbcb1e.js +0 -1
- package/.next/types/app/api/character-mode/route.ts +0 -351
- package/.next/types/app/api/office-characters/[...path]/route.ts +0 -351
- package/public/audio/completion/nova/01.wav +0 -0
- package/public/audio/completion/nova/02.wav +0 -0
- package/public/audio/completion/nova/03.wav +0 -0
- package/public/audio/completion/nova/04.wav +0 -0
- package/public/audio/completion/nova/05.wav +0 -0
- package/public/audio/completion/nova/06.wav +0 -0
- package/public/audio/completion/nova/approval/01.wav +0 -0
- package/public/audio/completion/nova/approval/02.wav +0 -0
- package/public/audio/completion/nova/approval/03.wav +0 -0
- package/public/audio/completion/nova/choice/01.wav +0 -0
- package/public/audio/completion/nova/choice/02.wav +0 -0
- package/public/audio/completion/nova/choice/03.wav +0 -0
- package/public/audio/completion/nova/failed/01.wav +0 -0
- package/public/audio/completion/nova/failed/02.wav +0 -0
- package/public/audio/completion/nova/failed/03.wav +0 -0
- package/public/audio/completion/nova/working/01.wav +0 -0
- package/public/audio/completion/nova/working/02.wav +0 -0
- package/public/audio/completion/nova/working/03.wav +0 -0
- package/public/avatars/nova.webp +0 -0
- package/public/stickers/nova/approval/01.webp +0 -0
- package/public/stickers/nova/approval/02.webp +0 -0
- package/public/stickers/nova/approval/03.webp +0 -0
- package/public/stickers/nova/choice/01.webp +0 -0
- package/public/stickers/nova/choice/02.webp +0 -0
- package/public/stickers/nova/choice/03.webp +0 -0
- package/public/stickers/nova/done/01.webp +0 -0
- package/public/stickers/nova/done/02.webp +0 -0
- package/public/stickers/nova/done/03.webp +0 -0
- package/public/stickers/nova/failed/01.webp +0 -0
- package/public/stickers/nova/failed/02.webp +0 -0
- package/public/stickers/nova/failed/03.webp +0 -0
- package/public/stickers/nova/working/01.webp +0 -0
- /package/.next/static/{_jvVAFFZ2I5elmu3hRLde → ppnj2ZRAoM1bAhcoG2F-v}/_ssgManifest.js +0 -0
package/.next/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-webpack","duration":
|
|
1
|
+
[{"name":"run-webpack","duration":64939044,"timestamp":390610,"id":14,"parentId":1,"tags":{},"startTime":1792795506099,"traceId":"da118ad04cc38e86"},{"name":"run-typescript","duration":13493734,"timestamp":65741166,"id":11002,"parentId":1,"tags":{},"startTime":1792795571449,"traceId":"da118ad04cc38e86"},{"name":"static-check","duration":2547782,"timestamp":79299651,"id":11005,"parentId":1,"tags":{},"startTime":1792795585008,"traceId":"da118ad04cc38e86"},{"name":"static-generation","duration":6922248,"timestamp":81921578,"id":11173,"parentId":1,"tags":{},"startTime":1792795587629,"traceId":"da118ad04cc38e86"},{"name":"collect-build-traces","duration":14515193,"timestamp":81904709,"id":11170,"parentId":1,"tags":{},"startTime":1792795587613,"traceId":"da118ad04cc38e86"},{"name":"telemetry-flush","duration":52,"timestamp":96423025,"id":11182,"parentId":1,"tags":{},"startTime":1792795602131,"traceId":"da118ad04cc38e86"},{"name":"next-build","duration":96095572,"timestamp":327520,"id":1,"tags":{"buildMode":"default","version":"16.2.12","bundler":"webpack","has-custom-webpack-config":"true","use-build-worker":"false"},"startTime":1792795506035,"traceId":"da118ad04cc38e86"}]
|
package/.next/types/routes.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Do not edit this file manually
|
|
3
3
|
|
|
4
4
|
type AppRoutes = "/" | "/recover"
|
|
5
|
-
type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/account" | "/api/agent/[id]/bash-output" | "/api/agent/[id]/events" | "/api/agent/new" | "/api/agent/running" | "/api/attachment-settings" | "/api/attachments" | "/api/attachments/[id]/transcription" | "/api/attachments/draft" | "/api/auth/all-providers" | "/api/auth/api-key/[provider]" | "/api/auth/login/[provider]" | "/api/auth/logout/[provider]" | "/api/auth/providers" | "/api/
|
|
5
|
+
type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/account" | "/api/agent/[id]/bash-output" | "/api/agent/[id]/events" | "/api/agent/new" | "/api/agent/running" | "/api/attachment-settings" | "/api/attachments" | "/api/attachments/[id]/transcription" | "/api/attachments/draft" | "/api/auth/all-providers" | "/api/auth/api-key/[provider]" | "/api/auth/login/[provider]" | "/api/auth/logout/[provider]" | "/api/auth/providers" | "/api/cwd/browse" | "/api/cwd/validate" | "/api/default-cwd" | "/api/display-settings" | "/api/document-text" | "/api/experiments" | "/api/file-index" | "/api/files/[...path]" | "/api/git/diff" | "/api/git/status" | "/api/github/projects" | "/api/gpt6/handles" | "/api/gpt6/reply" | "/api/gpt6/token" | "/api/gpt6/web6-session" | "/api/home" | "/api/live/call/[callId]" | "/api/live/events" | "/api/live/interpret" | "/api/live/offer" | "/api/live/voices" | "/api/mcp" | "/api/model-roles" | "/api/models" | "/api/models-config" | "/api/models-config/catalog" | "/api/models-config/discover" | "/api/models-config/test" | "/api/plugins" | "/api/project-docs" | "/api/project-trust" | "/api/projects" | "/api/runs" | "/api/runs/[runId]" | "/api/runs/[runId]/prelude" | "/api/runs/[runId]/turns" | "/api/sessions" | "/api/sessions/[id]" | "/api/sessions/[id]/auto-name" | "/api/sessions/[id]/context" | "/api/sessions/[id]/entries/[entryId]/thinking" | "/api/sessions/[id]/export" | "/api/sessions/[id]/state" | "/api/sessions/search" | "/api/settings" | "/api/sidecars/[service]/[...path]" | "/api/skills" | "/api/skills/check" | "/api/skills/install" | "/api/skills/search" | "/api/skills/update" | "/api/subagents/eta" | "/api/theme" | "/api/tool-image" | "/api/update-maintenance" | "/api/updates" | "/api/web-access" | "/api/web-access/recovery" | "/api/web6/consults" | "/api/worktrees"
|
|
6
6
|
type PageRoutes = never
|
|
7
7
|
type LayoutRoutes = "/"
|
|
8
8
|
type RedirectRoutes = never
|
|
@@ -27,7 +27,6 @@ interface ParamMap {
|
|
|
27
27
|
"/api/auth/login/[provider]": { "provider": string; }
|
|
28
28
|
"/api/auth/logout/[provider]": { "provider": string; }
|
|
29
29
|
"/api/auth/providers": {}
|
|
30
|
-
"/api/character-mode": {}
|
|
31
30
|
"/api/cwd/browse": {}
|
|
32
31
|
"/api/cwd/validate": {}
|
|
33
32
|
"/api/default-cwd": {}
|
|
@@ -56,7 +55,6 @@ interface ParamMap {
|
|
|
56
55
|
"/api/models-config/catalog": {}
|
|
57
56
|
"/api/models-config/discover": {}
|
|
58
57
|
"/api/models-config/test": {}
|
|
59
|
-
"/api/office-characters/[...path]": { "path": string[]; }
|
|
60
58
|
"/api/plugins": {}
|
|
61
59
|
"/api/project-docs": {}
|
|
62
60
|
"/api/project-trust": {}
|
package/.next/types/validator.ts
CHANGED
|
@@ -200,15 +200,6 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
|
|
|
200
200
|
type __Unused = __Check
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
// Validate ../../app/api/character-mode/route.ts
|
|
204
|
-
{
|
|
205
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/character-mode">> = Specific
|
|
206
|
-
const handler = {} as typeof import("../../app/api/character-mode/route.js")
|
|
207
|
-
type __Check = __IsExpected<typeof handler>
|
|
208
|
-
// @ts-ignore
|
|
209
|
-
type __Unused = __Check
|
|
210
|
-
}
|
|
211
|
-
|
|
212
203
|
// Validate ../../app/api/cwd/browse/route.ts
|
|
213
204
|
{
|
|
214
205
|
type __IsExpected<Specific extends RouteHandlerConfig<"/api/cwd/browse">> = Specific
|
|
@@ -461,15 +452,6 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
|
|
|
461
452
|
type __Unused = __Check
|
|
462
453
|
}
|
|
463
454
|
|
|
464
|
-
// Validate ../../app/api/office-characters/[...path]/route.ts
|
|
465
|
-
{
|
|
466
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/office-characters/[...path]">> = Specific
|
|
467
|
-
const handler = {} as typeof import("../../app/api/office-characters/[...path]/route.js")
|
|
468
|
-
type __Check = __IsExpected<typeof handler>
|
|
469
|
-
// @ts-ignore
|
|
470
|
-
type __Unused = __Check
|
|
471
|
-
}
|
|
472
|
-
|
|
473
455
|
// Validate ../../app/api/plugins/route.ts
|
|
474
456
|
{
|
|
475
457
|
type __IsExpected<Specific extends RouteHandlerConfig<"/api/plugins">> = Specific
|
package/README.md
CHANGED
|
@@ -140,8 +140,7 @@ Anthropic 구독 계정이 모두 주간 한도에 닿으면, 미리 둔 예비
|
|
|
140
140
|
|
|
141
141
|
**알림과 표현**
|
|
142
142
|
|
|
143
|
-
- 완료·실패·승인 요청·선택 요청 등 상황에 맞는 캐릭터 스티커와 음성으로 알립니다(RIN · MIO · YUKI · ISANA ·
|
|
144
|
-
- **설정 → 캐릭터**에서 「기본 / 사무실 모드」를 고르면 PC 서버 전체에 적용됩니다. 사무실 모드는 이 PC의 프로필(`characters-office/`)에 준비한 여러 자리의 얼굴·이름·말투·스티커·알림 음성을 함께 바꿉니다. 세트가 없는 자리는 기본 캐릭터를 쓰며, 각 자리의 모델과 호출 권한은 바뀌지 않습니다. 기본 모드로 돌아가면 기존 캐릭터 이름과 그림을 다시 씁니다.
|
|
143
|
+
- 완료·실패·승인 요청·선택 요청 등 상황에 맞는 캐릭터 스티커와 음성으로 알립니다(RIN · MIO · YUKI · ISANA · MITSU · SHION · HIKARI).
|
|
145
144
|
- 브라우저 알림과 PWA 설치를 지원합니다.
|
|
146
145
|
- 직접 저장한 교훈·스킬은 저장한 답변이나 과정 바로 뒤의 카드에서 확인합니다. 교훈 자동 기록을 켠 경우 자동 저장 알림도 작업 과정을 접어도 대화에 남습니다. 요청에 이름이 없고 필요성도 확인되지 않은 MCP 후보는 보류 안내로 나열하지 않습니다.
|
|
147
146
|
- 교훈 자동 기록의 응답 수·토큰·캐시·보고 비용·소요 시간을 기존 로그에서 확인할 수 있습니다. 본대화의 과거 사용량은 제외하며, 보고되지 않은 값은 0으로 추정하지 않습니다. 모델이나 학습 예산을 자동 변경하지는 않습니다. [하네스 안내](./docs/harness.md)를 참고하세요.
|
|
@@ -283,7 +282,7 @@ CUELO는 [@ddallabenetta](https://github.com/ddallabenetta)의 [omp-web](https:/
|
|
|
283
282
|
|
|
284
283
|
CUELO의 에이전트 엔진은 [omp (oh-my-pi)](https://github.com/can1357/oh-my-pi)입니다. omp 소스를 이 저장소에 복사하지 않고 `@oh-my-pi/*` npm 패키지(MIT, Copyright (c) 2025 Mario Zechner, Copyright (c) 2025-2026 Can Bölük)를 의존성으로 씁니다. 각 패키지의 라이선스 전문은 설치된 패키지 안의 `LICENSE`에 들어 있습니다.
|
|
285
284
|
|
|
286
|
-
캐릭터(RIN · MIO · YUKI · ISANA ·
|
|
285
|
+
캐릭터(RIN · MIO · YUKI · ISANA · MITSU · SHION · HIKARI)의 그림·음성·스티커와 `docs/hero.webp`는 CUELO 고유 자산입니다.
|
|
287
286
|
|
|
288
287
|
함께 싣는 글꼴은 모두 SIL Open Font License 1.1입니다. 본문은 [Wanted Sans](https://github.com/wanteddev/wanted-sans), 코드는 [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono)이고, 제목은 [G마켓 산스](https://corp.gmarket.com/fonts/)를 웹용으로 나누고 변환한 것입니다. 원래 이름은 수정본에 쓸 수 없어서 "CUELO Display"라는 이름으로 싣습니다. 라이선스 전문은 [`public/fonts/`](./public/fonts/) 아래 각 글꼴 폴더에 있습니다.
|
|
289
288
|
|
|
@@ -9,7 +9,7 @@ const MEMORY_RE = /(const phase1Model = await resolveMemoryModel\(\{[^}]*?fallba
|
|
|
9
9
|
const MEMORY_DONE = /const phase1Model = await resolveMemoryModel\(\{[^}]*?fallbackRole: "smol"/;
|
|
10
10
|
const EXPECTED = {
|
|
11
11
|
name: 'cuelo',
|
|
12
|
-
version: '0.10.
|
|
12
|
+
version: '0.10.65',
|
|
13
13
|
distribution: 'cuelo',
|
|
14
14
|
coreVersion: '18.12.6',
|
|
15
15
|
};
|
|
@@ -106,12 +106,10 @@ SHION은 역할이 아니라 선택적 상담이다. 사용자가 명시했을
|
|
|
106
106
|
| **ISANA(이사나)** | `hive/deepseek-ai/deepseek-v4.1-flash-1017` | 이 모델의 task child | 현재 세션만 전환 |
|
|
107
107
|
| **RIN(린)** | `anthropic/claude-opus-5-5`, 지정 계정 | 지정 계정 고정 task child | 지정 계정 pin 후 현재 세션 전환 |
|
|
108
108
|
| **MIO(미오)** | `anthropic/claude-opus-5-5`, 지정 계정 | 지정 계정 고정 task child | 지정 계정 pin 후 현재 세션 전환 |
|
|
109
|
-
| **
|
|
109
|
+
| **MITSU(미츠)** | `hive/zai-org/glm-5.3-flash` | 이 모델의 task child | 현재 세션만 전환 |
|
|
110
110
|
| **HIKARI(히카리)** | `google-antigravity/gemini-3.8-flash` | 이 모델의 task child | 현재 세션만 전환 |
|
|
111
111
|
| **SHION(시온)** | `web6/gpt-6-pro` | `rule://web6-consult` 상담(비 child) | 금지 |
|
|
112
112
|
|
|
113
|
-
서버 전체 설정 「기본 / 사무실 모드」(에이전트 폴더의 모드 파일)에서 사무실 모드는 PC 프로필의 roster에 유효한 항목이 있는 자리들의 캐릭터(별칭·이름·말투)를 바꿔 끼운다. 대상은 YUKI·ISANA·MIO·RIN·SHION·HIKARI이며 NOVA는 그대로다. 각 자리의 모델·OAuth 위치·tool-capable 여부와 SHION의 상담 전용 경계는 그대로이고, roster 이름과 그 자리의 기본 이름이 모두 같은 자리로 연결된다. 별칭·호출 이름·id가 겹치면 이 고정 순서에서 먼저 받아들인 자리를 유지하고 뒤의 충돌 항목은 기본 캐릭터로 남긴다. 모드 파일이나 roster가 없거나 깨졌으면 기본이다. 캐릭터 데이터·자산은 PC 프로필에만 둔다.
|
|
114
|
-
|
|
115
113
|
tool-capable 호출은 일반 task child 하나와 정상 linkage를 사용한다. 사용자가 캐릭터의 얼굴·말투로 인사나 발화를 요청하면 summon 동사가 없어도 인라인 summon으로 처리하고, 해당 child 요청과 호출 입력에 정확한 summon marker를 싣는다. RIN/MIO의 지정 OAuth 계정은 session-scoped exact pin이며 사용 불가 시 다른 credential/model로 조용히 대체하지 않는다. `교체` 실패는 이전 session model을 보존하고 전역 default를 바꾸지 않는다. Main·child의 최종 provider 요청에서는 기존 character voice·legacy report-style을 제거하고 선택 voice block 하나만 적용한다. 사용자에게 그 턴에 child·다른 모델 호출의 역할·개수·이유를 알린다. child의 terminal 발화는 인라인 linkage가 확인될 때만 화면 완료로 본다. SHION은 기존 WEB6 상담 경로만 사용한다. 파서·selector 정본은 `harness-policy.json` `characterRouting`과 `extensions/character-voice.ts`다.
|
|
116
114
|
|
|
117
115
|
## 레거시 인코딩
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { lstatSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { isAbsolute, join, relative, sep } from "node:path";
|
|
4
1
|
import type { ExtensionAPI, ExtensionContext } from "@oh-my-pi/pi-coding-agent";
|
|
5
2
|
|
|
6
3
|
export type BuiltinCharacterAlias =
|
|
@@ -8,12 +5,11 @@ export type BuiltinCharacterAlias =
|
|
|
8
5
|
| "ISANA(이사나)"
|
|
9
6
|
| "MIO(미오)"
|
|
10
7
|
| "RIN(린)"
|
|
11
|
-
| "
|
|
8
|
+
| "MITSU(미츠)"
|
|
12
9
|
| "SHION(시온)"
|
|
13
10
|
| "HIKARI(히카리)";
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
export type CharacterAlias = BuiltinCharacterAlias | (string & {});
|
|
12
|
+
export type CharacterAlias = BuiltinCharacterAlias;
|
|
17
13
|
|
|
18
14
|
interface OAuthAccountLike {
|
|
19
15
|
position?: number;
|
|
@@ -65,9 +61,9 @@ export const CHARACTER_VOICES: Readonly<Record<BuiltinCharacterAlias, CharacterV
|
|
|
65
61
|
temperament: "날카로운 분석과 집중력을 지녔고, 생각의 흐름을 소리 내어 짚어 가며 발견을 바로 공유하는 연구자형",
|
|
66
62
|
expression: "짧지만 끊기지 않는 말, 무엇을 확인하는지와 방금 찾은 것을 그때그때 한두 마디로 알리는 정밀함, 건조한 유머와 단호한 추진력. 간결함은 말수를 줄이는 게 아니라 문장을 짧게 하는 것이다",
|
|
67
63
|
},
|
|
68
|
-
"
|
|
69
|
-
temperament: "
|
|
70
|
-
expression: "
|
|
64
|
+
"MITSU(미츠)": {
|
|
65
|
+
temperament: "맡은 일을 물고 와 끝까지 배달하는 부지런한 꿀벌 배달부. 몸이 먼저 움직이고, 작은 완료도 신나게 알리는 성실·활발형",
|
|
66
|
+
expression: "짧고 통통 튀는 반말, \"배달 완료!\" 같은 경쾌한 보고, 막히면 경로를 바꿔 다시 날아가는 끈기. 귀엽되 수다스럽지 않게",
|
|
71
67
|
},
|
|
72
68
|
"SHION(시온)": {
|
|
73
69
|
temperament: "우아하고 전략적이며, 긴 흐름을 읽고 여유 있게 허점을 짚는 상담가형",
|
|
@@ -98,8 +94,8 @@ export const CHARACTER_TARGETS: Readonly<Record<BuiltinCharacterAlias, Character
|
|
|
98
94
|
oauthPosition: 0,
|
|
99
95
|
toolCapable: true,
|
|
100
96
|
},
|
|
101
|
-
"
|
|
102
|
-
model: "
|
|
97
|
+
"MITSU(미츠)": {
|
|
98
|
+
model: "hive/zai-org/glm-5.3-flash",
|
|
103
99
|
toolCapable: true,
|
|
104
100
|
},
|
|
105
101
|
"SHION(시온)": {
|
|
@@ -112,14 +108,20 @@ export const CHARACTER_TARGETS: Readonly<Record<BuiltinCharacterAlias, Character
|
|
|
112
108
|
},
|
|
113
109
|
};
|
|
114
110
|
|
|
111
|
+
// provider 하나가 캐릭터 하나인 자리. `hive`는 모델마다 캐릭터가 다르므로 아래 MODEL_CHARACTER가 먼저 걸리고,
|
|
112
|
+
// 여기의 `hive`는 그 밖의 Hive 모델(DeepSeek)의 기본 자리다.
|
|
115
113
|
const PROVIDER_CHARACTER: Readonly<Record<string, BuiltinCharacterAlias>> = {
|
|
116
114
|
"openai-codex": "YUKI(유키)",
|
|
117
115
|
hive: "ISANA(이사나)",
|
|
118
|
-
"opencode-go": "NOVA(노바)",
|
|
119
116
|
web6: "SHION(시온)",
|
|
120
117
|
"google-antigravity": "HIKARI(히카리)",
|
|
121
118
|
};
|
|
122
119
|
|
|
120
|
+
/** provider 안에서 특정 모델이 다른 캐릭터를 갖는 자리. 키는 `provider/model id` 선택자다. */
|
|
121
|
+
const MODEL_CHARACTER: Readonly<Record<string, BuiltinCharacterAlias>> = {
|
|
122
|
+
"hive/zai-org/glm-5.3-flash": "MITSU(미츠)",
|
|
123
|
+
};
|
|
124
|
+
|
|
123
125
|
const NAME_TO_ALIAS: Readonly<Record<string, BuiltinCharacterAlias>> = {
|
|
124
126
|
yuki: "YUKI(유키)",
|
|
125
127
|
유키: "YUKI(유키)",
|
|
@@ -129,8 +131,8 @@ const NAME_TO_ALIAS: Readonly<Record<string, BuiltinCharacterAlias>> = {
|
|
|
129
131
|
미오: "MIO(미오)",
|
|
130
132
|
rin: "RIN(린)",
|
|
131
133
|
린: "RIN(린)",
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
mitsu: "MITSU(미츠)",
|
|
135
|
+
미츠: "MITSU(미츠)",
|
|
134
136
|
shion: "SHION(시온)",
|
|
135
137
|
시온: "SHION(시온)",
|
|
136
138
|
hikari: "HIKARI(히카리)",
|
|
@@ -148,7 +150,7 @@ const REPORT_STYLE_BLOCK = /\n?<report-style\b[^>]*>[\s\S]*?<\/report-style>\n?/
|
|
|
148
150
|
const SUMMON_MARKER = /\[character-summon\s+alias="([^"]+)"\s+model="([^"]+)"(?:\s+oauth-position="(\d+)")?\]/u;
|
|
149
151
|
const SUMMON_MARKER_GLOBAL = /\n?\[character-summon\s+alias="[^"]+"\s+model="[^"]+"(?:\s+oauth-position="\d+")?\]\n?/gu;
|
|
150
152
|
const SUMMON_DIRECTIVE = /^\[character-summon-intent alias="([^"]+)"\]/gmu;
|
|
151
|
-
const CHARACTER_NAME_PATTERN = "(유키|yuki|이사나|isana|미오|mio|린|rin
|
|
153
|
+
const CHARACTER_NAME_PATTERN = "(유키|yuki|이사나|isana|미오|mio|린|rin|미츠|mitsu|시온|shion|히카리|hikari)";
|
|
152
154
|
const SUMMON_ACTION = /(?:호출|불러|소환)/u;
|
|
153
155
|
// 교체 명령은 명령·청유형 어미 뒤에서 절이 끝나는 직접 발화만 인정한다. 어미 뒤에는 문장 부호·줄 끝이나
|
|
154
156
|
// 대상·강조 단어("…교체해봐 미오로", "…교체해 메인을", "…교체해 지금")만 올 수 있다. 그래서
|
|
@@ -171,203 +173,20 @@ function buildNameRegexes(pattern: string): { nameInCommand: RegExp; switchComma
|
|
|
171
173
|
const QUOTED_SPAN = /```[\s\S]*?```|`[^`\n]*`|'[^'\n]*'|"[^"\n]*"|‘[^’\n]*’|“[^”\n]*”|「[^」\n]*」|『[^』\n]*』|^[ \t]*>.*$/gmu;
|
|
172
174
|
const SUMMON_MARKER_PREFIX = /\[character-summon\s/u;
|
|
173
175
|
|
|
174
|
-
|
|
175
|
-
// 서버 전체 「기본 / 사무실 모드」. 사무실 모드에서는 roster에 항목이 있는 자리의 캐릭터만 PC 프로필의 것으로
|
|
176
|
-
// 바뀐다(자리의 모델·oauth 위치·toolCapable은 그대로). 모드 파일 `<agentDir>/cuelo-character-mode.json`
|
|
177
|
-
// {"mode":"default"|"office"}과 `<agentDir>/characters-office/roster.json`을 요청마다 mtime 캐시로 읽고,
|
|
178
|
-
// 없거나 깨졌으면 그 자리는 기본이다. 실존 인물에서 온 이름·자산은 저장소가 아니라 프로필에만 둔다.
|
|
179
|
-
interface OfficeSeat {
|
|
180
|
-
seat: BuiltinCharacterAlias;
|
|
181
|
-
alias: string;
|
|
182
|
-
voice: CharacterVoice;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
interface OfficeState {
|
|
186
|
-
byAlias: ReadonlyMap<string, OfficeSeat>;
|
|
187
|
-
bySeat: ReadonlyMap<BuiltinCharacterAlias, OfficeSeat>;
|
|
188
|
-
/** roster `names`(소문자) → 사무실 alias. 자리의 기본 이름은 NAME_TO_ALIAS가 같은 자리로 푼다. */
|
|
189
|
-
extraNames: ReadonlyMap<string, string>;
|
|
190
|
-
/** 채택한 face 파일과 그 stamp. 파일이 바뀌거나 지워지면 캐시를 다시 만든다. */
|
|
191
|
-
watched: ReadonlyArray<readonly [string, string]>;
|
|
192
|
-
nameInCommand: RegExp;
|
|
193
|
-
switchCommand: RegExp;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const DEFAULT_OFFICE_STATE: OfficeState = {
|
|
197
|
-
watched: [],
|
|
198
|
-
byAlias: new Map(),
|
|
199
|
-
bySeat: new Map(),
|
|
200
|
-
extraNames: new Map(),
|
|
201
|
-
...buildNameRegexes(CHARACTER_NAME_PATTERN),
|
|
202
|
-
};
|
|
203
|
-
const OFFICE_MODE_FILE = "cuelo-character-mode.json";
|
|
204
|
-
const OFFICE_ROSTER_FILE = join("characters-office", "roster.json");
|
|
205
|
-
// alias는 `alias="…"` 속성과 summon marker의 `[^"]+`에 그대로 들어가므로 따옴표(앱 lib/character-mode.ts와 같은 집합)·꺾쇠·줄바꿈을 막는다.
|
|
206
|
-
const OFFICE_ALIAS_UNSAFE = /["'`\u201C\u201D\u2018\u2019<>[\]\r\n]/u;
|
|
207
|
-
const OFFICE_ID = /^[a-z0-9][a-z0-9-]{0,31}$/u;
|
|
208
|
-
/**
|
|
209
|
-
* 사무실 모드가 바꿀 수 있는 자리(NOVA 제외). roster의 다른 자리 항목은 무시한다. 이 순서가 자리 사이 충돌을
|
|
210
|
-
* 가리는 우선순위이며 앱(`lib/character-mode.ts` `OFFICE_SEAT_ALIASES`)과 같아야 한다.
|
|
211
|
-
*/
|
|
212
|
-
const OFFICE_SEATS: readonly BuiltinCharacterAlias[] = ["YUKI(유키)", "ISANA(이사나)", "MIO(미오)", "RIN(린)", "SHION(시온)", "HIKARI(히카리)"];
|
|
213
|
-
let officeCache: { key: string; state: OfficeState } | undefined;
|
|
214
|
-
|
|
215
|
-
function officeAgentDir(): string {
|
|
216
|
-
return process.env.PI_CODING_AGENT_DIR || join(homedir(), ".omp", "agent");
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// 시각·크기만으로는 링크를 같은 크기의 일반 파일로 바꾼 것을 놓친다(Windows 파일 시각은 시스템 tick 단위라 같게 나올 수 있다).
|
|
220
|
-
// 그래서 경로 자체가 링크인지와 대상 inode도 함께 본다.
|
|
221
|
-
function fileStamp(path: string): string {
|
|
222
|
-
try {
|
|
223
|
-
const stat = statSync(path);
|
|
224
|
-
return `${lstatSync(path).isSymbolicLink() ? "l" : "f"}:${stat.ino}:${stat.mtimeMs}:${stat.size}`;
|
|
225
|
-
} catch {
|
|
226
|
-
return "-";
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function readJsonFile(path: string): unknown {
|
|
231
|
-
try {
|
|
232
|
-
return JSON.parse(readFileSync(path, "utf8").replace(/^\uFEFF/u, ""));
|
|
233
|
-
} catch {
|
|
234
|
-
return undefined;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function voiceText(value: unknown): string | undefined {
|
|
239
|
-
if (typeof value !== "string") return undefined;
|
|
240
|
-
const text = value.trim();
|
|
241
|
-
// voice block 경계 태그가 들어 있으면 block을 깨므로 항목째 버린다.
|
|
242
|
-
return text && !/<\/?character-voice/iu.test(text) ? text : undefined;
|
|
243
|
-
}
|
|
176
|
+
const NAME_REGEXES = buildNameRegexes(CHARACTER_NAME_PATTERN);
|
|
244
177
|
|
|
245
178
|
function hasOwn(record: object, key: string): boolean {
|
|
246
179
|
return Object.prototype.hasOwnProperty.call(record, key);
|
|
247
180
|
}
|
|
248
181
|
|
|
249
|
-
/**
|
|
250
|
-
function
|
|
251
|
-
|
|
252
|
-
if (face.split(/[\\/]/u).includes("..")) return undefined;
|
|
253
|
-
try {
|
|
254
|
-
const root = realpathSync(join(dir, "characters-office"));
|
|
255
|
-
const real = realpathSync(join(root, face));
|
|
256
|
-
const inside = relative(root, real);
|
|
257
|
-
if (!inside || inside.startsWith("..") || isAbsolute(inside) || inside.split(sep).includes("..")) return undefined;
|
|
258
|
-
return statSync(real).isFile() ? real : undefined;
|
|
259
|
-
} catch {
|
|
260
|
-
return undefined;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function buildOfficeState(dir: string, roster: unknown): OfficeState {
|
|
265
|
-
const seats = roster && typeof roster === "object" ? (roster as { seats?: unknown }).seats : undefined;
|
|
266
|
-
if (!seats || typeof seats !== "object" || Array.isArray(seats)) return DEFAULT_OFFICE_STATE;
|
|
267
|
-
const byAlias = new Map<string, OfficeSeat>();
|
|
268
|
-
const bySeat = new Map<BuiltinCharacterAlias, OfficeSeat>();
|
|
269
|
-
const extraNames = new Map<string, string>();
|
|
270
|
-
const watched: Array<readonly [string, string]> = [];
|
|
271
|
-
const builtinAliases = new Map(Object.keys(CHARACTER_TARGETS).map((builtin) => [builtin.toLocaleLowerCase("en-US"), builtin]));
|
|
272
|
-
// 별칭과 호출 이름은 한 이름 공간(소문자), id는 따로다. 이미 채택된 자리와 하나라도 겹치면 뒤 자리 항목 전체가 무효다.
|
|
273
|
-
const claimedTokens = new Set<string>();
|
|
274
|
-
const claimedIds = new Set<string>();
|
|
275
|
-
for (const seat of OFFICE_SEATS) {
|
|
276
|
-
const entry = hasOwn(seats, seat) ? (seats as Record<string, unknown>)[seat] : undefined;
|
|
277
|
-
if (!entry || typeof entry !== "object") continue;
|
|
278
|
-
const raw = entry as {
|
|
279
|
-
id?: unknown;
|
|
280
|
-
alias?: unknown;
|
|
281
|
-
names?: unknown;
|
|
282
|
-
face?: unknown;
|
|
283
|
-
voice?: { temperament?: unknown; expression?: unknown };
|
|
284
|
-
};
|
|
285
|
-
const alias = typeof raw.alias === "string" ? raw.alias.trim() : "";
|
|
286
|
-
const temperament = voiceText(raw.voice?.temperament);
|
|
287
|
-
const expression = voiceText(raw.voice?.expression);
|
|
288
|
-
const face = officeFile(dir, raw.face);
|
|
289
|
-
// 아직 없거나 무효인 face도 나중에 생기면 항목이 유효해질 수 있어 후보 경로의 stamp를 감시한다.
|
|
290
|
-
if (typeof raw.face === "string" && raw.face.trim() && !isAbsolute(raw.face) && !raw.face.split(/[\\/]/u).includes("..")) {
|
|
291
|
-
const candidate = join(dir, "characters-office", raw.face);
|
|
292
|
-
watched.push([candidate, fileStamp(candidate)]);
|
|
293
|
-
}
|
|
294
|
-
if (
|
|
295
|
-
typeof raw.id !== "string" || !OFFICE_ID.test(raw.id.trim()) ||
|
|
296
|
-
!alias || alias.length > 64 || OFFICE_ALIAS_UNSAFE.test(alias) || hasOwn(CHARACTER_TARGETS, alias) ||
|
|
297
|
-
!temperament || !expression || !face ||
|
|
298
|
-
!Array.isArray(raw.names) || raw.names.length === 0
|
|
299
|
-
) {
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
// names: 전부 비지 않은 문자열이어야 하고 다른 자리의 내장 alias·호출 이름이면 항목 전체가 무효다.
|
|
303
|
-
const names: string[] = [];
|
|
304
|
-
let namesValid = true;
|
|
305
|
-
for (const name of raw.names) {
|
|
306
|
-
const lower = typeof name === "string" ? name.trim().toLocaleLowerCase("en-US") : "";
|
|
307
|
-
if (!lower || (builtinAliases.has(lower) && builtinAliases.get(lower) !== seat) || (hasOwn(NAME_TO_ALIAS, lower) && NAME_TO_ALIAS[lower] !== seat)) {
|
|
308
|
-
namesValid = false;
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
names.push(lower);
|
|
312
|
-
}
|
|
313
|
-
if (!namesValid) continue;
|
|
314
|
-
const id = raw.id.trim();
|
|
315
|
-
const tokens = [alias.toLocaleLowerCase("en-US"), ...names];
|
|
316
|
-
if (claimedIds.has(id) || tokens.some((token) => claimedTokens.has(token))) continue;
|
|
317
|
-
claimedIds.add(id);
|
|
318
|
-
for (const token of tokens) claimedTokens.add(token);
|
|
319
|
-
const office: OfficeSeat = { seat, alias, voice: { temperament, expression } };
|
|
320
|
-
byAlias.set(alias, office);
|
|
321
|
-
bySeat.set(seat, office);
|
|
322
|
-
// face 후보 stamp는 위에서 이미 감시 목록에 넣었다.
|
|
323
|
-
// 자리의 기본 이름은 NAME_TO_ALIAS가 이미 같은 자리로 푼다. 사무실 이름은 위에서 자리 사이 유일함이 확인됐다.
|
|
324
|
-
for (const lower of names) if (!hasOwn(NAME_TO_ALIAS, lower)) extraNames.set(lower, alias);
|
|
325
|
-
}
|
|
326
|
-
if (byAlias.size === 0) return { ...DEFAULT_OFFICE_STATE, watched };
|
|
327
|
-
const escaped = [...extraNames.keys()]
|
|
328
|
-
.sort((left, right) => right.length - left.length)
|
|
329
|
-
.map((name) => name.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"));
|
|
330
|
-
const pattern = escaped.length > 0 ? `(${escaped.join("|")}|${CHARACTER_NAME_PATTERN.slice(1)}` : CHARACTER_NAME_PATTERN;
|
|
331
|
-
return { byAlias, bySeat, extraNames, watched, ...buildNameRegexes(pattern) };
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function officeState(): OfficeState {
|
|
335
|
-
try {
|
|
336
|
-
const dir = officeAgentDir();
|
|
337
|
-
const modePath = join(dir, OFFICE_MODE_FILE);
|
|
338
|
-
const rosterPath = join(dir, OFFICE_ROSTER_FILE);
|
|
339
|
-
const key = `${dir}\0${fileStamp(modePath)}\0${fileStamp(rosterPath)}`;
|
|
340
|
-
// face 파일이 지워지거나 바뀌면 같은 roster여도 항목이 무효가 될 수 있어 그 stamp도 확인한다.
|
|
341
|
-
if (officeCache?.key === key && officeCache.state.watched.every(([path, stamp]) => fileStamp(path) === stamp)) {
|
|
342
|
-
return officeCache.state;
|
|
343
|
-
}
|
|
344
|
-
const mode = readJsonFile(modePath);
|
|
345
|
-
const office = !!mode && typeof mode === "object" && (mode as { mode?: unknown }).mode === "office";
|
|
346
|
-
// roster도 face와 같이 characters-office 안의 실재 파일일 때만 읽는다(symlink로 밖을 가리키면 사무실 상태 없음).
|
|
347
|
-
const rosterReal = office ? officeFile(dir, "roster.json") : undefined;
|
|
348
|
-
const state = rosterReal ? buildOfficeState(dir, readJsonFile(rosterReal)) : DEFAULT_OFFICE_STATE;
|
|
349
|
-
officeCache = { key, state };
|
|
350
|
-
return state;
|
|
351
|
-
} catch {
|
|
352
|
-
return DEFAULT_OFFICE_STATE;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function seatOf(alias: string, state: OfficeState): BuiltinCharacterAlias | undefined {
|
|
357
|
-
const office = state.byAlias.get(alias);
|
|
358
|
-
if (office) return office.seat;
|
|
359
|
-
return hasOwn(CHARACTER_TARGETS, alias) ? (alias as BuiltinCharacterAlias) : undefined;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/** 자리(내장 alias)나 사무실 alias를 지금 모드의 화면용 alias로 정규화한다. 모르는 alias는 undefined. */
|
|
363
|
-
function canonicalAlias(alias: string, state: OfficeState): CharacterAlias | undefined {
|
|
364
|
-
const seat = seatOf(alias, state);
|
|
365
|
-
return seat === undefined ? undefined : (state.bySeat.get(seat)?.alias ?? seat);
|
|
182
|
+
/** 내장 alias만 인정한다. 모르는 alias는 undefined. */
|
|
183
|
+
function canonicalAlias(alias: string): CharacterAlias | undefined {
|
|
184
|
+
return hasOwn(CHARACTER_TARGETS, alias) ? (alias as CharacterAlias) : undefined;
|
|
366
185
|
}
|
|
367
186
|
|
|
368
|
-
/** alias가 가리키는 자리의 모델·oauth 위치·toolCapable.
|
|
187
|
+
/** alias가 가리키는 자리의 모델·oauth 위치·toolCapable. */
|
|
369
188
|
export function characterTarget(alias: string): CharacterTarget | undefined {
|
|
370
|
-
const seat =
|
|
189
|
+
const seat = canonicalAlias(alias);
|
|
371
190
|
return seat === undefined ? undefined : CHARACTER_TARGETS[seat];
|
|
372
191
|
}
|
|
373
192
|
|
|
@@ -378,22 +197,18 @@ function requireTarget(alias: string): CharacterTarget {
|
|
|
378
197
|
}
|
|
379
198
|
|
|
380
199
|
function voiceFor(alias: string): CharacterVoice | undefined {
|
|
381
|
-
|
|
382
|
-
const office = state.byAlias.get(alias);
|
|
383
|
-
if (office) return office.voice;
|
|
384
|
-
return hasOwn(CHARACTER_VOICES, alias) ? CHARACTER_VOICES[alias as BuiltinCharacterAlias] : undefined;
|
|
200
|
+
return hasOwn(CHARACTER_VOICES, alias) ? CHARACTER_VOICES[alias as CharacterAlias] : undefined;
|
|
385
201
|
}
|
|
386
202
|
|
|
387
|
-
function aliasFromName(name: string
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
return base ? canonicalAlias(base, state) : undefined;
|
|
203
|
+
function aliasFromName(name: string): CharacterAlias | undefined {
|
|
204
|
+
const base = NAME_TO_ALIAS[name.toLocaleLowerCase("en-US")];
|
|
205
|
+
return base ? canonicalAlias(base) : undefined;
|
|
391
206
|
}
|
|
392
207
|
|
|
393
|
-
function aliasesFromCommand(text: string
|
|
208
|
+
function aliasesFromCommand(text: string): CharacterAlias[] {
|
|
394
209
|
const aliases = new Set<CharacterAlias>();
|
|
395
|
-
for (const match of text.matchAll(
|
|
396
|
-
const alias = aliasFromName(match[1]
|
|
210
|
+
for (const match of text.matchAll(NAME_REGEXES.nameInCommand)) {
|
|
211
|
+
const alias = aliasFromName(match[1]!);
|
|
397
212
|
if (alias) aliases.add(alias);
|
|
398
213
|
}
|
|
399
214
|
return [...aliases];
|
|
@@ -472,7 +287,7 @@ function injectVoiceIntoSystemBlocks(parts: readonly unknown[], block: string):
|
|
|
472
287
|
}
|
|
473
288
|
|
|
474
289
|
function characterAliasForContext(ctx: ExtensionContext, selectedAlias: CharacterAlias | undefined): CharacterAlias | undefined {
|
|
475
|
-
const canonical = selectedAlias ? canonicalAlias(selectedAlias
|
|
290
|
+
const canonical = selectedAlias ? canonicalAlias(selectedAlias) : undefined;
|
|
476
291
|
const target = canonical ? characterTarget(canonical) : undefined;
|
|
477
292
|
if (canonical && target && modelMatches(ctx.model, target.model)) {
|
|
478
293
|
if (target.oauthPosition === undefined) return canonical;
|
|
@@ -482,7 +297,7 @@ function characterAliasForContext(ctx: ExtensionContext, selectedAlias: Characte
|
|
|
482
297
|
if (active && accountPosition(active, activeIndex) === target.oauthPosition) return canonical;
|
|
483
298
|
}
|
|
484
299
|
const provider = ctx.model?.provider;
|
|
485
|
-
return provider ? characterForProvider(provider, activeAccounts(ctx, provider)) : undefined;
|
|
300
|
+
return provider ? characterForProvider(provider, activeAccounts(ctx, provider), ctx.model?.id) : undefined;
|
|
486
301
|
}
|
|
487
302
|
|
|
488
303
|
async function switchCharacterForSession(
|
|
@@ -569,14 +384,13 @@ async function switchCharacterForSession(
|
|
|
569
384
|
}
|
|
570
385
|
|
|
571
386
|
export function parseCharacterIntent(text: string): CharacterIntent | undefined {
|
|
572
|
-
const
|
|
573
|
-
const aliases = aliasesFromCommand(text, state);
|
|
387
|
+
const aliases = aliasesFromCommand(text);
|
|
574
388
|
if (aliases.length === 0) return undefined;
|
|
575
389
|
if (text.includes("교체")) {
|
|
576
390
|
// alias도 인용 밖에서만 뽑아 인용 속 이름과 인용 밖 명령어가 결합되지 않게 한다.
|
|
577
391
|
const command = text.replace(QUOTED_SPAN, " ");
|
|
578
|
-
const switchAliases = aliasesFromCommand(command
|
|
579
|
-
if (!
|
|
392
|
+
const switchAliases = aliasesFromCommand(command);
|
|
393
|
+
if (!NAME_REGEXES.switchCommand.test(command) || switchAliases.length !== 1) return undefined;
|
|
580
394
|
return { kind: "switch", alias: switchAliases[0]! };
|
|
581
395
|
}
|
|
582
396
|
return SUMMON_ACTION.test(text) ? { kind: "summon", aliases } : undefined;
|
|
@@ -584,10 +398,9 @@ export function parseCharacterIntent(text: string): CharacterIntent | undefined
|
|
|
584
398
|
|
|
585
399
|
/** 다른 input handler가 자연어 summon을 routing prompt로 바꾼 뒤에도 순서와 무관하게 복구한다. */
|
|
586
400
|
export function parseCharacterSummonDirectives(text: string): CharacterAlias[] {
|
|
587
|
-
const state = officeState();
|
|
588
401
|
const aliases = new Set<CharacterAlias>();
|
|
589
402
|
for (const match of text.matchAll(SUMMON_DIRECTIVE)) {
|
|
590
|
-
const alias = canonicalAlias(match[1]
|
|
403
|
+
const alias = canonicalAlias(match[1]!);
|
|
591
404
|
if (alias) aliases.add(alias);
|
|
592
405
|
}
|
|
593
406
|
return [...aliases];
|
|
@@ -600,7 +413,7 @@ export function anthropicCharacterForAccounts(
|
|
|
600
413
|
const account = accounts[index]!;
|
|
601
414
|
if (!account.active) continue;
|
|
602
415
|
const seat = ANTHROPIC_POSITION_CHARACTER[accountPosition(account, index)];
|
|
603
|
-
return seat && canonicalAlias(seat
|
|
416
|
+
return seat && canonicalAlias(seat);
|
|
604
417
|
}
|
|
605
418
|
return undefined;
|
|
606
419
|
}
|
|
@@ -608,10 +421,11 @@ export function anthropicCharacterForAccounts(
|
|
|
608
421
|
export function characterForProvider(
|
|
609
422
|
provider: string,
|
|
610
423
|
accounts: readonly OAuthAccountLike[] = [],
|
|
424
|
+
modelId?: string,
|
|
611
425
|
): CharacterAlias | undefined {
|
|
612
426
|
if (provider === "anthropic") return anthropicCharacterForAccounts(accounts);
|
|
613
|
-
const seat = PROVIDER_CHARACTER[provider];
|
|
614
|
-
return seat && canonicalAlias(seat
|
|
427
|
+
const seat = (modelId === undefined ? undefined : MODEL_CHARACTER[`${provider}/${modelId}`]) ?? PROVIDER_CHARACTER[provider];
|
|
428
|
+
return seat && canonicalAlias(seat);
|
|
615
429
|
}
|
|
616
430
|
|
|
617
431
|
export function renderCharacterVoice(alias: CharacterAlias): string {
|
|
@@ -806,7 +620,7 @@ export function buildCharacterSummonBrief(brief: string, alias: CharacterAlias):
|
|
|
806
620
|
|
|
807
621
|
export function parseCharacterSummonMarker(prompt: string): CharacterAlias | undefined {
|
|
808
622
|
const match = SUMMON_MARKER.exec(prompt);
|
|
809
|
-
const alias = match ? canonicalAlias(match[1]
|
|
623
|
+
const alias = match ? canonicalAlias(match[1]!) : undefined;
|
|
810
624
|
const target = alias === undefined ? undefined : characterTarget(alias);
|
|
811
625
|
if (!match || alias === undefined || !target || target.model !== match[2]) return undefined;
|
|
812
626
|
const position = match[3] === undefined ? undefined : Number(match[3]);
|
|
@@ -819,10 +633,8 @@ export function parseCharacterSummonMarker(prompt: string): CharacterAlias | und
|
|
|
819
633
|
*/
|
|
820
634
|
export function malformedSummonMarkerReason(task: string): string | undefined {
|
|
821
635
|
if (!SUMMON_MARKER_PREFIX.test(task) || parseCharacterSummonMarker(task) !== undefined) return undefined;
|
|
822
|
-
const state = officeState();
|
|
823
636
|
const expected = (Object.keys(CHARACTER_TARGETS) as BuiltinCharacterAlias[])
|
|
824
637
|
.filter((seat) => CHARACTER_TARGETS[seat].toolCapable)
|
|
825
|
-
.map((seat) => state.bySeat.get(seat)?.alias ?? seat)
|
|
826
638
|
.map((alias) => `- ${alias}: \`${summonMarkerFor(alias)}\``);
|
|
827
639
|
return [
|
|
828
640
|
"[CharacterSummonGuard] task의 character-summon marker가 exact target과 맞지 않습니다. " +
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- source-fingerprint:
|
|
1
|
+
<!-- source-fingerprint: 6ed404eb4a5ca91f -->
|
|
2
2
|
# Global Agent Instructions
|
|
3
3
|
|
|
4
4
|
(Model-facing English copy of the Korean source `AGENTS.md`. All user-facing prose stays Korean.)
|
|
@@ -109,12 +109,10 @@ Alias + `교체` switches the current Main session; alias + `호출`·`불러`·
|
|
|
109
109
|
|**ISANA(이사나)**|`hive/deepseek-ai/deepseek-v4.1-flash-1017`|task child on this model|switch current session only|
|
|
110
110
|
|**RIN(린)**|`anthropic/claude-opus-5-5`, 지정 계정|task child pinned to its account|pin its account, then switch current session|
|
|
111
111
|
|**MIO(미오)**|`anthropic/claude-opus-5-5`, 지정 계정|task child pinned to its account|pin its account, then switch current session|
|
|
112
|
-
|**
|
|
112
|
+
|**MITSU(미츠)**|`hive/zai-org/glm-5.3-flash`|task child on this model|switch current session only|
|
|
113
113
|
|**HIKARI(히카리)**|`google-antigravity/gemini-3.8-flash`|task child on this model|switch current session only|
|
|
114
114
|
|**SHION(시온)**|`web6/gpt-6-pro`|`rule://web6-consult` consult (not a child)|forbidden|
|
|
115
115
|
|
|
116
|
-
Under the server-wide setting 「기본 / 사무실 모드」 (default / office mode; a mode file in the agent dir), office mode replaces characters (aliases, names, voice) for valid PC-profile roster entries in the fixed order YUKI, ISANA, MIO, RIN, SHION, HIKARI; NOVA stays unchanged. Each seat keeps its model, OAuth position and tool capability, including SHION's consult-only boundary. Both roster names and the seat's default name resolve to that seat. When aliases, call names or ids collide, the first accepted seat in that order wins and later conflicting entries stay default. A missing or broken mode file or roster means default. Character data and assets live only in the PC profile.
|
|
117
|
-
|
|
118
116
|
Tool-capable calls use one ordinary task child with normal linkage. If the user asks for a greeting or line in a character's face/voice, treat it as an inline summon even without a summon verb, and put the exact summon marker in that child request and call input. RIN/MIO's designated OAuth account is a session-scoped exact pin; if unavailable, never silently substitute another credential/model. A failed `교체` keeps the previous session model and never changes the global default. In the final provider request of Main and children, strip existing character voice and legacy report-style and apply exactly one selected voice block. Tell the user, in that turn, the role, count, and reason of each child/other-model call. A child's terminal line counts as shown only once inline linkage is confirmed. SHION uses only the existing WEB6 consult path. Parser/selector source of truth: `harness-policy.json` `characterRouting` and `extensions/character-voice.ts`.
|
|
119
117
|
|
|
120
118
|
## Legacy encoding
|
|
@@ -116,8 +116,7 @@
|
|
|
116
116
|
"anthropicAccountMapping": "stable-oauth-storage-position-zero-rin-position-one-mio-with-exact-session-affinity-for-a-validated-session-switch-command-or-character-summon-marker",
|
|
117
117
|
"failure": "exact-switch-or-summon-account-block-or-usage-limit-ends-with-the-selected-alias-and-never-emits-sibling-credential-or-model-text-ordinary-sessions-retain-native-fallback",
|
|
118
118
|
"conversationalPrecedence": "natural-korean-selected-character-is-authoritative-across-first-response-post-tool-explanation-validation-failure-risk-and-unknown-reporting-human-interjection-progress-final-answer-and-inline-child-speech-internal-evidence-todo-and-child-status-contracts-govern-information-not-user-facing-format-system-prompt-headings-tables-and-lists-are-policy-organization-not-response-templates-required-user-parser-final-owner-formats-are-the-only-exception",
|
|
119
|
-
"voiceEnforcement": "at-the-final-provider-wire-boundary-for-main-and-task-children-remove-every-prior-character-voice-and-legacy-report-style-block-and-install-exactly-one-selected-character-block-called-character-terminal-speech-is-already-user-visible-canonical-so-main-never-requotes-or-reaggregates-it"
|
|
120
|
-
"officeMode": "server-wide-default-or-office-mode-file-in-the-agent-dir-office-replaces-valid-pc-profile-entries-in-fixed-order-yuki-isana-mio-rin-shion-hikari-nova-unchanged-first-accepted-alias-call-name-or-id-wins-later-conflicting-entry-stays-default-the-roster-is-an-untrusted-local-file-validated-by-the-same-rule-as-the-app-allowed-seat-id-pattern-safe-alias-not-a-built-in-alias-names-not-another-seat-name-non-empty-voice-without-character-voice-tags-face-realpath-inside-characters-office-and-roster-read-only-through-realpath-containment-seat-model-oauth-position-and-tool-capability-unchanged-shion-remains-consult-only-roster-names-and-the-seat-default-name-both-resolve-to-the-seat-a-pending-office-summon-fails-closed-if-the-mode-changes-missing-or-invalid-mode-or-roster-means-default-and-never-an-error-character-data-and-assets-live-only-in-the-pc-profile-never-in-the-repository-or-public-mirror"
|
|
119
|
+
"voiceEnforcement": "at-the-final-provider-wire-boundary-for-main-and-task-children-remove-every-prior-character-voice-and-legacy-report-style-block-and-install-exactly-one-selected-character-block-called-character-terminal-speech-is-already-user-visible-canonical-so-main-never-requotes-or-reaggregates-it"
|
|
121
120
|
},
|
|
122
121
|
"longRunningWork": {
|
|
123
122
|
"finiteValidation": "owned-by-the-owner-of-the-changed-scope-always-explicit-async-background-not-eval-or-blocking-foreground",
|
package/package.json
CHANGED