@xopcai/xopc 0.0.22 → 0.0.24

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.
Files changed (128) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/agents-CiZMJZRp.js +216 -0
  3. package/dist/gateway/static/root/assets/agents-CiZMJZRp.js.map +1 -0
  4. package/dist/gateway/static/root/assets/apps-page-tZz69XM3.js +2 -0
  5. package/dist/gateway/static/root/assets/apps-page-tZz69XM3.js.map +1 -0
  6. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CebH7fCz.js → attachment-preview-renderer-CxMJMbD2.js} +4 -4
  7. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CebH7fCz.js.map → attachment-preview-renderer-CxMJMbD2.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{attachment-process-heavy-Dbf1--O6.js → attachment-process-heavy-EFXPGfWk.js} +6 -6
  9. package/dist/gateway/static/root/assets/{attachment-process-heavy-Dbf1--O6.js.map → attachment-process-heavy-EFXPGfWk.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{attachment-utils-core-Dt6UxMPV.js → attachment-utils-core-ECbeoa9H.js} +1 -1
  11. package/dist/gateway/static/root/assets/attachment-utils-core-ECbeoa9H.js.map +1 -0
  12. package/dist/gateway/static/root/assets/channels-settings-BAvk9-aK.js +9 -0
  13. package/dist/gateway/static/root/assets/{channels-settings-BGueHxMv.js.map → channels-settings-BAvk9-aK.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/cn-BMCV0OMB.js +2 -0
  15. package/dist/gateway/static/root/assets/cn-BMCV0OMB.js.map +1 -0
  16. package/dist/gateway/static/root/assets/cron-page-CANqvhK7.js +2 -0
  17. package/dist/gateway/static/root/assets/{cron-page-DsVZzPqv.js.map → cron-page-CANqvhK7.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/cron-utils-DyOO6TdN.js +3 -0
  19. package/dist/gateway/static/root/assets/{cron-utils-zbRs2yND.js.map → cron-utils-DyOO6TdN.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/dist-Brod9LF3.js +2 -0
  21. package/dist/gateway/static/root/assets/{dist-CDA7gR_M.js.map → dist-Brod9LF3.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{docx-preview-DxcHM3sR.js → docx-preview-F-jKDMNv.js} +2 -2
  23. package/dist/gateway/static/root/assets/{docx-preview-DxcHM3sR.js.map → docx-preview-F-jKDMNv.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{excel-worksheet-utils-Dk66snKA.js → excel-worksheet-utils-DPfAinZn.js} +1 -1
  25. package/dist/gateway/static/root/assets/{excel-worksheet-utils-Dk66snKA.js.map → excel-worksheet-utils-DPfAinZn.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/extension-debug-page-CDD7ozsC.js +2 -0
  27. package/dist/gateway/static/root/assets/{extension-debug-page-CDLp4DAs.js.map → extension-debug-page-CDD7ozsC.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/extension-page-UUFMjoWf.js +2 -0
  29. package/dist/gateway/static/root/assets/{extension-page-DwSCjzHO.js.map → extension-page-UUFMjoWf.js.map} +1 -1
  30. package/dist/gateway/static/root/assets/extension-settings-page-CP9JNc4m.js +2 -0
  31. package/dist/gateway/static/root/assets/extension-settings-page-CP9JNc4m.js.map +1 -0
  32. package/dist/gateway/static/root/assets/index-BZvlG48D.js +150 -0
  33. package/dist/gateway/static/root/assets/index-BZvlG48D.js.map +1 -0
  34. package/dist/gateway/static/root/assets/index-DxkgyT8R.css +1 -0
  35. package/dist/gateway/static/root/assets/{jszip.min-DVUfmhpE.js → jszip.min-CL3dfyxs.js} +1 -1
  36. package/dist/gateway/static/root/assets/{jszip.min-DVUfmhpE.js.map → jszip.min-CL3dfyxs.js.map} +1 -1
  37. package/dist/gateway/static/root/assets/logs-page-Cr0eCGb4.js +2 -0
  38. package/dist/gateway/static/root/assets/{logs-page-ChJ0nsPh.js.map → logs-page-Cr0eCGb4.js.map} +1 -1
  39. package/dist/gateway/static/root/assets/{pdf--jE7rvON.js → pdf-CX6ji-QC.js} +1 -1
  40. package/dist/gateway/static/root/assets/{pdf--jE7rvON.js.map → pdf-CX6ji-QC.js.map} +1 -1
  41. package/dist/gateway/static/root/assets/sessions-page-DwLHN5GJ.js +2 -0
  42. package/dist/gateway/static/root/assets/{sessions-page-Cle4fPla.js.map → sessions-page-DwLHN5GJ.js.map} +1 -1
  43. package/dist/gateway/static/root/assets/settings-page-B3O3R0E4.js +2 -0
  44. package/dist/gateway/static/root/assets/settings-page-B3O3R0E4.js.map +1 -0
  45. package/dist/gateway/static/root/assets/skills-page-DgBYvH6B.js +3 -0
  46. package/dist/gateway/static/root/assets/{skills-page-B-smhcB2.js.map → skills-page-DgBYvH6B.js.map} +1 -1
  47. package/dist/gateway/static/root/assets/vendor-swr-B5fPo7KK.js +2 -0
  48. package/dist/gateway/static/root/assets/{vendor-swr-Dp4nzp5h.js.map → vendor-swr-B5fPo7KK.js.map} +1 -1
  49. package/dist/gateway/static/root/assets/{xlsx-DVk38js7.js → xlsx-CPtvfmVF.js} +1 -1
  50. package/dist/gateway/static/root/assets/{xlsx-DVk38js7.js.map → xlsx-CPtvfmVF.js.map} +1 -1
  51. package/dist/gateway/static/root/index.html +5 -4
  52. package/dist/package.js +1 -1
  53. package/dist/src/agent/image/tool-model-config.js +2 -2
  54. package/dist/src/agent/image/tool-model-config.js.map +1 -1
  55. package/dist/src/agent/tools/execute-code-tool.js +1 -1
  56. package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
  57. package/dist/src/cli/commands/extension-dev.d.ts +2 -0
  58. package/dist/src/cli/commands/extension-dev.js +196 -0
  59. package/dist/src/cli/commands/extension-dev.js.map +1 -0
  60. package/dist/src/cli/commands/extension-marketplace.d.ts +4 -0
  61. package/dist/src/cli/commands/extension-marketplace.js +145 -0
  62. package/dist/src/cli/commands/extension-marketplace.js.map +1 -0
  63. package/dist/src/cli/commands/extension-pack.d.ts +2 -0
  64. package/dist/src/cli/commands/extension-pack.js +242 -0
  65. package/dist/src/cli/commands/extension-pack.js.map +1 -0
  66. package/dist/src/cli/commands/extension.js +13 -0
  67. package/dist/src/cli/commands/extension.js.map +1 -1
  68. package/dist/src/cli/index.js +5 -1
  69. package/dist/src/cli/index.js.map +1 -1
  70. package/dist/src/config/schema.js +1 -1
  71. package/dist/src/config/schema.js.map +1 -1
  72. package/dist/src/extensions/api.d.ts +6 -1
  73. package/dist/src/extensions/api.js +30 -0
  74. package/dist/src/extensions/api.js.map +1 -1
  75. package/dist/src/extensions/engine-check.d.ts +14 -0
  76. package/dist/src/extensions/engine-check.js +148 -0
  77. package/dist/src/extensions/engine-check.js.map +1 -0
  78. package/dist/src/extensions/loader.js +23 -0
  79. package/dist/src/extensions/loader.js.map +1 -1
  80. package/dist/src/extensions/marketplace.d.ts +24 -0
  81. package/dist/src/extensions/marketplace.js +98 -0
  82. package/dist/src/extensions/marketplace.js.map +1 -0
  83. package/dist/src/extensions/normalize-manifest.js +16 -4
  84. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  85. package/dist/src/extensions/sdk/index.d.ts +2 -0
  86. package/dist/src/extensions/sdk/index.js +2 -1
  87. package/dist/src/extensions/sdk/index.js.map +1 -1
  88. package/dist/src/extensions/sdk/testing.d.ts +49 -3
  89. package/dist/src/extensions/sdk/testing.js +174 -5
  90. package/dist/src/extensions/sdk/testing.js.map +1 -1
  91. package/dist/src/extensions/types/core.d.ts +5 -0
  92. package/dist/src/extensions/types/manifest.d.ts +17 -0
  93. package/dist/src/extensions/when-context.d.ts +6 -0
  94. package/dist/src/extensions/when-context.js +28 -0
  95. package/dist/src/extensions/when-context.js.map +1 -0
  96. package/dist/src/extensions/when-expression.d.ts +11 -0
  97. package/dist/src/extensions/when-expression.js +215 -0
  98. package/dist/src/extensions/when-expression.js.map +1 -0
  99. package/dist/src/gateway/hono/app.js +1 -1
  100. package/dist/src/gateway/hono/app.js.map +1 -1
  101. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +28 -0
  102. package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
  103. package/dist/src/providers/index.d.ts +6 -3
  104. package/dist/src/providers/index.js +12 -23
  105. package/dist/src/providers/index.js.map +1 -1
  106. package/package.json +2 -1
  107. package/dist/gateway/static/root/assets/agents-BcLv59-r.js +0 -71
  108. package/dist/gateway/static/root/assets/agents-BcLv59-r.js.map +0 -1
  109. package/dist/gateway/static/root/assets/apps-page-Bl-yxbQo.js +0 -2
  110. package/dist/gateway/static/root/assets/apps-page-Bl-yxbQo.js.map +0 -1
  111. package/dist/gateway/static/root/assets/attachment-utils-core-Dt6UxMPV.js.map +0 -1
  112. package/dist/gateway/static/root/assets/channels-settings-BGueHxMv.js +0 -9
  113. package/dist/gateway/static/root/assets/cron-page-DsVZzPqv.js +0 -2
  114. package/dist/gateway/static/root/assets/cron-utils-zbRs2yND.js +0 -3
  115. package/dist/gateway/static/root/assets/dist-CDA7gR_M.js +0 -2
  116. package/dist/gateway/static/root/assets/extension-debug-page-CDLp4DAs.js +0 -2
  117. package/dist/gateway/static/root/assets/extension-page-DwSCjzHO.js +0 -2
  118. package/dist/gateway/static/root/assets/extension-settings-page-Rdmxe24_.js +0 -2
  119. package/dist/gateway/static/root/assets/extension-settings-page-Rdmxe24_.js.map +0 -1
  120. package/dist/gateway/static/root/assets/index-D9Wmfh2f.css +0 -1
  121. package/dist/gateway/static/root/assets/index-DG8WvMbu.js +0 -150
  122. package/dist/gateway/static/root/assets/index-DG8WvMbu.js.map +0 -1
  123. package/dist/gateway/static/root/assets/logs-page-ChJ0nsPh.js +0 -2
  124. package/dist/gateway/static/root/assets/sessions-page-Cle4fPla.js +0 -2
  125. package/dist/gateway/static/root/assets/settings-page-Dyo2NYdy.js +0 -2
  126. package/dist/gateway/static/root/assets/settings-page-Dyo2NYdy.js.map +0 -1
  127. package/dist/gateway/static/root/assets/skills-page-B-smhcB2.js +0 -3
  128. package/dist/gateway/static/root/assets/vendor-swr-Dp4nzp5h.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../src/config/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { getDefaultWorkspacePath } from '../agent/agent-scope.js';\n\n// ============================================\n// Agent Configs\n// ============================================\n\nexport const AgentModelRefSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n })\n .strict(),\n]);\n\nexport type AgentModelConfig = z.infer<typeof AgentModelRefSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n /** Parent directory: each agent’s Markdown root is `<expanded>/<agentId>/` (e.g. `.../workspace/main`). */\n workspace: z.string().default('~/.xopc/workspace'),\n model: z.union([\n z.string(),\n z.object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n }).strict(),\n ]).default(''), // Empty default - will be resolved dynamically at runtime\n /** Vision / image understanding model (provider/model). Falls back to heuristics when unset. */\n imageModel: AgentModelRefSchema.optional(),\n /** Image generation model (provider/model), e.g. openai/gpt-image-1. Thin REST wrapper; OpenAI supported. */\n imageGenerationModel: AgentModelRefSchema.optional(),\n /** Max image size for image tool loads (MB). */\n mediaMaxMb: z.number().positive().optional(),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n // Wall-clock limit for one user turn (LLM + tools). Default 30m if unset; cap 4h.\n maxTaskDurationMs: z.number().min(60000).max(14_400_000).optional(),\n // Reliability settings\n maxRequestsPerTurn: z.number().min(10).max(200).default(50),\n maxToolFailuresPerTurn: z.number().min(1).max(20).default(3),\n // Thinking ability settings\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n compaction: z.object({\n enabled: z.boolean().default(true),\n mode: z.enum(['default', 'safeguard']).default('default'),\n reserveTokens: z.number().default(8000),\n triggerThreshold: z.number().min(0.5).max(0.95).default(0.8),\n minMessagesBeforeCompact: z.number().default(10),\n keepRecentMessages: z.number().default(5),\n // Dual-strategy compaction\n evictionWindow: z.number().min(0.1).max(0.5).default(0.2),\n retentionWindow: z.number().min(3).max(20).default(6),\n }).optional(),\n pruning: z.object({\n enabled: z.boolean().default(true),\n maxToolResultChars: z.number().default(10000),\n headKeepRatio: z.number().default(0.3),\n tailKeepRatio: z.number().default(0.3),\n }).optional(),\n /**\n * Curated memory (`agents/<id>/memories/`) + pluggable external provider.\n * Only one external provider at a time.\n */\n memory: z\n .object({\n /** Master switch: curated snapshot, `curated_memory`, prefetch, and external provider. Default true. */\n enabled: z.boolean().optional(),\n /** When false, use workspace bootstrap only (no curated snapshot / tool). Default true. */\n useEnhancedSystem: z.boolean().optional(),\n /** Include USER.md in snapshot. Default true. */\n userProfileEnabled: z.boolean().optional(),\n memoryCharLimit: z.number().positive().optional(),\n userCharLimit: z.number().positive().optional(),\n provider: z.enum(['none', 'stub']).optional(),\n /** How often prefetched external memory is injected into the user message. */\n injectionFrequency: z.enum(['every-turn', 'first-turn']).optional(),\n /** Inject prefetch on turns 1, 1+N, 1+2N, … (only when injectionFrequency is every-turn). Min 1. */\n contextCadence: z.number().int().min(1).optional(),\n /** Reserved for future external “dialectic” sync cadence (not wired yet). */\n dialecticCadence: z.number().int().min(1).optional(),\n })\n .optional(),\n /** Cross-session transcript search (`session_search` tool). */\n sessionSearch: z\n .object({\n /** Model ref for per-session summaries (e.g. openai/gpt-4o-mini). */\n summaryModel: z.string().optional(),\n })\n .optional(),\n /**\n * Post-turn background review (Hermes-style): optional quiet follow-up that may call\n * `curated_memory` / `skill_manage` so durable facts and reusable workflows persist\n * without bloating the main user-visible turn.\n */\n backgroundReview: z\n .object({\n /** When true, nudges may run after successful turns. Default false (opt-in). */\n enabled: z.boolean().optional(),\n /** User-turn cadence for memory review. 0 disables the memory channel. Default 10. */\n memoryNudgeInterval: z.number().int().min(0).optional(),\n /** LLM rounds without `skill_manage` before a skill review. 0 disables the skill channel. Default 10. */\n skillNudgeInterval: z.number().int().min(0).optional(),\n /** Max tool executions for the review agent. Default 8. */\n maxToolRounds: z.number().int().min(1).max(32).optional(),\n /** Max prior messages passed into the review context (tail). Default 80. */\n maxHistoryMessages: z.number().int().min(10).max(200).optional(),\n /** Wall-clock cap for the review run (ms). Default 120000. */\n maxDurationMs: z.number().int().min(30_000).max(600_000).optional(),\n })\n .optional(),\n /** LLM pass for `web_extract` (markdown-focused extraction). */\n webExtract: z\n .object({\n model: z.string().optional(),\n maxLength: z.number().positive().optional(),\n })\n .optional(),\n /**\n * Headless Playwright tools (`browser_*`). Opt-in. Install browsers once: `npx playwright install chromium`.\n */\n browser: z\n .object({\n enabled: z.boolean().optional(),\n /** Default true when browser tools are enabled. */\n headless: z.boolean().optional(),\n })\n .optional(),\n /** Sub-agent delegation (`delegate_task`). Opt-in. */\n delegate: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Sandboxed `execute_code` (programmatic tool calls). Opt-in. */\n executeCode: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Optional full system prompt replacement (merged with per-agent entry; entry wins). */\n systemPromptOverride: z.string().optional(),\n /** Optional allowlist of skill names for `<available_skills>`; when set, replaces unfiltered list. */\n skills: z.array(z.string()).optional(),\n /** Disable built-in tools by name (e.g. `shell`, `web_search`). */\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n /** Opaque per-process params (reserved for extensions / future use). */\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentConfigSchema = z.object({\n id: z.string(),\n /** When true, this entry is the default routing agent. */\n default: z.boolean().optional(),\n name: z.string().optional(),\n /** Short human-readable summary for UIs (gateway console, pickers). */\n description: z.string().max(4000).optional(),\n enabled: z.boolean().default(true),\n /** Per-agent workspace root (`~` expanded at runtime). */\n workspace: z.string().optional(),\n /**\n * Internal agent state directory (`…/credentials`, `agent.json`, pid, inbox).\n * Default: `<stateDir>/agents/<id>/agent`.\n */\n agentDir: z.string().optional(),\n model: AgentModelRefSchema.optional(),\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n systemPromptOverride: z.string().optional(),\n skills: z.array(z.string()).optional(),\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentsConfigSchema = z.object({\n /** Default agent id when not specified (routing / session creation). */\n default: z.string().optional(),\n defaults: AgentDefaultsSchema.optional(),\n list: z.array(AgentConfigSchema).optional(),\n}).default({\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n} as any);\n\n// ============================================\n// Channel Configs (per-channel Zod lives in bundled extensions; root schema is open)\n// ============================================\n\nexport {\n TelegramTopicConfigSchema,\n TelegramGroupConfigSchema,\n TelegramAccountConfigSchema,\n TelegramConfigSchema,\n} from '../../extensions/telegram/src/config-schema.js';\nexport type { TelegramConfig } from '../../extensions/telegram/src/config-schema.js';\nexport { WeixinAccountConfigSchema, WeixinConfigSchema } from '../../extensions/weixin/src/config-schema.js';\nexport type { WeixinConfig } from '../../extensions/weixin/src/config-schema.js';\n\n// ============================================\n// Session Routing Configuration\n// ============================================\n\nexport const BindingMatchSchema = z.object({\n channel: z.string(),\n accountId: z.string().optional(),\n peerKind: z.string().optional(),\n peerId: z.string().optional(),\n guildId: z.string().optional(),\n teamId: z.string().optional(),\n memberRoleIds: z.array(z.string()).optional(),\n});\n\nexport const BindingRuleSchema = z.object({\n id: z.string().optional(),\n agentId: z.string(),\n priority: z.number().default(100),\n match: BindingMatchSchema,\n enabled: z.boolean().default(true),\n});\n\nexport const BindingsConfigSchema = z.array(BindingRuleSchema).default([]);\n\nexport const SessionDmScopeSchema = z.enum([\n 'main',\n 'per-peer',\n 'per-channel-peer',\n 'per-account-channel-peer',\n]);\n\nexport const SessionStorageConfigSchema = z.object({\n pruneAfterMs: z.number().optional(),\n maxEntries: z.number().optional(),\n});\n\nexport const SessionConfigSchema = z.object({\n dmScope: SessionDmScopeSchema.default('main'),\n identityLinks: z.record(z.string(), z.array(z.string())).optional(),\n storage: SessionStorageConfigSchema.optional(),\n}).default({\n dmScope: 'main',\n});\n\n/** Channel buckets — shapes validated post-parse by registered channel plugins. */\nexport const ChannelsConfigSchema = z.record(z.string(), z.unknown()).default({\n telegram: {\n enabled: false,\n botToken: '',\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n});\n\nexport const SearchProviderEntrySchema = z.object({\n type: z.enum(['brave', 'tavily', 'bing', 'searxng']),\n apiKey: z.string().optional(),\n /** SearXNG instance base URL (e.g. http://localhost:8080) */\n url: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type SearchProviderEntry = z.infer<typeof SearchProviderEntrySchema>;\n\nexport const WebSearchConfigSchema = z.object({\n maxResults: z.number().default(5),\n /** Ordered API providers; empty → HTML fallback only */\n providers: z.array(SearchProviderEntrySchema).default([]),\n});\n\nexport type WebSearchConfig = z.infer<typeof WebSearchConfigSchema>;\n\nexport const WebToolsConfigSchema = z.object({\n /** Search result HTML fallback: cn → Bing, otherwise DuckDuckGo */\n region: z.enum(['cn', 'global']).optional(),\n search: WebSearchConfigSchema.optional(),\n});\n\nexport type WebToolsConfig = z.infer<typeof WebToolsConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.optional(),\n}).default({\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n});\n\n// ============================================\n// Gateway Configuration\n// ============================================\n\nexport const GatewayAuthRateLimitSchema = z\n .object({\n enabled: z.boolean().default(true),\n maxAttempts: z.number().int().min(1).default(5),\n windowMs: z.number().default(900_000),\n blockDurationMs: z.number().default(300_000),\n })\n .optional();\n\nexport const GatewayAuthSchema = z\n .object({\n mode: z.enum(['none', 'token']).default('token'),\n token: z.string().optional(),\n rateLimit: GatewayAuthRateLimitSchema,\n })\n .default({\n mode: 'token',\n });\n\nexport const HeartbeatConfigSchema = z\n .object({\n enabled: z.boolean(),\n intervalMs: z.number(),\n /** When false, heartbeat instructions are only sent during heartbeat polling turns (not in every chat system prompt). */\n includeSystemPromptSection: z.boolean().optional().default(false),\n target: z.string().optional(),\n targetChatId: z.string().optional(),\n prompt: z.string().optional(),\n ackMaxChars: z.number().optional(),\n isolatedSession: z.boolean().optional(),\n activeHours: z\n .object({\n start: z.string(),\n end: z.string(),\n timezone: z.string().optional(),\n })\n .optional(),\n })\n .default({\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n });\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().optional(),\n port: z.number().optional(),\n auth: GatewayAuthSchema.optional(),\n heartbeat: HeartbeatConfigSchema.optional(),\n maxSseConnections: z.number().optional(),\n corsOrigins: z.array(z.string()).optional(),\n /** Base URL for the xopc skills marketplace (public REST API). */\n skillsStoreBaseUrl: z.string().url().optional(),\n}).default({\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n});\n\nexport const CronConfigSchema = z.object({\n enabled: z.boolean().optional(),\n maxConcurrentJobs: z.number().optional(),\n defaultTimezone: z.string().optional(),\n historyRetentionDays: z.number().optional(),\n enableMetrics: z.boolean().optional(),\n}).default({\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n});\n\nexport const ModelsDevConfigSchema = z.object({\n enabled: z.boolean().default(true),\n}).default({\n enabled: true,\n});\n\n// ============================================\n// STT (Speech-to-Text) Config\n// ============================================\n\nexport const STTProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n});\n\nexport const STTFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z.array(z.enum(['alibaba', 'openai'])).default(['alibaba', 'openai']),\n});\n\nexport const STTConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['alibaba', 'openai']).default('alibaba'),\n alibaba: STTProviderConfigSchema.optional(),\n openai: STTProviderConfigSchema.optional(),\n fallback: STTFallbackConfigSchema.optional(),\n});\n\n// ============================================\n// TTS (Text-to-Speech) Config\n// ============================================\n\nexport const TTSProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n voice: z.string().optional(),\n});\n\nexport const TTSFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z\n .array(z.enum(['openai', 'alibaba', 'edge', 'minimax']))\n .default(['openai', 'alibaba', 'minimax', 'edge']),\n});\n\nexport const TTSModelOverridesConfigSchema = z.object({\n enabled: z.boolean().default(true),\n allowText: z.boolean().default(true),\n allowProvider: z.boolean().default(false),\n allowVoice: z.boolean().default(true),\n allowModelId: z.boolean().default(true),\n allowVoiceSettings: z.boolean().default(false),\n allowNormalization: z.boolean().default(false),\n allowSeed: z.boolean().default(false),\n});\n\nexport const TTSEdgeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n voice: z.string().optional(),\n lang: z.string().optional(),\n outputFormat: z.string().optional(),\n pitch: z.string().optional(),\n rate: z.string().optional(),\n volume: z.string().optional(),\n proxy: z.string().optional(),\n timeoutMs: z.number().int().min(1000).max(120000).optional(),\n});\n\nexport const TTSSummarizationConfigSchema = z.object({\n enabled: z.boolean().optional(),\n targetLength: z.number().int().min(1).optional(),\n threshold: z.number().int().min(1).optional(),\n model: z.string().optional(),\n});\n\nexport const TTSConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['openai', 'alibaba', 'edge', 'minimax']).default('openai'),\n trigger: z\n .preprocess(\n (v) => (v === 'auto' ? 'inbound' : v),\n z.enum(['off', 'always', 'inbound', 'tagged']).default('always'),\n ),\n fallback: TTSFallbackConfigSchema.optional(),\n maxTextLength: z.number().int().min(1).default(512), // Conservative default to accommodate all providers (Alibaba limit is 512)\n timeoutMs: z.number().int().min(1000).max(180000).default(30000),\n summarization: TTSSummarizationConfigSchema.optional(),\n modelOverrides: TTSModelOverridesConfigSchema.optional(),\n alibaba: TTSProviderConfigSchema.optional(),\n openai: TTSProviderConfigSchema.optional(),\n edge: TTSEdgeConfigSchema.optional(),\n minimax: TTSProviderConfigSchema.optional(),\n});\n\n// ============================================\n// Extension Configs \n// ============================================\n\n// Security config for extensions \nexport const ExtensionSecurityConfigSchema = z.object({\n checkPermissions: z.boolean().default(true),\n allowUntrusted: z.boolean().default(false),\n allow: z.array(z.string()).default([]),\n trackProvenance: z.boolean().default(true),\n allowPromptInjection: z.boolean().default(false),\n});\n\n// Slot config for extensions \nexport const ExtensionSlotsConfigSchema = z.object({\n memory: z.string().optional(),\n tts: z.string().optional(),\n imageGeneration: z.string().optional(),\n webSearch: z.string().optional(),\n});\n\n// Complete extensions config\n// Extension config allows both known fields AND arbitrary extension-specific config\n// Known fields: enabled (array), allow (array), security (object), slots (object)\n// Arbitrary: any other key is extension-specific config (e.g., extensions.hello.greeting)\nexport const ExtensionsConfigSchema: z.ZodType<Record<string, unknown>> = z.record(z.string(), z.unknown());\n\n// ============================================\n// Update Config\n// ============================================\n\nexport const UpdateAutoConfigSchema = z\n .object({\n /** Enable automatic update installation. Default false. */\n enabled: z.boolean().default(false),\n /** Hours to wait before applying a stable update after first detection. */\n stableDelayHours: z.number().min(0).default(6),\n /** Additional random jitter hours for stable rollout (avoids thundering herd). */\n stableJitterHours: z.number().min(0).default(12),\n /** How often to re-check for beta updates (hours). Min 0.25. */\n betaCheckIntervalHours: z.number().min(0.25).default(1),\n })\n .strict()\n .optional();\n\nexport const UpdateConfigSchema = z\n .object({\n /** Check for updates on gateway startup. Default true. */\n checkOnStart: z.boolean().default(true),\n /** Update channel: stable (default), beta, or dev. */\n channel: z.enum(['stable', 'beta', 'dev']).default('stable'),\n /** Automatic update policy. */\n auto: UpdateAutoConfigSchema,\n })\n .strict()\n .optional();\n\nexport type UpdateConfig = z.infer<typeof UpdateConfigSchema>;\n\n// ============================================\n// Root Config\n// ============================================\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema,\n bindings: BindingsConfigSchema,\n session: SessionConfigSchema,\n channels: ChannelsConfigSchema,\n gateway: GatewayConfigSchema,\n tools: ToolsConfigSchema,\n cron: CronConfigSchema,\n extensions: ExtensionsConfigSchema.default({}),\n modelsDev: ModelsDevConfigSchema,\n stt: STTConfigSchema.optional(),\n tts: TTSConfigSchema.optional(),\n update: UpdateConfigSchema,\n}).default({\n agents: {\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'off',\n verboseDefault: 'off',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n },\n bindings: [],\n session: {\n dmScope: 'main' as const,\n },\n channels: {\n telegram: {\n enabled: false,\n botToken: '',\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n },\n gateway: {\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n },\n tools: {\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n },\n cron: {\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n },\n extensions: {\n allow: [],\n security: {\n checkPermissions: true,\n allowUntrusted: false,\n allow: [],\n trackProvenance: true,\n allowPromptInjection: false,\n },\n slots: {},\n },\n modelsDev: {\n enabled: true,\n },\n stt: {\n enabled: false,\n provider: 'alibaba',\n alibaba: {\n model: 'paraformer-v2',\n },\n openai: {\n model: 'whisper-1',\n },\n fallback: {\n enabled: true,\n order: ['alibaba', 'openai'],\n },\n },\n tts: {\n enabled: false,\n provider: 'openai',\n trigger: 'always',\n fallback: {\n enabled: true,\n order: ['openai', 'alibaba', 'minimax', 'edge'],\n },\n maxTextLength: 4096,\n timeoutMs: 30000,\n modelOverrides: {\n enabled: true,\n allowText: true,\n allowProvider: false,\n allowVoice: true,\n allowModelId: true,\n allowVoiceSettings: false,\n allowNormalization: false,\n allowSeed: false,\n },\n alibaba: {\n model: 'qwen-tts',\n voice: 'Cherry',\n },\n openai: {\n model: 'tts-1',\n voice: 'alloy',\n },\n edge: {\n enabled: true,\n voice: 'en-US-MichelleNeural',\n lang: 'en-US',\n outputFormat: 'audio-24khz-48kbitrate-mono-mp3',\n },\n minimax: {\n model: 'speech-2.8-hd',\n voice: 'male-qn-qingse',\n },\n },\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\nexport type GatewayAuthConfig = z.infer<typeof GatewayAuthSchema>;\nexport type GatewayAuthRateLimitConfig = z.infer<typeof GatewayAuthRateLimitSchema>;\nexport type STTConfig = z.infer<typeof STTConfigSchema>;\nexport type TTSConfig = z.infer<typeof TTSConfigSchema>;\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Parse a model reference string.\n */\nexport interface ParsedModelRef {\n provider: string;\n model: string;\n}\n\n/**\n * Default agent’s resolved Markdown workspace root (`resolveAgentWorkspaceDir` for the default agent id).\n */\nexport function getWorkspacePath(config: Config): string {\n return getDefaultWorkspacePath(config);\n}\n\n/**\n * Primary model ref from `agents.defaults.model` (string or `{ primary }`).\n * Returns undefined when unset or empty.\n */\nexport function getAgentDefaultModelRef(config: Config): string | undefined {\n const raw = config.agents?.defaults?.model;\n if (raw === undefined || raw === null) return undefined;\n const ref = typeof raw === 'string' ? raw : raw.primary;\n if (ref === undefined || ref === null) return undefined;\n const s = String(ref).trim();\n return s ? s : undefined;\n}\n\n/** `provider/model` or null when invalid. */\nexport function parseModelRef(ref: string): ParsedModelRef | null {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n if (idx <= 0 || idx === trimmed.length - 1) {\n return null;\n }\n return { provider: trimmed.slice(0, idx).trim(), model: trimmed.slice(idx + 1).trim() };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../src/config/schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { getDefaultWorkspacePath } from '../agent/agent-scope.js';\n\n// ============================================\n// Agent Configs\n// ============================================\n\nexport const AgentModelRefSchema = z.union([\n z.string(),\n z\n .object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n })\n .strict(),\n]);\n\nexport type AgentModelConfig = z.infer<typeof AgentModelRefSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n /** Parent directory: each agent’s Markdown root is `<expanded>/<agentId>/` (e.g. `.../workspace/main`). */\n workspace: z.string().default('~/.xopc/workspace'),\n model: z.union([\n z.string(),\n z.object({\n primary: z.string().optional(),\n fallbacks: z.array(z.string()).optional(),\n }).strict(),\n ]).default(''), // Empty default - will be resolved dynamically at runtime\n /** Vision / image understanding model (provider/model). Falls back to heuristics when unset. */\n imageModel: AgentModelRefSchema.optional(),\n /** Image generation model (provider/model), e.g. openai/gpt-image-1. Thin REST wrapper; OpenAI supported. */\n imageGenerationModel: AgentModelRefSchema.optional(),\n /** Max image size for image tool loads (MB). */\n mediaMaxMb: z.number().positive().optional(),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n // Wall-clock limit for one user turn (LLM + tools). Default 30m if unset; cap 4h.\n maxTaskDurationMs: z.number().min(60000).max(14_400_000).optional(),\n // Reliability settings\n maxRequestsPerTurn: z.number().min(10).max(200).default(50),\n maxToolFailuresPerTurn: z.number().min(1).max(20).default(3),\n // Thinking ability settings\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n compaction: z.object({\n enabled: z.boolean().default(true),\n mode: z.enum(['default', 'safeguard']).default('default'),\n reserveTokens: z.number().default(8000),\n triggerThreshold: z.number().min(0.5).max(0.95).default(0.8),\n minMessagesBeforeCompact: z.number().default(10),\n keepRecentMessages: z.number().default(5),\n // Dual-strategy compaction\n evictionWindow: z.number().min(0.1).max(0.5).default(0.2),\n retentionWindow: z.number().min(3).max(20).default(6),\n }).optional(),\n pruning: z.object({\n enabled: z.boolean().default(true),\n maxToolResultChars: z.number().default(10000),\n headKeepRatio: z.number().default(0.3),\n tailKeepRatio: z.number().default(0.3),\n }).optional(),\n /**\n * Curated memory (`agents/<id>/memories/`) + pluggable external provider.\n * Only one external provider at a time.\n */\n memory: z\n .object({\n /** Master switch: curated snapshot, `curated_memory`, prefetch, and external provider. Default true. */\n enabled: z.boolean().optional(),\n /** When false, use workspace bootstrap only (no curated snapshot / tool). Default true. */\n useEnhancedSystem: z.boolean().optional(),\n /** Include USER.md in snapshot. Default true. */\n userProfileEnabled: z.boolean().optional(),\n memoryCharLimit: z.number().positive().optional(),\n userCharLimit: z.number().positive().optional(),\n provider: z.enum(['none', 'stub']).optional(),\n /** How often prefetched external memory is injected into the user message. */\n injectionFrequency: z.enum(['every-turn', 'first-turn']).optional(),\n /** Inject prefetch on turns 1, 1+N, 1+2N, … (only when injectionFrequency is every-turn). Min 1. */\n contextCadence: z.number().int().min(1).optional(),\n /** Reserved for future external “dialectic” sync cadence (not wired yet). */\n dialecticCadence: z.number().int().min(1).optional(),\n })\n .optional(),\n /** Cross-session transcript search (`session_search` tool). */\n sessionSearch: z\n .object({\n /** Model ref for per-session summaries (e.g. openai/gpt-4o-mini). */\n summaryModel: z.string().optional(),\n })\n .optional(),\n /**\n * Post-turn background review (Hermes-style): optional quiet follow-up that may call\n * `curated_memory` / `skill_manage` so durable facts and reusable workflows persist\n * without bloating the main user-visible turn.\n */\n backgroundReview: z\n .object({\n /** When true, nudges may run after successful turns. Default false (opt-in). */\n enabled: z.boolean().optional(),\n /** User-turn cadence for memory review. 0 disables the memory channel. Default 10. */\n memoryNudgeInterval: z.number().int().min(0).optional(),\n /** LLM rounds without `skill_manage` before a skill review. 0 disables the skill channel. Default 10. */\n skillNudgeInterval: z.number().int().min(0).optional(),\n /** Max tool executions for the review agent. Default 8. */\n maxToolRounds: z.number().int().min(1).max(32).optional(),\n /** Max prior messages passed into the review context (tail). Default 80. */\n maxHistoryMessages: z.number().int().min(10).max(200).optional(),\n /** Wall-clock cap for the review run (ms). Default 120000. */\n maxDurationMs: z.number().int().min(30_000).max(600_000).optional(),\n })\n .optional(),\n /** LLM pass for `web_extract` (markdown-focused extraction). */\n webExtract: z\n .object({\n model: z.string().optional(),\n maxLength: z.number().positive().optional(),\n })\n .optional(),\n /**\n * Headless Playwright tools (`browser_*`). Opt-in. Install browsers once: `npx playwright install chromium`.\n */\n browser: z\n .object({\n enabled: z.boolean().optional(),\n /** Default true when browser tools are enabled. */\n headless: z.boolean().optional(),\n })\n .optional(),\n /** Sub-agent delegation (`delegate_task`). Opt-in. */\n delegate: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Sandboxed `execute_code` (programmatic tool calls). Opt-in. */\n executeCode: z\n .object({\n enabled: z.boolean().optional(),\n })\n .optional(),\n /** Optional full system prompt replacement (merged with per-agent entry; entry wins). */\n systemPromptOverride: z.string().optional(),\n /** Optional allowlist of skill names for `<available_skills>`; when set, replaces unfiltered list. */\n skills: z.array(z.string()).optional(),\n /** Disable built-in tools by name (e.g. `shell`, `web_search`). */\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n /** Opaque per-process params (reserved for extensions / future use). */\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentConfigSchema = z.object({\n id: z.string(),\n /** When true, this entry is the default routing agent. */\n default: z.boolean().optional(),\n name: z.string().optional(),\n /** Short human-readable summary for UIs (gateway console, pickers). */\n description: z.string().max(4000).optional(),\n enabled: z.boolean().default(true),\n /** Per-agent workspace root (`~` expanded at runtime). */\n workspace: z.string().optional(),\n /**\n * Internal agent state directory (`…/credentials`, `agent.json`, pid, inbox).\n * Default: `<stateDir>/agents/<id>/agent`.\n */\n agentDir: z.string().optional(),\n model: AgentModelRefSchema.optional(),\n thinkingDefault: z.enum(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive']).optional(),\n reasoningDefault: z.enum(['off', 'on', 'stream']).optional(),\n verboseDefault: z.enum(['off', 'on', 'full']).optional(),\n systemPromptOverride: z.string().optional(),\n skills: z.array(z.string()).optional(),\n tools: z\n .object({\n disable: z.array(z.string()).optional(),\n })\n .optional(),\n params: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const AgentsConfigSchema = z.object({\n /** Default agent id when not specified (routing / session creation). */\n default: z.string().optional(),\n defaults: AgentDefaultsSchema.optional(),\n list: z.array(AgentConfigSchema).optional(),\n}).default({\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n} as any);\n\n// ============================================\n// Channel Configs (per-channel Zod lives in bundled extensions; root schema is open)\n// ============================================\n\nexport {\n TelegramTopicConfigSchema,\n TelegramGroupConfigSchema,\n TelegramAccountConfigSchema,\n TelegramConfigSchema,\n} from '../../extensions/telegram/src/config-schema.js';\nexport type { TelegramConfig } from '../../extensions/telegram/src/config-schema.js';\nexport { WeixinAccountConfigSchema, WeixinConfigSchema } from '../../extensions/weixin/src/config-schema.js';\nexport type { WeixinConfig } from '../../extensions/weixin/src/config-schema.js';\n\n// ============================================\n// Session Routing Configuration\n// ============================================\n\nexport const BindingMatchSchema = z.object({\n channel: z.string(),\n accountId: z.string().optional(),\n peerKind: z.string().optional(),\n peerId: z.string().optional(),\n guildId: z.string().optional(),\n teamId: z.string().optional(),\n memberRoleIds: z.array(z.string()).optional(),\n});\n\nexport const BindingRuleSchema = z.object({\n id: z.string().optional(),\n agentId: z.string(),\n priority: z.number().default(100),\n match: BindingMatchSchema,\n enabled: z.boolean().default(true),\n});\n\nexport const BindingsConfigSchema = z.array(BindingRuleSchema).default([]);\n\nexport const SessionDmScopeSchema = z.enum([\n 'main',\n 'per-peer',\n 'per-channel-peer',\n 'per-account-channel-peer',\n]);\n\nexport const SessionStorageConfigSchema = z.object({\n pruneAfterMs: z.number().optional(),\n maxEntries: z.number().optional(),\n});\n\nexport const SessionConfigSchema = z.object({\n dmScope: SessionDmScopeSchema.default('main'),\n identityLinks: z.record(z.string(), z.array(z.string())).optional(),\n storage: SessionStorageConfigSchema.optional(),\n}).default({\n dmScope: 'main',\n});\n\n/** Channel buckets — shapes validated post-parse by registered channel plugins. */\nexport const ChannelsConfigSchema = z.record(z.string(), z.unknown()).default({\n telegram: {\n enabled: false,\n botToken: '',\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n});\n\nexport const SearchProviderEntrySchema = z.object({\n type: z.enum(['brave', 'tavily', 'bing', 'searxng']),\n apiKey: z.string().optional(),\n /** SearXNG instance base URL (e.g. http://localhost:8080) */\n url: z.string().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type SearchProviderEntry = z.infer<typeof SearchProviderEntrySchema>;\n\nexport const WebSearchConfigSchema = z.object({\n maxResults: z.number().default(5),\n /** Ordered API providers; empty → HTML fallback only */\n providers: z.array(SearchProviderEntrySchema).default([]),\n});\n\nexport type WebSearchConfig = z.infer<typeof WebSearchConfigSchema>;\n\nexport const WebToolsConfigSchema = z.object({\n /** Search result HTML fallback: cn → Bing, otherwise DuckDuckGo */\n region: z.enum(['cn', 'global']).optional(),\n search: WebSearchConfigSchema.optional(),\n});\n\nexport type WebToolsConfig = z.infer<typeof WebToolsConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.optional(),\n}).default({\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n});\n\n// ============================================\n// Gateway Configuration\n// ============================================\n\nexport const GatewayAuthRateLimitSchema = z\n .object({\n enabled: z.boolean().default(true),\n maxAttempts: z.number().int().min(1).default(5),\n windowMs: z.number().default(900_000),\n blockDurationMs: z.number().default(300_000),\n })\n .optional();\n\nexport const GatewayAuthSchema = z\n .object({\n mode: z.enum(['none', 'token']).default('token'),\n token: z.string().optional(),\n rateLimit: GatewayAuthRateLimitSchema,\n })\n .default({\n mode: 'token',\n });\n\nexport const HeartbeatConfigSchema = z\n .object({\n enabled: z.boolean(),\n intervalMs: z.number(),\n /** When false, heartbeat instructions are only sent during heartbeat polling turns (not in every chat system prompt). */\n includeSystemPromptSection: z.boolean().optional().default(false),\n target: z.string().optional(),\n targetChatId: z.string().optional(),\n prompt: z.string().optional(),\n ackMaxChars: z.number().optional(),\n isolatedSession: z.boolean().optional(),\n activeHours: z\n .object({\n start: z.string(),\n end: z.string(),\n timezone: z.string().optional(),\n })\n .optional(),\n })\n .default({\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n });\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().optional(),\n port: z.number().optional(),\n auth: GatewayAuthSchema.optional(),\n heartbeat: HeartbeatConfigSchema.optional(),\n maxSseConnections: z.number().optional(),\n corsOrigins: z.array(z.string()).optional(),\n /** Base URL for the xopc skills marketplace (public REST API). */\n skillsStoreBaseUrl: z.string().url().optional(),\n}).default({\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n});\n\nexport const CronConfigSchema = z.object({\n enabled: z.boolean().optional(),\n maxConcurrentJobs: z.number().optional(),\n defaultTimezone: z.string().optional(),\n historyRetentionDays: z.number().optional(),\n enableMetrics: z.boolean().optional(),\n}).default({\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n});\n\nexport const ModelsDevConfigSchema = z.object({\n enabled: z.boolean().default(true),\n}).default({\n enabled: true,\n});\n\n// ============================================\n// STT (Speech-to-Text) Config\n// ============================================\n\nexport const STTProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n});\n\nexport const STTFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z.array(z.enum(['alibaba', 'openai'])).default(['alibaba', 'openai']),\n});\n\nexport const STTConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['alibaba', 'openai']).default('alibaba'),\n alibaba: STTProviderConfigSchema.optional(),\n openai: STTProviderConfigSchema.optional(),\n fallback: STTFallbackConfigSchema.optional(),\n});\n\n// ============================================\n// TTS (Text-to-Speech) Config\n// ============================================\n\nexport const TTSProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n voice: z.string().optional(),\n});\n\nexport const TTSFallbackConfigSchema = z.object({\n enabled: z.boolean().default(true),\n order: z\n .array(z.enum(['openai', 'alibaba', 'edge', 'minimax']))\n .default(['openai', 'alibaba', 'minimax', 'edge']),\n});\n\nexport const TTSModelOverridesConfigSchema = z.object({\n enabled: z.boolean().default(true),\n allowText: z.boolean().default(true),\n allowProvider: z.boolean().default(false),\n allowVoice: z.boolean().default(true),\n allowModelId: z.boolean().default(true),\n allowVoiceSettings: z.boolean().default(false),\n allowNormalization: z.boolean().default(false),\n allowSeed: z.boolean().default(false),\n});\n\nexport const TTSEdgeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n voice: z.string().optional(),\n lang: z.string().optional(),\n outputFormat: z.string().optional(),\n pitch: z.string().optional(),\n rate: z.string().optional(),\n volume: z.string().optional(),\n proxy: z.string().optional(),\n timeoutMs: z.number().int().min(1000).max(120000).optional(),\n});\n\nexport const TTSSummarizationConfigSchema = z.object({\n enabled: z.boolean().optional(),\n targetLength: z.number().int().min(1).optional(),\n threshold: z.number().int().min(1).optional(),\n model: z.string().optional(),\n});\n\nexport const TTSConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['openai', 'alibaba', 'edge', 'minimax']).default('openai'),\n trigger: z\n .preprocess(\n (v) => (v === 'auto' ? 'inbound' : v),\n z.enum(['off', 'always', 'inbound', 'tagged']).default('always'),\n ),\n fallback: TTSFallbackConfigSchema.optional(),\n maxTextLength: z.number().int().min(1).default(512), // Conservative default to accommodate all providers (Alibaba limit is 512)\n timeoutMs: z.number().int().min(1000).max(180000).default(60000),\n summarization: TTSSummarizationConfigSchema.optional(),\n modelOverrides: TTSModelOverridesConfigSchema.optional(),\n alibaba: TTSProviderConfigSchema.optional(),\n openai: TTSProviderConfigSchema.optional(),\n edge: TTSEdgeConfigSchema.optional(),\n minimax: TTSProviderConfigSchema.optional(),\n});\n\n// ============================================\n// Extension Configs \n// ============================================\n\n// Security config for extensions \nexport const ExtensionSecurityConfigSchema = z.object({\n checkPermissions: z.boolean().default(true),\n allowUntrusted: z.boolean().default(false),\n allow: z.array(z.string()).default([]),\n trackProvenance: z.boolean().default(true),\n allowPromptInjection: z.boolean().default(false),\n});\n\n// Slot config for extensions \nexport const ExtensionSlotsConfigSchema = z.object({\n memory: z.string().optional(),\n tts: z.string().optional(),\n imageGeneration: z.string().optional(),\n webSearch: z.string().optional(),\n});\n\n// Complete extensions config\n// Extension config allows both known fields AND arbitrary extension-specific config\n// Known fields: enabled (array), allow (array), security (object), slots (object)\n// Arbitrary: any other key is extension-specific config (e.g., extensions.hello.greeting)\nexport const ExtensionsConfigSchema: z.ZodType<Record<string, unknown>> = z.record(z.string(), z.unknown());\n\n// ============================================\n// Update Config\n// ============================================\n\nexport const UpdateAutoConfigSchema = z\n .object({\n /** Enable automatic update installation. Default false. */\n enabled: z.boolean().default(false),\n /** Hours to wait before applying a stable update after first detection. */\n stableDelayHours: z.number().min(0).default(6),\n /** Additional random jitter hours for stable rollout (avoids thundering herd). */\n stableJitterHours: z.number().min(0).default(12),\n /** How often to re-check for beta updates (hours). Min 0.25. */\n betaCheckIntervalHours: z.number().min(0.25).default(1),\n })\n .strict()\n .optional();\n\nexport const UpdateConfigSchema = z\n .object({\n /** Check for updates on gateway startup. Default true. */\n checkOnStart: z.boolean().default(true),\n /** Update channel: stable (default), beta, or dev. */\n channel: z.enum(['stable', 'beta', 'dev']).default('stable'),\n /** Automatic update policy. */\n auto: UpdateAutoConfigSchema,\n })\n .strict()\n .optional();\n\nexport type UpdateConfig = z.infer<typeof UpdateConfigSchema>;\n\n// ============================================\n// Root Config\n// ============================================\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema,\n bindings: BindingsConfigSchema,\n session: SessionConfigSchema,\n channels: ChannelsConfigSchema,\n gateway: GatewayConfigSchema,\n tools: ToolsConfigSchema,\n cron: CronConfigSchema,\n extensions: ExtensionsConfigSchema.default({}),\n modelsDev: ModelsDevConfigSchema,\n stt: STTConfigSchema.optional(),\n tts: TTSConfigSchema.optional(),\n update: UpdateConfigSchema,\n}).default({\n agents: {\n defaults: {\n workspace: '~/.xopc/workspace',\n model: '', // Empty default - will be resolved dynamically at runtime\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n maxRequestsPerTurn: 50,\n maxToolFailuresPerTurn: 3,\n thinkingDefault: 'medium',\n reasoningDefault: 'off',\n verboseDefault: 'off',\n compaction: {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n },\n pruning: {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n },\n },\n },\n bindings: [],\n session: {\n dmScope: 'main' as const,\n },\n channels: {\n telegram: {\n enabled: false,\n botToken: '',\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n },\n gateway: {\n host: '127.0.0.1',\n port: 18790,\n auth: {\n mode: 'token',\n },\n heartbeat: {\n enabled: true,\n intervalMs: 1_800_000,\n includeSystemPromptSection: false,\n },\n maxSseConnections: 100,\n corsOrigins: [],\n skillsStoreBaseUrl: 'https://store.xopc.ai',\n },\n tools: {\n web: {\n search: {\n maxResults: 5,\n providers: [],\n },\n },\n },\n cron: {\n enabled: true,\n maxConcurrentJobs: 5,\n defaultTimezone: 'UTC',\n historyRetentionDays: 7,\n enableMetrics: true,\n },\n extensions: {\n allow: [],\n security: {\n checkPermissions: true,\n allowUntrusted: false,\n allow: [],\n trackProvenance: true,\n allowPromptInjection: false,\n },\n slots: {},\n },\n modelsDev: {\n enabled: true,\n },\n stt: {\n enabled: false,\n provider: 'alibaba',\n alibaba: {\n model: 'paraformer-v2',\n },\n openai: {\n model: 'whisper-1',\n },\n fallback: {\n enabled: true,\n order: ['alibaba', 'openai'],\n },\n },\n tts: {\n enabled: false,\n provider: 'openai',\n trigger: 'always',\n fallback: {\n enabled: true,\n order: ['openai', 'alibaba', 'minimax', 'edge'],\n },\n maxTextLength: 4096,\n timeoutMs: 30000,\n modelOverrides: {\n enabled: true,\n allowText: true,\n allowProvider: false,\n allowVoice: true,\n allowModelId: true,\n allowVoiceSettings: false,\n allowNormalization: false,\n allowSeed: false,\n },\n alibaba: {\n model: 'qwen-tts',\n voice: 'Cherry',\n },\n openai: {\n model: 'tts-1',\n voice: 'alloy',\n },\n edge: {\n enabled: true,\n voice: 'en-US-MichelleNeural',\n lang: 'en-US',\n outputFormat: 'audio-24khz-48kbitrate-mono-mp3',\n },\n minimax: {\n model: 'speech-2.8-hd',\n voice: 'male-qn-qingse',\n },\n },\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\nexport type GatewayAuthConfig = z.infer<typeof GatewayAuthSchema>;\nexport type GatewayAuthRateLimitConfig = z.infer<typeof GatewayAuthRateLimitSchema>;\nexport type STTConfig = z.infer<typeof STTConfigSchema>;\nexport type TTSConfig = z.infer<typeof TTSConfigSchema>;\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Parse a model reference string.\n */\nexport interface ParsedModelRef {\n provider: string;\n model: string;\n}\n\n/**\n * Default agent’s resolved Markdown workspace root (`resolveAgentWorkspaceDir` for the default agent id).\n */\nexport function getWorkspacePath(config: Config): string {\n return getDefaultWorkspacePath(config);\n}\n\n/**\n * Primary model ref from `agents.defaults.model` (string or `{ primary }`).\n * Returns undefined when unset or empty.\n */\nexport function getAgentDefaultModelRef(config: Config): string | undefined {\n const raw = config.agents?.defaults?.model;\n if (raw === undefined || raw === null) return undefined;\n const ref = typeof raw === 'string' ? raw : raw.primary;\n if (ref === undefined || ref === null) return undefined;\n const s = String(ref).trim();\n return s ? s : undefined;\n}\n\n/** `provider/model` or null when invalid. */\nexport function parseModelRef(ref: string): ParsedModelRef | null {\n const trimmed = ref.trim();\n const idx = trimmed.indexOf('/');\n if (idx <= 0 || idx === trimmed.length - 1) {\n return null;\n }\n return { provider: trimmed.slice(0, idx).trim(), model: trimmed.slice(idx + 1).trim() };\n}\n"],"mappings":"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"}
@@ -5,7 +5,8 @@
5
5
  */
6
6
  import type { AgentTool } from '@mariozechner/pi-agent-core';
7
7
  import type { Command } from 'commander';
8
- import type { ExtensionApi, ExtensionLogger, ExtensionRuntime, GatewayMethodHandler, HttpRequestHandler, ExtensionCommand, ExtensionReloadHandler, ExtensionService, FlagConfig, FlagValue, ShortcutConfig, HookHandlerMap, ExtensionHookEvent } from './types/index.js';
8
+ import type { ExtensionApi, ExtensionLogger, ExtensionRuntime, GatewayMethodHandler, HttpRequestHandler, ExtensionCommand, ExtensionCommandHandler, ExtensionReloadHandler, ExtensionService, FlagConfig, FlagValue, ShortcutConfig, HookHandlerMap, ExtensionHookEvent } from './types/index.js';
9
+ import type { CommandContribution } from './types/manifest.js';
9
10
  import type { ChannelPlugin } from '../channels/plugin-types.js';
10
11
  import type { Config } from '../config/config-surface.js';
11
12
  import { EventEmitter } from 'events';
@@ -30,6 +31,7 @@ export declare class ExtensionApiImpl implements ExtensionApi {
30
31
  private readonly _runtime;
31
32
  private _reloadConfigPrefixes;
32
33
  private _registeredCommandIds;
34
+ private readonly _manifestCommands;
33
35
  constructor(id: string, name: string, version: string | undefined, source: string, config: Config, extensionConfig: Record<string, unknown>, _logger: ExtensionLogger, _resolvePath: (input: string) => string, _coreRegistry?: ExtensionRegistryImpl, runtime?: ExtensionRuntime);
34
36
  get logger(): ExtensionLogger;
35
37
  get runtime(): ExtensionRuntime;
@@ -61,6 +63,9 @@ export declare class ExtensionApiImpl implements ExtensionApi {
61
63
  }): void;
62
64
  registerHttpRoute(path: string, handler: HttpRequestHandler): void;
63
65
  registerCommand(command: ExtensionCommand): void;
66
+ /** Injected from manifest `ui.contributions.commands` by the loader. */
67
+ _setManifestCommands(commands: CommandContribution[]): void;
68
+ onCommand(commandId: string, handler: ExtensionCommandHandler): void;
64
69
  registerReload(handler: ExtensionReloadHandler): void;
65
70
  /** Called from loader when manifest declares `reload.configPrefixes`. */
66
71
  _setReloadConfigPrefixes(prefixes: string[]): void;
@@ -18,6 +18,7 @@ var ExtensionApiImpl = class {
18
18
  _runtime;
19
19
  _reloadConfigPrefixes = [];
20
20
  _registeredCommandIds = [];
21
+ _manifestCommands = /* @__PURE__ */ new Map();
21
22
  constructor(id, name, version, source, config, extensionConfig, _logger, _resolvePath, _coreRegistry, runtime) {
22
23
  this.id = id;
23
24
  this.name = name;
@@ -131,6 +132,34 @@ var ExtensionApiImpl = class {
131
132
  this._eventBus.emit("command:register", command);
132
133
  this._logger.info(`Registered chat command: /${command.name}`);
133
134
  }
135
+ /** Injected from manifest `ui.contributions.commands` by the loader. */
136
+ _setManifestCommands(commands) {
137
+ this._manifestCommands.clear();
138
+ for (const c of commands) this._manifestCommands.set(c.id, c);
139
+ }
140
+ onCommand(commandId, handler) {
141
+ const meta = this._manifestCommands.get(commandId);
142
+ if (!meta) {
143
+ this._logger.warn(`onCommand: unknown command id "${commandId}" — registering runtime-only chat command`);
144
+ const name = commandId.includes(".") ? (commandId.split(".").pop() ?? commandId).trim() : commandId;
145
+ this.registerCommand({
146
+ name: name || commandId,
147
+ description: commandId,
148
+ handler
149
+ });
150
+ return;
151
+ }
152
+ let name;
153
+ if (meta.chatAlias?.trim()) name = meta.chatAlias.trim().replace(/^\//, "");
154
+ else name = meta.id.includes(".") ? meta.id.split(".").pop() ?? meta.id : meta.id;
155
+ if (!name) name = meta.id;
156
+ this.registerCommand({
157
+ name,
158
+ description: meta.title,
159
+ handler
160
+ });
161
+ this._logger.info(`Bound manifest command "${commandId}" as /${name}`);
162
+ }
134
163
  registerReload(handler) {
135
164
  const prefixes = this._reloadConfigPrefixes.length > 0 ? this._reloadConfigPrefixes : [`extensions.${this.id}`];
136
165
  this._registry.addReloadRegistration({
@@ -212,6 +241,7 @@ var ExtensionApiImpl = class {
212
241
  _cleanup() {
213
242
  for (const commandId of this._registeredCommandIds) commandRegistry.unregister(commandId);
214
243
  this._registeredCommandIds = [];
244
+ this._manifestCommands.clear();
215
245
  this._registry.removeReloadRegistration(this.id);
216
246
  this._typedEventBus.cleanupAll();
217
247
  this._eventBus.removeAllListeners();
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","names":[],"sources":["../../../src/extensions/api.ts"],"sourcesContent":["/**\n * Extension API Implementation\n * \n * Complete extension API with strong typing, security, and provider support.\n */\n\nimport type { AgentTool } from '@mariozechner/pi-agent-core';\nimport type { Command } from 'commander';\nimport type {\n ExtensionApi,\n ExtensionLogger,\n ExtensionRuntime,\n ExtensionCliRegistration,\n GatewayMethodHandler,\n HttpRequestHandler,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionReloadHandler,\n ExtensionService,\n FlagConfig,\n FlagValue,\n ShortcutConfig,\n HookHandlerMap,\n ExtensionHookEvent,\n HookExecutionMode,\n} from './types/index.js';\nimport type { CommandDefinition } from '../chat-commands/types.js';\nimport { commandRegistry } from '../chat-commands/registry.js';\nimport type { ChannelPlugin } from '../channels/plugin-types.js';\nimport {\n HOOK_EXECUTION_MODES,\n} from './types/hooks.js';\nimport type { Config } from '../config/config-surface.js';\nimport type { Config as SchemaConfig } from '../config/schema.js';\nimport { resolve, isAbsolute } from 'path';\nimport { EventEmitter } from 'events';\nimport { createLogger } from '../utils/logger.js';\nimport { TypedEventBus } from './typed-event-bus.js';\nimport { ExtensionRegistryImpl } from './loader.js';\n\nexport class ExtensionApiImpl implements ExtensionApi {\n private _tools: Map<string, AgentTool> = new Map();\n private _hooks: Map<string, Set<Function>> = new Map();\n // Strongly typed hooks (for on() method)\n private _typedHooks: Map<ExtensionHookEvent, Set<Function>> = new Map();\n private _eventBus = new EventEmitter();\n private _typedEventBus: TypedEventBus;\n \n // Unified Registry\n private _registry: ExtensionRegistryImpl;\n\n private readonly _runtime: ExtensionRuntime;\n\n private _reloadConfigPrefixes: string[] = [];\n private _registeredCommandIds: string[] = [];\n\n constructor(\n public readonly id: string,\n public readonly name: string,\n public readonly version: string | undefined,\n public readonly source: string,\n public readonly config: Config,\n public readonly extensionConfig: Record<string, unknown>,\n private readonly _logger: ExtensionLogger,\n private readonly _resolvePath: (input: string) => string,\n private readonly _coreRegistry?: ExtensionRegistryImpl,\n runtime?: ExtensionRuntime,\n ) {\n // Initialize typed event bus\n this._typedEventBus = new TypedEventBus({\n logger: _logger,\n });\n \n this._registry = _coreRegistry ?? new ExtensionRegistryImpl();\n this._runtime =\n runtime ??\n ({\n config: this.config,\n log: this._logger,\n } as ExtensionRuntime);\n }\n\n get logger(): ExtensionLogger {\n return this._logger;\n }\n\n get runtime(): ExtensionRuntime {\n return this._runtime;\n }\n\n registerTool(tool: AgentTool): void {\n if (this._tools.has(tool.name)) {\n this._logger.warn(`Tool ${tool.name} already registered, overwriting`);\n }\n this._tools.set(tool.name, tool);\n this._logger.info(`Registered tool: ${tool.name}`);\n }\n\n registerHook(event: string, handler: Function, opts?: { priority?: number; once?: boolean }): void {\n if (!this._hooks.has(event)) {\n this._hooks.set(event, new Set());\n }\n this._hooks.get(event)!.add(handler);\n\n if (opts?.once) {\n const wrapper = async (...args: unknown[]) => {\n await handler(...args);\n this._hooks.get(event)?.delete(wrapper);\n };\n this._hooks.get(event)!.add(wrapper);\n }\n\n this._logger.info(`Registered hook: ${event}`);\n }\n\n /**\n * Strongly typed hook registration\n * Provides compile-time type checking and IDE autocomplete\n * \n * @example\n * api.on('before_agent_start', async (event, ctx) => {\n * console.log('Agent starting with prompt:', event.prompt);\n * return { systemPrompt: event.systemPrompt };\n * });\n */\n onHook<K extends ExtensionHookEvent>(\n hookName: K,\n handler: HookHandlerMap[K],\n _opts?: { priority?: number },\n ): void {\n // Get execution mode for this hook\n const mode = (HOOK_EXECUTION_MODES as Record<string, HookExecutionMode>)[hookName];\n \n if (!this._typedHooks.has(hookName)) {\n this._typedHooks.set(hookName, new Set());\n }\n \n this._typedHooks.get(hookName)!.add(handler);\n\n this._logger.debug(`Registered typed hook: ${hookName} (mode: ${mode})`);\n }\n\n /**\n * Get typed hooks for a specific event\n */\n _getTypedHooks<K extends ExtensionHookEvent>(hookName: K): HookHandlerMap[K][] {\n const hooks = this._typedHooks.get(hookName);\n return hooks ? Array.from(hooks) as HookHandlerMap[K][] : [];\n }\n\n /** Adds a ChannelPlugin to the extension registry; emits `channel:register` for observability. */\n registerChannel(registration: { plugin: ChannelPlugin }): void {\n const plugin = registration.plugin;\n this._registry.addChannelPlugin(plugin);\n this._eventBus.emit('channel:register', plugin);\n this._logger.info(`Registered channel plugin: ${plugin.id}`);\n }\n\n registerHttpRoute(path: string, handler: HttpRequestHandler): void {\n this._eventBus.emit('http:route', { path, handler });\n this._logger.info(`Registered HTTP route: ${path}`);\n }\n\n registerCommand(command: ExtensionCommand): void {\n const commandId = `ext.${this.id}.${command.name}`;\n\n const definition: CommandDefinition = {\n id: commandId,\n name: command.name,\n aliases: command.aliases,\n description: command.description,\n category: 'extension',\n scope: command.scope ?? ['global'],\n acceptsArgs: command.acceptsArgs,\n examples: command.examples,\n handler: async (ctx, args) => {\n const extensionCtx: ExtensionCommandContext = {\n sessionKey: ctx.sessionKey,\n source: ctx.source,\n isGroup: ctx.isGroup,\n config: ctx.config as SchemaConfig as ExtensionCommandContext['config'],\n reply: (text: string) => ctx.reply(text),\n };\n\n const result = await command.handler(args, extensionCtx);\n\n if (!result) {\n return { content: '', success: true };\n }\n return {\n content: result.content,\n success: result.success ?? true,\n };\n },\n };\n\n commandRegistry.register(definition);\n this._registeredCommandIds.push(commandId);\n this._registry.addCommand(command);\n\n this._eventBus.emit('command:register', command);\n this._logger.info(`Registered chat command: /${command.name}`);\n }\n\n registerReload(handler: ExtensionReloadHandler): void {\n const prefixes =\n this._reloadConfigPrefixes.length > 0\n ? this._reloadConfigPrefixes\n : [`extensions.${this.id}`];\n\n this._registry.addReloadRegistration({\n extensionId: this.id,\n handler,\n configPrefixes: prefixes,\n });\n this._logger.info('Registered reload handler');\n }\n\n /** Called from loader when manifest declares `reload.configPrefixes`. */\n _setReloadConfigPrefixes(prefixes: string[]): void {\n this._reloadConfigPrefixes = [...prefixes];\n }\n\n registerService(service: ExtensionService): void {\n this._eventBus.emit('service:register', service);\n this._logger.info(`Registered service: ${service.id}`);\n }\n\n registerGatewayMethod(method: string, handler: GatewayMethodHandler): void {\n this._eventBus.emit('gateway:method', { method, handler });\n this._logger.info(`Registered gateway method: ${method}`);\n }\n\n registerCli(\n factory: (ctx: { program: Command }) => void,\n opts?: { commands: string[] },\n ): void {\n const reg: ExtensionCliRegistration = {\n extensionId: this.id,\n commands: opts?.commands ?? [],\n factory,\n };\n this._registry.addCliRegistration(reg);\n this._eventBus.emit('cli:register', reg);\n this._logger.info(\n `Registered CLI factory${opts?.commands?.length ? ` (${opts.commands.join(', ')})` : ''}`,\n );\n }\n\n resolvePath(input: string): string {\n return this._resolvePath(input);\n }\n\n emit(event: string, data: unknown): void {\n this._eventBus.emit(event, data);\n }\n\n on(event: string, handler: (data: unknown) => void): void {\n this._eventBus.on(event, handler);\n }\n\n off(event: string, handler: (data: unknown) => void): void {\n this._eventBus.off(event, handler);\n }\n\n // Typed Event Bus\n get events(): TypedEventBus {\n return this._typedEventBus;\n }\n\n // Unified Registry Methods\n \n /**\n * Register a full ProviderPlugin\n */\n registerProvider(plugin: import('./types/providers.js').ProviderPlugin): void {\n import('../providers/plugin-registry.js').then(({ getProviderRegistry }) => {\n const registry = getProviderRegistry();\n registry.register(plugin);\n this._logger.info(`Extension registered provider: ${plugin.id}`);\n }).catch((err: unknown) => {\n this._logger.error(`Failed to register provider: ${err instanceof Error ? err.message : String(err)}`);\n });\n }\n\n /**\n * Register a full ProviderPlugin (alias for registerProvider)\n */\n registerProviderPlugin(plugin: import('./types/providers.js').ProviderPlugin): void {\n this.registerProvider(plugin);\n }\n\n registerFlag(_name: string, _config: FlagConfig): void {\n // this._registry.registerFlag(name, config, this.id);\n }\n\n getFlag(_name: string): FlagValue {\n return undefined; // this._registry.getFlag(name);\n }\n\n registerShortcut(_key: string, _config: ShortcutConfig): void {\n // this._registry.registerShortcut(key, config, { extensionId: this.id });\n }\n\n // Internal methods for extension manager\n _getTools(): Map<string, AgentTool> {\n return this._tools;\n }\n\n _getHooks(): Map<string, Set<Function>> {\n return this._hooks;\n }\n\n _getEventBus(): EventEmitter {\n return this._eventBus;\n }\n\n _cleanup(): void {\n for (const commandId of this._registeredCommandIds) {\n commandRegistry.unregister(commandId);\n }\n this._registeredCommandIds = [];\n\n this._registry.removeReloadRegistration(this.id);\n\n this._typedEventBus.cleanupAll();\n this._eventBus.removeAllListeners();\n this._hooks.clear();\n this._typedHooks.clear();\n }\n}\n\n// ============================================================================\n// Default Logger\n// ============================================================================\n\nexport function createExtensionLogger(prefix: string): ExtensionLogger {\n const childLogger = createLogger(`Extension:${prefix}`);\n\n return {\n debug: (msg: string) => childLogger.debug(msg),\n info: (msg: string) => childLogger.info(msg),\n warn: (msg: string) => childLogger.warn(msg),\n error: (msg: string) => childLogger.error(msg),\n };\n}\n\n// ============================================================================\n// Path Resolver\n// ============================================================================\n\nexport function createPathResolver(extensionDir: string, workspaceDir: string) {\n return (input: string): string => {\n if (input.startsWith('~')) {\n return input.replace('~', process.env.HOME || '');\n }\n if (input.startsWith('.')) {\n return resolve(extensionDir, input);\n }\n if (!isAbsolute(input)) {\n return resolve(workspaceDir, input);\n }\n return input;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api.js","names":[],"sources":["../../../src/extensions/api.ts"],"sourcesContent":["/**\n * Extension API Implementation\n * \n * Complete extension API with strong typing, security, and provider support.\n */\n\nimport type { AgentTool } from '@mariozechner/pi-agent-core';\nimport type { Command } from 'commander';\nimport type {\n ExtensionApi,\n ExtensionLogger,\n ExtensionRuntime,\n ExtensionCliRegistration,\n GatewayMethodHandler,\n HttpRequestHandler,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionCommandHandler,\n ExtensionReloadHandler,\n ExtensionService,\n FlagConfig,\n FlagValue,\n ShortcutConfig,\n HookHandlerMap,\n ExtensionHookEvent,\n HookExecutionMode,\n} from './types/index.js';\nimport type { CommandContribution } from './types/manifest.js';\nimport type { CommandDefinition } from '../chat-commands/types.js';\nimport { commandRegistry } from '../chat-commands/registry.js';\nimport type { ChannelPlugin } from '../channels/plugin-types.js';\nimport {\n HOOK_EXECUTION_MODES,\n} from './types/hooks.js';\nimport type { Config } from '../config/config-surface.js';\nimport type { Config as SchemaConfig } from '../config/schema.js';\nimport { resolve, isAbsolute } from 'path';\nimport { EventEmitter } from 'events';\nimport { createLogger } from '../utils/logger.js';\nimport { TypedEventBus } from './typed-event-bus.js';\nimport { ExtensionRegistryImpl } from './loader.js';\n\nexport class ExtensionApiImpl implements ExtensionApi {\n private _tools: Map<string, AgentTool> = new Map();\n private _hooks: Map<string, Set<Function>> = new Map();\n // Strongly typed hooks (for on() method)\n private _typedHooks: Map<ExtensionHookEvent, Set<Function>> = new Map();\n private _eventBus = new EventEmitter();\n private _typedEventBus: TypedEventBus;\n \n // Unified Registry\n private _registry: ExtensionRegistryImpl;\n\n private readonly _runtime: ExtensionRuntime;\n\n private _reloadConfigPrefixes: string[] = [];\n private _registeredCommandIds: string[] = [];\n private readonly _manifestCommands = new Map<string, CommandContribution>();\n\n constructor(\n public readonly id: string,\n public readonly name: string,\n public readonly version: string | undefined,\n public readonly source: string,\n public readonly config: Config,\n public readonly extensionConfig: Record<string, unknown>,\n private readonly _logger: ExtensionLogger,\n private readonly _resolvePath: (input: string) => string,\n private readonly _coreRegistry?: ExtensionRegistryImpl,\n runtime?: ExtensionRuntime,\n ) {\n // Initialize typed event bus\n this._typedEventBus = new TypedEventBus({\n logger: _logger,\n });\n \n this._registry = _coreRegistry ?? new ExtensionRegistryImpl();\n this._runtime =\n runtime ??\n ({\n config: this.config,\n log: this._logger,\n } as ExtensionRuntime);\n }\n\n get logger(): ExtensionLogger {\n return this._logger;\n }\n\n get runtime(): ExtensionRuntime {\n return this._runtime;\n }\n\n registerTool(tool: AgentTool): void {\n if (this._tools.has(tool.name)) {\n this._logger.warn(`Tool ${tool.name} already registered, overwriting`);\n }\n this._tools.set(tool.name, tool);\n this._logger.info(`Registered tool: ${tool.name}`);\n }\n\n registerHook(event: string, handler: Function, opts?: { priority?: number; once?: boolean }): void {\n if (!this._hooks.has(event)) {\n this._hooks.set(event, new Set());\n }\n this._hooks.get(event)!.add(handler);\n\n if (opts?.once) {\n const wrapper = async (...args: unknown[]) => {\n await handler(...args);\n this._hooks.get(event)?.delete(wrapper);\n };\n this._hooks.get(event)!.add(wrapper);\n }\n\n this._logger.info(`Registered hook: ${event}`);\n }\n\n /**\n * Strongly typed hook registration\n * Provides compile-time type checking and IDE autocomplete\n * \n * @example\n * api.on('before_agent_start', async (event, ctx) => {\n * console.log('Agent starting with prompt:', event.prompt);\n * return { systemPrompt: event.systemPrompt };\n * });\n */\n onHook<K extends ExtensionHookEvent>(\n hookName: K,\n handler: HookHandlerMap[K],\n _opts?: { priority?: number },\n ): void {\n // Get execution mode for this hook\n const mode = (HOOK_EXECUTION_MODES as Record<string, HookExecutionMode>)[hookName];\n \n if (!this._typedHooks.has(hookName)) {\n this._typedHooks.set(hookName, new Set());\n }\n \n this._typedHooks.get(hookName)!.add(handler);\n\n this._logger.debug(`Registered typed hook: ${hookName} (mode: ${mode})`);\n }\n\n /**\n * Get typed hooks for a specific event\n */\n _getTypedHooks<K extends ExtensionHookEvent>(hookName: K): HookHandlerMap[K][] {\n const hooks = this._typedHooks.get(hookName);\n return hooks ? Array.from(hooks) as HookHandlerMap[K][] : [];\n }\n\n /** Adds a ChannelPlugin to the extension registry; emits `channel:register` for observability. */\n registerChannel(registration: { plugin: ChannelPlugin }): void {\n const plugin = registration.plugin;\n this._registry.addChannelPlugin(plugin);\n this._eventBus.emit('channel:register', plugin);\n this._logger.info(`Registered channel plugin: ${plugin.id}`);\n }\n\n registerHttpRoute(path: string, handler: HttpRequestHandler): void {\n this._eventBus.emit('http:route', { path, handler });\n this._logger.info(`Registered HTTP route: ${path}`);\n }\n\n registerCommand(command: ExtensionCommand): void {\n const commandId = `ext.${this.id}.${command.name}`;\n\n const definition: CommandDefinition = {\n id: commandId,\n name: command.name,\n aliases: command.aliases,\n description: command.description,\n category: 'extension',\n scope: command.scope ?? ['global'],\n acceptsArgs: command.acceptsArgs,\n examples: command.examples,\n handler: async (ctx, args) => {\n const extensionCtx: ExtensionCommandContext = {\n sessionKey: ctx.sessionKey,\n source: ctx.source,\n isGroup: ctx.isGroup,\n config: ctx.config as SchemaConfig as ExtensionCommandContext['config'],\n reply: (text: string) => ctx.reply(text),\n };\n\n const result = await command.handler(args, extensionCtx);\n\n if (!result) {\n return { content: '', success: true };\n }\n return {\n content: result.content,\n success: result.success ?? true,\n };\n },\n };\n\n commandRegistry.register(definition);\n this._registeredCommandIds.push(commandId);\n this._registry.addCommand(command);\n\n this._eventBus.emit('command:register', command);\n this._logger.info(`Registered chat command: /${command.name}`);\n }\n\n /** Injected from manifest `ui.contributions.commands` by the loader. */\n _setManifestCommands(commands: CommandContribution[]): void {\n this._manifestCommands.clear();\n for (const c of commands) {\n this._manifestCommands.set(c.id, c);\n }\n }\n\n onCommand(commandId: string, handler: ExtensionCommandHandler): void {\n const meta = this._manifestCommands.get(commandId);\n if (!meta) {\n this._logger.warn(\n `onCommand: unknown command id \"${commandId}\" — registering runtime-only chat command`,\n );\n const name = commandId.includes('.')\n ? (commandId.split('.').pop() ?? commandId).trim()\n : commandId;\n this.registerCommand({\n name: name || commandId,\n description: commandId,\n handler,\n });\n return;\n }\n let name: string;\n if (meta.chatAlias?.trim()) {\n name = meta.chatAlias.trim().replace(/^\\//, '');\n } else {\n name = meta.id.includes('.') ? (meta.id.split('.').pop() ?? meta.id) : meta.id;\n }\n if (!name) {\n name = meta.id;\n }\n this.registerCommand({\n name,\n description: meta.title,\n handler,\n });\n this._logger.info(`Bound manifest command \"${commandId}\" as /${name}`);\n }\n\n registerReload(handler: ExtensionReloadHandler): void {\n const prefixes =\n this._reloadConfigPrefixes.length > 0\n ? this._reloadConfigPrefixes\n : [`extensions.${this.id}`];\n\n this._registry.addReloadRegistration({\n extensionId: this.id,\n handler,\n configPrefixes: prefixes,\n });\n this._logger.info('Registered reload handler');\n }\n\n /** Called from loader when manifest declares `reload.configPrefixes`. */\n _setReloadConfigPrefixes(prefixes: string[]): void {\n this._reloadConfigPrefixes = [...prefixes];\n }\n\n registerService(service: ExtensionService): void {\n this._eventBus.emit('service:register', service);\n this._logger.info(`Registered service: ${service.id}`);\n }\n\n registerGatewayMethod(method: string, handler: GatewayMethodHandler): void {\n this._eventBus.emit('gateway:method', { method, handler });\n this._logger.info(`Registered gateway method: ${method}`);\n }\n\n registerCli(\n factory: (ctx: { program: Command }) => void,\n opts?: { commands: string[] },\n ): void {\n const reg: ExtensionCliRegistration = {\n extensionId: this.id,\n commands: opts?.commands ?? [],\n factory,\n };\n this._registry.addCliRegistration(reg);\n this._eventBus.emit('cli:register', reg);\n this._logger.info(\n `Registered CLI factory${opts?.commands?.length ? ` (${opts.commands.join(', ')})` : ''}`,\n );\n }\n\n resolvePath(input: string): string {\n return this._resolvePath(input);\n }\n\n emit(event: string, data: unknown): void {\n this._eventBus.emit(event, data);\n }\n\n on(event: string, handler: (data: unknown) => void): void {\n this._eventBus.on(event, handler);\n }\n\n off(event: string, handler: (data: unknown) => void): void {\n this._eventBus.off(event, handler);\n }\n\n // Typed Event Bus\n get events(): TypedEventBus {\n return this._typedEventBus;\n }\n\n // Unified Registry Methods\n \n /**\n * Register a full ProviderPlugin\n */\n registerProvider(plugin: import('./types/providers.js').ProviderPlugin): void {\n import('../providers/plugin-registry.js').then(({ getProviderRegistry }) => {\n const registry = getProviderRegistry();\n registry.register(plugin);\n this._logger.info(`Extension registered provider: ${plugin.id}`);\n }).catch((err: unknown) => {\n this._logger.error(`Failed to register provider: ${err instanceof Error ? err.message : String(err)}`);\n });\n }\n\n /**\n * Register a full ProviderPlugin (alias for registerProvider)\n */\n registerProviderPlugin(plugin: import('./types/providers.js').ProviderPlugin): void {\n this.registerProvider(plugin);\n }\n\n registerFlag(_name: string, _config: FlagConfig): void {\n // this._registry.registerFlag(name, config, this.id);\n }\n\n getFlag(_name: string): FlagValue {\n return undefined; // this._registry.getFlag(name);\n }\n\n registerShortcut(_key: string, _config: ShortcutConfig): void {\n // this._registry.registerShortcut(key, config, { extensionId: this.id });\n }\n\n // Internal methods for extension manager\n _getTools(): Map<string, AgentTool> {\n return this._tools;\n }\n\n _getHooks(): Map<string, Set<Function>> {\n return this._hooks;\n }\n\n _getEventBus(): EventEmitter {\n return this._eventBus;\n }\n\n _cleanup(): void {\n for (const commandId of this._registeredCommandIds) {\n commandRegistry.unregister(commandId);\n }\n this._registeredCommandIds = [];\n this._manifestCommands.clear();\n\n this._registry.removeReloadRegistration(this.id);\n\n this._typedEventBus.cleanupAll();\n this._eventBus.removeAllListeners();\n this._hooks.clear();\n this._typedHooks.clear();\n }\n}\n\n// ============================================================================\n// Default Logger\n// ============================================================================\n\nexport function createExtensionLogger(prefix: string): ExtensionLogger {\n const childLogger = createLogger(`Extension:${prefix}`);\n\n return {\n debug: (msg: string) => childLogger.debug(msg),\n info: (msg: string) => childLogger.info(msg),\n warn: (msg: string) => childLogger.warn(msg),\n error: (msg: string) => childLogger.error(msg),\n };\n}\n\n// ============================================================================\n// Path Resolver\n// ============================================================================\n\nexport function createPathResolver(extensionDir: string, workspaceDir: string) {\n return (input: string): string => {\n if (input.startsWith('~')) {\n return input.replace('~', process.env.HOME || '');\n }\n if (input.startsWith('.')) {\n return resolve(extensionDir, input);\n }\n if (!isAbsolute(input)) {\n return resolve(workspaceDir, input);\n }\n return input;\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Light semver range check for `manifest.engines.xopc` without a `semver` dependency.
3
+ * Supports: ^, ~, >=, >, <=, <, =, exact, space-combined (AND). No ||, x-ranges, or pre-release.
4
+ */
5
+ export interface EngineCheckResult {
6
+ compatible: boolean;
7
+ reason?: string;
8
+ parseWarning?: boolean;
9
+ }
10
+ /**
11
+ * @param currentVersion — e.g. from `PACKAGE_VERSION`
12
+ * @param requiredRange — e.g. `">=1.0.0 <2.0.0"` or `"^0.0.1"`
13
+ */
14
+ export declare function checkEngineCompatibility(currentVersion: string, requiredRange: string): EngineCheckResult;
@@ -0,0 +1,148 @@
1
+ //#region src/extensions/engine-check.ts
2
+ function parseSemver(s) {
3
+ const m = s.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)$/);
4
+ if (!m) return null;
5
+ return {
6
+ major: +m[1],
7
+ minor: +m[2],
8
+ patch: +m[3]
9
+ };
10
+ }
11
+ function compareSemver(a, b) {
12
+ if (a.major !== b.major) return a.major < b.major ? -1 : 1;
13
+ if (a.minor !== b.minor) return a.minor < b.minor ? -1 : 1;
14
+ if (a.patch !== b.patch) return a.patch < b.patch ? -1 : 1;
15
+ return 0;
16
+ }
17
+ const gte = (a, b) => compareSemver(a, b) >= 0;
18
+ const gt = (a, b) => compareSemver(a, b) > 0;
19
+ const lt = (a, b) => compareSemver(a, b) < 0;
20
+ const lte = (a, b) => compareSemver(a, b) <= 0;
21
+ const eq = (a, b) => compareSemver(a, b) === 0;
22
+ function checkToken(current, token) {
23
+ const t = token.trim();
24
+ if (!t) return {
25
+ sat: true,
26
+ warn: false
27
+ };
28
+ if (t.startsWith("^")) {
29
+ const v = parseSemver(t.slice(1).trim());
30
+ if (!v) return {
31
+ sat: true,
32
+ warn: true
33
+ };
34
+ const upper = {
35
+ major: v.major + 1,
36
+ minor: 0,
37
+ patch: 0
38
+ };
39
+ return {
40
+ sat: gte(current, v) && lt(current, upper),
41
+ warn: false
42
+ };
43
+ }
44
+ if (t.startsWith("~")) {
45
+ const v = parseSemver(t.slice(1).trim());
46
+ if (!v) return {
47
+ sat: true,
48
+ warn: true
49
+ };
50
+ const upper = {
51
+ major: v.major,
52
+ minor: v.minor + 1,
53
+ patch: 0
54
+ };
55
+ return {
56
+ sat: gte(current, v) && lt(current, upper),
57
+ warn: false
58
+ };
59
+ }
60
+ const comp = t.match(/^(>=|<=|>|=|<)\s*(.+)$/);
61
+ if (comp) {
62
+ const op = comp[1];
63
+ const v = parseSemver(String(comp[2] ?? "").trim());
64
+ if (!v) return {
65
+ sat: true,
66
+ warn: true
67
+ };
68
+ switch (op) {
69
+ case ">=": return {
70
+ sat: gte(current, v),
71
+ warn: false
72
+ };
73
+ case "<=": return {
74
+ sat: lte(current, v),
75
+ warn: false
76
+ };
77
+ case ">": return {
78
+ sat: gt(current, v),
79
+ warn: false
80
+ };
81
+ case "<": return {
82
+ sat: lt(current, v),
83
+ warn: false
84
+ };
85
+ case "=": return {
86
+ sat: eq(current, v),
87
+ warn: false
88
+ };
89
+ default: return {
90
+ sat: true,
91
+ warn: true
92
+ };
93
+ }
94
+ }
95
+ const exact = parseSemver(t);
96
+ if (exact) return {
97
+ sat: eq(current, exact),
98
+ warn: false
99
+ };
100
+ return {
101
+ sat: true,
102
+ warn: true
103
+ };
104
+ }
105
+ /**
106
+ * @param currentVersion — e.g. from `PACKAGE_VERSION`
107
+ * @param requiredRange — e.g. `">=1.0.0 <2.0.0"` or `"^0.0.1"`
108
+ */
109
+ function checkEngineCompatibility(currentVersion, requiredRange) {
110
+ const current = parseSemver(currentVersion.trim());
111
+ if (!current) return {
112
+ compatible: true,
113
+ parseWarning: true,
114
+ reason: `Current xopc version could not be parsed: ${currentVersion}`
115
+ };
116
+ const range = requiredRange.trim();
117
+ if (!range) return {
118
+ compatible: true,
119
+ parseWarning: true
120
+ };
121
+ const parts = range.split(/\s+/).filter(Boolean);
122
+ if (parts.length === 0) return {
123
+ compatible: true,
124
+ parseWarning: true
125
+ };
126
+ let anyWarn = false;
127
+ for (const p of parts) {
128
+ const { sat, warn } = checkToken(current, p);
129
+ if (warn) {
130
+ anyWarn = true;
131
+ continue;
132
+ }
133
+ if (!sat) return {
134
+ compatible: false,
135
+ reason: `xopc version ${currentVersion} does not satisfy engines.xopc: "${requiredRange}"`
136
+ };
137
+ }
138
+ if (anyWarn) return {
139
+ compatible: true,
140
+ parseWarning: true,
141
+ reason: `Could not fully parse engines.xopc range: "${requiredRange}"`
142
+ };
143
+ return { compatible: true };
144
+ }
145
+ //#endregion
146
+ export { checkEngineCompatibility };
147
+
148
+ //# sourceMappingURL=engine-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-check.js","names":[],"sources":["../../../src/extensions/engine-check.ts"],"sourcesContent":["/**\n * Light semver range check for `manifest.engines.xopc` without a `semver` dependency.\n * Supports: ^, ~, >=, >, <=, <, =, exact, space-combined (AND). No ||, x-ranges, or pre-release.\n */\n\nexport interface EngineCheckResult {\n compatible: boolean;\n reason?: string;\n parseWarning?: boolean;\n}\n\ninterface SemVer {\n major: number;\n minor: number;\n patch: number;\n}\n\nfunction parseSemver(s: string): SemVer | null {\n const t = s.trim().replace(/^v/i, '');\n const m = t.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!m) return null;\n return { major: +m[1]!, minor: +m[2]!, patch: +m[3]! };\n}\n\nfunction compareSemver(a: SemVer, b: SemVer): number {\n if (a.major !== b.major) return a.major < b.major ? -1 : 1;\n if (a.minor !== b.minor) return a.minor < b.minor ? -1 : 1;\n if (a.patch !== b.patch) return a.patch < b.patch ? -1 : 1;\n return 0;\n}\n\nconst gte = (a: SemVer, b: SemVer) => compareSemver(a, b) >= 0;\nconst gt = (a: SemVer, b: SemVer) => compareSemver(a, b) > 0;\nconst lt = (a: SemVer, b: SemVer) => compareSemver(a, b) < 0;\nconst lte = (a: SemVer, b: SemVer) => compareSemver(a, b) <= 0;\nconst eq = (a: SemVer, b: SemVer) => compareSemver(a, b) === 0;\n\nfunction checkToken(current: SemVer, token: string): { sat: boolean; warn: boolean } {\n const t = token.trim();\n if (!t) return { sat: true, warn: false };\n\n if (t.startsWith('^')) {\n const v = parseSemver(t.slice(1).trim());\n if (!v) return { sat: true, warn: true };\n const upper: SemVer = { major: v.major + 1, minor: 0, patch: 0 };\n return { sat: gte(current, v) && lt(current, upper), warn: false };\n }\n\n if (t.startsWith('~')) {\n const v = parseSemver(t.slice(1).trim());\n if (!v) return { sat: true, warn: true };\n const upper: SemVer = { major: v.major, minor: v.minor + 1, patch: 0 };\n return { sat: gte(current, v) && lt(current, upper), warn: false };\n }\n\n const comp = t.match(/^(>=|<=|>|=|<)\\s*(.+)$/);\n if (comp) {\n const op = comp[1]!;\n const v = parseSemver(String(comp[2] ?? '').trim());\n if (!v) return { sat: true, warn: true };\n switch (op) {\n case '>=':\n return { sat: gte(current, v), warn: false };\n case '<=':\n return { sat: lte(current, v), warn: false };\n case '>':\n return { sat: gt(current, v), warn: false };\n case '<':\n return { sat: lt(current, v), warn: false };\n case '=':\n return { sat: eq(current, v), warn: false };\n default:\n return { sat: true, warn: true };\n }\n }\n\n const exact = parseSemver(t);\n if (exact) {\n return { sat: eq(current, exact), warn: false };\n }\n\n return { sat: true, warn: true };\n}\n\n/**\n * @param currentVersion — e.g. from `PACKAGE_VERSION`\n * @param requiredRange — e.g. `\">=1.0.0 <2.0.0\"` or `\"^0.0.1\"`\n */\nexport function checkEngineCompatibility(\n currentVersion: string,\n requiredRange: string,\n): EngineCheckResult {\n const current = parseSemver(currentVersion.trim());\n if (!current) {\n return {\n compatible: true,\n parseWarning: true,\n reason: `Current xopc version could not be parsed: ${currentVersion}`,\n };\n }\n\n const range = requiredRange.trim();\n if (!range) {\n return { compatible: true, parseWarning: true };\n }\n\n const parts = range.split(/\\s+/).filter(Boolean);\n if (parts.length === 0) {\n return { compatible: true, parseWarning: true };\n }\n\n let anyWarn = false;\n for (const p of parts) {\n const { sat, warn } = checkToken(current, p);\n if (warn) {\n anyWarn = true;\n continue;\n }\n if (!sat) {\n return {\n compatible: false,\n reason: `xopc version ${currentVersion} does not satisfy engines.xopc: \"${requiredRange}\"`,\n };\n }\n }\n\n if (anyWarn) {\n return {\n compatible: true,\n parseWarning: true,\n reason: `Could not fully parse engines.xopc range: \"${requiredRange}\"`,\n };\n }\n\n return { compatible: true };\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
1
2
  import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
2
3
  import { createLogger, createServiceLogger } from "../utils/logger/index.js";
3
4
  import { init_logger } from "../utils/logger.js";
@@ -8,6 +9,7 @@ import { ActivationPlanner } from "./activation-planner.js";
8
9
  import { mergeActivationContext } from "./activation-context.js";
9
10
  import { ManifestRegistry } from "./manifest-registry.js";
10
11
  import { normalizeExtensionManifest } from "./normalize-manifest.js";
12
+ import { checkEngineCompatibility } from "./engine-check.js";
11
13
  import { bundledChannelPlugins } from "../generated/bundled-channel-plugins.js";
12
14
  import "../channels/plugins/bundled.js";
13
15
  import { DEFAULT_SECURITY_CONFIG, checkExtensionPathSafety, isExtensionAllowed, logSecurityIssue, provenanceTracker } from "./security.js";
@@ -31,6 +33,7 @@ import { createJiti } from "jiti";
31
33
  init_agent_scope();
32
34
  init_loader();
33
35
  init_paths();
36
+ init_package_version();
34
37
  init_logger();
35
38
  init_plugin_registry();
36
39
  const EXTENSION_MANIFEST_FILE = "xopc.extension.json";
@@ -445,6 +448,24 @@ var ExtensionLoader = class {
445
448
  this.diagnostics.error(config.id, `Failed to load manifest`);
446
449
  return null;
447
450
  }
451
+ if (manifest.engines?.xopc) {
452
+ const range = manifest.engines.xopc;
453
+ const engineResult = checkEngineCompatibility(PACKAGE_VERSION, range);
454
+ if (engineResult.parseWarning) log.warn({
455
+ extensionId: config.id,
456
+ range,
457
+ reason: engineResult.reason
458
+ }, "Engine range parse warning — loading anyway");
459
+ else if (!engineResult.compatible) {
460
+ log.warn({
461
+ extensionId: config.id,
462
+ range,
463
+ currentVersion: PACKAGE_VERSION
464
+ }, "Extension engine requirement not met (engines.xopc) — skipping load");
465
+ this.diagnostics.error(config.id, engineResult.reason ?? "Incompatible xopc version (engines.xopc)");
466
+ return null;
467
+ }
468
+ }
448
469
  if (manifest.configSchema) try {
449
470
  const schema = manifest.configSchema;
450
471
  const extensionConfig = config.config;
@@ -633,6 +654,8 @@ var ExtensionLoader = class {
633
654
  } : void 0;
634
655
  const api = new ExtensionApiImpl(manifest.id, manifest.name, manifest.version, extensionDir, appConfig, extensionOnly, logger, resolvePath, this.registry, runtime);
635
656
  if (manifest.reload?.configPrefixes?.length) api._setReloadConfigPrefixes(manifest.reload.configPrefixes);
657
+ const manifestCommands = manifest.ui?.contributions?.commands;
658
+ if (manifestCommands?.length) api._setManifestCommands(manifestCommands);
636
659
  return api;
637
660
  }
638
661
  async initializeExtension(module, api, _manifest) {