@aitne/daemon 0.1.6 → 0.1.8
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/dist/adapters/dashboard-adapter.d.ts +18 -2
- package/dist/adapters/dashboard-adapter.d.ts.map +1 -1
- package/dist/adapters/dashboard-adapter.js +101 -51
- package/dist/adapters/dashboard-adapter.js.map +1 -1
- package/dist/adapters/discord.d.ts +8 -0
- package/dist/adapters/discord.d.ts.map +1 -1
- package/dist/adapters/discord.js +100 -21
- package/dist/adapters/discord.js.map +1 -1
- package/dist/adapters/message-hub.d.ts.map +1 -1
- package/dist/adapters/message-hub.js +7 -1
- package/dist/adapters/message-hub.js.map +1 -1
- package/dist/adapters/notification-manager.d.ts +102 -2
- package/dist/adapters/notification-manager.d.ts.map +1 -1
- package/dist/adapters/notification-manager.js +228 -8
- package/dist/adapters/notification-manager.js.map +1 -1
- package/dist/adapters/outbound-text.d.ts +16 -0
- package/dist/adapters/outbound-text.d.ts.map +1 -1
- package/dist/adapters/outbound-text.js +118 -1
- package/dist/adapters/outbound-text.js.map +1 -1
- package/dist/adapters/primary-platform-resolver.d.ts +69 -0
- package/dist/adapters/primary-platform-resolver.d.ts.map +1 -0
- package/dist/adapters/primary-platform-resolver.js +55 -0
- package/dist/adapters/primary-platform-resolver.js.map +1 -0
- package/dist/adapters/slack-adapter.d.ts +28 -0
- package/dist/adapters/slack-adapter.d.ts.map +1 -1
- package/dist/adapters/slack-adapter.js +134 -35
- package/dist/adapters/slack-adapter.js.map +1 -1
- package/dist/adapters/telegram-adapter.d.ts +7 -1
- package/dist/adapters/telegram-adapter.d.ts.map +1 -1
- package/dist/adapters/telegram-adapter.js +49 -18
- package/dist/adapters/telegram-adapter.js.map +1 -1
- package/dist/adapters/whatsapp-adapter.d.ts +33 -0
- package/dist/adapters/whatsapp-adapter.d.ts.map +1 -1
- package/dist/adapters/whatsapp-adapter.js +84 -0
- package/dist/adapters/whatsapp-adapter.js.map +1 -1
- package/dist/api/directory-picker.d.ts.map +1 -1
- package/dist/api/directory-picker.js +14 -0
- package/dist/api/directory-picker.js.map +1 -1
- package/dist/api/env-writer.d.ts.map +1 -1
- package/dist/api/env-writer.js +6 -1
- package/dist/api/env-writer.js.map +1 -1
- package/dist/api/helpers/agent-errors.d.ts +2600 -0
- package/dist/api/helpers/agent-errors.d.ts.map +1 -0
- package/dist/api/helpers/agent-errors.js +2506 -0
- package/dist/api/helpers/agent-errors.js.map +1 -0
- package/dist/api/integration-route-gate.d.ts.map +1 -1
- package/dist/api/integration-route-gate.js +10 -3
- package/dist/api/integration-route-gate.js.map +1 -1
- package/dist/api/routes/agent-schedule-plan-match.d.ts +5 -0
- package/dist/api/routes/agent-schedule-plan-match.d.ts.map +1 -0
- package/dist/api/routes/agent-schedule-plan-match.js +101 -0
- package/dist/api/routes/agent-schedule-plan-match.js.map +1 -0
- package/dist/api/routes/agent-schedule.d.ts +4 -0
- package/dist/api/routes/agent-schedule.d.ts.map +1 -0
- package/dist/api/routes/agent-schedule.js +750 -0
- package/dist/api/routes/agent-schedule.js.map +1 -0
- package/dist/api/routes/agent.d.ts.map +1 -1
- package/dist/api/routes/agent.js +209 -366
- package/dist/api/routes/agent.js.map +1 -1
- package/dist/api/routes/apple-calendar.d.ts.map +1 -1
- package/dist/api/routes/apple-calendar.js +109 -27
- package/dist/api/routes/apple-calendar.js.map +1 -1
- package/dist/api/routes/attachments.d.ts.map +1 -1
- package/dist/api/routes/attachments.js +113 -21
- package/dist/api/routes/attachments.js.map +1 -1
- package/dist/api/routes/backends.d.ts.map +1 -1
- package/dist/api/routes/backends.js +100 -4
- package/dist/api/routes/backends.js.map +1 -1
- package/dist/api/routes/books.d.ts.map +1 -1
- package/dist/api/routes/books.js +58 -18
- package/dist/api/routes/books.js.map +1 -1
- package/dist/api/routes/calendar.d.ts +3 -2
- package/dist/api/routes/calendar.d.ts.map +1 -1
- package/dist/api/routes/calendar.js +330 -55
- package/dist/api/routes/calendar.js.map +1 -1
- package/dist/api/routes/commands.d.ts.map +1 -1
- package/dist/api/routes/commands.js +20 -1
- package/dist/api/routes/commands.js.map +1 -1
- package/dist/api/routes/context/index.d.ts +33 -0
- package/dist/api/routes/context/index.d.ts.map +1 -0
- package/dist/api/routes/context/index.js +193 -0
- package/dist/api/routes/context/index.js.map +1 -0
- package/dist/api/routes/context/locks.d.ts +4 -0
- package/dist/api/routes/context/locks.d.ts.map +1 -0
- package/dist/api/routes/context/locks.js +136 -0
- package/dist/api/routes/context/locks.js.map +1 -0
- package/dist/api/routes/context/path-resolve.d.ts +15 -0
- package/dist/api/routes/context/path-resolve.d.ts.map +1 -0
- package/dist/api/routes/context/path-resolve.js +109 -0
- package/dist/api/routes/context/path-resolve.js.map +1 -0
- package/dist/api/routes/context/permissions.d.ts +35 -0
- package/dist/api/routes/context/permissions.d.ts.map +1 -0
- package/dist/api/routes/context/permissions.js +192 -0
- package/dist/api/routes/context/permissions.js.map +1 -0
- package/dist/api/routes/context/read.d.ts +4 -0
- package/dist/api/routes/context/read.d.ts.map +1 -0
- package/dist/api/routes/context/read.js +295 -0
- package/dist/api/routes/context/read.js.map +1 -0
- package/dist/api/routes/context/repair.d.ts +4 -0
- package/dist/api/routes/context/repair.d.ts.map +1 -0
- package/dist/api/routes/context/repair.js +114 -0
- package/dist/api/routes/context/repair.js.map +1 -0
- package/dist/api/routes/context/snapshots.d.ts +4 -0
- package/dist/api/routes/context/snapshots.d.ts.map +1 -0
- package/dist/api/routes/context/snapshots.js +177 -0
- package/dist/api/routes/context/snapshots.js.map +1 -0
- package/dist/api/routes/context/write.d.ts +4 -0
- package/dist/api/routes/context/write.d.ts.map +1 -0
- package/dist/api/routes/context/write.js +570 -0
- package/dist/api/routes/context/write.js.map +1 -0
- package/dist/api/routes/context.d.ts +2 -43
- package/dist/api/routes/context.d.ts.map +1 -1
- package/dist/api/routes/context.js +415 -558
- package/dist/api/routes/context.js.map +1 -1
- package/dist/api/routes/dashboard/config.d.ts +4 -0
- package/dist/api/routes/dashboard/config.d.ts.map +1 -0
- package/dist/api/routes/dashboard/config.js +499 -0
- package/dist/api/routes/dashboard/config.js.map +1 -0
- package/dist/api/routes/dashboard/conversations.d.ts +4 -0
- package/dist/api/routes/dashboard/conversations.d.ts.map +1 -0
- package/dist/api/routes/dashboard/conversations.js +309 -0
- package/dist/api/routes/dashboard/conversations.js.map +1 -0
- package/dist/api/routes/dashboard/cost-approvals.d.ts +29 -0
- package/dist/api/routes/dashboard/cost-approvals.d.ts.map +1 -0
- package/dist/api/routes/dashboard/cost-approvals.js +259 -0
- package/dist/api/routes/dashboard/cost-approvals.js.map +1 -0
- package/dist/api/routes/dashboard/index.d.ts +27 -0
- package/dist/api/routes/dashboard/index.d.ts.map +1 -0
- package/dist/api/routes/dashboard/index.js +47 -0
- package/dist/api/routes/dashboard/index.js.map +1 -0
- package/dist/api/routes/dashboard/messaging.d.ts +4 -0
- package/dist/api/routes/dashboard/messaging.d.ts.map +1 -0
- package/dist/api/routes/dashboard/messaging.js +351 -0
- package/dist/api/routes/dashboard/messaging.js.map +1 -0
- package/dist/api/routes/dashboard/notifications.d.ts +4 -0
- package/dist/api/routes/dashboard/notifications.d.ts.map +1 -0
- package/dist/api/routes/dashboard/notifications.js +109 -0
- package/dist/api/routes/dashboard/notifications.js.map +1 -0
- package/dist/api/routes/dashboard/oauth-google.d.ts +4 -0
- package/dist/api/routes/dashboard/oauth-google.d.ts.map +1 -0
- package/dist/api/routes/dashboard/oauth-google.js +293 -0
- package/dist/api/routes/dashboard/oauth-google.js.map +1 -0
- package/dist/api/routes/dashboard/schedule-readonly.d.ts +4 -0
- package/dist/api/routes/dashboard/schedule-readonly.d.ts.map +1 -0
- package/dist/api/routes/dashboard/schedule-readonly.js +46 -0
- package/dist/api/routes/dashboard/schedule-readonly.js.map +1 -0
- package/dist/api/routes/dashboard/secrets.d.ts +24 -0
- package/dist/api/routes/dashboard/secrets.d.ts.map +1 -0
- package/dist/api/routes/dashboard/secrets.js +307 -0
- package/dist/api/routes/dashboard/secrets.js.map +1 -0
- package/dist/api/routes/dashboard/snapshots.d.ts +4 -0
- package/dist/api/routes/dashboard/snapshots.d.ts.map +1 -0
- package/dist/api/routes/dashboard/snapshots.js +33 -0
- package/dist/api/routes/dashboard/snapshots.js.map +1 -0
- package/dist/api/routes/dashboard.d.ts.map +1 -1
- package/dist/api/routes/dashboard.js +20 -12
- package/dist/api/routes/dashboard.js.map +1 -1
- package/dist/api/routes/delegated.d.ts +5 -4
- package/dist/api/routes/delegated.d.ts.map +1 -1
- package/dist/api/routes/delegated.js +6 -5
- package/dist/api/routes/delegated.js.map +1 -1
- package/dist/api/routes/docs.d.ts.map +1 -1
- package/dist/api/routes/docs.js +72 -9
- package/dist/api/routes/docs.js.map +1 -1
- package/dist/api/routes/entities.d.ts.map +1 -1
- package/dist/api/routes/entities.js +112 -43
- package/dist/api/routes/entities.js.map +1 -1
- package/dist/api/routes/fs.d.ts.map +1 -1
- package/dist/api/routes/fs.js +27 -12
- package/dist/api/routes/fs.js.map +1 -1
- package/dist/api/routes/git-templates.d.ts.map +1 -1
- package/dist/api/routes/git-templates.js +107 -27
- package/dist/api/routes/git-templates.js.map +1 -1
- package/dist/api/routes/git.d.ts.map +1 -1
- package/dist/api/routes/git.js +55 -11
- package/dist/api/routes/git.js.map +1 -1
- package/dist/api/routes/github.d.ts.map +1 -1
- package/dist/api/routes/github.js +110 -17
- package/dist/api/routes/github.js.map +1 -1
- package/dist/api/routes/integrations/crud-patch.d.ts +17 -0
- package/dist/api/routes/integrations/crud-patch.d.ts.map +1 -0
- package/dist/api/routes/integrations/crud-patch.js +600 -0
- package/dist/api/routes/integrations/crud-patch.js.map +1 -0
- package/dist/api/routes/integrations/crud.d.ts +16 -0
- package/dist/api/routes/integrations/crud.d.ts.map +1 -0
- package/dist/api/routes/integrations/crud.js +158 -0
- package/dist/api/routes/integrations/crud.js.map +1 -0
- package/dist/api/routes/integrations/exec.d.ts +23 -0
- package/dist/api/routes/integrations/exec.d.ts.map +1 -0
- package/dist/api/routes/integrations/exec.js +356 -0
- package/dist/api/routes/integrations/exec.js.map +1 -0
- package/dist/api/routes/integrations/index.d.ts +62 -0
- package/dist/api/routes/integrations/index.d.ts.map +1 -0
- package/dist/api/routes/integrations/index.js +70 -0
- package/dist/api/routes/integrations/index.js.map +1 -0
- package/dist/api/routes/integrations/integrations/crud.d.ts +16 -0
- package/dist/api/routes/integrations/integrations/crud.d.ts.map +1 -0
- package/dist/api/routes/integrations/integrations/crud.js +158 -0
- package/dist/api/routes/integrations/integrations/crud.js.map +1 -0
- package/dist/api/routes/integrations/integrations/index.d.ts +55 -0
- package/dist/api/routes/integrations/integrations/index.d.ts.map +1 -0
- package/dist/api/routes/integrations/integrations/index.js +65 -0
- package/dist/api/routes/integrations/integrations/index.js.map +1 -0
- package/dist/api/routes/integrations/integrations/invoke.d.ts +38 -0
- package/dist/api/routes/integrations/integrations/invoke.d.ts.map +1 -0
- package/dist/api/routes/integrations/integrations/invoke.js +320 -0
- package/dist/api/routes/integrations/integrations/invoke.js.map +1 -0
- package/dist/api/routes/integrations/integrations/probe.d.ts +21 -0
- package/dist/api/routes/integrations/integrations/probe.d.ts.map +1 -0
- package/dist/api/routes/integrations/integrations/probe.js +247 -0
- package/dist/api/routes/integrations/integrations/probe.js.map +1 -0
- package/dist/api/routes/integrations/invoke.d.ts +38 -0
- package/dist/api/routes/integrations/invoke.d.ts.map +1 -0
- package/dist/api/routes/integrations/invoke.js +320 -0
- package/dist/api/routes/integrations/invoke.js.map +1 -0
- package/dist/api/routes/integrations/probe.d.ts +21 -0
- package/dist/api/routes/integrations/probe.d.ts.map +1 -0
- package/dist/api/routes/integrations/probe.js +247 -0
- package/dist/api/routes/integrations/probe.js.map +1 -0
- package/dist/api/routes/integrations.d.ts.map +1 -1
- package/dist/api/routes/integrations.js +65 -13
- package/dist/api/routes/integrations.js.map +1 -1
- package/dist/api/routes/knowledge.d.ts.map +1 -1
- package/dist/api/routes/knowledge.js +13 -2
- package/dist/api/routes/knowledge.js.map +1 -1
- package/dist/api/routes/mail/_pa_wip_mail/app-password.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/app-password.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/app-password.js +192 -0
- package/dist/api/routes/mail/_pa_wip_mail/app-password.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/body-helpers.d.ts +55 -0
- package/dist/api/routes/mail/_pa_wip_mail/body-helpers.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/body-helpers.js +91 -0
- package/dist/api/routes/mail/_pa_wip_mail/body-helpers.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/dependencies.d.ts +36 -0
- package/dist/api/routes/mail/_pa_wip_mail/dependencies.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/dependencies.js +2 -0
- package/dist/api/routes/mail/_pa_wip_mail/dependencies.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/gating.d.ts +45 -0
- package/dist/api/routes/mail/_pa_wip_mail/gating.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/gating.js +98 -0
- package/dist/api/routes/mail/_pa_wip_mail/gating.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/accounts.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/accounts.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/accounts.js +289 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/accounts.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/app-password.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/app-password.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/app-password.js +192 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/app-password.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/body-helpers.d.ts +55 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/body-helpers.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/body-helpers.js +91 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/body-helpers.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/dependencies.d.ts +36 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/dependencies.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/dependencies.js +2 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/dependencies.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/drafts.d.ts +5 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/drafts.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/drafts.js +139 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/drafts.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/gating.d.ts +45 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/gating.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/gating.js +98 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/gating.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/index.d.ts +18 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/index.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/index.js +40 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/index.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/messages.d.ts +15 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/messages.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/messages.js +239 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/messages.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/outlook-config.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/outlook-config.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/outlook-config.js +73 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/outlook-config.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/provider-resolver.d.ts +64 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/provider-resolver.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/provider-resolver.js +286 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/provider-resolver.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/providers.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/providers.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/providers.js +73 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/providers.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/tags-folders.d.ts +5 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/tags-folders.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/tags-folders.js +35 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/tags-folders.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/validators.d.ts +23 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/validators.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/validators.js +131 -0
- package/dist/api/routes/mail/_pa_wip_mail/mail/validators.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/provider-resolver.d.ts +64 -0
- package/dist/api/routes/mail/_pa_wip_mail/provider-resolver.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/provider-resolver.js +286 -0
- package/dist/api/routes/mail/_pa_wip_mail/provider-resolver.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/search-health.d.ts +4 -0
- package/dist/api/routes/mail/_pa_wip_mail/search-health.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/search-health.js +131 -0
- package/dist/api/routes/mail/_pa_wip_mail/search-health.js.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/validators.d.ts +23 -0
- package/dist/api/routes/mail/_pa_wip_mail/validators.d.ts.map +1 -0
- package/dist/api/routes/mail/_pa_wip_mail/validators.js +131 -0
- package/dist/api/routes/mail/_pa_wip_mail/validators.js.map +1 -0
- package/dist/api/routes/mail/accounts.d.ts +4 -0
- package/dist/api/routes/mail/accounts.d.ts.map +1 -0
- package/dist/api/routes/mail/accounts.js +289 -0
- package/dist/api/routes/mail/accounts.js.map +1 -0
- package/dist/api/routes/mail/app-password.d.ts +4 -0
- package/dist/api/routes/mail/app-password.d.ts.map +1 -0
- package/dist/api/routes/mail/app-password.js +192 -0
- package/dist/api/routes/mail/app-password.js.map +1 -0
- package/dist/api/routes/mail/body-helpers.d.ts +56 -0
- package/dist/api/routes/mail/body-helpers.d.ts.map +1 -0
- package/dist/api/routes/mail/body-helpers.js +91 -0
- package/dist/api/routes/mail/body-helpers.js.map +1 -0
- package/dist/api/routes/mail/dependencies.d.ts +36 -0
- package/dist/api/routes/mail/dependencies.d.ts.map +1 -0
- package/dist/api/routes/mail/dependencies.js +2 -0
- package/dist/api/routes/mail/dependencies.js.map +1 -0
- package/dist/api/routes/mail/drafts.d.ts +5 -0
- package/dist/api/routes/mail/drafts.d.ts.map +1 -0
- package/dist/api/routes/mail/drafts.js +139 -0
- package/dist/api/routes/mail/drafts.js.map +1 -0
- package/dist/api/routes/mail/gating.d.ts +45 -0
- package/dist/api/routes/mail/gating.d.ts.map +1 -0
- package/dist/api/routes/mail/gating.js +99 -0
- package/dist/api/routes/mail/gating.js.map +1 -0
- package/dist/api/routes/mail/index.d.ts +18 -0
- package/dist/api/routes/mail/index.d.ts.map +1 -0
- package/dist/api/routes/mail/index.js +40 -0
- package/dist/api/routes/mail/index.js.map +1 -0
- package/dist/api/routes/mail/messages.d.ts +15 -0
- package/dist/api/routes/mail/messages.d.ts.map +1 -0
- package/dist/api/routes/mail/messages.js +239 -0
- package/dist/api/routes/mail/messages.js.map +1 -0
- package/dist/api/routes/mail/outlook-config.d.ts +4 -0
- package/dist/api/routes/mail/outlook-config.d.ts.map +1 -0
- package/dist/api/routes/mail/outlook-config.js +73 -0
- package/dist/api/routes/mail/outlook-config.js.map +1 -0
- package/dist/api/routes/mail/provider-resolver.d.ts +64 -0
- package/dist/api/routes/mail/provider-resolver.d.ts.map +1 -0
- package/dist/api/routes/mail/provider-resolver.js +286 -0
- package/dist/api/routes/mail/provider-resolver.js.map +1 -0
- package/dist/api/routes/mail/providers.d.ts +4 -0
- package/dist/api/routes/mail/providers.d.ts.map +1 -0
- package/dist/api/routes/mail/providers.js +73 -0
- package/dist/api/routes/mail/providers.js.map +1 -0
- package/dist/api/routes/mail/search-health.d.ts +4 -0
- package/dist/api/routes/mail/search-health.d.ts.map +1 -0
- package/dist/api/routes/mail/search-health.js +131 -0
- package/dist/api/routes/mail/search-health.js.map +1 -0
- package/dist/api/routes/mail/tags-folders.d.ts +5 -0
- package/dist/api/routes/mail/tags-folders.d.ts.map +1 -0
- package/dist/api/routes/mail/tags-folders.js +35 -0
- package/dist/api/routes/mail/tags-folders.js.map +1 -0
- package/dist/api/routes/mail/validators.d.ts +23 -0
- package/dist/api/routes/mail/validators.d.ts.map +1 -0
- package/dist/api/routes/mail/validators.js +131 -0
- package/dist/api/routes/mail/validators.js.map +1 -0
- package/dist/api/routes/mail.d.ts.map +1 -1
- package/dist/api/routes/mail.js +259 -67
- package/dist/api/routes/mail.js.map +1 -1
- package/dist/api/routes/managed-tasks.d.ts.map +1 -1
- package/dist/api/routes/managed-tasks.js +142 -54
- package/dist/api/routes/managed-tasks.js.map +1 -1
- package/dist/api/routes/mcp.d.ts.map +1 -1
- package/dist/api/routes/mcp.js +115 -47
- package/dist/api/routes/mcp.js.map +1 -1
- package/dist/api/routes/metrics.d.ts +1 -1
- package/dist/api/routes/metrics.js +2 -2
- package/dist/api/routes/notion.d.ts.map +1 -1
- package/dist/api/routes/notion.js +230 -54
- package/dist/api/routes/notion.js.map +1 -1
- package/dist/api/routes/observations.d.ts.map +1 -1
- package/dist/api/routes/observations.js +40 -169
- package/dist/api/routes/observations.js.map +1 -1
- package/dist/api/routes/obsidian.d.ts.map +1 -1
- package/dist/api/routes/obsidian.js +193 -32
- package/dist/api/routes/obsidian.js.map +1 -1
- package/dist/api/routes/profile-questions.d.ts.map +1 -1
- package/dist/api/routes/profile-questions.js +19 -3
- package/dist/api/routes/profile-questions.js.map +1 -1
- package/dist/api/routes/receipts.d.ts.map +1 -1
- package/dist/api/routes/receipts.js +64 -24
- package/dist/api/routes/receipts.js.map +1 -1
- package/dist/api/routes/recurring-schedules.d.ts.map +1 -1
- package/dist/api/routes/recurring-schedules.js +243 -13
- package/dist/api/routes/recurring-schedules.js.map +1 -1
- package/dist/api/routes/repositories.d.ts.map +1 -1
- package/dist/api/routes/repositories.js +278 -104
- package/dist/api/routes/repositories.js.map +1 -1
- package/dist/api/routes/schedule-model-resolver.d.ts +153 -0
- package/dist/api/routes/schedule-model-resolver.d.ts.map +1 -0
- package/dist/api/routes/schedule-model-resolver.js +282 -0
- package/dist/api/routes/schedule-model-resolver.js.map +1 -0
- package/dist/api/routes/schedule-options.d.ts +25 -0
- package/dist/api/routes/schedule-options.d.ts.map +1 -0
- package/dist/api/routes/schedule-options.js +77 -0
- package/dist/api/routes/schedule-options.js.map +1 -0
- package/dist/api/routes/schedule-validation.d.ts +146 -0
- package/dist/api/routes/schedule-validation.d.ts.map +1 -0
- package/dist/api/routes/schedule-validation.js +153 -0
- package/dist/api/routes/schedule-validation.js.map +1 -0
- package/dist/api/routes/setup.d.ts.map +1 -1
- package/dist/api/routes/setup.js +100 -26
- package/dist/api/routes/setup.js.map +1 -1
- package/dist/api/routes/skills.d.ts.map +1 -1
- package/dist/api/routes/skills.js +81 -30
- package/dist/api/routes/skills.js.map +1 -1
- package/dist/api/routes/sot-bindings.d.ts.map +1 -1
- package/dist/api/routes/sot-bindings.js +46 -11
- package/dist/api/routes/sot-bindings.js.map +1 -1
- package/dist/api/routes/sse.d.ts.map +1 -1
- package/dist/api/routes/sse.js +6 -1
- package/dist/api/routes/sse.js.map +1 -1
- package/dist/api/routes/system.d.ts.map +1 -1
- package/dist/api/routes/system.js +15 -2
- package/dist/api/routes/system.js.map +1 -1
- package/dist/api/routes/travel-bookings.d.ts.map +1 -1
- package/dist/api/routes/travel-bookings.js +26 -9
- package/dist/api/routes/travel-bookings.js.map +1 -1
- package/dist/api/routes/travel-time.d.ts.map +1 -1
- package/dist/api/routes/travel-time.js +50 -10
- package/dist/api/routes/travel-time.js.map +1 -1
- package/dist/api/routes/wiki.d.ts.map +1 -1
- package/dist/api/routes/wiki.js +49 -8
- package/dist/api/routes/wiki.js.map +1 -1
- package/dist/api/server.d.ts +15 -3
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +32 -10
- package/dist/api/server.js.map +1 -1
- package/dist/bootstrap/adapters.d.ts.map +1 -1
- package/dist/bootstrap/adapters.js +7 -4
- package/dist/bootstrap/adapters.js.map +1 -1
- package/dist/bootstrap/api.d.ts +205 -0
- package/dist/bootstrap/api.d.ts.map +1 -0
- package/dist/bootstrap/api.js +443 -0
- package/dist/bootstrap/api.js.map +1 -0
- package/dist/bootstrap/db.d.ts +119 -0
- package/dist/bootstrap/db.d.ts.map +1 -0
- package/dist/bootstrap/db.js +294 -0
- package/dist/bootstrap/db.js.map +1 -0
- package/dist/bootstrap/event-pipeline.d.ts +308 -0
- package/dist/bootstrap/event-pipeline.d.ts.map +1 -0
- package/dist/bootstrap/event-pipeline.js +704 -0
- package/dist/bootstrap/event-pipeline.js.map +1 -0
- package/dist/bootstrap/observers.d.ts +148 -0
- package/dist/bootstrap/observers.d.ts.map +1 -0
- package/dist/bootstrap/observers.js +558 -0
- package/dist/bootstrap/observers.js.map +1 -0
- package/dist/bootstrap/schedule-helpers.d.ts +122 -0
- package/dist/bootstrap/schedule-helpers.d.ts.map +1 -1
- package/dist/bootstrap/schedule-helpers.js +202 -4
- package/dist/bootstrap/schedule-helpers.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -3
- package/dist/config.js.map +1 -1
- package/dist/core/abort-utils.d.ts +14 -0
- package/dist/core/abort-utils.d.ts.map +1 -0
- package/dist/core/abort-utils.js +36 -0
- package/dist/core/abort-utils.js.map +1 -0
- package/dist/core/agent-core.d.ts +22 -3
- package/dist/core/agent-core.d.ts.map +1 -1
- package/dist/core/agent-core.js +3 -1
- package/dist/core/agent-core.js.map +1 -1
- package/dist/core/backends/auth-health-monitor.js +2 -3
- package/dist/core/backends/auth-health-monitor.js.map +1 -1
- package/dist/core/backends/backend-router.d.ts +11 -1
- package/dist/core/backends/backend-router.d.ts.map +1 -1
- package/dist/core/backends/backend-router.js +97 -2
- package/dist/core/backends/backend-router.js.map +1 -1
- package/dist/core/backends/claude-code-core.d.ts +51 -0
- package/dist/core/backends/claude-code-core.d.ts.map +1 -1
- package/dist/core/backends/claude-code-core.js +134 -11
- package/dist/core/backends/claude-code-core.js.map +1 -1
- package/dist/core/backends/claude-tool-collection.js +1 -1
- package/dist/core/backends/codex-core.d.ts +13 -1
- package/dist/core/backends/codex-core.d.ts.map +1 -1
- package/dist/core/backends/codex-core.js +436 -22
- package/dist/core/backends/codex-core.js.map +1 -1
- package/dist/core/backends/gemini-cli-core.d.ts +5 -1
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
- package/dist/core/backends/gemini-cli-core.js +298 -15
- package/dist/core/backends/gemini-cli-core.js.map +1 -1
- package/dist/core/backends/install-methods.d.ts.map +1 -1
- package/dist/core/backends/install-methods.js +22 -0
- package/dist/core/backends/install-methods.js.map +1 -1
- package/dist/core/backends/model-registry.d.ts +9 -4
- package/dist/core/backends/model-registry.d.ts.map +1 -1
- package/dist/core/backends/model-registry.js +153 -23
- package/dist/core/backends/model-registry.js.map +1 -1
- package/dist/core/backends/native-skill-discovery-probe.d.ts +80 -0
- package/dist/core/backends/native-skill-discovery-probe.d.ts.map +1 -0
- package/dist/core/backends/native-skill-discovery-probe.js +175 -0
- package/dist/core/backends/native-skill-discovery-probe.js.map +1 -0
- package/dist/core/backends/opencode-basic-auth-fetch.d.ts +27 -0
- package/dist/core/backends/opencode-basic-auth-fetch.d.ts.map +1 -0
- package/dist/core/backends/opencode-basic-auth-fetch.js +40 -0
- package/dist/core/backends/opencode-basic-auth-fetch.js.map +1 -0
- package/dist/core/backends/opencode-config-builder.d.ts +86 -0
- package/dist/core/backends/opencode-config-builder.d.ts.map +1 -0
- package/dist/core/backends/opencode-config-builder.js +172 -0
- package/dist/core/backends/opencode-config-builder.js.map +1 -0
- package/dist/core/backends/opencode-core.d.ts +316 -0
- package/dist/core/backends/opencode-core.d.ts.map +1 -0
- package/dist/core/backends/opencode-core.js +1502 -0
- package/dist/core/backends/opencode-core.js.map +1 -0
- package/dist/core/backends/opencode-event-mapper.d.ts +133 -0
- package/dist/core/backends/opencode-event-mapper.d.ts.map +1 -0
- package/dist/core/backends/opencode-event-mapper.js +198 -0
- package/dist/core/backends/opencode-event-mapper.js.map +1 -0
- package/dist/core/backends/opencode-mcp.d.ts +82 -0
- package/dist/core/backends/opencode-mcp.d.ts.map +1 -0
- package/dist/core/backends/opencode-mcp.js +165 -0
- package/dist/core/backends/opencode-mcp.js.map +1 -0
- package/dist/core/backends/opencode-server-manager.d.ts +114 -0
- package/dist/core/backends/opencode-server-manager.d.ts.map +1 -0
- package/dist/core/backends/opencode-server-manager.js +222 -0
- package/dist/core/backends/opencode-server-manager.js.map +1 -0
- package/dist/core/backends/opencode-types.d.ts +46 -0
- package/dist/core/backends/opencode-types.d.ts.map +1 -0
- package/dist/core/backends/opencode-types.js +14 -0
- package/dist/core/backends/opencode-types.js.map +1 -0
- package/dist/core/backends/plan-presets.d.ts +18 -5
- package/dist/core/backends/plan-presets.d.ts.map +1 -1
- package/dist/core/backends/plan-presets.js +144 -23
- package/dist/core/backends/plan-presets.js.map +1 -1
- package/dist/core/backends/process-config-cascade.d.ts +35 -0
- package/dist/core/backends/process-config-cascade.d.ts.map +1 -1
- package/dist/core/backends/process-config-cascade.js +35 -1
- package/dist/core/backends/process-config-cascade.js.map +1 -1
- package/dist/core/backends/prompt-utils.d.ts.map +1 -1
- package/dist/core/backends/prompt-utils.js +0 -2
- package/dist/core/backends/prompt-utils.js.map +1 -1
- package/dist/core/backends/quota-reset-hints.d.ts +44 -0
- package/dist/core/backends/quota-reset-hints.d.ts.map +1 -0
- package/dist/core/backends/quota-reset-hints.js +117 -0
- package/dist/core/backends/quota-reset-hints.js.map +1 -0
- package/dist/core/bang-commands/commands-close.d.ts +24 -0
- package/dist/core/bang-commands/commands-close.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-close.js +24 -0
- package/dist/core/bang-commands/commands-close.js.map +1 -0
- package/dist/core/bang-commands/commands-cost.d.ts.map +1 -1
- package/dist/core/bang-commands/commands-cost.js +13 -0
- package/dist/core/bang-commands/commands-cost.js.map +1 -1
- package/dist/core/bang-commands/commands-help.d.ts.map +1 -1
- package/dist/core/bang-commands/commands-help.js +44 -5
- package/dist/core/bang-commands/commands-help.js.map +1 -1
- package/dist/core/bang-commands/commands-report.d.ts.map +1 -1
- package/dist/core/bang-commands/commands-report.js +1 -0
- package/dist/core/bang-commands/commands-report.js.map +1 -1
- package/dist/core/bang-commands/commands-stop-start.d.ts.map +1 -1
- package/dist/core/bang-commands/commands-stop-start.js +2 -0
- package/dist/core/bang-commands/commands-stop-start.js.map +1 -1
- package/dist/core/bang-commands/commands-wiki.d.ts.map +1 -1
- package/dist/core/bang-commands/commands-wiki.js +12 -1
- package/dist/core/bang-commands/commands-wiki.js.map +1 -1
- package/dist/core/bang-commands/format-utils.d.ts +13 -1
- package/dist/core/bang-commands/format-utils.d.ts.map +1 -1
- package/dist/core/bang-commands/format-utils.js +21 -2
- package/dist/core/bang-commands/format-utils.js.map +1 -1
- package/dist/core/bang-commands/index.d.ts +1 -0
- package/dist/core/bang-commands/index.d.ts.map +1 -1
- package/dist/core/bang-commands/index.js +3 -0
- package/dist/core/bang-commands/index.js.map +1 -1
- package/dist/core/bang-commands/registry.d.ts +50 -0
- package/dist/core/bang-commands/registry.d.ts.map +1 -1
- package/dist/core/bang-commands/registry.js +164 -19
- package/dist/core/bang-commands/registry.js.map +1 -1
- package/dist/core/channel-timeline.d.ts +18 -1
- package/dist/core/channel-timeline.d.ts.map +1 -1
- package/dist/core/channel-timeline.js +44 -0
- package/dist/core/channel-timeline.js.map +1 -1
- package/dist/core/context/activity-view-runner.js +9 -1
- package/dist/core/context/activity-view-runner.js.map +1 -1
- package/dist/core/context/default-schedules-runner.js +44 -4
- package/dist/core/context/default-schedules-runner.js.map +1 -1
- package/dist/core/context/domain-index-runner.js +9 -1
- package/dist/core/context/domain-index-runner.js.map +1 -1
- package/dist/core/context/entity-source-rename.d.ts.map +1 -1
- package/dist/core/context/entity-source-rename.js +9 -1
- package/dist/core/context/entity-source-rename.js.map +1 -1
- package/dist/core/context/policy-index-runner.js +9 -1
- package/dist/core/context/policy-index-runner.js.map +1 -1
- package/dist/core/context/reconciler-runner.js +9 -1
- package/dist/core/context/reconciler-runner.js.map +1 -1
- package/dist/core/context-builder.d.ts +97 -2
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +303 -30
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/context-frontmatter.d.ts +6 -0
- package/dist/core/context-frontmatter.d.ts.map +1 -1
- package/dist/core/context-frontmatter.js +120 -8
- package/dist/core/context-frontmatter.js.map +1 -1
- package/dist/core/context-health.js +21 -9
- package/dist/core/context-health.js.map +1 -1
- package/dist/core/context-validation/_pa_wip_context_validation/index.d.ts +19 -0
- package/dist/core/context-validation/_pa_wip_context_validation/index.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/index.js +19 -0
- package/dist/core/context-validation/_pa_wip_context_validation/index.js.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/prepare-write.d.ts +94 -0
- package/dist/core/context-validation/_pa_wip_context_validation/prepare-write.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/prepare-write.js +130 -0
- package/dist/core/context-validation/_pa_wip_context_validation/prepare-write.js.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/routine-rulebook.d.ts +60 -0
- package/dist/core/context-validation/_pa_wip_context_validation/routine-rulebook.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/routine-rulebook.js +156 -0
- package/dist/core/context-validation/_pa_wip_context_validation/routine-rulebook.js.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/section.d.ts +41 -0
- package/dist/core/context-validation/_pa_wip_context_validation/section.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/section.js +82 -0
- package/dist/core/context-validation/_pa_wip_context_validation/section.js.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/snapshot-debounce.d.ts +52 -0
- package/dist/core/context-validation/_pa_wip_context_validation/snapshot-debounce.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/snapshot-debounce.js +110 -0
- package/dist/core/context-validation/_pa_wip_context_validation/snapshot-debounce.js.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/today.d.ts +85 -0
- package/dist/core/context-validation/_pa_wip_context_validation/today.d.ts.map +1 -0
- package/dist/core/context-validation/_pa_wip_context_validation/today.js +162 -0
- package/dist/core/context-validation/_pa_wip_context_validation/today.js.map +1 -0
- package/dist/core/context-validation/index.d.ts +19 -0
- package/dist/core/context-validation/index.d.ts.map +1 -0
- package/dist/core/context-validation/index.js +19 -0
- package/dist/core/context-validation/index.js.map +1 -0
- package/dist/core/context-validation/prepare-write.d.ts +95 -0
- package/dist/core/context-validation/prepare-write.d.ts.map +1 -0
- package/dist/core/context-validation/prepare-write.js +135 -0
- package/dist/core/context-validation/prepare-write.js.map +1 -0
- package/dist/core/context-validation/routine-rulebook.d.ts +60 -0
- package/dist/core/context-validation/routine-rulebook.d.ts.map +1 -0
- package/dist/core/context-validation/routine-rulebook.js +156 -0
- package/dist/core/context-validation/routine-rulebook.js.map +1 -0
- package/dist/core/context-validation/section.d.ts +41 -0
- package/dist/core/context-validation/section.d.ts.map +1 -0
- package/dist/core/context-validation/section.js +82 -0
- package/dist/core/context-validation/section.js.map +1 -0
- package/dist/core/context-validation/snapshot-debounce.d.ts +52 -0
- package/dist/core/context-validation/snapshot-debounce.d.ts.map +1 -0
- package/dist/core/context-validation/snapshot-debounce.js +110 -0
- package/dist/core/context-validation/snapshot-debounce.js.map +1 -0
- package/dist/core/context-validation/today.d.ts +85 -0
- package/dist/core/context-validation/today.d.ts.map +1 -0
- package/dist/core/context-validation/today.js +168 -0
- package/dist/core/context-validation/today.js.map +1 -0
- package/dist/core/daemon-api-cli.d.ts +6 -5
- package/dist/core/daemon-api-cli.d.ts.map +1 -1
- package/dist/core/daemon-api-cli.js +73 -32
- package/dist/core/daemon-api-cli.js.map +1 -1
- package/dist/core/dispatcher-error-handling.d.ts +13 -0
- package/dist/core/dispatcher-error-handling.d.ts.map +1 -1
- package/dist/core/dispatcher-error-handling.js +69 -0
- package/dist/core/dispatcher-error-handling.js.map +1 -1
- package/dist/core/dispatcher-hourly-check.d.ts +73 -1
- package/dist/core/dispatcher-hourly-check.d.ts.map +1 -1
- package/dist/core/dispatcher-hourly-check.js +249 -151
- package/dist/core/dispatcher-hourly-check.js.map +1 -1
- package/dist/core/dispatcher-message-handler.d.ts +11 -1
- package/dist/core/dispatcher-message-handler.d.ts.map +1 -1
- package/dist/core/dispatcher-message-handler.js +165 -47
- package/dist/core/dispatcher-message-handler.js.map +1 -1
- package/dist/core/dispatcher-morning-routine.d.ts +38 -30
- package/dist/core/dispatcher-morning-routine.d.ts.map +1 -1
- package/dist/core/dispatcher-morning-routine.js +162 -104
- package/dist/core/dispatcher-morning-routine.js.map +1 -1
- package/dist/core/dispatcher-prompt.d.ts +4 -1
- package/dist/core/dispatcher-prompt.d.ts.map +1 -1
- package/dist/core/dispatcher-prompt.js +18 -2
- package/dist/core/dispatcher-prompt.js.map +1 -1
- package/dist/core/dispatcher-repository-helpers.d.ts.map +1 -1
- package/dist/core/dispatcher-repository-helpers.js +5 -1
- package/dist/core/dispatcher-repository-helpers.js.map +1 -1
- package/dist/core/dispatcher-result-processor.d.ts.map +1 -1
- package/dist/core/dispatcher-result-processor.js +9 -4
- package/dist/core/dispatcher-result-processor.js.map +1 -1
- package/dist/core/dispatcher-scheduled-tasks.d.ts +1 -1
- package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -1
- package/dist/core/dispatcher-scheduled-tasks.js +79 -16
- package/dist/core/dispatcher-scheduled-tasks.js.map +1 -1
- package/dist/core/dispatcher-types.d.ts +84 -12
- package/dist/core/dispatcher-types.d.ts.map +1 -1
- package/dist/core/dispatcher-types.js.map +1 -1
- package/dist/core/dispatcher.d.ts +50 -1
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/dispatcher.js +143 -8
- package/dist/core/dispatcher.js.map +1 -1
- package/dist/core/dm-freshness-metrics.d.ts +6 -5
- package/dist/core/dm-freshness-metrics.d.ts.map +1 -1
- package/dist/core/dm-freshness-metrics.js +7 -6
- package/dist/core/dm-freshness-metrics.js.map +1 -1
- package/dist/core/evening-review-verify.d.ts +164 -0
- package/dist/core/evening-review-verify.d.ts.map +1 -0
- package/dist/core/evening-review-verify.js +637 -0
- package/dist/core/evening-review-verify.js.map +1 -0
- package/dist/core/fetch-window-prompt-loader.d.ts +47 -0
- package/dist/core/fetch-window-prompt-loader.d.ts.map +1 -0
- package/dist/core/fetch-window-prompt-loader.js +72 -0
- package/dist/core/fetch-window-prompt-loader.js.map +1 -0
- package/dist/core/management-md.d.ts.map +1 -1
- package/dist/core/management-md.js +23 -9
- package/dist/core/management-md.js.map +1 -1
- package/dist/core/management-registry.d.ts +13 -21
- package/dist/core/management-registry.d.ts.map +1 -1
- package/dist/core/management-registry.js +27 -48
- package/dist/core/management-registry.js.map +1 -1
- package/dist/core/metrics.d.ts +88 -1
- package/dist/core/metrics.d.ts.map +1 -1
- package/dist/core/metrics.js +78 -2
- package/dist/core/metrics.js.map +1 -1
- package/dist/core/morning/agent-journal-appender.d.ts +197 -0
- package/dist/core/morning/agent-journal-appender.d.ts.map +1 -0
- package/dist/core/morning/agent-journal-appender.js +458 -0
- package/dist/core/morning/agent-journal-appender.js.map +1 -0
- package/dist/core/morning/handoff-parser.d.ts +45 -0
- package/dist/core/morning/handoff-parser.d.ts.map +1 -0
- package/dist/core/morning/handoff-parser.js +117 -0
- package/dist/core/morning/handoff-parser.js.map +1 -0
- package/dist/core/morning/journal-skeleton-builder.d.ts +157 -0
- package/dist/core/morning/journal-skeleton-builder.d.ts.map +1 -0
- package/dist/core/morning/journal-skeleton-builder.js +303 -0
- package/dist/core/morning/journal-skeleton-builder.js.map +1 -0
- package/dist/core/morning/orchestrator.d.ts +312 -0
- package/dist/core/morning/orchestrator.d.ts.map +1 -0
- package/dist/core/morning/orchestrator.js +827 -0
- package/dist/core/morning/orchestrator.js.map +1 -0
- package/dist/core/morning/parent-audit-emitter.d.ts +82 -0
- package/dist/core/morning/parent-audit-emitter.d.ts.map +1 -0
- package/dist/core/morning/parent-audit-emitter.js +120 -0
- package/dist/core/morning/parent-audit-emitter.js.map +1 -0
- package/dist/core/morning/roadmap-skeleton-builder.d.ts +159 -0
- package/dist/core/morning/roadmap-skeleton-builder.d.ts.map +1 -0
- package/dist/core/morning/roadmap-skeleton-builder.js +338 -0
- package/dist/core/morning/roadmap-skeleton-builder.js.map +1 -0
- package/dist/core/output-language-policy.js +1 -1
- package/dist/core/output-language-policy.js.map +1 -1
- package/dist/core/policy-files.d.ts +19 -2
- package/dist/core/policy-files.d.ts.map +1 -1
- package/dist/core/policy-files.js +65 -7
- package/dist/core/policy-files.js.map +1 -1
- package/dist/core/pre-pass-freshness.d.ts +28 -0
- package/dist/core/pre-pass-freshness.d.ts.map +1 -0
- package/dist/core/pre-pass-freshness.js +10 -0
- package/dist/core/pre-pass-freshness.js.map +1 -0
- package/dist/core/previous-week-digest.d.ts +130 -0
- package/dist/core/previous-week-digest.d.ts.map +1 -0
- package/dist/core/previous-week-digest.js +257 -0
- package/dist/core/previous-week-digest.js.map +1 -0
- package/dist/core/prompts.js +3 -3
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/quiet-hours-sync.d.ts.map +1 -1
- package/dist/core/quiet-hours-sync.js +7 -0
- package/dist/core/quiet-hours-sync.js.map +1 -1
- package/dist/core/recurrence.d.ts +13 -0
- package/dist/core/recurrence.d.ts.map +1 -1
- package/dist/core/recurrence.js +108 -13
- package/dist/core/recurrence.js.map +1 -1
- package/dist/core/release-assets.d.ts +21 -1
- package/dist/core/release-assets.d.ts.map +1 -1
- package/dist/core/release-assets.js +58 -3
- package/dist/core/release-assets.js.map +1 -1
- package/dist/core/repository-management-docs.d.ts.map +1 -1
- package/dist/core/repository-management-docs.js +14 -4
- package/dist/core/repository-management-docs.js.map +1 -1
- package/dist/core/review-context.d.ts.map +1 -1
- package/dist/core/review-context.js +29 -1
- package/dist/core/review-context.js.map +1 -1
- package/dist/core/roadmap-maintenance.d.ts +213 -0
- package/dist/core/roadmap-maintenance.d.ts.map +1 -0
- package/dist/core/roadmap-maintenance.js +706 -0
- package/dist/core/roadmap-maintenance.js.map +1 -0
- package/dist/core/roadmap-validate.d.ts +5 -0
- package/dist/core/roadmap-validate.d.ts.map +1 -1
- package/dist/core/roadmap-validate.js +6 -69
- package/dist/core/roadmap-validate.js.map +1 -1
- package/dist/core/routine-acquisition-plan.d.ts +43 -7
- package/dist/core/routine-acquisition-plan.d.ts.map +1 -1
- package/dist/core/routine-acquisition-plan.js +99 -8
- package/dist/core/routine-acquisition-plan.js.map +1 -1
- package/dist/core/routine-fetch-window-retry.d.ts +41 -2
- package/dist/core/routine-fetch-window-retry.d.ts.map +1 -1
- package/dist/core/routine-fetch-window-retry.js +91 -8
- package/dist/core/routine-fetch-window-retry.js.map +1 -1
- package/dist/core/routine-fetch-window-runner.d.ts +55 -21
- package/dist/core/routine-fetch-window-runner.d.ts.map +1 -1
- package/dist/core/routine-fetch-window-runner.js +258 -35
- package/dist/core/routine-fetch-window-runner.js.map +1 -1
- package/dist/core/routine-windows.d.ts +17 -13
- package/dist/core/routine-windows.d.ts.map +1 -1
- package/dist/core/routine-windows.js +78 -36
- package/dist/core/routine-windows.js.map +1 -1
- package/dist/core/scheduler.d.ts +121 -37
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +359 -80
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-manager.d.ts +25 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +32 -15
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/skeleton.d.ts.map +1 -1
- package/dist/core/skeleton.js +23 -23
- package/dist/core/skeleton.js.map +1 -1
- package/dist/core/skills-compiler.d.ts +275 -25
- package/dist/core/skills-compiler.d.ts.map +1 -1
- package/dist/core/skills-compiler.js +844 -205
- package/dist/core/skills-compiler.js.map +1 -1
- package/dist/core/skills-manifest.d.ts +104 -0
- package/dist/core/skills-manifest.d.ts.map +1 -1
- package/dist/core/skills-manifest.js +350 -39
- package/dist/core/skills-manifest.js.map +1 -1
- package/dist/core/wiki/git-precompile.d.ts +9 -0
- package/dist/core/wiki/git-precompile.d.ts.map +1 -1
- package/dist/core/wiki/git-precompile.js +7 -1
- package/dist/core/wiki/git-precompile.js.map +1 -1
- package/dist/core/workdir.d.ts +30 -1
- package/dist/core/workdir.d.ts.map +1 -1
- package/dist/core/workdir.js +140 -15
- package/dist/core/workdir.js.map +1 -1
- package/dist/db/entities-store.d.ts +5 -5
- package/dist/db/entities-store.js +5 -5
- package/dist/db/hourly-check-signals.d.ts.map +1 -1
- package/dist/db/hourly-check-signals.js +121 -35
- package/dist/db/hourly-check-signals.js.map +1 -1
- package/dist/db/observations.d.ts +1 -1
- package/dist/db/observations.js +1 -1
- package/dist/db/observations.js.map +1 -1
- package/dist/db/recurring-schedules.d.ts +32 -1
- package/dist/db/recurring-schedules.d.ts.map +1 -1
- package/dist/db/recurring-schedules.js +29 -10
- package/dist/db/recurring-schedules.js.map +1 -1
- package/dist/db/repositories-store.d.ts +2 -1
- package/dist/db/repositories-store.d.ts.map +1 -1
- package/dist/db/repositories-store.js +38 -3
- package/dist/db/repositories-store.js.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +157 -51
- package/dist/db/schema.js.map +1 -1
- package/dist/db/wiki-store.d.ts.map +1 -1
- package/dist/db/wiki-store.js +3 -0
- package/dist/db/wiki-store.js.map +1 -1
- package/dist/index.js +308 -1473
- package/dist/index.js.map +1 -1
- package/dist/messaging/magic-phrase.d.ts +16 -0
- package/dist/messaging/magic-phrase.d.ts.map +1 -1
- package/dist/messaging/magic-phrase.js +53 -0
- package/dist/messaging/magic-phrase.js.map +1 -1
- package/dist/messaging/owner-channels.d.ts +24 -0
- package/dist/messaging/owner-channels.d.ts.map +1 -1
- package/dist/messaging/owner-channels.js +38 -0
- package/dist/messaging/owner-channels.js.map +1 -1
- package/dist/messaging/setup-welcome-dm.d.ts +30 -0
- package/dist/messaging/setup-welcome-dm.d.ts.map +1 -0
- package/dist/messaging/setup-welcome-dm.js +86 -0
- package/dist/messaging/setup-welcome-dm.js.map +1 -0
- package/dist/observers/calendar-poller.d.ts +2 -0
- package/dist/observers/calendar-poller.d.ts.map +1 -1
- package/dist/observers/calendar-poller.js +76 -54
- package/dist/observers/calendar-poller.js.map +1 -1
- package/dist/observers/delegated-sync-worker.d.ts +62 -0
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
- package/dist/observers/delegated-sync-worker.js +128 -1
- package/dist/observers/delegated-sync-worker.js.map +1 -1
- package/dist/observers/git-watcher.d.ts +22 -0
- package/dist/observers/git-watcher.d.ts.map +1 -1
- package/dist/observers/git-watcher.js +31 -7
- package/dist/observers/git-watcher.js.map +1 -1
- package/dist/observers/imminent-event-scheduler.d.ts +2 -0
- package/dist/observers/imminent-event-scheduler.d.ts.map +1 -1
- package/dist/observers/imminent-event-scheduler.js +29 -0
- package/dist/observers/imminent-event-scheduler.js.map +1 -1
- package/dist/observers/notion-poller.d.ts +2 -0
- package/dist/observers/notion-poller.d.ts.map +1 -1
- package/dist/observers/notion-poller.js +44 -6
- package/dist/observers/notion-poller.js.map +1 -1
- package/dist/observers/poll-guard.d.ts +63 -0
- package/dist/observers/poll-guard.d.ts.map +1 -0
- package/dist/observers/poll-guard.js +89 -0
- package/dist/observers/poll-guard.js.map +1 -0
- package/dist/safety/absolute-block-audit.d.ts +17 -0
- package/dist/safety/absolute-block-audit.d.ts.map +1 -1
- package/dist/safety/absolute-block-audit.js +28 -2
- package/dist/safety/absolute-block-audit.js.map +1 -1
- package/dist/safety/agent-write-tracker.d.ts +42 -1
- package/dist/safety/agent-write-tracker.d.ts.map +1 -1
- package/dist/safety/agent-write-tracker.js +81 -1
- package/dist/safety/agent-write-tracker.js.map +1 -1
- package/dist/safety/always-disallowed.d.ts +34 -0
- package/dist/safety/always-disallowed.d.ts.map +1 -1
- package/dist/safety/always-disallowed.js +114 -7
- package/dist/safety/always-disallowed.js.map +1 -1
- package/dist/safety/audit.d.ts +20 -0
- package/dist/safety/audit.d.ts.map +1 -1
- package/dist/safety/audit.js +126 -0
- package/dist/safety/audit.js.map +1 -1
- package/dist/safety/risk-classifier.d.ts +17 -1
- package/dist/safety/risk-classifier.d.ts.map +1 -1
- package/dist/safety/risk-classifier.js +75 -7
- package/dist/safety/risk-classifier.js.map +1 -1
- package/dist/safety/subprocess-block-scanner.d.ts +89 -0
- package/dist/safety/subprocess-block-scanner.d.ts.map +1 -0
- package/dist/safety/subprocess-block-scanner.js +177 -0
- package/dist/safety/subprocess-block-scanner.js.map +1 -0
- package/dist/scheduler/hourly-check-gate.d.ts +23 -9
- package/dist/scheduler/hourly-check-gate.d.ts.map +1 -1
- package/dist/scheduler/hourly-check-gate.js +11 -6
- package/dist/scheduler/hourly-check-gate.js.map +1 -1
- package/dist/secrets/backend-api-key-env.d.ts.map +1 -1
- package/dist/secrets/backend-api-key-env.js +1 -0
- package/dist/secrets/backend-api-key-env.js.map +1 -1
- package/dist/services/delegated-backend-invoker.d.ts.map +1 -1
- package/dist/services/delegated-backend-invoker.js +8 -1
- package/dist/services/delegated-backend-invoker.js.map +1 -1
- package/dist/services/delegated-invoker-audit.d.ts.map +1 -1
- package/dist/services/delegated-invoker-audit.js +5 -1
- package/dist/services/delegated-invoker-audit.js.map +1 -1
- package/dist/services/delegated-proxy-config.d.ts +3 -2
- package/dist/services/delegated-proxy-config.d.ts.map +1 -1
- package/dist/services/delegated-proxy-config.js.map +1 -1
- package/dist/services/integrations/extract-write-item-id.d.ts +5 -2
- package/dist/services/integrations/extract-write-item-id.d.ts.map +1 -1
- package/dist/services/integrations/extract-write-item-id.js.map +1 -1
- package/dist/services/mcp/generators/index.d.ts +1 -0
- package/dist/services/mcp/generators/index.d.ts.map +1 -1
- package/dist/services/mcp/generators/index.js +3 -0
- package/dist/services/mcp/generators/index.js.map +1 -1
- package/dist/services/mcp/sdk-observations-server.d.ts +60 -0
- package/dist/services/mcp/sdk-observations-server.d.ts.map +1 -0
- package/dist/services/mcp/sdk-observations-server.js +161 -0
- package/dist/services/mcp/sdk-observations-server.js.map +1 -0
- package/dist/services/mcp/session-materializer.d.ts.map +1 -1
- package/dist/services/mcp/session-materializer.js +13 -9
- package/dist/services/mcp/session-materializer.js.map +1 -1
- package/dist/services/mcp/types.d.ts +1 -0
- package/dist/services/mcp/types.d.ts.map +1 -1
- package/dist/services/notion.d.ts +19 -1
- package/dist/services/notion.d.ts.map +1 -1
- package/dist/services/notion.js +41 -2
- package/dist/services/notion.js.map +1 -1
- package/dist/services/observations-batch.d.ts +100 -0
- package/dist/services/observations-batch.d.ts.map +1 -0
- package/dist/services/observations-batch.js +258 -0
- package/dist/services/observations-batch.js.map +1 -0
- package/dist/services/voice/transcriber.d.ts +23 -0
- package/dist/services/voice/transcriber.d.ts.map +1 -1
- package/dist/services/voice/transcriber.js +55 -0
- package/dist/services/voice/transcriber.js.map +1 -1
- package/dist/settings/runtime-settings.d.ts +9 -6
- package/dist/settings/runtime-settings.d.ts.map +1 -1
- package/dist/settings/runtime-settings.js +50 -17
- package/dist/settings/runtime-settings.js.map +1 -1
- package/package.json +3 -2
- package/dist/api/delegated-proxy-helper.d.ts +0 -33
- package/dist/api/delegated-proxy-helper.d.ts.map +0 -1
- package/dist/api/delegated-proxy-helper.js +0 -54
- package/dist/api/delegated-proxy-helper.js.map +0 -1
- package/dist/core/roadmap-merge.d.ts +0 -7
- package/dist/core/roadmap-merge.d.ts.map +0 -1
- package/dist/core/roadmap-merge.js +0 -187
- package/dist/core/roadmap-merge.js.map +0 -1
- package/dist/db/test-schemas.d.ts +0 -23
- package/dist/db/test-schemas.d.ts.map +0 -1
- package/dist/db/test-schemas.js +0 -111
- package/dist/db/test-schemas.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { dirname, join, relative } from "node:path";
|
|
3
3
|
import { APP_NAME, BACKEND_IDS, INTEGRATION_DESCRIPTORS, INTEGRATION_KEYS, applyIntegrationModeFilter, collectSessionDeniedTools, filterDeniedToolsForBackend, selectSkillVariantFile, selectTaskFlowVariantSuffix, substituteBrandTokens, } from "@aitne/shared";
|
|
4
|
-
import { getProfileForEvent, getProfileForProcess,
|
|
4
|
+
import { getProfileForEvent, getProfileForProcess, resolveSkillManifest, resolveSkillManifestForProcess, } from "./skills-manifest.js";
|
|
5
5
|
import { applyCharacterBlockRewrite, buildCharacterBlock } from "./character-block.js";
|
|
6
6
|
import { applyOutputLanguagePointerRewrite, renderOutputLanguagePolicyPointer, } from "./output-language-policy.js";
|
|
7
7
|
import { createLogger } from "../logging.js";
|
|
8
|
+
import { loadFetchWindowSystemPrompt } from "./fetch-window-prompt-loader.js";
|
|
8
9
|
import { substituteIntegrationRoutingTables } from "./management-md.js";
|
|
9
10
|
import { loadCurationDeclaration, } from "./skill-curation/declarations.js";
|
|
10
11
|
import { listBuiltinSlugs, resolveBuiltinSkillDir, } from "./skill-source-paths.js";
|
|
@@ -13,6 +14,18 @@ import { hasCurationAnchors, spliceCurationAnchors, } from "./skill-curation/spl
|
|
|
13
14
|
// Exported so tests can spy on `logger.warn` (e.g. the missing-reference
|
|
14
15
|
// branch of `renderReferenceIncludes`). Production callers do not import it.
|
|
15
16
|
export const logger = createLogger("skills-compiler");
|
|
17
|
+
// docs/design/appendices/fetch-window-cost-reduction.md Phase 1.5 — single shared constant
|
|
18
|
+
// for the pre-pass process key. Typed as `ProcessKey` (not the inferred
|
|
19
|
+
// string literal) so a rename in `@aitne/shared/process-key.ts` lights up
|
|
20
|
+
// here rather than silently dead-branching the slim materializer.
|
|
21
|
+
const FETCH_WINDOW_PROCESS_KEY = "routine.fetch_window";
|
|
22
|
+
// Single skill kept in the slim fetch_window CLI session: the
|
|
23
|
+
// `observations` SKILL.md is the POST contract for
|
|
24
|
+
// `/api/observations/batch` and the fetcher's only structural assertion.
|
|
25
|
+
// The other skills the wide path inlines (`mail`, `notion`,
|
|
26
|
+
// `external-services`, `attach`) are already restated by the integration
|
|
27
|
+
// partial the runner inlines into the user prompt.
|
|
28
|
+
const FETCH_WINDOW_SLIM_SKILL = "observations";
|
|
16
29
|
/**
|
|
17
30
|
* Check whether the skill AND task-flow variants a given integration would
|
|
18
31
|
* require when delegated to `delegatedBackend` are all present on disk.
|
|
@@ -151,7 +164,7 @@ function missingVariantsForMode(workspaceDir, integrationKey, pinnedState) {
|
|
|
151
164
|
// required.
|
|
152
165
|
const sessionBackendsToCheck = pinnedState.mode === "native"
|
|
153
166
|
? [pinnedState.nativeBackend]
|
|
154
|
-
: BACKEND_IDS;
|
|
167
|
+
: BACKEND_IDS.filter((backend) => backend !== "opencode");
|
|
155
168
|
// De-dup with sets — the same file path can come up under multiple
|
|
156
169
|
// session backends when descriptors share a slug.
|
|
157
170
|
const skills = new Set();
|
|
@@ -357,9 +370,20 @@ export class SkillsCompiler {
|
|
|
357
370
|
const profileName = params.processKey
|
|
358
371
|
? getProfileForProcess(params.processKey)
|
|
359
372
|
: getProfileForEvent(params.eventType);
|
|
373
|
+
// `evening-review-slimdown.md` §2.1 — route through the predicate-aware
|
|
374
|
+
// wrapper so the evening rulebook gate (and any future per-event
|
|
375
|
+
// predicate) is consulted exactly once per session, at materialization
|
|
376
|
+
// time. The wrapper passes non-conditional events through verbatim, so
|
|
377
|
+
// every other process key keeps its old behaviour.
|
|
378
|
+
const manifestOpts = {
|
|
379
|
+
...(params.contextDir ? { contextDir: params.contextDir } : {}),
|
|
380
|
+
...(params.db !== undefined ? { db: params.db } : {}),
|
|
381
|
+
...(params.messageText !== undefined ? { messageText: params.messageText } : {}),
|
|
382
|
+
};
|
|
383
|
+
const hasManifestOpts = Object.keys(manifestOpts).length > 0;
|
|
360
384
|
const manifestSkills = params.processKey
|
|
361
|
-
?
|
|
362
|
-
:
|
|
385
|
+
? resolveSkillManifestForProcess(params.processKey, hasManifestOpts ? manifestOpts : undefined)
|
|
386
|
+
: resolveSkillManifest(params.eventType, hasManifestOpts ? manifestOpts : undefined);
|
|
363
387
|
// Custom bang command override: when the dispatcher passes a slug array
|
|
364
388
|
// we use it verbatim, ignoring the manifest. Empty array is allowed and
|
|
365
389
|
// means "no skills." `null` keeps manifest behavior — the override is a
|
|
@@ -378,13 +402,32 @@ export class SkillsCompiler {
|
|
|
378
402
|
// adds their first account mid-session (0→N transition). Filtering
|
|
379
403
|
// here would leave the skill dir absent forever since refresh only
|
|
380
404
|
// writes into existing dirs.
|
|
405
|
+
// docs/design/appendices/opencode-backend.md §6.5 / Phase 4 — opencode discovers
|
|
406
|
+
// skills via cwd auto-discovery from `.claude/skills/` (V2) AND uses
|
|
407
|
+
// a per-process agent file at `.opencode/agent/<slug>.md` (V5,
|
|
408
|
+
// singular `agent/`). Routing through `materializeCliSession` would
|
|
409
|
+
// inline skill bodies into AGENTS.md, which we explicitly do NOT
|
|
410
|
+
// want for opencode (skills are auto-discovered by the `skill` tool).
|
|
381
411
|
if (params.backendId === "claude") {
|
|
382
412
|
this.materializeClaudeSession(params.sessionDir, profileName, skills, profileBodyOverride, params.processKey ?? params.eventType, params.wikiWorkspaceName);
|
|
383
413
|
}
|
|
414
|
+
else if (params.backendId === "opencode") {
|
|
415
|
+
this.materializeOpencodeSession(params.sessionDir, profileName, skills, profileBodyOverride, params.processKey ?? params.eventType, params.wikiWorkspaceName);
|
|
416
|
+
}
|
|
384
417
|
else {
|
|
385
418
|
this.materializeCliSession(params.sessionDir, profileName, skills, params.backendId, params.processKey ?? params.eventType, profileBodyOverride, params.wikiWorkspaceName);
|
|
386
419
|
}
|
|
387
|
-
|
|
420
|
+
// docs/design/appendices/fetch-window-cost-reduction.md Phase 1.5 — the slim
|
|
421
|
+
// CLI materializer drops every manifest skill except `observations`.
|
|
422
|
+
// The Claude path is wide for fetch_window today (Phase 1 swaps only
|
|
423
|
+
// the system prompt, not the workdir layout). Report what was
|
|
424
|
+
// actually written so log lines / callers see truth, not the
|
|
425
|
+
// manifest's pre-narrow list.
|
|
426
|
+
const effectiveSkills = params.backendId !== "claude"
|
|
427
|
+
&& (params.processKey ?? params.eventType) === FETCH_WINDOW_PROCESS_KEY
|
|
428
|
+
? [FETCH_WINDOW_SLIM_SKILL]
|
|
429
|
+
: skills;
|
|
430
|
+
return { profile: profileName, skills: effectiveSkills };
|
|
388
431
|
}
|
|
389
432
|
/** Read raw profile .md without safety injection. */
|
|
390
433
|
readProfile(profileName) {
|
|
@@ -492,8 +535,39 @@ export class SkillsCompiler {
|
|
|
492
535
|
mkdirSync(dirname(join(sessionDir, "CLAUDE.md")), { recursive: true });
|
|
493
536
|
writeFileSync(join(sessionDir, "CLAUDE.md"), profileContent, "utf-8");
|
|
494
537
|
}
|
|
538
|
+
this.writeSkillsDir(sessionDir, join(".claude", "skills"), skillSlugs, "claude", processKey, wikiWorkspaceName);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* docs/design/appendices/skills-unification.md Phase 1 — per-backend skill-dir writer.
|
|
542
|
+
*
|
|
543
|
+
* Writes `<sessionDir>/<destSkillsRootRelative>/<slug>/SKILL.md` for each
|
|
544
|
+
* slug, applying the full per-skill transformation pipeline:
|
|
545
|
+
* variant resolution → brand tokens → partial / reference inlining →
|
|
546
|
+
* service strip → mode filter → deny filter → curation splice → mail
|
|
547
|
+
* `accounts.md`. The destination directory is the only thing that varies
|
|
548
|
+
* across backends:
|
|
549
|
+
*
|
|
550
|
+
* - Claude → `.claude/skills`
|
|
551
|
+
* - OpenCode → `.opencode/skills`
|
|
552
|
+
* - Codex → `.codex/skills`
|
|
553
|
+
* - Gemini → `.gemini/skills`
|
|
554
|
+
*
|
|
555
|
+
* For Codex sessions, this method ALSO prepends a one-line read-sensitive
|
|
556
|
+
* banner to each materialised SKILL.md whose body references a read-
|
|
557
|
+
* sensitive `/api/*` endpoint (those endpoints 401 on Codex because the
|
|
558
|
+
* Codex backend does not hold the read-sensitive token). The banner
|
|
559
|
+
* points the agent at the `## Read-sensitive endpoints are UNAVAILABLE`
|
|
560
|
+
* section already rendered into `AGENTS.md`.
|
|
561
|
+
*
|
|
562
|
+
* Returns the list of slugs that ended up on disk (slugs whose variant
|
|
563
|
+
* resolved to `null` for same-backend native MCP and slugs whose source
|
|
564
|
+
* SKILL.md was missing are excluded). Callers use this list to render
|
|
565
|
+
* the `<skill-index>` block from a stable, post-materialisation source.
|
|
566
|
+
*/
|
|
567
|
+
writeSkillsDir(sessionDir, destSkillsRootRelative, skillSlugs, sessionBackend, processKey, wikiWorkspaceName) {
|
|
568
|
+
const materialised = [];
|
|
495
569
|
const skillsRoot = this.getSourceSkillsRoot();
|
|
496
|
-
const destSkillsRoot = join(sessionDir,
|
|
570
|
+
const destSkillsRoot = join(sessionDir, destSkillsRootRelative);
|
|
497
571
|
mkdirSync(destSkillsRoot, { recursive: true });
|
|
498
572
|
// Re-materialize cleanup: a previous turn (especially one with a wider
|
|
499
573
|
// skill set or a different custom-command override) may have left
|
|
@@ -504,11 +578,19 @@ export class SkillsCompiler {
|
|
|
504
578
|
// `syncAllUserSkills` is the authoritative writer for that subset.
|
|
505
579
|
pruneStaleBuiltinSkillDirs(destSkillsRoot, skillsRoot, skillSlugs);
|
|
506
580
|
for (const skillSlug of skillSlugs) {
|
|
581
|
+
// docs/design/appendices/opencode-backend.md §10 D6 / Phase 4 — slug must match
|
|
582
|
+
// opencode's skill-name lint regex `[a-z0-9-]{1,64}` because a
|
|
583
|
+
// future opencode release may reject names that fall outside it.
|
|
584
|
+
// Warn at materialisation; do not strip the skill (every Aitne
|
|
585
|
+
// built-in slug already conforms — see audit acceptance criterion).
|
|
586
|
+
if (!isValidSkillSlug(skillSlug)) {
|
|
587
|
+
logger.warn({ skillSlug, expected: "[a-z0-9-]{1,64}" }, "skills_compiler.skill_slug_invalid");
|
|
588
|
+
}
|
|
507
589
|
const src = resolveBuiltinSkillDir(skillsRoot, skillSlug);
|
|
508
590
|
if (!existsSync(join(src, "SKILL.md"))) {
|
|
509
591
|
continue;
|
|
510
592
|
}
|
|
511
|
-
const variantFile = this.resolveSkillVariantFile(skillSlug,
|
|
593
|
+
const variantFile = this.resolveSkillVariantFile(skillSlug, sessionBackend);
|
|
512
594
|
const destDir = join(destSkillsRoot, skillSlug);
|
|
513
595
|
// DELEGATED-MODE-V2-DESIGN.md §4.1.2 — same-backend native MCP. The
|
|
514
596
|
// agent already has the connector's tools in its inventory; a skill
|
|
@@ -545,10 +627,10 @@ export class SkillsCompiler {
|
|
|
545
627
|
//
|
|
546
628
|
// Order: refs BEFORE strip-services. The CLI paths
|
|
547
629
|
// (`materializeCliSession` inline + directory copy) both run refs
|
|
548
|
-
// before strip; aligning
|
|
630
|
+
// before strip; aligning here preserves the byte-equivalence
|
|
549
631
|
// contract (plan §3.1) for the case where a reference file carries
|
|
550
632
|
// `<!-- service:* -->` markers — strip-first would leak those on
|
|
551
|
-
// Claude while CLI scrubs them.
|
|
633
|
+
// Claude/OpenCode while CLI scrubs them.
|
|
552
634
|
const destSkillMdForRefs = join(destDir, "SKILL.md");
|
|
553
635
|
if (existsSync(destSkillMdForRefs)) {
|
|
554
636
|
const raw = readFileSync(destSkillMdForRefs, "utf-8");
|
|
@@ -578,18 +660,20 @@ export class SkillsCompiler {
|
|
|
578
660
|
const destSkillMdForMode = join(destDir, "SKILL.md");
|
|
579
661
|
if (existsSync(destSkillMdForMode)) {
|
|
580
662
|
const raw = readFileSync(destSkillMdForMode, "utf-8");
|
|
581
|
-
const filtered = applyIntegrationModeFilter(raw, this.integrations,
|
|
663
|
+
const filtered = applyIntegrationModeFilter(raw, this.integrations, sessionBackend);
|
|
582
664
|
if (filtered !== raw) {
|
|
583
665
|
writeFileSync(destSkillMdForMode, filtered, "utf-8");
|
|
584
666
|
}
|
|
585
667
|
}
|
|
586
668
|
// §7.7 — apply tool-deny policy AFTER partial includes and
|
|
587
|
-
// service-section stripping. For Claude this rewrites the
|
|
588
|
-
// `allowed-tools` frontmatter; the
|
|
669
|
+
// service-section stripping. For the Claude SDK this rewrites the
|
|
670
|
+
// `allowed-tools` frontmatter (hard); for opencode the rewrite is
|
|
671
|
+
// a soft-enforcement prose body addition that the runtime config
|
|
672
|
+
// doubles up via `permission.bash.deny` rules.
|
|
589
673
|
const destSkillMdForDeny = join(destDir, "SKILL.md");
|
|
590
674
|
if (existsSync(destSkillMdForDeny)) {
|
|
591
675
|
const raw = readFileSync(destSkillMdForDeny, "utf-8");
|
|
592
|
-
const filtered = applyAllDeniedToolsForSkill(raw, skillSlug,
|
|
676
|
+
const filtered = applyAllDeniedToolsForSkill(raw, skillSlug, sessionBackend, this.integrations);
|
|
593
677
|
if (filtered !== raw) {
|
|
594
678
|
writeFileSync(destSkillMdForDeny, filtered, "utf-8");
|
|
595
679
|
}
|
|
@@ -608,7 +692,141 @@ export class SkillsCompiler {
|
|
|
608
692
|
? renderMailAccountsMd(this.mailAccounts)
|
|
609
693
|
: EMPTY_MAIL_ACCOUNTS_MD, "utf-8");
|
|
610
694
|
}
|
|
695
|
+
// Phase 1 §"Codex read-sensitive banner inheritance" — prepend the
|
|
696
|
+
// 3-line caveat banner to every Codex skill body that touches a
|
|
697
|
+
// read-sensitive `/api/*` endpoint. Skipped for the other three
|
|
698
|
+
// backends: Claude / Gemini hold the read-sensitive token; OpenCode
|
|
699
|
+
// surfaces those routes via its own credential flow.
|
|
700
|
+
if (sessionBackend === "codex") {
|
|
701
|
+
prependCodexReadSensitiveBanner(join(destDir, "SKILL.md"));
|
|
702
|
+
}
|
|
703
|
+
materialised.push(skillSlug);
|
|
611
704
|
}
|
|
705
|
+
return materialised;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* docs/design/appendices/opencode-backend.md §6.5 / Phase 4 — opencode-specific
|
|
709
|
+
* materialisation.
|
|
710
|
+
*
|
|
711
|
+
* Three on-disk artefacts are written per session:
|
|
712
|
+
* 1. `AGENTS.md` (cwd-auto-discovered by opencode per V1) — same
|
|
713
|
+
* shape as `materializeCliSession` produces for Codex EXCEPT
|
|
714
|
+
* skill bodies are NOT inlined (skills auto-discover from
|
|
715
|
+
* `.claude/skills/` via opencode's `skill` tool — V2). Includes
|
|
716
|
+
* safety, character, behavioral rules, daemon-API, integration
|
|
717
|
+
* routing tables, and the runtime profile body.
|
|
718
|
+
* 2. `.opencode/agent/<profile-slug>.md` (singular `agent/` per V5)
|
|
719
|
+
* — the per-process agent persona with V5-correct frontmatter
|
|
720
|
+
* (`mode: primary`, `permission` block keyed only on
|
|
721
|
+
* `edit/bash/webfetch/doom_loop/external_directory` — NO `read`
|
|
722
|
+
* key per V5 contract). Body is the profile body; opencode
|
|
723
|
+
* invokes this via `session.prompt({ body: { agent: <slug> } })`
|
|
724
|
+
* so the per-agent permission overrides the server-level
|
|
725
|
+
* defaults.
|
|
726
|
+
* 3. `.opencode/skills/<slug>/` via `writeSkillsDir` — every
|
|
727
|
+
* manifest skill becomes a discoverable SKILL.md tree opencode
|
|
728
|
+
* reads on `skill` tool activation. `.claude/skills/` is
|
|
729
|
+
* intentionally NOT written: docs/design/appendices/skills-unification.md Phase 1
|
|
730
|
+
* flipped opencode from V2 path (b) (`.claude/skills/`
|
|
731
|
+
* redundancy-avoiding alias) to V2 path (c) (`.opencode/skills/`)
|
|
732
|
+
* so each backend lives under its own brand-aligned namespace.
|
|
733
|
+
*
|
|
734
|
+
* The dispatcher passes `agent: <slug>` (where `<slug>` matches the
|
|
735
|
+
* profile filename without `.md`) on every `session.prompt` call so
|
|
736
|
+
* the right agent file is selected.
|
|
737
|
+
*/
|
|
738
|
+
materializeOpencodeSession(sessionDir, profileName, skillSlugs, profileBodyOverride, processKey, wikiWorkspaceName) {
|
|
739
|
+
// ── 1. AGENTS.md — cwd context (no skill inlining) ──
|
|
740
|
+
let profileContent = profileBodyOverride !== null
|
|
741
|
+
? profileBodyOverride.trim()
|
|
742
|
+
: (this.readProfile(profileName) ?? "");
|
|
743
|
+
profileContent = substituteWikiWorkspaceTokens(profileContent, processKey, wikiWorkspaceName);
|
|
744
|
+
const safetyContent = this.readSafetyPreamble();
|
|
745
|
+
const characterBlock = buildCharacterBlock(this.character);
|
|
746
|
+
// DELEGATED-MODE-V2-DESIGN.md §4.3.3-§4.3.4 — same-backend deny prose.
|
|
747
|
+
// Opencode's MCP-tool deny is server-level only (§5.6 v1: drop the
|
|
748
|
+
// server from config to deny). The prose duplicates intent so the
|
|
749
|
+
// agent doesn't waste tokens drafting calls that will be dropped.
|
|
750
|
+
const sameBackendDenyBlock = buildSameBackendDenyBlock(this.integrations, "opencode");
|
|
751
|
+
const rawInstruction = renderCliInstructionFile({
|
|
752
|
+
backendId: "opencode",
|
|
753
|
+
processKey,
|
|
754
|
+
profileName,
|
|
755
|
+
profileContent,
|
|
756
|
+
safetyContent,
|
|
757
|
+
characterBlock,
|
|
758
|
+
skillSlugs,
|
|
759
|
+
// R3 — OpenCode never gets a `<skill-index>` block. The cwd
|
|
760
|
+
// auto-discovery loader is the source of truth; emitting an index
|
|
761
|
+
// here would inject a second listing the runtime ignores and the
|
|
762
|
+
// agent could mistake for canonical. The `## Skills` slug manifest
|
|
763
|
+
// (no path, no inlined bodies) survives as a turn-scope hint.
|
|
764
|
+
skillPreamble: null,
|
|
765
|
+
skillIndexBlock: null,
|
|
766
|
+
sameBackendDenyBlock,
|
|
767
|
+
});
|
|
768
|
+
const instruction = substituteWikiWorkspaceTokens(substituteIntegrationRoutingTables(rawInstruction, this.integrations), processKey, wikiWorkspaceName);
|
|
769
|
+
writeFileSync(join(sessionDir, "AGENTS.md"), instruction, "utf-8");
|
|
770
|
+
// ── 2. .opencode/agent/<profileName>.md — V5 frontmatter wrapper ──
|
|
771
|
+
this.writeOpencodeAgentFile(sessionDir, profileName, profileContent, safetyContent, characterBlock);
|
|
772
|
+
// ── 3. .opencode/skills/ — auto-discovered by opencode 1.14+ ──
|
|
773
|
+
// docs/design/appendices/skills-unification.md Phase 1 — opencode 1.14+ auto-discovers
|
|
774
|
+
// skills from `.opencode/skills/<slug>/SKILL.md` (V2 path (c),
|
|
775
|
+
// empirically verified). The earlier path (b) (`.claude/skills/`)
|
|
776
|
+
// worked as a redundancy-avoiding alias; per-backend brand-aligned
|
|
777
|
+
// naming now picks (c) explicitly.
|
|
778
|
+
this.writeSkillsDir(sessionDir, join(".opencode", "skills"), skillSlugs, "opencode", processKey, wikiWorkspaceName);
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* docs/design/appendices/opencode-backend.md §6.5 / V5 — write the per-process agent
|
|
782
|
+
* profile to `.opencode/agent/<slug>.md` (singular `agent/`; the
|
|
783
|
+
* plural form does NOT register per V5).
|
|
784
|
+
*
|
|
785
|
+
* Frontmatter shape (V5-correct keys only):
|
|
786
|
+
* - `mode: primary` — opencode's primary-agent mode; subagent is
|
|
787
|
+
* reserved for the disabled `task` tool path.
|
|
788
|
+
* - NO `permission` block here — the server-level
|
|
789
|
+
* `OpencodeRuntimeConfig.permission` is the per-session truth and
|
|
790
|
+
* is stricter for narrow agents (delegated runs use a separate
|
|
791
|
+
* `delegated-<callId>` agent file with its own tight permission).
|
|
792
|
+
* Emitting `permission: {}` here would NOT widen anything (the
|
|
793
|
+
* server-level deny still wins), but the absence keeps the
|
|
794
|
+
* frontmatter a manifest and avoids drift between two seats.
|
|
795
|
+
* - NO `model` field — opencode falls back to `OPENCODE_CONFIG_CONTENT.model`
|
|
796
|
+
* (set per-session by `OpencodeCore`'s runtime-config builder),
|
|
797
|
+
* and the dispatcher additionally overrides per `session.prompt`
|
|
798
|
+
* body. Pinning here would either drift from the per-call value
|
|
799
|
+
* or duplicate it.
|
|
800
|
+
*
|
|
801
|
+
* Body composition mirrors AGENTS.md (safety + character + profile)
|
|
802
|
+
* so an `agent: <slug>` invocation that REPLACES opencode's default
|
|
803
|
+
* cwd context still gets safety/character rules — V5 confirmed the
|
|
804
|
+
* agent body becomes the system prompt for that turn.
|
|
805
|
+
*/
|
|
806
|
+
writeOpencodeAgentFile(sessionDir, profileName, profileBody, safetyContent, characterBlock) {
|
|
807
|
+
const agentDir = join(sessionDir, ".opencode", "agent");
|
|
808
|
+
mkdirSync(agentDir, { recursive: true });
|
|
809
|
+
// Strip a description from the profile body's first paragraph for
|
|
810
|
+
// the frontmatter `description` field. Opencode displays this in
|
|
811
|
+
// its agent picker; we use a stable phrasing so re-renders produce
|
|
812
|
+
// identical bytes.
|
|
813
|
+
const description = `${APP_NAME} ${profileName} — per-process persona`;
|
|
814
|
+
const frontmatter = [
|
|
815
|
+
"---",
|
|
816
|
+
`description: ${description}`,
|
|
817
|
+
"mode: primary",
|
|
818
|
+
"---",
|
|
819
|
+
"",
|
|
820
|
+
].join("\n");
|
|
821
|
+
const bodySections = [];
|
|
822
|
+
if (safetyContent)
|
|
823
|
+
bodySections.push(safetyContent);
|
|
824
|
+
if (characterBlock)
|
|
825
|
+
bodySections.push(characterBlock);
|
|
826
|
+
if (profileBody.trim())
|
|
827
|
+
bodySections.push(profileBody.trim());
|
|
828
|
+
const body = bodySections.join("\n\n");
|
|
829
|
+
writeFileSync(join(agentDir, `${profileName}.md`), `${frontmatter}${body}\n`, "utf-8");
|
|
612
830
|
}
|
|
613
831
|
/**
|
|
614
832
|
* P22 §1.5 — splice CURATION anchors in a single skill's materialized
|
|
@@ -648,64 +866,121 @@ export class SkillsCompiler {
|
|
|
648
866
|
writeFileSync(skillMdPath, result.body, "utf-8");
|
|
649
867
|
}
|
|
650
868
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
869
|
+
/**
|
|
870
|
+
* docs/design/appendices/skills-unification.md Phase 1 item 15 — the slim path does NOT
|
|
871
|
+
* emit a `<skill-index>` block or the skill-discovery preamble. The
|
|
872
|
+
* fetch_window system prompt is a self-contained operational contract
|
|
873
|
+
* (one-window-one-curl, no sub-tasks, exactly-one JSON-on-stdout) and
|
|
874
|
+
* the only skill copied (`observations`) is referenced inline by the
|
|
875
|
+
* runner-emitted user prompt. Adding the index would mis-signal the
|
|
876
|
+
* fetcher to scan for skills before executing the acquisition plan.
|
|
877
|
+
*
|
|
878
|
+
* docs/design/appendices/fetch-window-cost-reduction.md Phase 1.5 — slim instruction-file
|
|
879
|
+
* materializer for `routine.fetch_window` on Codex / Gemini CLI.
|
|
880
|
+
*
|
|
881
|
+
* Mirrors the Claude SDK's Phase 1 systemPrompt swap (the same
|
|
882
|
+
* `agent-assets/system-prompts/routine-fetch-window.md` template is the
|
|
883
|
+
* single source of truth): write the slim body verbatim as AGENTS.md /
|
|
884
|
+
* GEMINI.md and copy only the `observations` skill — the
|
|
885
|
+
* `/api/observations/batch` POST contract is the fetcher's sole
|
|
886
|
+
* structural assertion. The integration partial inlined by the runner
|
|
887
|
+
* (`routine-fetch-window-runner.ts:reassemblePrompt`) covers the
|
|
888
|
+
* per-attempt call shape, so `mail` / `notion` / `external-services` /
|
|
889
|
+
* `attach` skill bodies are deliberately omitted.
|
|
890
|
+
*
|
|
891
|
+
* No safety preamble / character / behavioral-rules / daemon-API
|
|
892
|
+
* sections — the slim template restates the only rules the fetcher
|
|
893
|
+
* needs (localhost-only curl, no sub-tasks, no context writes, no
|
|
894
|
+
* notify, JSON-on-stdout-and-exit). The destructive-action policy layer
|
|
895
|
+
* (absolute-block list, Codex sandbox, Gemini admin TOML) still applies
|
|
896
|
+
* unchanged at runtime.
|
|
897
|
+
*
|
|
898
|
+
* The `<mcp-servers>` section is appended downstream by
|
|
899
|
+
* `services/mcp/session-materializer.ts:appendMcpSection` exactly as on
|
|
900
|
+
* the wide path — Phase 3's allowlist filter, when it lands, will scope
|
|
901
|
+
* that section without further changes here.
|
|
902
|
+
*/
|
|
903
|
+
materializeFetchWindowCliSession(sessionDir, backendId) {
|
|
904
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
905
|
+
const slim = loadFetchWindowSystemPrompt();
|
|
906
|
+
writeFileSync(join(sessionDir, cliInstructionFileName(backendId)), slim, "utf-8");
|
|
907
|
+
// Copy ONLY the `observations` skill dir. The wide path's prune step
|
|
908
|
+
// is replaced by an explicit single-slug list — `pruneStaleBuiltinSkillDirs`
|
|
909
|
+
// removes any other built-in skill dir that a prior re-materialization
|
|
910
|
+
// (e.g. a fallback-driven wide path on the same workdir) may have left.
|
|
911
|
+
const cliSkillsRoot = cliSkillsDirName(backendId);
|
|
912
|
+
if (cliSkillsRoot === null)
|
|
913
|
+
return; // Claude-only — fetch_window slim runs on Claude SDK natively.
|
|
659
914
|
const skillsRoot = this.getSourceSkillsRoot();
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
915
|
+
const destSkillsRoot = join(sessionDir, cliSkillsRoot, "skills");
|
|
916
|
+
mkdirSync(destSkillsRoot, { recursive: true });
|
|
917
|
+
pruneStaleBuiltinSkillDirs(destSkillsRoot, skillsRoot, [FETCH_WINDOW_SLIM_SKILL]);
|
|
918
|
+
const src = resolveBuiltinSkillDir(skillsRoot, FETCH_WINDOW_SLIM_SKILL);
|
|
919
|
+
const skillMdPath = join(src, "SKILL.md");
|
|
920
|
+
if (!existsSync(skillMdPath))
|
|
921
|
+
return;
|
|
922
|
+
const destDir = join(destSkillsRoot, FETCH_WINDOW_SLIM_SKILL);
|
|
923
|
+
cpSync(src, destDir, { recursive: true });
|
|
924
|
+
substituteBrandTokensInDir(destDir);
|
|
925
|
+
// No `substituteWikiWorkspaceTokensInDir` — fetch_window never touches
|
|
926
|
+
// wiki workspace state, and the resolver is a no-op for non-wiki
|
|
927
|
+
// process keys anyway.
|
|
928
|
+
let adapted = substituteBrandTokens(readFileSync(skillMdPath, "utf-8"));
|
|
929
|
+
// observations/SKILL.md ships no `{{> base }}` or `{{> ref:* }}`
|
|
930
|
+
// directives today, but run the resolvers anyway so a future curation
|
|
931
|
+
// edit cannot silently drop content. Idempotent on plain content.
|
|
932
|
+
adapted = substituteBrandTokens(renderPartialIncludes(adapted, join(src, "SKILL.base.md")));
|
|
933
|
+
adapted = substituteBrandTokens(renderReferenceIncludes(adapted, src));
|
|
934
|
+
// Mode-conditional filter — observations/SKILL.md carries
|
|
935
|
+
// `<!-- mode:<predicate>:notion -->` markers (lines 273-345 today)
|
|
936
|
+
// because the source / consume contract differs across `direct` /
|
|
937
|
+
// `delegated-same` / `delegated-cross` / `native` / `disabled`. The
|
|
938
|
+
// wide path applies this filter at `materializeCliSession`; the
|
|
939
|
+
// slim path must match so the agent doesn't get every mode's prose
|
|
940
|
+
// for every integration. Idempotent on bodies that lack markers.
|
|
941
|
+
adapted = applyIntegrationModeFilter(adapted, this.integrations, backendId);
|
|
942
|
+
// Tool-deny policy stays in force — even though the fetcher is fed a
|
|
943
|
+
// narrow allowlist, the soft-enforcement prose lands in the body
|
|
944
|
+
// BEFORE the CLI frontmatter strip so it's not lost.
|
|
945
|
+
adapted = applyAllDeniedToolsForSkill(adapted, FETCH_WINDOW_SLIM_SKILL, backendId, this.integrations);
|
|
946
|
+
// docs/design/appendices/skills-unification.md Phase 1 §R6 — frontmatter stays intact
|
|
947
|
+
// across all backends. `adaptSkillForCli` is gone; the source body's
|
|
948
|
+
// YAML preamble flows through verbatim.
|
|
949
|
+
writeFileSync(join(destDir, "SKILL.md"), adapted, "utf-8");
|
|
950
|
+
this.spliceCurationAnchorsInSkill(destDir, FETCH_WINDOW_SLIM_SKILL);
|
|
951
|
+
}
|
|
952
|
+
materializeCliSession(sessionDir, profileName, skillSlugs, backendId, processKey, profileBodyOverride, wikiWorkspaceName) {
|
|
953
|
+
// docs/design/appendices/fetch-window-cost-reduction.md Phase 1.5 — divert
|
|
954
|
+
// `routine.fetch_window` to a slim materializer that mirrors the
|
|
955
|
+
// Claude SDK's Phase 1 systemPrompt swap. Custom bang commands cannot
|
|
956
|
+
// reach this branch (they bind to `messaging.custom_command`), so
|
|
957
|
+
// `profileBodyOverride` is intentionally NOT forwarded.
|
|
958
|
+
if (processKey === FETCH_WINDOW_PROCESS_KEY) {
|
|
959
|
+
this.materializeFetchWindowCliSession(sessionDir, backendId);
|
|
960
|
+
return;
|
|
703
961
|
}
|
|
962
|
+
// docs/design/appendices/skills-unification.md Phase 1 — directory-based skill delivery.
|
|
963
|
+
// The Codex / Gemini CLIs have no native cwd auto-discovery today, so
|
|
964
|
+
// the instruction file (AGENTS.md / GEMINI.md) carries a compact
|
|
965
|
+
// `<skill-index>` block and the agent `Read`s each `SKILL.md` from the
|
|
966
|
+
// per-backend dir on demand. Skill bodies are NEVER inlined into the
|
|
967
|
+
// instruction file.
|
|
968
|
+
//
|
|
969
|
+
// OpenCode reaches `materializeOpencodeSession` instead, so this method
|
|
970
|
+
// only handles Codex and Gemini. The defensive `null` check below
|
|
971
|
+
// protects future backends that might temporarily route through here
|
|
972
|
+
// before getting their own materialiser.
|
|
973
|
+
const cliSkillsDir = cliSkillsDirName(backendId);
|
|
974
|
+
if (cliSkillsDir === null) {
|
|
975
|
+
throw new Error(`materializeCliSession: no skills directory mapped for backend "${backendId}"`);
|
|
976
|
+
}
|
|
977
|
+
const destSkillsRootRelative = join(cliSkillsDir, "skills");
|
|
978
|
+
const materialisedSlugs = this.writeSkillsDir(sessionDir, destSkillsRootRelative, skillSlugs, backendId, processKey, wikiWorkspaceName);
|
|
704
979
|
// Read profile and safety separately so renderCliInstructionFile can
|
|
705
980
|
// place safety at the top level for prominence (instead of burying it
|
|
706
981
|
// inside the profile section). For custom bang commands the dispatcher
|
|
707
982
|
// passes a `profileBodyOverride` that replaces the persona body; the
|
|
708
|
-
// safety + character +
|
|
983
|
+
// safety + character + skill index sections still wrap around it via
|
|
709
984
|
// `renderCliInstructionFile`.
|
|
710
985
|
let profileContent = profileBodyOverride !== null
|
|
711
986
|
? profileBodyOverride.trim()
|
|
@@ -721,6 +996,18 @@ export class SkillsCompiler {
|
|
|
721
996
|
// prose duplicates intent so the agent doesn't waste tokens drafting
|
|
722
997
|
// calls that will be denied at the policy layer.
|
|
723
998
|
const sameBackendDenyBlock = buildSameBackendDenyBlock(this.integrations, backendId);
|
|
999
|
+
// docs/design/appendices/skills-unification.md Phase 1 §"Skill preamble" — render the
|
|
1000
|
+
// universal preamble + `<skill-index>` block. The index is derived
|
|
1001
|
+
// from the **materialised** SKILL.md frontmatter on disk so curation /
|
|
1002
|
+
// mode-filter / deny passes are reflected. Reading post-materialisation
|
|
1003
|
+
// also keeps user-authored slugs synced by `syncAllUserSkills` (which
|
|
1004
|
+
// runs LATER from the workdir layer) out of the index — those land in
|
|
1005
|
+
// the same dir but are appended after this render. The
|
|
1006
|
+
// `refreshSkillIndexBlock` helper (called by workdir.ts post-sync) is
|
|
1007
|
+
// responsible for splicing user-authored slugs into the block.
|
|
1008
|
+
const skillPreamble = loadSkillIndexPreamble(this.workspaceDir);
|
|
1009
|
+
const destSkillsRootAbs = join(sessionDir, destSkillsRootRelative);
|
|
1010
|
+
const skillIndexBlock = renderSkillIndexBlock(destSkillsRootAbs, destSkillsRootRelative);
|
|
724
1011
|
const rawInstruction = renderCliInstructionFile({
|
|
725
1012
|
backendId,
|
|
726
1013
|
processKey,
|
|
@@ -728,89 +1015,18 @@ export class SkillsCompiler {
|
|
|
728
1015
|
profileContent,
|
|
729
1016
|
safetyContent,
|
|
730
1017
|
characterBlock,
|
|
731
|
-
skillSlugs,
|
|
732
|
-
|
|
1018
|
+
skillSlugs: materialisedSlugs,
|
|
1019
|
+
skillPreamble,
|
|
1020
|
+
skillIndexBlock,
|
|
733
1021
|
sameBackendDenyBlock,
|
|
734
1022
|
});
|
|
735
1023
|
// INTEGRATION_NATIVE_MODE_DESIGN.md §7.3 — substitute the
|
|
736
1024
|
// `<integration-routing-table>` placeholder in the rendered
|
|
737
1025
|
// instruction file. Runs after the whole document is assembled so
|
|
738
|
-
// placeholders anywhere (profile body,
|
|
739
|
-
//
|
|
740
|
-
// placeholder string is present.
|
|
1026
|
+
// placeholders anywhere (profile body, preamble, index) all resolve
|
|
1027
|
+
// in one pass.
|
|
741
1028
|
const instruction = substituteWikiWorkspaceTokens(substituteIntegrationRoutingTables(rawInstruction, this.integrations), processKey, wikiWorkspaceName);
|
|
742
|
-
writeFileSync(join(sessionDir, backendId
|
|
743
|
-
// Copy skills to the backend-specific skill directory for native CLI
|
|
744
|
-
// discovery: .codex/skills/<slug>/ or .gemini/skills/<slug>/
|
|
745
|
-
const cliSkillsDir = cliSkillsDirName(backendId);
|
|
746
|
-
const destSkillsRoot = join(sessionDir, cliSkillsDir, "skills");
|
|
747
|
-
mkdirSync(destSkillsRoot, { recursive: true });
|
|
748
|
-
// See `materializeClaudeSession` — same prune contract for CLI workdirs.
|
|
749
|
-
pruneStaleBuiltinSkillDirs(destSkillsRoot, skillsRoot, skillSlugs);
|
|
750
|
-
for (const skillSlug of skillSlugs) {
|
|
751
|
-
const src = resolveBuiltinSkillDir(skillsRoot, skillSlug);
|
|
752
|
-
const variantFile = this.resolveSkillVariantFile(skillSlug, backendId);
|
|
753
|
-
const destDir = join(destSkillsRoot, skillSlug);
|
|
754
|
-
// §4.1.2 same-backend short-circuit: no SKILL.md / .codex/skills/<slug>
|
|
755
|
-
// / .gemini/skills/<slug> directory written. The connector ships its
|
|
756
|
-
// own descriptions; injecting prose only confuses the dispatch.
|
|
757
|
-
// Remove any prior-materialization leftovers so a mode flip doesn't
|
|
758
|
-
// leak stale prose into the workdir.
|
|
759
|
-
if (variantFile === null) {
|
|
760
|
-
if (existsSync(destDir)) {
|
|
761
|
-
rmSync(destDir, { recursive: true, force: true });
|
|
762
|
-
}
|
|
763
|
-
continue;
|
|
764
|
-
}
|
|
765
|
-
const variantPath = join(src, variantFile);
|
|
766
|
-
if (!existsSync(variantPath)) {
|
|
767
|
-
continue;
|
|
768
|
-
}
|
|
769
|
-
// Copy the whole skill directory (scripts/, references/, etc.)
|
|
770
|
-
cpSync(src, destDir, { recursive: true });
|
|
771
|
-
// Resolve `{APP_NAME}` brand tokens in the verbatim copy before any
|
|
772
|
-
// downstream transform reads them. Source-of-truth: branding.ts.
|
|
773
|
-
substituteBrandTokensInDir(destDir);
|
|
774
|
-
substituteWikiWorkspaceTokensInDir(destDir, processKey, wikiWorkspaceName);
|
|
775
|
-
// Render variant (resolving partials), adapt frontmatter for CLI, and
|
|
776
|
-
// write as SKILL.md in the dest dir.
|
|
777
|
-
let adapted = substituteBrandTokens(readFileSync(variantPath, "utf-8"));
|
|
778
|
-
// SKILL.base.md and references/*.md are read directly from src by these
|
|
779
|
-
// inliners; wrap the results so future tokens added to those files still
|
|
780
|
-
// reach single-point-of-change. Idempotent.
|
|
781
|
-
adapted = substituteBrandTokens(renderPartialIncludes(adapted, join(src, "SKILL.base.md")));
|
|
782
|
-
// Resolve `{{> ref:<name> }}` directives — keeps the
|
|
783
|
-
// `.codex/skills/<slug>/SKILL.md` and `.gemini/skills/<slug>/SKILL.md`
|
|
784
|
-
// bodies byte-identical to the inline-into-AGENTS.md / GEMINI.md
|
|
785
|
-
// copy emitted above (modulo CLI frontmatter strip), preserving the
|
|
786
|
-
// "guaranteed availability" contract that motivated this resolver.
|
|
787
|
-
adapted = substituteBrandTokens(renderReferenceIncludes(adapted, src));
|
|
788
|
-
adapted = substituteWikiWorkspaceTokens(adapted, processKey, wikiWorkspaceName);
|
|
789
|
-
if (skillSlug === "external-services" && this.configuredServices.size > 0) {
|
|
790
|
-
adapted = stripUnconfiguredServices(adapted, this.configuredServices);
|
|
791
|
-
}
|
|
792
|
-
// Mode-conditional filter — keep this dest-dir copy byte-aligned with
|
|
793
|
-
// the inline copy emitted into AGENTS.md / GEMINI.md (modulo
|
|
794
|
-
// adaptSkillForCli's frontmatter strip). The filter is idempotent so
|
|
795
|
-
// running it on both copies independently is safe.
|
|
796
|
-
adapted = applyIntegrationModeFilter(adapted, this.integrations, backendId);
|
|
797
|
-
// §7.7 — apply tool-deny policy BEFORE adaptSkillForCli strips
|
|
798
|
-
// frontmatter so the soft-enforcement prose block lands in body
|
|
799
|
-
// content (CLI skills carry only `name` + `description` in
|
|
800
|
-
// frontmatter, no `allowed-tools` to filter).
|
|
801
|
-
adapted = applyAllDeniedToolsForSkill(adapted, skillSlug, backendId, this.integrations);
|
|
802
|
-
adapted = adaptSkillForCli(adapted);
|
|
803
|
-
writeFileSync(join(destDir, "SKILL.md"), adapted, "utf-8");
|
|
804
|
-
// P22 — splice CURATION anchors against overlay/seed JSON so the
|
|
805
|
-
// CLI-side .codex/.gemini skill copy stays byte-equivalent to the
|
|
806
|
-
// Claude-side copy after curation. No-op when no curation context.
|
|
807
|
-
this.spliceCurationAnchorsInSkill(destDir, skillSlug);
|
|
808
|
-
if (skillSlug === "mail") {
|
|
809
|
-
writeFileSync(join(destDir, "accounts.md"), this.mailAccounts.length > 0
|
|
810
|
-
? renderMailAccountsMd(this.mailAccounts)
|
|
811
|
-
: EMPTY_MAIL_ACCOUNTS_MD, "utf-8");
|
|
812
|
-
}
|
|
813
|
-
}
|
|
1029
|
+
writeFileSync(join(sessionDir, cliInstructionFileName(backendId)), instruction, "utf-8");
|
|
814
1030
|
}
|
|
815
1031
|
}
|
|
816
1032
|
export const EMPTY_MAIL_ACCOUNTS_MD = [
|
|
@@ -843,16 +1059,171 @@ export function renderMailAccountsMd(accounts) {
|
|
|
843
1059
|
].join("\n");
|
|
844
1060
|
}
|
|
845
1061
|
/**
|
|
846
|
-
*
|
|
847
|
-
*
|
|
1062
|
+
* docs/design/appendices/opencode-backend.md §10 D6 — opencode 1.14.50 documents
|
|
1063
|
+
* `[a-z0-9-]{1,64}` as the legal skill-slug pattern. Aitne's existing
|
|
1064
|
+
* built-ins all conform; this helper is the predicate the build-time
|
|
1065
|
+
* validator (`validateBuiltinSkillSourceTree`) and the user-skill PUT
|
|
1066
|
+
* endpoint both gate on.
|
|
1067
|
+
*
|
|
1068
|
+
* docs/design/appendices/skills-unification.md Phase 1 §R5 / item 6 — promoted from a
|
|
1069
|
+
* runtime warn to a build-time throw at SkillsCompiler construction so
|
|
1070
|
+
* a malformed source tree refuses to boot the daemon.
|
|
1071
|
+
*
|
|
1072
|
+
* Exported for unit testing (`skills-compiler.test.ts` regression).
|
|
1073
|
+
*/
|
|
1074
|
+
export function isValidSkillSlug(slug) {
|
|
1075
|
+
return /^[a-z0-9-]{1,64}$/.test(slug);
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* docs/design/appendices/skills-unification.md Phase 1 §R5 / item 6 — build-time invariant
|
|
1079
|
+
* pass over `agent-assets/skills/`. Throws on:
|
|
1080
|
+
* - Any built-in slug that doesn't match `[a-z0-9-]{1,64}`.
|
|
1081
|
+
* - Any SKILL.md (incl. variants like `SKILL.delegated.<backend>.md`)
|
|
1082
|
+
* whose `description` exceeds `SKILL_DESCRIPTION_MAX_LENGTH`.
|
|
1083
|
+
* - Any SKILL.md missing `name` or `description`.
|
|
1084
|
+
*
|
|
1085
|
+
* No-op when the source tree is absent (test workspaces / partial-clone
|
|
1086
|
+
* scenarios). Memoised per workspace dir + skill-tree fingerprint so
|
|
1087
|
+
* repeated SkillsCompiler constructions in the same process don't pay
|
|
1088
|
+
* the walk cost twice; tests that mutate source between constructions
|
|
1089
|
+
* get fresh validation because the fingerprint shifts.
|
|
1090
|
+
*
|
|
1091
|
+
* Exported for tests that exercise the failure paths in isolation.
|
|
1092
|
+
*/
|
|
1093
|
+
export function validateBuiltinSkillSourceTree(skillsRoot) {
|
|
1094
|
+
if (!existsSync(skillsRoot))
|
|
1095
|
+
return;
|
|
1096
|
+
const fingerprint = computeSkillTreeFingerprint(skillsRoot);
|
|
1097
|
+
const cached = validatedTreeCache.get(skillsRoot);
|
|
1098
|
+
if (cached === fingerprint)
|
|
1099
|
+
return;
|
|
1100
|
+
for (const slug of listBuiltinSlugs(skillsRoot)) {
|
|
1101
|
+
if (!isValidSkillSlug(slug)) {
|
|
1102
|
+
throw new Error(`skills_compiler.invalid_slug: ${slug} (expected [a-z0-9-]{1,64})`);
|
|
1103
|
+
}
|
|
1104
|
+
const skillDir = resolveBuiltinSkillDir(skillsRoot, slug);
|
|
1105
|
+
const skillMdPath = join(skillDir, "SKILL.md");
|
|
1106
|
+
if (!existsSync(skillMdPath))
|
|
1107
|
+
continue; // skip slugs that ship only a variant
|
|
1108
|
+
const primaryContent = readFileSync(skillMdPath, "utf-8");
|
|
1109
|
+
const primaryFm = parseSkillFrontmatter(primaryContent);
|
|
1110
|
+
// Stub primary (no frontmatter) — treat the whole skill as a test
|
|
1111
|
+
// scaffold and skip its variants too. Production builds always have
|
|
1112
|
+
// proper frontmatter; the fingerprint cache picks up any future
|
|
1113
|
+
// primary-content fix automatically.
|
|
1114
|
+
if (!primaryFm.name && !primaryFm.description)
|
|
1115
|
+
continue;
|
|
1116
|
+
if (!primaryFm.name) {
|
|
1117
|
+
throw new Error(`skills_compiler.missing_frontmatter_name: ${slug}/SKILL.md`);
|
|
1118
|
+
}
|
|
1119
|
+
if (!primaryFm.description) {
|
|
1120
|
+
throw new Error(`skills_compiler.missing_frontmatter_description: ${slug}/SKILL.md`);
|
|
1121
|
+
}
|
|
1122
|
+
if (primaryFm.description.length > SKILL_DESCRIPTION_MAX_LENGTH) {
|
|
1123
|
+
throw new Error(`skills_compiler.description_too_long: ${slug}/SKILL.md `
|
|
1124
|
+
+ `(${primaryFm.description.length} > ${SKILL_DESCRIPTION_MAX_LENGTH})`);
|
|
1125
|
+
}
|
|
1126
|
+
// Variant validation — only run when the primary is well-formed. Each
|
|
1127
|
+
// variant is shipped to the model the same way the primary is, so the
|
|
1128
|
+
// same description-length cap applies. Variants that are stub
|
|
1129
|
+
// sentinels in tests are caught by the primary-stub short-circuit
|
|
1130
|
+
// above (this loop never runs for those).
|
|
1131
|
+
const entries = readdirSync(skillDir, { withFileTypes: true });
|
|
1132
|
+
for (const entry of entries) {
|
|
1133
|
+
if (!entry.isFile())
|
|
1134
|
+
continue;
|
|
1135
|
+
const name = entry.name;
|
|
1136
|
+
if (!name.startsWith("SKILL.") || !name.endsWith(".md"))
|
|
1137
|
+
continue;
|
|
1138
|
+
if (name === "SKILL.base.md")
|
|
1139
|
+
continue; // base partial — frontmatter optional
|
|
1140
|
+
const variantContent = readFileSync(join(skillDir, name), "utf-8");
|
|
1141
|
+
const variantFm = parseSkillFrontmatter(variantContent);
|
|
1142
|
+
if (!variantFm.name || !variantFm.description) {
|
|
1143
|
+
throw new Error(`skills_compiler.variant_missing_frontmatter: ${slug}/${name}`);
|
|
1144
|
+
}
|
|
1145
|
+
if (variantFm.description.length > SKILL_DESCRIPTION_MAX_LENGTH) {
|
|
1146
|
+
throw new Error(`skills_compiler.description_too_long: ${slug}/${name} `
|
|
1147
|
+
+ `(${variantFm.description.length} > ${SKILL_DESCRIPTION_MAX_LENGTH})`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
validatedTreeCache.set(skillsRoot, fingerprint);
|
|
1152
|
+
}
|
|
1153
|
+
const validatedTreeCache = new Map();
|
|
1154
|
+
function computeSkillTreeFingerprint(skillsRoot) {
|
|
1155
|
+
// mtime-only fingerprint over SKILL*.md files: enough to bust the
|
|
1156
|
+
// cache on a source-tree edit between constructions without paying
|
|
1157
|
+
// the cost of a full content hash. Tests that mutate files within
|
|
1158
|
+
// the same millisecond should call SkillsCompiler.invalidateValidator()
|
|
1159
|
+
// — but in practice the millisecond resolution suffices.
|
|
1160
|
+
const parts = [];
|
|
1161
|
+
for (const slug of listBuiltinSlugs(skillsRoot).sort()) {
|
|
1162
|
+
const skillDir = resolveBuiltinSkillDir(skillsRoot, slug);
|
|
1163
|
+
let entries;
|
|
1164
|
+
try {
|
|
1165
|
+
entries = readdirSync(skillDir, { withFileTypes: true });
|
|
1166
|
+
}
|
|
1167
|
+
catch {
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
for (const e of entries) {
|
|
1171
|
+
if (!e.isFile())
|
|
1172
|
+
continue;
|
|
1173
|
+
const name = e.name;
|
|
1174
|
+
if (!name.startsWith("SKILL") || !name.endsWith(".md"))
|
|
1175
|
+
continue;
|
|
1176
|
+
try {
|
|
1177
|
+
const stat = statSync(join(skillDir, name));
|
|
1178
|
+
parts.push(`${slug}/${name}:${stat.mtimeMs}:${stat.size}`);
|
|
1179
|
+
}
|
|
1180
|
+
catch { /* ignore */ }
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return parts.join("|");
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Return the backend-specific dotfile namespace name for a given backend's
|
|
1187
|
+
* skill directory, **without** the trailing `skills` segment — callers
|
|
1188
|
+
* join `skills` themselves. Returns `null` only for Claude (which is
|
|
1189
|
+
* dispatched through `materializeClaudeSession` and writes
|
|
1190
|
+
* `<sessionDir>/.claude/skills/` directly).
|
|
1191
|
+
*
|
|
1192
|
+
* docs/design/appendices/skills-unification.md Phase 1 — every non-Claude backend now writes
|
|
1193
|
+
* to its own brand-aligned namespace:
|
|
1194
|
+
* - `codex` → `.codex`
|
|
1195
|
+
* - `gemini` → `.gemini`
|
|
1196
|
+
* - `opencode` → `.opencode` (V2 path (c); flipped from prior `.claude/`
|
|
1197
|
+
* redundancy-avoiding alias).
|
|
848
1198
|
*/
|
|
849
1199
|
export function cliSkillsDirName(backendId) {
|
|
850
1200
|
switch (backendId) {
|
|
851
1201
|
case "codex": return ".codex";
|
|
852
1202
|
case "gemini": return ".gemini";
|
|
1203
|
+
case "opencode": return ".opencode";
|
|
853
1204
|
default: return null;
|
|
854
1205
|
}
|
|
855
1206
|
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Return the CLI instruction-file name for a given backend. Codex and
|
|
1209
|
+
* OpenCode both auto-discover `AGENTS.md` from cwd; Gemini reads
|
|
1210
|
+
* `GEMINI.md`. Throws for `claude` — the Claude SDK consumes a per-cwd
|
|
1211
|
+
* `CLAUDE.md` written by `materializeClaudeSession`, not an instruction
|
|
1212
|
+
* file from this helper.
|
|
1213
|
+
*
|
|
1214
|
+
* Single helper so the choice is consistent between the wide
|
|
1215
|
+
* `materializeCliSession` and the slim `materializeFetchWindowCliSession`
|
|
1216
|
+
* paths (docs/design/appendices/fetch-window-cost-reduction.md §4.5.7).
|
|
1217
|
+
*/
|
|
1218
|
+
export function cliInstructionFileName(backendId) {
|
|
1219
|
+
switch (backendId) {
|
|
1220
|
+
case "codex":
|
|
1221
|
+
case "opencode":
|
|
1222
|
+
return "AGENTS.md";
|
|
1223
|
+
case "gemini":
|
|
1224
|
+
return "GEMINI.md";
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
856
1227
|
/**
|
|
857
1228
|
* Session instruction files the live-overwrite path (design §15.6.1 /
|
|
858
1229
|
* §15.9) walks when the owner PATCHes `character` mid-session. Each file
|
|
@@ -888,8 +1259,27 @@ const CHARACTER_INSTRUCTION_FILES = [
|
|
|
888
1259
|
*/
|
|
889
1260
|
export function rewriteCharacterBlock(workdir, character) {
|
|
890
1261
|
const summary = { rewritten: 0, skipped: 0, failed: 0 };
|
|
891
|
-
|
|
892
|
-
|
|
1262
|
+
const targets = CHARACTER_INSTRUCTION_FILES.map((name) => join(workdir, name));
|
|
1263
|
+
// docs/design/appendices/opencode-backend.md §6.5 — opencode also carries the character
|
|
1264
|
+
// block inside `.opencode/agent/<slug>.md` (the per-process persona
|
|
1265
|
+
// body). Walk the dir so a mid-session character PATCH lands on every
|
|
1266
|
+
// active opencode agent file (typically one per workdir). Defensive
|
|
1267
|
+
// existence check below — a non-opencode workdir simply has no
|
|
1268
|
+
// `.opencode/agent/` dir and contributes zero rewrites.
|
|
1269
|
+
const opencodeAgentDir = join(workdir, ".opencode", "agent");
|
|
1270
|
+
if (existsSync(opencodeAgentDir)) {
|
|
1271
|
+
try {
|
|
1272
|
+
for (const entry of readdirSync(opencodeAgentDir, { withFileTypes: true })) {
|
|
1273
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
1274
|
+
targets.push(join(opencodeAgentDir, entry.name));
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
catch (err) {
|
|
1279
|
+
logger.warn({ err, opencodeAgentDir }, "rewriteCharacterBlock failed to enumerate opencode agent dir");
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
for (const target of targets) {
|
|
893
1283
|
if (!existsSync(target)) {
|
|
894
1284
|
summary.skipped++;
|
|
895
1285
|
continue;
|
|
@@ -919,7 +1309,7 @@ export function rewriteCharacterBlock(workdir, character) {
|
|
|
919
1309
|
return summary;
|
|
920
1310
|
}
|
|
921
1311
|
function renderCliInstructionFile(params) {
|
|
922
|
-
const toolName = params.backendId
|
|
1312
|
+
const toolName = cliInstructionFileName(params.backendId);
|
|
923
1313
|
const parts = [
|
|
924
1314
|
`# ${APP_NAME} ${toolName}`,
|
|
925
1315
|
"",
|
|
@@ -964,22 +1354,40 @@ function renderCliInstructionFile(params) {
|
|
|
964
1354
|
// For Gemini / Claude the section is informational; the position is
|
|
965
1355
|
// kept consistent so the rendered file shape is uniform.
|
|
966
1356
|
parts.push(renderDaemonApiUsageSection(params.backendId !== "codex"), "");
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1357
|
+
// docs/design/appendices/skills-unification.md Phase 1 §R2 — preamble + `<skill-index>`
|
|
1358
|
+
// sit after Character (already emitted above) and **before** the
|
|
1359
|
+
// Runtime profile (which carries the integration routing table
|
|
1360
|
+
// substitution). Codex / Gemini only — `skillPreamble` and
|
|
1361
|
+
// `skillIndexBlock` are `null` for OpenCode (R3) so the section is
|
|
1362
|
+
// suppressed entirely and the `## Skills` slug manifest below holds.
|
|
1363
|
+
if (params.skillPreamble) {
|
|
1364
|
+
parts.push(params.skillPreamble.trim(), "");
|
|
970
1365
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1366
|
+
if (params.skillIndexBlock) {
|
|
1367
|
+
parts.push(params.skillIndexBlock, "");
|
|
1368
|
+
}
|
|
1369
|
+
parts.push("## Runtime profile", "", params.profileContent.trim(), "");
|
|
1370
|
+
// docs/design/appendices/skills-unification.md Phase 1 §R3 — the `## Skills` slug manifest
|
|
1371
|
+
// only fires for OpenCode (no `<skill-index>` block; cwd auto-discovery
|
|
1372
|
+
// already enumerates the skills, but the manifest pins the per-turn
|
|
1373
|
+
// active set so the agent doesn't grab unrelated user skills). Codex /
|
|
1374
|
+
// Gemini suppress this section since their `<skill-index>` above already
|
|
1375
|
+
// serves as the canonical listing — duplicating it here would risk the
|
|
1376
|
+
// agent mistaking the manifest for the authoritative path source.
|
|
1377
|
+
if (!params.skillIndexBlock) {
|
|
1378
|
+
parts.push("## Skills", "");
|
|
1379
|
+
if (params.skillSlugs.length === 0) {
|
|
1380
|
+
parts.push("No process-scoped built-in skills were selected for this turn.", "");
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
parts.push("Active built-in skills for this turn (cwd auto-discovery loads them):", "");
|
|
1384
|
+
for (const slug of params.skillSlugs) {
|
|
1385
|
+
parts.push(`- \`${slug}\``);
|
|
979
1386
|
}
|
|
1387
|
+
parts.push("");
|
|
980
1388
|
}
|
|
1389
|
+
parts.push("User-authored skills may also be discovered from the same directory.");
|
|
981
1390
|
}
|
|
982
|
-
parts.push("", "User-authored skills may also exist under `skills/<name>/SKILL.md`.");
|
|
983
1391
|
return parts.join("\n");
|
|
984
1392
|
}
|
|
985
1393
|
function renderDaemonApiUsageSection(readSensitiveAvailable) {
|
|
@@ -993,7 +1401,7 @@ function renderDaemonApiUsageSection(readSensitiveAvailable) {
|
|
|
993
1401
|
lines.push("- The wrapper auto-attaches session auth for read-sensitive endpoints.");
|
|
994
1402
|
}
|
|
995
1403
|
else {
|
|
996
|
-
lines.push("", "### Read-sensitive endpoints are UNAVAILABLE on this backend", "", "Codex sessions do not receive the read-sensitive daemon token. The", "wrapper still prepends headers it can supply, but the daemon answers", "personal-data reads with `401 Unauthorized` regardless. Endpoints", "below are affected; the skill
|
|
1404
|
+
lines.push("", "### Read-sensitive endpoints are UNAVAILABLE on this backend", "", "Codex sessions do not receive the read-sensitive daemon token. The", "wrapper still prepends headers it can supply, but the daemon answers", "personal-data reads with `401 Unauthorized` regardless. Endpoints", "below are affected; the per-skill `SKILL.md` files under", "`.codex/skills/<name>/` listed in `<skill-index>` describe them as if", "they were available — treat their `curl /api/*` examples as a", "contract you cannot satisfy on this backend.", "", "- Context vault: `GET /api/context/*`, `GET /api/context/list/*`", "- Mail (multi-provider): `GET /api/mail/*` (read), search, providers", "- Calendar (direct mode): `GET /api/calendar/*`", "- Notion (direct mode): `GET /api/notion/{query,search,pages}`", "- Obsidian: `GET /api/obsidian/*`", "- Observations: `GET /api/observations`", "- Reading list / receipts / travel bookings", "", "If a skill body directs you at one of these reads, stop and tell", "the user the task needs a different backend (Claude or Gemini).", "Do not hammer the endpoint — the 401 is permanent for this", "session, not transient. Writes and autonomous-tier endpoints", "stay reachable; the gate is read-sensitive scope only.");
|
|
997
1405
|
}
|
|
998
1406
|
return lines.join("\n");
|
|
999
1407
|
}
|
|
@@ -1022,53 +1430,283 @@ function stripFrontmatter(content) {
|
|
|
1022
1430
|
return content.slice(endIdx + 4).replace(/^\n+/, "");
|
|
1023
1431
|
}
|
|
1024
1432
|
/**
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1031
|
-
* in `SKILLS-PHASE-2-PLAN.md` §3.2 / §5; the Claude Agent SDK reads it
|
|
1032
|
-
* verbatim from `q.when_to_use` (verified against
|
|
1033
|
-
* `claude-agent-sdk@0.2.98/cli.js`). Preserving it on the CLI side keeps
|
|
1034
|
-
* the per-backend skill frontmatter aligned even though Codex / Gemini
|
|
1035
|
-
* do not currently consume the field — drift would surface as a missing
|
|
1036
|
-
* activation hint when they eventually do.
|
|
1037
|
-
*
|
|
1038
|
-
* Assumes `name`, `description`, and `when_to_use` are each single-line
|
|
1039
|
-
* YAML scalars (no `|` / `>` block forms). A multi-line `when_to_use:`
|
|
1040
|
-
* is matched only by its first line — the `.+` regex stops at the
|
|
1041
|
-
* newline — but since YAML block scalars start with the line that
|
|
1042
|
-
* contains only `|` or `>`, the captured value would be the empty
|
|
1043
|
-
* indicator and the inlined value would be useless. Phase 2 v1 keeps
|
|
1044
|
-
* this conservative: callers must use single-line scalars (NG5).
|
|
1433
|
+
* docs/design/appendices/skills-unification.md Phase 1 — parse the `name` and `description`
|
|
1434
|
+
* single-line YAML scalars out of a SKILL.md frontmatter block. Returns
|
|
1435
|
+
* `{ name: null, description: null }` when no frontmatter is present or
|
|
1436
|
+
* neither key is set. Multi-line block scalars (`description: |` /
|
|
1437
|
+
* `description: >`) are rejected at the regex level — the schema enforces
|
|
1438
|
+
* single-line scalars across all backends (R6).
|
|
1045
1439
|
*/
|
|
1046
|
-
export function
|
|
1440
|
+
export function parseSkillFrontmatter(content) {
|
|
1047
1441
|
if (!content.startsWith("---"))
|
|
1048
|
-
return
|
|
1442
|
+
return { name: null, description: null };
|
|
1049
1443
|
const endIdx = content.indexOf("\n---", 3);
|
|
1050
1444
|
if (endIdx < 0)
|
|
1051
|
-
return
|
|
1052
|
-
const
|
|
1053
|
-
const
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1445
|
+
return { name: null, description: null };
|
|
1446
|
+
const fm = content.slice(4, endIdx);
|
|
1447
|
+
const nameMatch = fm.match(/^name:\s*(.+)$/m);
|
|
1448
|
+
const descMatch = fm.match(/^description:\s*(.+)$/m);
|
|
1449
|
+
return {
|
|
1450
|
+
name: nameMatch ? nameMatch[1].trim() : null,
|
|
1451
|
+
description: descMatch ? descMatch[1].trim() : null,
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* docs/design/appendices/skills-unification.md Phase 1 §R5 — hard upper bound on a
|
|
1456
|
+
* SKILL.md `description` scalar. Enforced at SkillsCompiler construction
|
|
1457
|
+
* for built-in skills (refuses to boot on violation) and at
|
|
1458
|
+
* `PUT /api/skills/<slug>` for user-authored skills (HTTP 400). Sized to
|
|
1459
|
+
* fit the model's selection decision without pinning enough prose to
|
|
1460
|
+
* encode body content.
|
|
1461
|
+
*/
|
|
1462
|
+
export const SKILL_DESCRIPTION_MAX_LENGTH = 280;
|
|
1463
|
+
/**
|
|
1464
|
+
* docs/design/appendices/skills-unification.md Phase 1 §"Codex read-sensitive banner
|
|
1465
|
+
* inheritance" — endpoints flagged `RiskTier.ReadSensitive` by
|
|
1466
|
+
* `safety/risk-classifier.ts` that a Codex session cannot satisfy (no
|
|
1467
|
+
* read-sensitive token). Any SKILL.md whose body references one of these
|
|
1468
|
+
* prefixes triggers a one-line banner prepend on the Codex copy. Listed
|
|
1469
|
+
* literally (not derived from `API_RISK` at module-load time) so the
|
|
1470
|
+
* core/skills-compiler module stays independent of safety/risk-classifier
|
|
1471
|
+
* — a circular import would invert the bootstrap order.
|
|
1472
|
+
*
|
|
1473
|
+
* Drift guard: `skills-compiler.test.ts` pins this list against the
|
|
1474
|
+
* RiskTier.ReadSensitive GET-prefix set in `risk-classifier.ts` so a new
|
|
1475
|
+
* read-sensitive endpoint added to API_RISK surfaces here at test time
|
|
1476
|
+
* instead of as silent 401 retries in a future Codex session.
|
|
1477
|
+
*
|
|
1478
|
+
* Exported for the drift-guard regression test only — production code
|
|
1479
|
+
* MUST use {@link skillBodyTouchesReadSensitive} to keep the
|
|
1480
|
+
* "literal prefix" decision encapsulated.
|
|
1481
|
+
*/
|
|
1482
|
+
export const READ_SENSITIVE_API_PREFIXES = [
|
|
1483
|
+
"/api/apple-calendar",
|
|
1484
|
+
"/api/books",
|
|
1485
|
+
"/api/calendar",
|
|
1486
|
+
"/api/context",
|
|
1487
|
+
"/api/entities",
|
|
1488
|
+
"/api/mail",
|
|
1489
|
+
"/api/mcp/servers",
|
|
1490
|
+
"/api/notion",
|
|
1491
|
+
"/api/observations",
|
|
1492
|
+
"/api/obsidian",
|
|
1493
|
+
"/api/receipts",
|
|
1494
|
+
"/api/travel-bookings",
|
|
1495
|
+
];
|
|
1496
|
+
function skillBodyTouchesReadSensitive(skillBody) {
|
|
1497
|
+
return READ_SENSITIVE_API_PREFIXES.some((prefix) => skillBody.includes(prefix));
|
|
1498
|
+
}
|
|
1499
|
+
const CODEX_READ_SENSITIVE_BANNER_HEADER = "<!-- codex-read-sensitive-banner -->";
|
|
1500
|
+
const CODEX_READ_SENSITIVE_BANNER = [
|
|
1501
|
+
CODEX_READ_SENSITIVE_BANNER_HEADER,
|
|
1502
|
+
"> NOTE (Codex session): Some endpoints in this skill are read-sensitive and",
|
|
1503
|
+
"> return 401 here. See `## Read-sensitive endpoints are UNAVAILABLE` in",
|
|
1504
|
+
"> AGENTS.md before invoking. Do not retry on 401 — stop and notify the user.",
|
|
1505
|
+
"",
|
|
1506
|
+
].join("\n");
|
|
1507
|
+
/**
|
|
1508
|
+
* docs/design/appendices/skills-unification.md Phase 1 §"Codex read-sensitive banner
|
|
1509
|
+
* inheritance" — prepend the 3-line caveat banner to a Codex skill body
|
|
1510
|
+
* whose contents reference any read-sensitive `/api/*` endpoint. The
|
|
1511
|
+
* banner sits immediately after the YAML frontmatter (so the frontmatter
|
|
1512
|
+
* parser on the agent side still picks up `name`/`description`/
|
|
1513
|
+
* `allowed-tools` first) and is idempotent — re-running on an already-
|
|
1514
|
+
* banner-bearing file is a no-op (the HTML-comment sentinel lets us
|
|
1515
|
+
* detect prior insertion without false positives from user prose).
|
|
1516
|
+
*
|
|
1517
|
+
* No-op when:
|
|
1518
|
+
* - The skill body references zero read-sensitive endpoints.
|
|
1519
|
+
* - The banner is already present (sentinel hit).
|
|
1520
|
+
*/
|
|
1521
|
+
function prependCodexReadSensitiveBanner(skillMdPath) {
|
|
1522
|
+
if (!existsSync(skillMdPath))
|
|
1523
|
+
return;
|
|
1524
|
+
const content = readFileSync(skillMdPath, "utf-8");
|
|
1525
|
+
if (!skillBodyTouchesReadSensitive(content))
|
|
1526
|
+
return;
|
|
1527
|
+
if (content.includes(CODEX_READ_SENSITIVE_BANNER_HEADER))
|
|
1528
|
+
return;
|
|
1529
|
+
if (!content.startsWith("---")) {
|
|
1530
|
+
writeFileSync(skillMdPath, CODEX_READ_SENSITIVE_BANNER + content, "utf-8");
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
const fmCloseIdx = content.indexOf("\n---", 3);
|
|
1534
|
+
if (fmCloseIdx < 0) {
|
|
1535
|
+
writeFileSync(skillMdPath, CODEX_READ_SENSITIVE_BANNER + content, "utf-8");
|
|
1536
|
+
return;
|
|
1068
1537
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1538
|
+
const afterFm = fmCloseIdx + 4; // include `\n---`
|
|
1539
|
+
// Skip a single trailing newline after `---` so the banner sits on its
|
|
1540
|
+
// own line cleanly. If no newline follows, we still emit one before the
|
|
1541
|
+
// banner so the prose split is unambiguous.
|
|
1542
|
+
const head = content.slice(0, afterFm);
|
|
1543
|
+
const tail = content.slice(afterFm).replace(/^\n+/, "");
|
|
1544
|
+
writeFileSync(skillMdPath, `${head}\n\n${CODEX_READ_SENSITIVE_BANNER}${tail ? `\n${tail}` : ""}`, "utf-8");
|
|
1071
1545
|
}
|
|
1546
|
+
/**
|
|
1547
|
+
* docs/design/appendices/skills-unification.md Phase 1 §"Skill preamble" — load the static
|
|
1548
|
+
* preamble shipped at
|
|
1549
|
+
* `agent-assets/system-prompts/skill-index-instruction.md`. The preamble
|
|
1550
|
+
* is constant per backend (Codex / Gemini) and explains the on-demand
|
|
1551
|
+
* skill-load protocol. Returns a built-in minimal fallback when the asset
|
|
1552
|
+
* is missing so tests that don't seed the system-prompts dir still
|
|
1553
|
+
* produce deterministic output.
|
|
1554
|
+
*/
|
|
1555
|
+
function loadSkillIndexPreamble(workspaceDir) {
|
|
1556
|
+
const path = join(workspaceDir, "agent-assets", "system-prompts", "skill-index-instruction.md");
|
|
1557
|
+
if (existsSync(path)) {
|
|
1558
|
+
return readFileSync(path, "utf-8").trim();
|
|
1559
|
+
}
|
|
1560
|
+
return [
|
|
1561
|
+
"## Skills",
|
|
1562
|
+
"",
|
|
1563
|
+
"Skills are materialised on disk under the per-backend dotfile",
|
|
1564
|
+
"directory. When your task matches an entry in `<skill-index>` below,",
|
|
1565
|
+
"`Read` its `SKILL.md` and follow the contents.",
|
|
1566
|
+
].join("\n");
|
|
1567
|
+
}
|
|
1568
|
+
/**
|
|
1569
|
+
* docs/design/appendices/skills-unification.md Phase 1 §"`<skill-index>` block" — render
|
|
1570
|
+
* the per-slug index from the **materialised** SKILL.md frontmatter on
|
|
1571
|
+
* disk. Walking the destination dir (instead of the source manifest)
|
|
1572
|
+
* keeps the index in sync with what the agent will actually find when
|
|
1573
|
+
* it reads:
|
|
1574
|
+
*
|
|
1575
|
+
* - Same-backend native MCP slugs whose variant resolved to `null` are
|
|
1576
|
+
* correctly omitted (no SKILL.md was written).
|
|
1577
|
+
* - User-authored slugs synced AFTER `writeSkillsDir` (via
|
|
1578
|
+
* `syncAllUserSkills` from the workdir layer) appear automatically
|
|
1579
|
+
* when this is called from the post-sync refresh helper.
|
|
1580
|
+
* - Frontmatter that has gone through curation / mode filter / deny
|
|
1581
|
+
* pass / read-sensitive banner reflects the post-pipeline state.
|
|
1582
|
+
*
|
|
1583
|
+
* The block is emitted with a fixed XML-style envelope so tests can pin
|
|
1584
|
+
* its placement and the splicer in `refreshSkillIndexBlock` can locate
|
|
1585
|
+
* it for in-place rewrites between turns.
|
|
1586
|
+
*
|
|
1587
|
+
* `destSkillsRootRelative` is the on-disk path the agent should Read
|
|
1588
|
+
* (`.codex/skills` or `.gemini/skills`); it gets embedded in the header
|
|
1589
|
+
* sentence verbatim. Built-ins and user-authored slugs are not
|
|
1590
|
+
* distinguished here — see R4.
|
|
1591
|
+
*/
|
|
1592
|
+
/**
|
|
1593
|
+
* docs/design/appendices/skills-unification.md Phase 1 — splice sentinels.
|
|
1594
|
+
*
|
|
1595
|
+
* The visible `<skill-index>` / `</skill-index>` XML-style tags are the
|
|
1596
|
+
* agent-facing contract; they MUST stay in the rendered output for the
|
|
1597
|
+
* preamble's protocol to make sense. But using them as the splicer's
|
|
1598
|
+
* region markers is fragile — any profile body, skill body, or user
|
|
1599
|
+
* prose that quotes the tag verbatim would be misidentified as the
|
|
1600
|
+
* splice region and silently corrupted on `refreshSkillIndexBlock`.
|
|
1601
|
+
*
|
|
1602
|
+
* The sentinels below are unique HTML comments emitted immediately
|
|
1603
|
+
* outside the visible tags. The splicer keys on them instead, so even
|
|
1604
|
+
* a profile that quotes `<skill-index>` cannot collide with the splice
|
|
1605
|
+
* region. Comments render as low-signal tokens to the model and add
|
|
1606
|
+
* ~50 bytes per session — negligible against the ~3 KB block.
|
|
1607
|
+
*/
|
|
1608
|
+
const SKILL_INDEX_START_SENTINEL = "<!-- skill-index:start -->";
|
|
1609
|
+
const SKILL_INDEX_END_SENTINEL = "<!-- skill-index:end -->";
|
|
1610
|
+
export function renderSkillIndexBlock(destSkillsRootAbs, destSkillsRootRelative) {
|
|
1611
|
+
const lines = [
|
|
1612
|
+
SKILL_INDEX_START_SENTINEL,
|
|
1613
|
+
"<skill-index>",
|
|
1614
|
+
`The following skills are materialized at \`${destSkillsRootRelative}/<name>/SKILL.md\`.`,
|
|
1615
|
+
"When your task matches a skill's `description`, `Read` the `SKILL.md`",
|
|
1616
|
+
"to load its guidance and follow it. Skill bodies are NOT inlined in",
|
|
1617
|
+
"this prompt — read them on demand. Multiple skills may be loaded in",
|
|
1618
|
+
"one turn.",
|
|
1619
|
+
"",
|
|
1620
|
+
];
|
|
1621
|
+
let entryCount = 0;
|
|
1622
|
+
if (existsSync(destSkillsRootAbs)) {
|
|
1623
|
+
const slugs = readdirSync(destSkillsRootAbs, { withFileTypes: true })
|
|
1624
|
+
.filter((e) => e.isDirectory())
|
|
1625
|
+
.map((e) => e.name)
|
|
1626
|
+
.sort((a, b) => a.localeCompare(b));
|
|
1627
|
+
for (const slug of slugs) {
|
|
1628
|
+
const skillMdPath = join(destSkillsRootAbs, slug, "SKILL.md");
|
|
1629
|
+
if (!existsSync(skillMdPath))
|
|
1630
|
+
continue;
|
|
1631
|
+
const fm = parseSkillFrontmatter(readFileSync(skillMdPath, "utf-8"));
|
|
1632
|
+
if (!fm.name || !fm.description)
|
|
1633
|
+
continue;
|
|
1634
|
+
lines.push(`- name: ${fm.name}`);
|
|
1635
|
+
lines.push(` description: ${fm.description}`);
|
|
1636
|
+
entryCount++;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
if (entryCount === 0) {
|
|
1640
|
+
lines.push("(No skills materialized this turn — proceed with the runtime profile only.)");
|
|
1641
|
+
}
|
|
1642
|
+
lines.push("</skill-index>", SKILL_INDEX_END_SENTINEL);
|
|
1643
|
+
return lines.join("\n");
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* docs/design/appendices/skills-unification.md Phase 1 — re-render the `<skill-index>` block
|
|
1647
|
+
* inside an existing instruction file. Called by the workdir layer AFTER
|
|
1648
|
+
* `syncAllUserSkills` so user-authored slugs land in the index alongside
|
|
1649
|
+
* the built-ins (`renderSkillIndexBlock` reads the dest dir on disk, so a
|
|
1650
|
+
* post-sync re-render naturally picks them up).
|
|
1651
|
+
*
|
|
1652
|
+
* No-op when:
|
|
1653
|
+
* - The backend is Claude (no instruction file with `<skill-index>`).
|
|
1654
|
+
* - The instruction file is missing (the session has not been
|
|
1655
|
+
* materialised yet).
|
|
1656
|
+
* - The instruction file carries no `<skill-index>` block (slim
|
|
1657
|
+
* fetch_window sessions, or future backends that opt out).
|
|
1658
|
+
*
|
|
1659
|
+
* Idempotent — re-running with the same dest contents produces an
|
|
1660
|
+
* identical instruction file.
|
|
1661
|
+
*/
|
|
1662
|
+
export function refreshSkillIndexBlock(sessionDir, backendId) {
|
|
1663
|
+
// docs/design/appendices/skills-unification.md Phase 1 §R3 — OpenCode never gets a
|
|
1664
|
+
// `<skill-index>` block. The cwd auto-discovery loader is the source
|
|
1665
|
+
// of truth; emitting an index would inject a second listing the
|
|
1666
|
+
// runtime ignores. Also matters in fallback workdirs where codex and
|
|
1667
|
+
// opencode share AGENTS.md: a stray opencode refresh would clobber
|
|
1668
|
+
// the codex-rendered sentinels with opencode's skill listing.
|
|
1669
|
+
if (backendId === "claude" || backendId === "opencode")
|
|
1670
|
+
return;
|
|
1671
|
+
const cliRoot = cliSkillsDirName(backendId);
|
|
1672
|
+
if (cliRoot === null)
|
|
1673
|
+
return;
|
|
1674
|
+
const destSkillsRootRelative = join(cliRoot, "skills");
|
|
1675
|
+
const destSkillsRootAbs = join(sessionDir, destSkillsRootRelative);
|
|
1676
|
+
const fileName = backendId === "gemini" ? "GEMINI.md" : "AGENTS.md";
|
|
1677
|
+
const instructionPath = join(sessionDir, fileName);
|
|
1678
|
+
if (!existsSync(instructionPath))
|
|
1679
|
+
return;
|
|
1680
|
+
const current = readFileSync(instructionPath, "utf-8");
|
|
1681
|
+
// Splice on the HTML-comment sentinels, NOT on the visible
|
|
1682
|
+
// `<skill-index>` tags — the sentinels are unique enough that a
|
|
1683
|
+
// profile body or user-authored skill that quotes the visible tag
|
|
1684
|
+
// cannot collide with the splice region.
|
|
1685
|
+
const startIdx = current.indexOf(SKILL_INDEX_START_SENTINEL);
|
|
1686
|
+
const endIdx = startIdx >= 0
|
|
1687
|
+
? current.indexOf(SKILL_INDEX_END_SENTINEL, startIdx + SKILL_INDEX_START_SENTINEL.length)
|
|
1688
|
+
: -1;
|
|
1689
|
+
if (startIdx < 0 || endIdx < 0)
|
|
1690
|
+
return; // OpenCode (no index) or slim path
|
|
1691
|
+
const replacement = renderSkillIndexBlock(destSkillsRootAbs, destSkillsRootRelative);
|
|
1692
|
+
const next = current.slice(0, startIdx) +
|
|
1693
|
+
replacement +
|
|
1694
|
+
current.slice(endIdx + SKILL_INDEX_END_SENTINEL.length);
|
|
1695
|
+
if (next !== current) {
|
|
1696
|
+
writeFileSync(instructionPath, next, "utf-8");
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* docs/design/appendices/skills-unification.md Phase 1 §R6 — `adaptSkillForCli` (which used
|
|
1701
|
+
* to retain only `name`/`description`/`when_to_use` and strip
|
|
1702
|
+
* `allowed-tools` from CLI-bound copies) is deleted. The source
|
|
1703
|
+
* SKILL.md frontmatter is byte-identical across all backends post-
|
|
1704
|
+
* materialisation. Codex / Gemini tolerate unknown YAML keys; OpenCode's
|
|
1705
|
+
* permissive frontmatter parser does too (verified against
|
|
1706
|
+
* `docs/design/appendices/opencode-backend.md` §5.5). The `when_to_use:` field has been
|
|
1707
|
+
* dropped from every built-in SKILL.md (Phase 0.1 of the sister doc) so
|
|
1708
|
+
* there is no per-backend fork to maintain.
|
|
1709
|
+
*/
|
|
1072
1710
|
/**
|
|
1073
1711
|
* Resolve `{{> base }}` include directives in a skill/task-flow variant file.
|
|
1074
1712
|
* Reads `SKILL.base.md` (or `<key>.base.md` for task flows) from `basePath`
|
|
@@ -1313,10 +1951,11 @@ function appendCliDenyBlock(content, namespacedDenied) {
|
|
|
1313
1951
|
* own deny list.
|
|
1314
1952
|
*
|
|
1315
1953
|
* Hard enforcement of the same deny list for cross-backend delegated
|
|
1316
|
-
* calls lives at the `POST /api/integrations/:key/
|
|
1317
|
-
* (DELEGATED-MODE-V2-DESIGN.md §4.3.2
|
|
1318
|
-
*
|
|
1319
|
-
*
|
|
1954
|
+
* calls lives at the `POST /api/integrations/:key/exec` task-mode
|
|
1955
|
+
* chokepoint (DELEGATED-MODE-V2-DESIGN.md §4.3.2; the legacy `/invoke`
|
|
1956
|
+
* RPC was retired 2026-05-01). For same-backend native MCP it is
|
|
1957
|
+
* enforced via SDK `disallowedTools` (Claude) / admin policy (Gemini);
|
|
1958
|
+
* see `collectSessionDeniedTools` (§4.3.3).
|
|
1320
1959
|
*/
|
|
1321
1960
|
export function applyAllDeniedToolsForSkill(content, skillSlug, backendId, integrations) {
|
|
1322
1961
|
let result = content;
|