@vetta-org/plugin-sdk 0.0.4 → 0.1.1

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 (59) hide show
  1. package/dist/agent.d.ts +5 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js.map +1 -1
  4. package/dist/command.d.ts +43 -0
  5. package/dist/command.d.ts.map +1 -1
  6. package/dist/command.js.map +1 -1
  7. package/dist/context.d.ts +6 -2
  8. package/dist/context.d.ts.map +1 -1
  9. package/dist/context.js.map +1 -1
  10. package/dist/conversation.d.ts +8 -1
  11. package/dist/conversation.d.ts.map +1 -1
  12. package/dist/conversation.js.map +1 -1
  13. package/dist/file-explorer.d.ts +87 -0
  14. package/dist/file-explorer.d.ts.map +1 -0
  15. package/dist/file-explorer.js +2 -0
  16. package/dist/file-explorer.js.map +1 -0
  17. package/dist/fs.d.ts +25 -0
  18. package/dist/fs.d.ts.map +1 -1
  19. package/dist/fs.js.map +1 -1
  20. package/dist/hooks.d.ts +4 -6
  21. package/dist/hooks.d.ts.map +1 -1
  22. package/dist/hooks.js +4 -6
  23. package/dist/hooks.js.map +1 -1
  24. package/dist/host-bridge.d.ts +2 -2
  25. package/dist/host-bridge.d.ts.map +1 -1
  26. package/dist/host-bridge.js.map +1 -1
  27. package/dist/images.d.ts +0 -41
  28. package/dist/images.d.ts.map +1 -1
  29. package/dist/images.js.map +1 -1
  30. package/dist/index.d.ts +11 -5
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/network.d.ts +38 -0
  35. package/dist/network.d.ts.map +1 -0
  36. package/dist/network.js +2 -0
  37. package/dist/network.js.map +1 -0
  38. package/dist/official.d.ts +0 -1
  39. package/dist/official.d.ts.map +1 -1
  40. package/dist/official.js.map +1 -1
  41. package/dist/permissions.d.ts +1 -1
  42. package/dist/permissions.d.ts.map +1 -1
  43. package/dist/permissions.js.map +1 -1
  44. package/dist/prompt-attachment.d.ts +15 -0
  45. package/dist/prompt-attachment.d.ts.map +1 -0
  46. package/dist/prompt-attachment.js +2 -0
  47. package/dist/prompt-attachment.js.map +1 -0
  48. package/dist/shortcuts.d.ts +60 -0
  49. package/dist/shortcuts.d.ts.map +1 -0
  50. package/dist/shortcuts.js +34 -0
  51. package/dist/shortcuts.js.map +1 -0
  52. package/dist/storage.d.ts +31 -0
  53. package/dist/storage.d.ts.map +1 -0
  54. package/dist/storage.js +2 -0
  55. package/dist/storage.js.map +1 -0
  56. package/dist/ui.d.ts +64 -9
  57. package/dist/ui.d.ts.map +1 -1
  58. package/dist/ui.js.map +1 -1
  59. package/package.json +1 -1
package/dist/agent.d.ts CHANGED
@@ -10,6 +10,11 @@ export interface PluginAgentToolApi {
10
10
  export interface PluginAgentToolRegistration<TInput = unknown> {
11
11
  id: string;
12
12
  name?: string;
13
+ /**
14
+ * Host UI display name for this tool (e.g. Work-mode tool headers).
15
+ * Supports `%catalogKey%` resolved against the plugin's locales; bare strings
16
+ * are used as literals. Not sent to the model — use {@link description} for that.
17
+ */
13
18
  label?: string;
14
19
  description: string;
15
20
  parameters: PluginJsonSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { ConversationScenario } from \"./scenario.js\";\n\nexport type PluginJsonSchema = object;\n\nexport interface PluginAgentToolApi {\n\tfs: PluginFsApi;\n\tconversation: PluginConversationApi;\n}\n\nexport interface PluginAgentToolRegistration<TInput = unknown> {\n\tid: string;\n\tname?: string;\n\tlabel?: string;\n\tdescription: string;\n\tparameters: PluginJsonSchema;\n\ttimeoutMs?: number;\n\t/**\n\t * 允许该工具出现的对话场景 slug 列表。**fail-closed**:未声明/空数组 = 所有场景都不激活。\n\t * 插件须显式声明。\n\t */\n\tscope_use?: readonly ConversationScenario[];\n\t/** 需要的会话能力 slug(如 \"knowledge\");全满足才激活。一般插件无需设置。 */\n\trequires?: string[];\n\t/** 允许该工具出现的工作模式 slug(agent_mode 轴,如 \"work\"/\"coding\")。缺省/空 = 通用。见 ADR-0046。 */\n\tagent_mode?: readonly string[];\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginAgentToolHandler<TInput>;\n}\n\nexport interface PluginSystemPromptBlock {\n\tid: string;\n\tcontent: string;\n\tpriority?: number;\n\tenabled?: boolean;\n}\n\nexport type PluginDynamicSystemPromptOperation =\n\t| { type: \"addBlock\"; block: PluginSystemPromptBlock }\n\t| { type: \"replaceBlock\"; blockId: string; block: Omit<PluginSystemPromptBlock, \"id\"> }\n\t| {\n\t\t\ttype: \"updateBlock\";\n\t\t\tblockId: string;\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>;\n\t }\n\t| { type: \"removeBlock\"; blockId: string }\n\t| { type: \"setBlockEnabled\"; blockId: string; enabled: boolean }\n\t| { type: \"setToolEnabled\"; toolName: string; enabled: boolean }\n\t| { type: \"requestContinuation\"; result: PluginContinuationResult };\n\nexport interface PluginSystemPromptMessage {\n\trole: string;\n\ttext: string;\n\ttimestamp?: number;\n\ttoolName?: string;\n}\n\nexport interface PluginSystemPromptProviderContext {\n\tplugin: {\n\t\tid: string;\n\t\tproviderId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: {\n\t\tid: string;\n\t\tcwd: string;\n\t\tscenario: ConversationScenario;\n\t};\n\tmodel: {\n\t\tprovider: string;\n\t\tid: string;\n\t\tapi: string;\n\t\tinput: readonly string[];\n\t\tcontextWindow?: number;\n\t\tmaxTokens?: number;\n\t};\n\tconversation: {\n\t\tmessages: readonly PluginSystemPromptMessage[];\n\t\tmessageCount: number;\n\t};\n\truntime: {\n\t\tactiveToolNames: readonly string[];\n\t\tavailableToolNames: readonly string[];\n\t\trunIndex: number;\n\t};\n\ttrigger: {\n\t\tkind: \"agent-run\";\n\t\ttimestamp: number;\n\t};\n\tsystemPrompt?: {\n\t\tbase: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t\tcurrent: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t};\n}\n\nexport interface PluginSystemPromptBlockView extends PluginSystemPromptBlock {\n\ttype: string;\n\tsource: {\n\t\tkind: \"core\" | \"plugin\";\n\t\tpluginId?: string;\n\t};\n\tpriority: number;\n\tenabled: boolean;\n}\n\nexport interface PluginAgentActions {\n\tsystemPrompt: {\n\t\taddBlock(block: PluginSystemPromptBlock): void;\n\t\treplaceBlock(blockId: string, block: Omit<PluginSystemPromptBlock, \"id\">): void;\n\t\tupdateBlock(\n\t\t\tblockId: string,\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>,\n\t\t): void;\n\t\tremoveBlock(blockId: string): void;\n\t\tsetBlockEnabled(blockId: string, enabled: boolean): void;\n\t};\n\ttools: {\n\t\tsetEnabled(toolName: string, enabled: boolean): void;\n\t\tenable(toolName: string): void;\n\t\tdisable(toolName: string): void;\n\t};\n\tcontinuation: {\n\t\trequest(result: PluginContinuationResult): void;\n\t};\n}\n\nexport interface PluginAgentHandlerContext<TTrigger> {\n\tinvocationId: string;\n\tplugin: {\n\t\tid: string;\n\t\tcontributionId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: PluginSystemPromptProviderContext[\"session\"];\n\tmodel: PluginSystemPromptProviderContext[\"model\"];\n\tconversation: PluginSystemPromptProviderContext[\"conversation\"];\n\truntime: PluginSystemPromptProviderContext[\"runtime\"];\n\ttrigger: TTrigger;\n\tsystemPrompt?: PluginSystemPromptProviderContext[\"systemPrompt\"];\n\tactions: PluginAgentActions;\n\thost: PluginAgentToolApi;\n}\n\nexport type PluginAgentToolHandler<TInput = unknown> = (\n\tcontext: PluginAgentHandlerContext<{\n\t\tkind: \"tool-call\";\n\t\ttimestamp: number;\n\t\ttoolCallId: string;\n\t\ttoolId: string;\n\t\ttoolName: string;\n\t\tinput: TInput;\n\t}>,\n) => unknown | Promise<unknown>;\n\nexport type PluginSystemPromptProviderHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"agent-run\"; timestamp: number }>,\n) => void | PluginDynamicSystemPromptOperation[] | Promise<void | PluginDynamicSystemPromptOperation[]>;\n\nexport interface PluginSystemPromptProviderRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\t/**\n\t * Large context is opt-in. Omitted fields are not serialized across the\n\t * host/renderer boundary.\n\t */\n\tcontext?: {\n\t\tsystemPrompt?: \"none\" | \"blocks\" | \"rendered\" | \"full\";\n\t\tconversation?: \"summary\" | \"messages\";\n\t};\n\thandler: PluginSystemPromptProviderHandler;\n}\n\nexport interface PluginContinuationResult {\n\ttext: string;\n\t/** Stable key used by the host to suppress duplicate continuations in a session. */\n\tidempotencyKey?: string;\n}\n\nexport type PluginContinuationHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"continuation\"; timestamp: number }>,\n) => PluginContinuationResult | null | Promise<PluginContinuationResult | null>;\n\nexport interface PluginContinuationRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginContinuationHandler;\n}\n\nexport interface PluginAgentApi {\n\tregisterTool<TInput = unknown>(registration: PluginAgentToolRegistration<TInput>): Disposable;\n\t/** Register a provider evaluated before every Agent run. */\n\tregisterSystemPromptProvider(registration: PluginSystemPromptProviderRegistration): Disposable;\n\t/**\n\t * Register a policy consulted when the agent reaches a natural stopping point.\n\t * Return null to allow the agent to stop, or a message to continue with another turn.\n\t */\n\tregisterContinuationProvider(registration: PluginContinuationRegistration): Disposable;\n}\n"]}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { ConversationScenario } from \"./scenario.js\";\n\nexport type PluginJsonSchema = object;\n\nexport interface PluginAgentToolApi {\n\tfs: PluginFsApi;\n\tconversation: PluginConversationApi;\n}\n\nexport interface PluginAgentToolRegistration<TInput = unknown> {\n\tid: string;\n\tname?: string;\n\t/**\n\t * Host UI display name for this tool (e.g. Work-mode tool headers).\n\t * Supports `%catalogKey%` resolved against the plugin's locales; bare strings\n\t * are used as literals. Not sent to the model — use {@link description} for that.\n\t */\n\tlabel?: string;\n\tdescription: string;\n\tparameters: PluginJsonSchema;\n\ttimeoutMs?: number;\n\t/**\n\t * 允许该工具出现的对话场景 slug 列表。**fail-closed**:未声明/空数组 = 所有场景都不激活。\n\t * 插件须显式声明。\n\t */\n\tscope_use?: readonly ConversationScenario[];\n\t/** 需要的会话能力 slug(如 \"knowledge\");全满足才激活。一般插件无需设置。 */\n\trequires?: string[];\n\t/** 允许该工具出现的工作模式 slug(agent_mode 轴,如 \"work\"/\"coding\")。缺省/空 = 通用。见 ADR-0046。 */\n\tagent_mode?: readonly string[];\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginAgentToolHandler<TInput>;\n}\n\nexport interface PluginSystemPromptBlock {\n\tid: string;\n\tcontent: string;\n\tpriority?: number;\n\tenabled?: boolean;\n}\n\nexport type PluginDynamicSystemPromptOperation =\n\t| { type: \"addBlock\"; block: PluginSystemPromptBlock }\n\t| { type: \"replaceBlock\"; blockId: string; block: Omit<PluginSystemPromptBlock, \"id\"> }\n\t| {\n\t\t\ttype: \"updateBlock\";\n\t\t\tblockId: string;\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>;\n\t }\n\t| { type: \"removeBlock\"; blockId: string }\n\t| { type: \"setBlockEnabled\"; blockId: string; enabled: boolean }\n\t| { type: \"setToolEnabled\"; toolName: string; enabled: boolean }\n\t| { type: \"requestContinuation\"; result: PluginContinuationResult };\n\nexport interface PluginSystemPromptMessage {\n\trole: string;\n\ttext: string;\n\ttimestamp?: number;\n\ttoolName?: string;\n}\n\nexport interface PluginSystemPromptProviderContext {\n\tplugin: {\n\t\tid: string;\n\t\tproviderId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: {\n\t\tid: string;\n\t\tcwd: string;\n\t\tscenario: ConversationScenario;\n\t};\n\tmodel: {\n\t\tprovider: string;\n\t\tid: string;\n\t\tapi: string;\n\t\tinput: readonly string[];\n\t\tcontextWindow?: number;\n\t\tmaxTokens?: number;\n\t};\n\tconversation: {\n\t\tmessages: readonly PluginSystemPromptMessage[];\n\t\tmessageCount: number;\n\t};\n\truntime: {\n\t\tactiveToolNames: readonly string[];\n\t\tavailableToolNames: readonly string[];\n\t\trunIndex: number;\n\t};\n\ttrigger: {\n\t\tkind: \"agent-run\";\n\t\ttimestamp: number;\n\t};\n\tsystemPrompt?: {\n\t\tbase: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t\tcurrent: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t};\n}\n\nexport interface PluginSystemPromptBlockView extends PluginSystemPromptBlock {\n\ttype: string;\n\tsource: {\n\t\tkind: \"core\" | \"plugin\";\n\t\tpluginId?: string;\n\t};\n\tpriority: number;\n\tenabled: boolean;\n}\n\nexport interface PluginAgentActions {\n\tsystemPrompt: {\n\t\taddBlock(block: PluginSystemPromptBlock): void;\n\t\treplaceBlock(blockId: string, block: Omit<PluginSystemPromptBlock, \"id\">): void;\n\t\tupdateBlock(\n\t\t\tblockId: string,\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>,\n\t\t): void;\n\t\tremoveBlock(blockId: string): void;\n\t\tsetBlockEnabled(blockId: string, enabled: boolean): void;\n\t};\n\ttools: {\n\t\tsetEnabled(toolName: string, enabled: boolean): void;\n\t\tenable(toolName: string): void;\n\t\tdisable(toolName: string): void;\n\t};\n\tcontinuation: {\n\t\trequest(result: PluginContinuationResult): void;\n\t};\n}\n\nexport interface PluginAgentHandlerContext<TTrigger> {\n\tinvocationId: string;\n\tplugin: {\n\t\tid: string;\n\t\tcontributionId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: PluginSystemPromptProviderContext[\"session\"];\n\tmodel: PluginSystemPromptProviderContext[\"model\"];\n\tconversation: PluginSystemPromptProviderContext[\"conversation\"];\n\truntime: PluginSystemPromptProviderContext[\"runtime\"];\n\ttrigger: TTrigger;\n\tsystemPrompt?: PluginSystemPromptProviderContext[\"systemPrompt\"];\n\tactions: PluginAgentActions;\n\thost: PluginAgentToolApi;\n}\n\nexport type PluginAgentToolHandler<TInput = unknown> = (\n\tcontext: PluginAgentHandlerContext<{\n\t\tkind: \"tool-call\";\n\t\ttimestamp: number;\n\t\ttoolCallId: string;\n\t\ttoolId: string;\n\t\ttoolName: string;\n\t\tinput: TInput;\n\t}>,\n) => unknown | Promise<unknown>;\n\nexport type PluginSystemPromptProviderHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"agent-run\"; timestamp: number }>,\n) => void | PluginDynamicSystemPromptOperation[] | Promise<void | PluginDynamicSystemPromptOperation[]>;\n\nexport interface PluginSystemPromptProviderRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\t/**\n\t * Large context is opt-in. Omitted fields are not serialized across the\n\t * host/renderer boundary.\n\t */\n\tcontext?: {\n\t\tsystemPrompt?: \"none\" | \"blocks\" | \"rendered\" | \"full\";\n\t\tconversation?: \"summary\" | \"messages\";\n\t};\n\thandler: PluginSystemPromptProviderHandler;\n}\n\nexport interface PluginContinuationResult {\n\ttext: string;\n\t/** Stable key used by the host to suppress duplicate continuations in a session. */\n\tidempotencyKey?: string;\n}\n\nexport type PluginContinuationHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"continuation\"; timestamp: number }>,\n) => PluginContinuationResult | null | Promise<PluginContinuationResult | null>;\n\nexport interface PluginContinuationRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginContinuationHandler;\n}\n\nexport interface PluginAgentApi {\n\tregisterTool<TInput = unknown>(registration: PluginAgentToolRegistration<TInput>): Disposable;\n\t/** Register a provider evaluated before every Agent run. */\n\tregisterSystemPromptProvider(registration: PluginSystemPromptProviderRegistration): Disposable;\n\t/**\n\t * Register a policy consulted when the agent reaches a natural stopping point.\n\t * Return null to allow the agent to stop, or a message to continue with another turn.\n\t */\n\tregisterContinuationProvider(registration: PluginContinuationRegistration): Disposable;\n}\n"]}
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { ConversationScenario } from \"./scenario.js\";\n\nexport type PluginJsonSchema = object;\n\nexport interface PluginAgentToolApi {\n\tfs: PluginFsApi;\n\tconversation: PluginConversationApi;\n}\n\nexport interface PluginAgentToolRegistration<TInput = unknown> {\n\tid: string;\n\tname?: string;\n\tlabel?: string;\n\tdescription: string;\n\tparameters: PluginJsonSchema;\n\ttimeoutMs?: number;\n\t/**\n\t * 允许该工具出现的对话场景 slug 列表。**fail-closed**:未声明/空数组 = 所有场景都不激活。\n\t * 插件须显式声明。\n\t */\n\tscope_use?: readonly ConversationScenario[];\n\t/** 需要的会话能力 slug(如 \"knowledge\");全满足才激活。一般插件无需设置。 */\n\trequires?: string[];\n\t/** 允许该工具出现的工作模式 slug(agent_mode 轴,如 \"work\"/\"coding\")。缺省/空 = 通用。见 ADR-0046。 */\n\tagent_mode?: readonly string[];\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginAgentToolHandler<TInput>;\n}\n\nexport interface PluginSystemPromptBlock {\n\tid: string;\n\tcontent: string;\n\tpriority?: number;\n\tenabled?: boolean;\n}\n\nexport type PluginDynamicSystemPromptOperation =\n\t| { type: \"addBlock\"; block: PluginSystemPromptBlock }\n\t| { type: \"replaceBlock\"; blockId: string; block: Omit<PluginSystemPromptBlock, \"id\"> }\n\t| {\n\t\t\ttype: \"updateBlock\";\n\t\t\tblockId: string;\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>;\n\t }\n\t| { type: \"removeBlock\"; blockId: string }\n\t| { type: \"setBlockEnabled\"; blockId: string; enabled: boolean }\n\t| { type: \"setToolEnabled\"; toolName: string; enabled: boolean }\n\t| { type: \"requestContinuation\"; result: PluginContinuationResult };\n\nexport interface PluginSystemPromptMessage {\n\trole: string;\n\ttext: string;\n\ttimestamp?: number;\n\ttoolName?: string;\n}\n\nexport interface PluginSystemPromptProviderContext {\n\tplugin: {\n\t\tid: string;\n\t\tproviderId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: {\n\t\tid: string;\n\t\tcwd: string;\n\t\tscenario: ConversationScenario;\n\t};\n\tmodel: {\n\t\tprovider: string;\n\t\tid: string;\n\t\tapi: string;\n\t\tinput: readonly string[];\n\t\tcontextWindow?: number;\n\t\tmaxTokens?: number;\n\t};\n\tconversation: {\n\t\tmessages: readonly PluginSystemPromptMessage[];\n\t\tmessageCount: number;\n\t};\n\truntime: {\n\t\tactiveToolNames: readonly string[];\n\t\tavailableToolNames: readonly string[];\n\t\trunIndex: number;\n\t};\n\ttrigger: {\n\t\tkind: \"agent-run\";\n\t\ttimestamp: number;\n\t};\n\tsystemPrompt?: {\n\t\tbase: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t\tcurrent: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t};\n}\n\nexport interface PluginSystemPromptBlockView extends PluginSystemPromptBlock {\n\ttype: string;\n\tsource: {\n\t\tkind: \"core\" | \"plugin\";\n\t\tpluginId?: string;\n\t};\n\tpriority: number;\n\tenabled: boolean;\n}\n\nexport interface PluginAgentActions {\n\tsystemPrompt: {\n\t\taddBlock(block: PluginSystemPromptBlock): void;\n\t\treplaceBlock(blockId: string, block: Omit<PluginSystemPromptBlock, \"id\">): void;\n\t\tupdateBlock(\n\t\t\tblockId: string,\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>,\n\t\t): void;\n\t\tremoveBlock(blockId: string): void;\n\t\tsetBlockEnabled(blockId: string, enabled: boolean): void;\n\t};\n\ttools: {\n\t\tsetEnabled(toolName: string, enabled: boolean): void;\n\t\tenable(toolName: string): void;\n\t\tdisable(toolName: string): void;\n\t};\n\tcontinuation: {\n\t\trequest(result: PluginContinuationResult): void;\n\t};\n}\n\nexport interface PluginAgentHandlerContext<TTrigger> {\n\tinvocationId: string;\n\tplugin: {\n\t\tid: string;\n\t\tcontributionId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: PluginSystemPromptProviderContext[\"session\"];\n\tmodel: PluginSystemPromptProviderContext[\"model\"];\n\tconversation: PluginSystemPromptProviderContext[\"conversation\"];\n\truntime: PluginSystemPromptProviderContext[\"runtime\"];\n\ttrigger: TTrigger;\n\tsystemPrompt?: PluginSystemPromptProviderContext[\"systemPrompt\"];\n\tactions: PluginAgentActions;\n\thost: PluginAgentToolApi;\n}\n\nexport type PluginAgentToolHandler<TInput = unknown> = (\n\tcontext: PluginAgentHandlerContext<{\n\t\tkind: \"tool-call\";\n\t\ttimestamp: number;\n\t\ttoolCallId: string;\n\t\ttoolId: string;\n\t\ttoolName: string;\n\t\tinput: TInput;\n\t}>,\n) => unknown | Promise<unknown>;\n\nexport type PluginSystemPromptProviderHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"agent-run\"; timestamp: number }>,\n) => void | PluginDynamicSystemPromptOperation[] | Promise<void | PluginDynamicSystemPromptOperation[]>;\n\nexport interface PluginSystemPromptProviderRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\t/**\n\t * Large context is opt-in. Omitted fields are not serialized across the\n\t * host/renderer boundary.\n\t */\n\tcontext?: {\n\t\tsystemPrompt?: \"none\" | \"blocks\" | \"rendered\" | \"full\";\n\t\tconversation?: \"summary\" | \"messages\";\n\t};\n\thandler: PluginSystemPromptProviderHandler;\n}\n\nexport interface PluginContinuationResult {\n\ttext: string;\n\t/** Stable key used by the host to suppress duplicate continuations in a session. */\n\tidempotencyKey?: string;\n}\n\nexport type PluginContinuationHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"continuation\"; timestamp: number }>,\n) => PluginContinuationResult | null | Promise<PluginContinuationResult | null>;\n\nexport interface PluginContinuationRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginContinuationHandler;\n}\n\nexport interface PluginAgentApi {\n\tregisterTool<TInput = unknown>(registration: PluginAgentToolRegistration<TInput>): Disposable;\n\t/** Register a provider evaluated before every Agent run. */\n\tregisterSystemPromptProvider(registration: PluginSystemPromptProviderRegistration): Disposable;\n\t/**\n\t * Register a policy consulted when the agent reaches a natural stopping point.\n\t * Return null to allow the agent to stop, or a message to continue with another turn.\n\t */\n\tregisterContinuationProvider(registration: PluginContinuationRegistration): Disposable;\n}\n"]}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { ConversationScenario } from \"./scenario.js\";\n\nexport type PluginJsonSchema = object;\n\nexport interface PluginAgentToolApi {\n\tfs: PluginFsApi;\n\tconversation: PluginConversationApi;\n}\n\nexport interface PluginAgentToolRegistration<TInput = unknown> {\n\tid: string;\n\tname?: string;\n\t/**\n\t * Host UI display name for this tool (e.g. Work-mode tool headers).\n\t * Supports `%catalogKey%` resolved against the plugin's locales; bare strings\n\t * are used as literals. Not sent to the model — use {@link description} for that.\n\t */\n\tlabel?: string;\n\tdescription: string;\n\tparameters: PluginJsonSchema;\n\ttimeoutMs?: number;\n\t/**\n\t * 允许该工具出现的对话场景 slug 列表。**fail-closed**:未声明/空数组 = 所有场景都不激活。\n\t * 插件须显式声明。\n\t */\n\tscope_use?: readonly ConversationScenario[];\n\t/** 需要的会话能力 slug(如 \"knowledge\");全满足才激活。一般插件无需设置。 */\n\trequires?: string[];\n\t/** 允许该工具出现的工作模式 slug(agent_mode 轴,如 \"work\"/\"coding\")。缺省/空 = 通用。见 ADR-0046。 */\n\tagent_mode?: readonly string[];\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginAgentToolHandler<TInput>;\n}\n\nexport interface PluginSystemPromptBlock {\n\tid: string;\n\tcontent: string;\n\tpriority?: number;\n\tenabled?: boolean;\n}\n\nexport type PluginDynamicSystemPromptOperation =\n\t| { type: \"addBlock\"; block: PluginSystemPromptBlock }\n\t| { type: \"replaceBlock\"; blockId: string; block: Omit<PluginSystemPromptBlock, \"id\"> }\n\t| {\n\t\t\ttype: \"updateBlock\";\n\t\t\tblockId: string;\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>;\n\t }\n\t| { type: \"removeBlock\"; blockId: string }\n\t| { type: \"setBlockEnabled\"; blockId: string; enabled: boolean }\n\t| { type: \"setToolEnabled\"; toolName: string; enabled: boolean }\n\t| { type: \"requestContinuation\"; result: PluginContinuationResult };\n\nexport interface PluginSystemPromptMessage {\n\trole: string;\n\ttext: string;\n\ttimestamp?: number;\n\ttoolName?: string;\n}\n\nexport interface PluginSystemPromptProviderContext {\n\tplugin: {\n\t\tid: string;\n\t\tproviderId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: {\n\t\tid: string;\n\t\tcwd: string;\n\t\tscenario: ConversationScenario;\n\t};\n\tmodel: {\n\t\tprovider: string;\n\t\tid: string;\n\t\tapi: string;\n\t\tinput: readonly string[];\n\t\tcontextWindow?: number;\n\t\tmaxTokens?: number;\n\t};\n\tconversation: {\n\t\tmessages: readonly PluginSystemPromptMessage[];\n\t\tmessageCount: number;\n\t};\n\truntime: {\n\t\tactiveToolNames: readonly string[];\n\t\tavailableToolNames: readonly string[];\n\t\trunIndex: number;\n\t};\n\ttrigger: {\n\t\tkind: \"agent-run\";\n\t\ttimestamp: number;\n\t};\n\tsystemPrompt?: {\n\t\tbase: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t\tcurrent: {\n\t\t\tblocks?: readonly PluginSystemPromptBlockView[];\n\t\t\trendered?: string;\n\t\t};\n\t};\n}\n\nexport interface PluginSystemPromptBlockView extends PluginSystemPromptBlock {\n\ttype: string;\n\tsource: {\n\t\tkind: \"core\" | \"plugin\";\n\t\tpluginId?: string;\n\t};\n\tpriority: number;\n\tenabled: boolean;\n}\n\nexport interface PluginAgentActions {\n\tsystemPrompt: {\n\t\taddBlock(block: PluginSystemPromptBlock): void;\n\t\treplaceBlock(blockId: string, block: Omit<PluginSystemPromptBlock, \"id\">): void;\n\t\tupdateBlock(\n\t\t\tblockId: string,\n\t\t\tpatch: Partial<Pick<PluginSystemPromptBlock, \"content\" | \"priority\" | \"enabled\">>,\n\t\t): void;\n\t\tremoveBlock(blockId: string): void;\n\t\tsetBlockEnabled(blockId: string, enabled: boolean): void;\n\t};\n\ttools: {\n\t\tsetEnabled(toolName: string, enabled: boolean): void;\n\t\tenable(toolName: string): void;\n\t\tdisable(toolName: string): void;\n\t};\n\tcontinuation: {\n\t\trequest(result: PluginContinuationResult): void;\n\t};\n}\n\nexport interface PluginAgentHandlerContext<TTrigger> {\n\tinvocationId: string;\n\tplugin: {\n\t\tid: string;\n\t\tcontributionId: string;\n\t\tsettings: Readonly<Record<string, unknown>>;\n\t};\n\tsession: PluginSystemPromptProviderContext[\"session\"];\n\tmodel: PluginSystemPromptProviderContext[\"model\"];\n\tconversation: PluginSystemPromptProviderContext[\"conversation\"];\n\truntime: PluginSystemPromptProviderContext[\"runtime\"];\n\ttrigger: TTrigger;\n\tsystemPrompt?: PluginSystemPromptProviderContext[\"systemPrompt\"];\n\tactions: PluginAgentActions;\n\thost: PluginAgentToolApi;\n}\n\nexport type PluginAgentToolHandler<TInput = unknown> = (\n\tcontext: PluginAgentHandlerContext<{\n\t\tkind: \"tool-call\";\n\t\ttimestamp: number;\n\t\ttoolCallId: string;\n\t\ttoolId: string;\n\t\ttoolName: string;\n\t\tinput: TInput;\n\t}>,\n) => unknown | Promise<unknown>;\n\nexport type PluginSystemPromptProviderHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"agent-run\"; timestamp: number }>,\n) => void | PluginDynamicSystemPromptOperation[] | Promise<void | PluginDynamicSystemPromptOperation[]>;\n\nexport interface PluginSystemPromptProviderRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\t/**\n\t * Large context is opt-in. Omitted fields are not serialized across the\n\t * host/renderer boundary.\n\t */\n\tcontext?: {\n\t\tsystemPrompt?: \"none\" | \"blocks\" | \"rendered\" | \"full\";\n\t\tconversation?: \"summary\" | \"messages\";\n\t};\n\thandler: PluginSystemPromptProviderHandler;\n}\n\nexport interface PluginContinuationResult {\n\ttext: string;\n\t/** Stable key used by the host to suppress duplicate continuations in a session. */\n\tidempotencyKey?: string;\n}\n\nexport type PluginContinuationHandler = (\n\tcontext: PluginAgentHandlerContext<{ kind: \"continuation\"; timestamp: number }>,\n) => PluginContinuationResult | null | Promise<PluginContinuationResult | null>;\n\nexport interface PluginContinuationRegistration {\n\tid: string;\n\ttimeoutMs?: number;\n\tcontext?: { conversation?: \"summary\" | \"messages\" };\n\thandler: PluginContinuationHandler;\n}\n\nexport interface PluginAgentApi {\n\tregisterTool<TInput = unknown>(registration: PluginAgentToolRegistration<TInput>): Disposable;\n\t/** Register a provider evaluated before every Agent run. */\n\tregisterSystemPromptProvider(registration: PluginSystemPromptProviderRegistration): Disposable;\n\t/**\n\t * Register a policy consulted when the agent reaches a natural stopping point.\n\t * Return null to allow the agent to stop, or a message to continue with another turn.\n\t */\n\tregisterContinuationProvider(registration: PluginContinuationRegistration): Disposable;\n}\n"]}
package/dist/command.d.ts CHANGED
@@ -12,14 +12,57 @@ export interface PluginCommandRunResult {
12
12
  /** Process exit code; null when the process was killed by a signal/timeout. */
13
13
  exitCode: number | null;
14
14
  }
15
+ import type { Disposable } from "./disposable.js";
16
+ export interface PluginCommandSpawnOptions {
17
+ /** Working directory. Must resolve inside a host-allowed root (e.g. a project). */
18
+ cwd?: string;
19
+ /** Extra environment entries, merged over the host process env (PATH preserved). */
20
+ env?: Record<string, string>;
21
+ /**
22
+ * Ask the host to allocate a free localhost port. Every literal `{{PORT}}`
23
+ * in args/env values is substituted with it, and the handle exposes `port`.
24
+ */
25
+ allocatePort?: boolean;
26
+ }
27
+ export interface PluginCommandSpawnExit {
28
+ exitCode: number | null;
29
+ signal: string | null;
30
+ }
31
+ export interface PluginCommandSpawnStatus {
32
+ running: boolean;
33
+ pid: number;
34
+ port?: number;
35
+ exit?: PluginCommandSpawnExit;
36
+ /** Ring-buffered combined stdout+stderr tail (~64KB), for diagnostics. */
37
+ recentOutput: string;
38
+ }
39
+ /** Handle to a long-lived process started via {@link PluginCommandApi.spawn}. */
40
+ export interface PluginCommandSpawnHandle {
41
+ spawnId: string;
42
+ pid: number;
43
+ /** Present when `allocatePort` was requested. */
44
+ port?: number;
45
+ /** SIGTERM the process tree; SIGKILL after a grace period. Idempotent. */
46
+ stop(): Promise<void>;
47
+ status(): Promise<PluginCommandSpawnStatus>;
48
+ /** Fires once when the process exits (any reason). */
49
+ onExit(listener: (exit: PluginCommandSpawnExit) => void): Disposable;
50
+ }
15
51
  /**
16
52
  * Run an allowed host command (e.g. `git`). execFile semantics — NO shell, args
17
53
  * are passed as an array (no string splitting, no injection). The executable
18
54
  * must be declared in plugin.json's `commands` and currently enabled by the
19
55
  * user; otherwise the call is rejected (and the host notifies the user). Needs
20
56
  * the `agent.command.run` permission.
57
+ *
58
+ * `spawn` starts a long-lived process instead (ADR-0054, e.g. a local dev
59
+ * server): same manifest `commands` declaration and user toggle, but gated by
60
+ * the separate `agent.command.spawn` permission. The child runs in its own
61
+ * process group; the host kills the whole tree on stop, plugin unload/disable,
62
+ * and app quit.
21
63
  */
22
64
  export interface PluginCommandApi {
23
65
  run(file: string, args?: string[], options?: PluginCommandRunOptions): Promise<PluginCommandRunResult>;
66
+ spawn(file: string, args?: string[], options?: PluginCommandSpawnOptions): Promise<PluginCommandSpawnHandle>;
24
67
  }
25
68
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACvC,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAChC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACvG","sourcesContent":["export interface PluginCommandRunOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/** Hard timeout in ms; the host clamps to its own maximum. */\n\ttimeoutMs?: number;\n}\n\nexport interface PluginCommandRunResult {\n\tstdout: string;\n\tstderr: string;\n\t/** Process exit code; null when the process was killed by a signal/timeout. */\n\texitCode: number | null;\n}\n\n/**\n * Run an allowed host command (e.g. `git`). execFile semantics — NO shell, args\n * are passed as an array (no string splitting, no injection). The executable\n * must be declared in plugin.json's `commands` and currently enabled by the\n * user; otherwise the call is rejected (and the host notifies the user). Needs\n * the `agent.command.run` permission.\n */\nexport interface PluginCommandApi {\n\trun(file: string, args?: string[], options?: PluginCommandRunOptions): Promise<PluginCommandRunResult>;\n}\n"]}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACvC,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,yBAAyB;IACzC,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC5C,sDAAsD;IACtD,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,GAAG,UAAU,CAAC;CACrE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAChC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACvG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC7G","sourcesContent":["export interface PluginCommandRunOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/** Hard timeout in ms; the host clamps to its own maximum. */\n\ttimeoutMs?: number;\n}\n\nexport interface PluginCommandRunResult {\n\tstdout: string;\n\tstderr: string;\n\t/** Process exit code; null when the process was killed by a signal/timeout. */\n\texitCode: number | null;\n}\n\nimport type { Disposable } from \"./disposable.js\";\n\nexport interface PluginCommandSpawnOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/**\n\t * Ask the host to allocate a free localhost port. Every literal `{{PORT}}`\n\t * in args/env values is substituted with it, and the handle exposes `port`.\n\t */\n\tallocatePort?: boolean;\n}\n\nexport interface PluginCommandSpawnExit {\n\texitCode: number | null;\n\tsignal: string | null;\n}\n\nexport interface PluginCommandSpawnStatus {\n\trunning: boolean;\n\tpid: number;\n\tport?: number;\n\texit?: PluginCommandSpawnExit;\n\t/** Ring-buffered combined stdout+stderr tail (~64KB), for diagnostics. */\n\trecentOutput: string;\n}\n\n/** Handle to a long-lived process started via {@link PluginCommandApi.spawn}. */\nexport interface PluginCommandSpawnHandle {\n\tspawnId: string;\n\tpid: number;\n\t/** Present when `allocatePort` was requested. */\n\tport?: number;\n\t/** SIGTERM the process tree; SIGKILL after a grace period. Idempotent. */\n\tstop(): Promise<void>;\n\tstatus(): Promise<PluginCommandSpawnStatus>;\n\t/** Fires once when the process exits (any reason). */\n\tonExit(listener: (exit: PluginCommandSpawnExit) => void): Disposable;\n}\n\n/**\n * Run an allowed host command (e.g. `git`). execFile semantics — NO shell, args\n * are passed as an array (no string splitting, no injection). The executable\n * must be declared in plugin.json's `commands` and currently enabled by the\n * user; otherwise the call is rejected (and the host notifies the user). Needs\n * the `agent.command.run` permission.\n *\n * `spawn` starts a long-lived process instead (ADR-0054, e.g. a local dev\n * server): same manifest `commands` declaration and user toggle, but gated by\n * the separate `agent.command.spawn` permission. The child runs in its own\n * process group; the host kills the whole tree on stop, plugin unload/disable,\n * and app quit.\n */\nexport interface PluginCommandApi {\n\trun(file: string, args?: string[], options?: PluginCommandRunOptions): Promise<PluginCommandRunResult>;\n\tspawn(file: string, args?: string[], options?: PluginCommandSpawnOptions): Promise<PluginCommandSpawnHandle>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"","sourcesContent":["export interface PluginCommandRunOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/** Hard timeout in ms; the host clamps to its own maximum. */\n\ttimeoutMs?: number;\n}\n\nexport interface PluginCommandRunResult {\n\tstdout: string;\n\tstderr: string;\n\t/** Process exit code; null when the process was killed by a signal/timeout. */\n\texitCode: number | null;\n}\n\n/**\n * Run an allowed host command (e.g. `git`). execFile semantics — NO shell, args\n * are passed as an array (no string splitting, no injection). The executable\n * must be declared in plugin.json's `commands` and currently enabled by the\n * user; otherwise the call is rejected (and the host notifies the user). Needs\n * the `agent.command.run` permission.\n */\nexport interface PluginCommandApi {\n\trun(file: string, args?: string[], options?: PluginCommandRunOptions): Promise<PluginCommandRunResult>;\n}\n"]}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"","sourcesContent":["export interface PluginCommandRunOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/** Hard timeout in ms; the host clamps to its own maximum. */\n\ttimeoutMs?: number;\n}\n\nexport interface PluginCommandRunResult {\n\tstdout: string;\n\tstderr: string;\n\t/** Process exit code; null when the process was killed by a signal/timeout. */\n\texitCode: number | null;\n}\n\nimport type { Disposable } from \"./disposable.js\";\n\nexport interface PluginCommandSpawnOptions {\n\t/** Working directory. Must resolve inside a host-allowed root (e.g. a project). */\n\tcwd?: string;\n\t/** Extra environment entries, merged over the host process env (PATH preserved). */\n\tenv?: Record<string, string>;\n\t/**\n\t * Ask the host to allocate a free localhost port. Every literal `{{PORT}}`\n\t * in args/env values is substituted with it, and the handle exposes `port`.\n\t */\n\tallocatePort?: boolean;\n}\n\nexport interface PluginCommandSpawnExit {\n\texitCode: number | null;\n\tsignal: string | null;\n}\n\nexport interface PluginCommandSpawnStatus {\n\trunning: boolean;\n\tpid: number;\n\tport?: number;\n\texit?: PluginCommandSpawnExit;\n\t/** Ring-buffered combined stdout+stderr tail (~64KB), for diagnostics. */\n\trecentOutput: string;\n}\n\n/** Handle to a long-lived process started via {@link PluginCommandApi.spawn}. */\nexport interface PluginCommandSpawnHandle {\n\tspawnId: string;\n\tpid: number;\n\t/** Present when `allocatePort` was requested. */\n\tport?: number;\n\t/** SIGTERM the process tree; SIGKILL after a grace period. Idempotent. */\n\tstop(): Promise<void>;\n\tstatus(): Promise<PluginCommandSpawnStatus>;\n\t/** Fires once when the process exits (any reason). */\n\tonExit(listener: (exit: PluginCommandSpawnExit) => void): Disposable;\n}\n\n/**\n * Run an allowed host command (e.g. `git`). execFile semantics — NO shell, args\n * are passed as an array (no string splitting, no injection). The executable\n * must be declared in plugin.json's `commands` and currently enabled by the\n * user; otherwise the call is rejected (and the host notifies the user). Needs\n * the `agent.command.run` permission.\n *\n * `spawn` starts a long-lived process instead (ADR-0054, e.g. a local dev\n * server): same manifest `commands` declaration and user toggle, but gated by\n * the separate `agent.command.spawn` permission. The child runs in its own\n * process group; the host kills the whole tree on stop, plugin unload/disable,\n * and app quit.\n */\nexport interface PluginCommandApi {\n\trun(file: string, args?: string[], options?: PluginCommandRunOptions): Promise<PluginCommandRunResult>;\n\tspawn(file: string, args?: string[], options?: PluginCommandSpawnOptions): Promise<PluginCommandSpawnHandle>;\n}\n"]}
package/dist/context.d.ts CHANGED
@@ -3,12 +3,14 @@ import type { PluginAppActionsApi } from "./app-actions.js";
3
3
  import type { PluginCommandApi } from "./command.js";
4
4
  import type { PluginConversationApi } from "./conversation.js";
5
5
  import type { Disposable } from "./disposable.js";
6
+ import type { PluginFileExplorerApi } from "./file-explorer.js";
6
7
  import type { PluginFsApi } from "./fs.js";
7
8
  import type { PluginI18nApi } from "./i18n.js";
8
- import type { PluginImagesApi } from "./images.js";
9
+ import type { PluginNetworkApi } from "./network.js";
9
10
  import type { PluginOfficialApi } from "./official.js";
10
11
  import type { PluginPermission } from "./permissions.js";
11
12
  import type { PluginSettingsApi } from "./settings.js";
13
+ import type { PluginStorageApi } from "./storage.js";
12
14
  import type { PluginUiApi } from "./ui.js";
13
15
  export interface PluginPermissionApi {
14
16
  has(permission: PluginPermission): boolean;
@@ -23,13 +25,15 @@ export interface PluginContext {
23
25
  };
24
26
  permissions: PluginPermissionApi;
25
27
  ui: PluginUiApi;
28
+ fileExplorer: PluginFileExplorerApi;
26
29
  conversation: PluginConversationApi;
27
30
  agent: PluginAgentApi;
28
31
  appActions: PluginAppActionsApi;
29
32
  official: PluginOfficialApi;
30
33
  fs: PluginFsApi;
31
34
  command: PluginCommandApi;
32
- images: PluginImagesApi;
35
+ network: PluginNetworkApi;
36
+ storage: PluginStorageApi;
33
37
  settings: PluginSettingsApi;
34
38
  i18n: PluginI18nApi;
35
39
  /** 当前工作模式(agent_mode 轴)。开发者据此做模式定制。见 ADR-0046。 */
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IACnC,GAAG,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC;IAC3C,OAAO,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC5C;AAED,mGAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,mBAAmB,CAAC;IACjC,EAAE,EAAE,WAAW,CAAC;IAChB,YAAY,EAAE,qBAAqB,CAAC;IACpC,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,gGAAkD;IAClD,YAAY,IAAI,SAAS,CAAC;IAC1B,8FAA4C;IAC5C,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,UAAU,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,UAAU,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAEvE","sourcesContent":["import type { PluginAgentApi } from \"./agent.js\";\nimport type { PluginAppActionsApi } from \"./app-actions.js\";\nimport type { PluginCommandApi } from \"./command.js\";\nimport type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { PluginI18nApi } from \"./i18n.js\";\nimport type { PluginImagesApi } from \"./images.js\";\nimport type { PluginOfficialApi } from \"./official.js\";\nimport type { PluginPermission } from \"./permissions.js\";\nimport type { PluginSettingsApi } from \"./settings.js\";\nimport type { PluginUiApi } from \"./ui.js\";\n\nexport interface PluginPermissionApi {\n\thas(permission: PluginPermission): boolean;\n\trequire(permission: PluginPermission): void;\n}\n\n/** 工作模式(agent_mode 轴,见 ADR-0046)。宿主 Work/Coding,未来可能扩展。 */\nexport type AgentMode = \"work\" | \"coding\";\n\nexport interface PluginContext {\n\tplugin: {\n\t\tid: string;\n\t\tversion: string;\n\t};\n\tpermissions: PluginPermissionApi;\n\tui: PluginUiApi;\n\tconversation: PluginConversationApi;\n\tagent: PluginAgentApi;\n\tappActions: PluginAppActionsApi;\n\tofficial: PluginOfficialApi;\n\tfs: PluginFsApi;\n\tcommand: PluginCommandApi;\n\timages: PluginImagesApi;\n\tsettings: PluginSettingsApi;\n\ti18n: PluginI18nApi;\n\t/** 当前工作模式(agent_mode 轴)。开发者据此做模式定制。见 ADR-0046。 */\n\tgetAgentMode(): AgentMode;\n\t/** 订阅工作模式变更(纯全局实时切换)。返回 Disposable 取消订阅。 */\n\tonAgentModeChanged(listener: (mode: AgentMode) => void): Disposable;\n}\n\nexport interface PluginDefinition {\n\tactivate(ctx: PluginContext): void | Promise<void>;\n\tdeactivate?(): void | Promise<void>;\n}\n\nexport function definePlugin(plugin: PluginDefinition): PluginDefinition {\n\treturn plugin;\n}\n"]}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IACnC,GAAG,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC;IAC3C,OAAO,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC5C;AAED,mGAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,mBAAmB,CAAC;IACjC,EAAE,EAAE,WAAW,CAAC;IAChB,YAAY,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,qBAAqB,CAAC;IACpC,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,gGAAkD;IAClD,YAAY,IAAI,SAAS,CAAC;IAC1B,8FAA4C;IAC5C,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,UAAU,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,UAAU,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAEvE","sourcesContent":["import type { PluginAgentApi } from \"./agent.js\";\nimport type { PluginAppActionsApi } from \"./app-actions.js\";\nimport type { PluginCommandApi } from \"./command.js\";\nimport type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFileExplorerApi } from \"./file-explorer.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { PluginI18nApi } from \"./i18n.js\";\nimport type { PluginNetworkApi } from \"./network.js\";\nimport type { PluginOfficialApi } from \"./official.js\";\nimport type { PluginPermission } from \"./permissions.js\";\nimport type { PluginSettingsApi } from \"./settings.js\";\nimport type { PluginStorageApi } from \"./storage.js\";\nimport type { PluginUiApi } from \"./ui.js\";\n\nexport interface PluginPermissionApi {\n\thas(permission: PluginPermission): boolean;\n\trequire(permission: PluginPermission): void;\n}\n\n/** 工作模式(agent_mode 轴,见 ADR-0046)。宿主 Work/Coding,未来可能扩展。 */\nexport type AgentMode = \"work\" | \"coding\";\n\nexport interface PluginContext {\n\tplugin: {\n\t\tid: string;\n\t\tversion: string;\n\t};\n\tpermissions: PluginPermissionApi;\n\tui: PluginUiApi;\n\tfileExplorer: PluginFileExplorerApi;\n\tconversation: PluginConversationApi;\n\tagent: PluginAgentApi;\n\tappActions: PluginAppActionsApi;\n\tofficial: PluginOfficialApi;\n\tfs: PluginFsApi;\n\tcommand: PluginCommandApi;\n\tnetwork: PluginNetworkApi;\n\tstorage: PluginStorageApi;\n\tsettings: PluginSettingsApi;\n\ti18n: PluginI18nApi;\n\t/** 当前工作模式(agent_mode 轴)。开发者据此做模式定制。见 ADR-0046。 */\n\tgetAgentMode(): AgentMode;\n\t/** 订阅工作模式变更(纯全局实时切换)。返回 Disposable 取消订阅。 */\n\tonAgentModeChanged(listener: (mode: AgentMode) => void): Disposable;\n}\n\nexport interface PluginDefinition {\n\tactivate(ctx: PluginContext): void | Promise<void>;\n\tdeactivate?(): void | Promise<void>;\n}\n\nexport function definePlugin(plugin: PluginDefinition): PluginDefinition {\n\treturn plugin;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAgDA,MAAM,UAAU,YAAY,CAAC,MAAwB,EAAoB;IACxE,OAAO,MAAM,CAAC;AAAA,CACd","sourcesContent":["import type { PluginAgentApi } from \"./agent.js\";\nimport type { PluginAppActionsApi } from \"./app-actions.js\";\nimport type { PluginCommandApi } from \"./command.js\";\nimport type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { PluginI18nApi } from \"./i18n.js\";\nimport type { PluginImagesApi } from \"./images.js\";\nimport type { PluginOfficialApi } from \"./official.js\";\nimport type { PluginPermission } from \"./permissions.js\";\nimport type { PluginSettingsApi } from \"./settings.js\";\nimport type { PluginUiApi } from \"./ui.js\";\n\nexport interface PluginPermissionApi {\n\thas(permission: PluginPermission): boolean;\n\trequire(permission: PluginPermission): void;\n}\n\n/** 工作模式(agent_mode 轴,见 ADR-0046)。宿主 Work/Coding,未来可能扩展。 */\nexport type AgentMode = \"work\" | \"coding\";\n\nexport interface PluginContext {\n\tplugin: {\n\t\tid: string;\n\t\tversion: string;\n\t};\n\tpermissions: PluginPermissionApi;\n\tui: PluginUiApi;\n\tconversation: PluginConversationApi;\n\tagent: PluginAgentApi;\n\tappActions: PluginAppActionsApi;\n\tofficial: PluginOfficialApi;\n\tfs: PluginFsApi;\n\tcommand: PluginCommandApi;\n\timages: PluginImagesApi;\n\tsettings: PluginSettingsApi;\n\ti18n: PluginI18nApi;\n\t/** 当前工作模式(agent_mode 轴)。开发者据此做模式定制。见 ADR-0046。 */\n\tgetAgentMode(): AgentMode;\n\t/** 订阅工作模式变更(纯全局实时切换)。返回 Disposable 取消订阅。 */\n\tonAgentModeChanged(listener: (mode: AgentMode) => void): Disposable;\n}\n\nexport interface PluginDefinition {\n\tactivate(ctx: PluginContext): void | Promise<void>;\n\tdeactivate?(): void | Promise<void>;\n}\n\nexport function definePlugin(plugin: PluginDefinition): PluginDefinition {\n\treturn plugin;\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAoDA,MAAM,UAAU,YAAY,CAAC,MAAwB,EAAoB;IACxE,OAAO,MAAM,CAAC;AAAA,CACd","sourcesContent":["import type { PluginAgentApi } from \"./agent.js\";\nimport type { PluginAppActionsApi } from \"./app-actions.js\";\nimport type { PluginCommandApi } from \"./command.js\";\nimport type { PluginConversationApi } from \"./conversation.js\";\nimport type { Disposable } from \"./disposable.js\";\nimport type { PluginFileExplorerApi } from \"./file-explorer.js\";\nimport type { PluginFsApi } from \"./fs.js\";\nimport type { PluginI18nApi } from \"./i18n.js\";\nimport type { PluginNetworkApi } from \"./network.js\";\nimport type { PluginOfficialApi } from \"./official.js\";\nimport type { PluginPermission } from \"./permissions.js\";\nimport type { PluginSettingsApi } from \"./settings.js\";\nimport type { PluginStorageApi } from \"./storage.js\";\nimport type { PluginUiApi } from \"./ui.js\";\n\nexport interface PluginPermissionApi {\n\thas(permission: PluginPermission): boolean;\n\trequire(permission: PluginPermission): void;\n}\n\n/** 工作模式(agent_mode 轴,见 ADR-0046)。宿主 Work/Coding,未来可能扩展。 */\nexport type AgentMode = \"work\" | \"coding\";\n\nexport interface PluginContext {\n\tplugin: {\n\t\tid: string;\n\t\tversion: string;\n\t};\n\tpermissions: PluginPermissionApi;\n\tui: PluginUiApi;\n\tfileExplorer: PluginFileExplorerApi;\n\tconversation: PluginConversationApi;\n\tagent: PluginAgentApi;\n\tappActions: PluginAppActionsApi;\n\tofficial: PluginOfficialApi;\n\tfs: PluginFsApi;\n\tcommand: PluginCommandApi;\n\tnetwork: PluginNetworkApi;\n\tstorage: PluginStorageApi;\n\tsettings: PluginSettingsApi;\n\ti18n: PluginI18nApi;\n\t/** 当前工作模式(agent_mode 轴)。开发者据此做模式定制。见 ADR-0046。 */\n\tgetAgentMode(): AgentMode;\n\t/** 订阅工作模式变更(纯全局实时切换)。返回 Disposable 取消订阅。 */\n\tonAgentModeChanged(listener: (mode: AgentMode) => void): Disposable;\n}\n\nexport interface PluginDefinition {\n\tactivate(ctx: PluginContext): void | Promise<void>;\n\tdeactivate?(): void | Promise<void>;\n}\n\nexport function definePlugin(plugin: PluginDefinition): PluginDefinition {\n\treturn plugin;\n}\n"]}
@@ -28,6 +28,7 @@ export type ConversationEvent = {
28
28
  type: "tool-call-start";
29
29
  toolCallId: string;
30
30
  toolName: string;
31
+ args?: Record<string, unknown>;
31
32
  } | {
32
33
  type: "tool-call-end";
33
34
  toolCallId: string;
@@ -44,7 +45,13 @@ export interface PluginConversationApi {
44
45
  insertText(text: string): void;
45
46
  /** Abort the active conversation's current turn. */
46
47
  abort(): Promise<void>;
47
- /** Subscribe to real-time conversation events. */
48
+ /**
49
+ * Subscribe to real-time conversation events. The listener is replayed one
50
+ * `conversation-changed` with the current state right after subscribing (in a
51
+ * microtask), so logic keyed off the active conversation — e.g. deciding
52
+ * whether an activity tab belongs in the tab bar for this cwd — runs without
53
+ * waiting for the next session switch.
54
+ */
48
55
  on(listener: (event: ConversationEvent) => void): Disposable;
49
56
  }
50
57
  //# sourceMappingURL=conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,iBAAiB;IACjC,wEAAwE;IACxE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,YAAY,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACrC,2EAA2E;IAC3E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,sEAAsE;IACtE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oDAAoD;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,kDAAkD;IAClD,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,UAAU,CAAC;CAC7D","sourcesContent":["import type { Disposable } from \"./disposable.js\";\n\nexport interface ConversationState {\n\t/** Active session runtimeId, or null when no conversation is active. */\n\tid: string | null;\n\tcwd: string | null;\n\tsessionPath: string | null;\n\tmodel: string | null;\n\tisStreaming: boolean;\n}\n\nexport interface ConversationMessage {\n\tid: string;\n\trole: \"user\" | \"assistant\" | \"compaction\";\n\ttext: string;\n\ttimestamp?: number;\n}\n\nexport type ConversationEvent =\n\t| { type: \"turn-start\" }\n\t| { type: \"turn-end\"; stopReason: string }\n\t| { type: \"message-added\"; message: ConversationMessage }\n\t| { type: \"message-updated\"; delta: string }\n\t| { type: \"tool-call-start\"; toolCallId: string; toolName: string }\n\t| { type: \"tool-call-end\"; toolCallId: string; toolName: string; isError: boolean }\n\t| { type: \"conversation-changed\"; conversation: ConversationState };\n\nexport interface PluginConversationApi {\n\t/** Send a prompt into the active conversation (renders as a user turn). */\n\tsendPrompt(text: string): Promise<void>;\n\t/** Fill the input bar without sending; the user can edit and send. */\n\tinsertText(text: string): void;\n\t/** Abort the active conversation's current turn. */\n\tabort(): Promise<void>;\n\t/** Subscribe to real-time conversation events. */\n\ton(listener: (event: ConversationEvent) => void): Disposable;\n}\n"]}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,iBAAiB;IACjC,wEAAwE;IACxE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACjG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,YAAY,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACrC,2EAA2E;IAC3E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,sEAAsE;IACtE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oDAAoD;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;;OAMG;IACH,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,UAAU,CAAC;CAC7D","sourcesContent":["import type { Disposable } from \"./disposable.js\";\n\nexport interface ConversationState {\n\t/** Active session runtimeId, or null when no conversation is active. */\n\tid: string | null;\n\tcwd: string | null;\n\tsessionPath: string | null;\n\tmodel: string | null;\n\tisStreaming: boolean;\n}\n\nexport interface ConversationMessage {\n\tid: string;\n\trole: \"user\" | \"assistant\" | \"compaction\";\n\ttext: string;\n\ttimestamp?: number;\n}\n\nexport type ConversationEvent =\n\t| { type: \"turn-start\" }\n\t| { type: \"turn-end\"; stopReason: string }\n\t| { type: \"message-added\"; message: ConversationMessage }\n\t| { type: \"message-updated\"; delta: string }\n\t| { type: \"tool-call-start\"; toolCallId: string; toolName: string; args?: Record<string, unknown> }\n\t| { type: \"tool-call-end\"; toolCallId: string; toolName: string; isError: boolean }\n\t| { type: \"conversation-changed\"; conversation: ConversationState };\n\nexport interface PluginConversationApi {\n\t/** Send a prompt into the active conversation (renders as a user turn). */\n\tsendPrompt(text: string): Promise<void>;\n\t/** Fill the input bar without sending; the user can edit and send. */\n\tinsertText(text: string): void;\n\t/** Abort the active conversation's current turn. */\n\tabort(): Promise<void>;\n\t/**\n\t * Subscribe to real-time conversation events. The listener is replayed one\n\t * `conversation-changed` with the current state right after subscribing (in a\n\t * microtask), so logic keyed off the active conversation — e.g. deciding\n\t * whether an activity tab belongs in the tab bar for this cwd — runs without\n\t * waiting for the next session switch.\n\t */\n\ton(listener: (event: ConversationEvent) => void): Disposable;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"","sourcesContent":["import type { Disposable } from \"./disposable.js\";\n\nexport interface ConversationState {\n\t/** Active session runtimeId, or null when no conversation is active. */\n\tid: string | null;\n\tcwd: string | null;\n\tsessionPath: string | null;\n\tmodel: string | null;\n\tisStreaming: boolean;\n}\n\nexport interface ConversationMessage {\n\tid: string;\n\trole: \"user\" | \"assistant\" | \"compaction\";\n\ttext: string;\n\ttimestamp?: number;\n}\n\nexport type ConversationEvent =\n\t| { type: \"turn-start\" }\n\t| { type: \"turn-end\"; stopReason: string }\n\t| { type: \"message-added\"; message: ConversationMessage }\n\t| { type: \"message-updated\"; delta: string }\n\t| { type: \"tool-call-start\"; toolCallId: string; toolName: string }\n\t| { type: \"tool-call-end\"; toolCallId: string; toolName: string; isError: boolean }\n\t| { type: \"conversation-changed\"; conversation: ConversationState };\n\nexport interface PluginConversationApi {\n\t/** Send a prompt into the active conversation (renders as a user turn). */\n\tsendPrompt(text: string): Promise<void>;\n\t/** Fill the input bar without sending; the user can edit and send. */\n\tinsertText(text: string): void;\n\t/** Abort the active conversation's current turn. */\n\tabort(): Promise<void>;\n\t/** Subscribe to real-time conversation events. */\n\ton(listener: (event: ConversationEvent) => void): Disposable;\n}\n"]}
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"","sourcesContent":["import type { Disposable } from \"./disposable.js\";\n\nexport interface ConversationState {\n\t/** Active session runtimeId, or null when no conversation is active. */\n\tid: string | null;\n\tcwd: string | null;\n\tsessionPath: string | null;\n\tmodel: string | null;\n\tisStreaming: boolean;\n}\n\nexport interface ConversationMessage {\n\tid: string;\n\trole: \"user\" | \"assistant\" | \"compaction\";\n\ttext: string;\n\ttimestamp?: number;\n}\n\nexport type ConversationEvent =\n\t| { type: \"turn-start\" }\n\t| { type: \"turn-end\"; stopReason: string }\n\t| { type: \"message-added\"; message: ConversationMessage }\n\t| { type: \"message-updated\"; delta: string }\n\t| { type: \"tool-call-start\"; toolCallId: string; toolName: string; args?: Record<string, unknown> }\n\t| { type: \"tool-call-end\"; toolCallId: string; toolName: string; isError: boolean }\n\t| { type: \"conversation-changed\"; conversation: ConversationState };\n\nexport interface PluginConversationApi {\n\t/** Send a prompt into the active conversation (renders as a user turn). */\n\tsendPrompt(text: string): Promise<void>;\n\t/** Fill the input bar without sending; the user can edit and send. */\n\tinsertText(text: string): void;\n\t/** Abort the active conversation's current turn. */\n\tabort(): Promise<void>;\n\t/**\n\t * Subscribe to real-time conversation events. The listener is replayed one\n\t * `conversation-changed` with the current state right after subscribing (in a\n\t * microtask), so logic keyed off the active conversation — e.g. deciding\n\t * whether an activity tab belongs in the tab bar for this cwd — runs without\n\t * waiting for the next session switch.\n\t */\n\ton(listener: (event: ConversationEvent) => void): Disposable;\n}\n"]}
@@ -0,0 +1,87 @@
1
+ import type { ReactNode } from "react";
2
+ import type { Disposable } from "./disposable.js";
3
+ /** Metadata exposed by the host file explorer. Reading contents still requires `fs.read`. */
4
+ export interface PluginFileExplorerEntry {
5
+ name: string;
6
+ path: string;
7
+ isDirectory: boolean;
8
+ size: number;
9
+ modifiedAt: number;
10
+ }
11
+ export interface PluginWorkspaceRoot {
12
+ name: string;
13
+ path: string;
14
+ }
15
+ /** Declarative matcher shared by menu actions and decorations. */
16
+ export interface PluginFileExplorerWhen {
17
+ resourceType?: "file" | "directory";
18
+ /** Lower-case extensions without a leading dot. Matching is case-insensitive. */
19
+ extensions?: readonly string[];
20
+ /** Exact basenames. Matching is case-insensitive. */
21
+ fileNames?: readonly string[];
22
+ }
23
+ export interface PluginFileExplorerActionContext {
24
+ entry: PluginFileExplorerEntry;
25
+ workspaceRoot: PluginWorkspaceRoot | null;
26
+ }
27
+ export interface PluginFileExplorerContextMenuContribution {
28
+ id: string;
29
+ label: string;
30
+ icon?: ReactNode;
31
+ when?: PluginFileExplorerWhen;
32
+ /** Lower values render first. Defaults to 100. */
33
+ order?: number;
34
+ run(context: PluginFileExplorerActionContext): void | Promise<void>;
35
+ }
36
+ export interface PluginFileExplorerToolbarContext {
37
+ workspaceRoot: PluginWorkspaceRoot;
38
+ selection: readonly PluginFileExplorerEntry[];
39
+ }
40
+ export interface PluginFileExplorerToolbarContribution {
41
+ id: string;
42
+ label: string;
43
+ icon?: ReactNode;
44
+ /** Lower values render first. Defaults to 100. */
45
+ order?: number;
46
+ run(context: PluginFileExplorerToolbarContext): void | Promise<void>;
47
+ }
48
+ export interface PluginFileExplorerDecoration {
49
+ /** Replaces the host's default file/folder icon. */
50
+ icon?: ReactNode;
51
+ /** Compact status text rendered after the filename. Keep to one or two characters. */
52
+ badge?: string;
53
+ tooltip?: string;
54
+ }
55
+ export interface PluginFileExplorerDecorationProvider {
56
+ id: string;
57
+ when?: PluginFileExplorerWhen;
58
+ /** Higher values win when multiple providers return a decoration. Defaults to 0. */
59
+ priority?: number;
60
+ provideDecoration(entry: PluginFileExplorerEntry): PluginFileExplorerDecoration | null;
61
+ }
62
+ export type PluginFileExplorerChange = {
63
+ type: "changed" | "created" | "deleted";
64
+ path: string;
65
+ } | {
66
+ type: "moved";
67
+ path: string;
68
+ oldPath: string;
69
+ };
70
+ export interface PluginFileExplorerRevealOptions {
71
+ /** Select the revealed entry. Defaults to true. */
72
+ select?: boolean;
73
+ /** Move DOM focus to the row after revealing it. Defaults to false. */
74
+ focus?: boolean;
75
+ }
76
+ export interface PluginFileExplorerApi {
77
+ getWorkspaceRoots(): readonly PluginWorkspaceRoot[];
78
+ getSelection(): readonly PluginFileExplorerEntry[];
79
+ reveal(path: string, options?: PluginFileExplorerRevealOptions): Promise<void>;
80
+ refresh(path?: string): Promise<void>;
81
+ onDidChangeSelection(listener: (selection: readonly PluginFileExplorerEntry[]) => void): Disposable;
82
+ onDidChangeFiles(listener: (changes: readonly PluginFileExplorerChange[]) => void): Disposable;
83
+ registerContextMenuAction(contribution: PluginFileExplorerContextMenuContribution): Disposable;
84
+ registerToolbarAction(contribution: PluginFileExplorerToolbarContribution): Disposable;
85
+ registerDecorationProvider(contribution: PluginFileExplorerDecorationProvider): Disposable;
86
+ }
87
+ //# sourceMappingURL=file-explorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-explorer.d.ts","sourceRoot":"","sources":["../src/file-explorer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport type { Disposable } from \"./disposable.js\";\n\n/** Metadata exposed by the host file explorer. Reading contents still requires `fs.read`. */\nexport interface PluginFileExplorerEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginWorkspaceRoot {\n\tname: string;\n\tpath: string;\n}\n\n/** Declarative matcher shared by menu actions and decorations. */\nexport interface PluginFileExplorerWhen {\n\tresourceType?: \"file\" | \"directory\";\n\t/** Lower-case extensions without a leading dot. Matching is case-insensitive. */\n\textensions?: readonly string[];\n\t/** Exact basenames. Matching is case-insensitive. */\n\tfileNames?: readonly string[];\n}\n\nexport interface PluginFileExplorerActionContext {\n\tentry: PluginFileExplorerEntry;\n\tworkspaceRoot: PluginWorkspaceRoot | null;\n}\n\nexport interface PluginFileExplorerContextMenuContribution {\n\tid: string;\n\tlabel: string;\n\ticon?: ReactNode;\n\twhen?: PluginFileExplorerWhen;\n\t/** Lower values render first. Defaults to 100. */\n\torder?: number;\n\trun(context: PluginFileExplorerActionContext): void | Promise<void>;\n}\n\nexport interface PluginFileExplorerToolbarContext {\n\tworkspaceRoot: PluginWorkspaceRoot;\n\tselection: readonly PluginFileExplorerEntry[];\n}\n\nexport interface PluginFileExplorerToolbarContribution {\n\tid: string;\n\tlabel: string;\n\ticon?: ReactNode;\n\t/** Lower values render first. Defaults to 100. */\n\torder?: number;\n\trun(context: PluginFileExplorerToolbarContext): void | Promise<void>;\n}\n\nexport interface PluginFileExplorerDecoration {\n\t/** Replaces the host's default file/folder icon. */\n\ticon?: ReactNode;\n\t/** Compact status text rendered after the filename. Keep to one or two characters. */\n\tbadge?: string;\n\ttooltip?: string;\n}\n\nexport interface PluginFileExplorerDecorationProvider {\n\tid: string;\n\twhen?: PluginFileExplorerWhen;\n\t/** Higher values win when multiple providers return a decoration. Defaults to 0. */\n\tpriority?: number;\n\tprovideDecoration(\n\t\tentry: PluginFileExplorerEntry,\n\t): PluginFileExplorerDecoration | null;\n}\n\nexport type PluginFileExplorerChange =\n\t| { type: \"changed\" | \"created\" | \"deleted\"; path: string }\n\t| { type: \"moved\"; path: string; oldPath: string };\n\nexport interface PluginFileExplorerRevealOptions {\n\t/** Select the revealed entry. Defaults to true. */\n\tselect?: boolean;\n\t/** Move DOM focus to the row after revealing it. Defaults to false. */\n\tfocus?: boolean;\n}\n\nexport interface PluginFileExplorerApi {\n\tgetWorkspaceRoots(): readonly PluginWorkspaceRoot[];\n\tgetSelection(): readonly PluginFileExplorerEntry[];\n\treveal(path: string, options?: PluginFileExplorerRevealOptions): Promise<void>;\n\trefresh(path?: string): Promise<void>;\n\tonDidChangeSelection(listener: (selection: readonly PluginFileExplorerEntry[]) => void): Disposable;\n\tonDidChangeFiles(listener: (changes: readonly PluginFileExplorerChange[]) => void): Disposable;\n\tregisterContextMenuAction(contribution: PluginFileExplorerContextMenuContribution): Disposable;\n\tregisterToolbarAction(contribution: PluginFileExplorerToolbarContribution): Disposable;\n\tregisterDecorationProvider(contribution: PluginFileExplorerDecorationProvider): Disposable;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file-explorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-explorer.js","sourceRoot":"","sources":["../src/file-explorer.ts"],"names":[],"mappings":"","sourcesContent":["import type { ReactNode } from \"react\";\nimport type { Disposable } from \"./disposable.js\";\n\n/** Metadata exposed by the host file explorer. Reading contents still requires `fs.read`. */\nexport interface PluginFileExplorerEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginWorkspaceRoot {\n\tname: string;\n\tpath: string;\n}\n\n/** Declarative matcher shared by menu actions and decorations. */\nexport interface PluginFileExplorerWhen {\n\tresourceType?: \"file\" | \"directory\";\n\t/** Lower-case extensions without a leading dot. Matching is case-insensitive. */\n\textensions?: readonly string[];\n\t/** Exact basenames. Matching is case-insensitive. */\n\tfileNames?: readonly string[];\n}\n\nexport interface PluginFileExplorerActionContext {\n\tentry: PluginFileExplorerEntry;\n\tworkspaceRoot: PluginWorkspaceRoot | null;\n}\n\nexport interface PluginFileExplorerContextMenuContribution {\n\tid: string;\n\tlabel: string;\n\ticon?: ReactNode;\n\twhen?: PluginFileExplorerWhen;\n\t/** Lower values render first. Defaults to 100. */\n\torder?: number;\n\trun(context: PluginFileExplorerActionContext): void | Promise<void>;\n}\n\nexport interface PluginFileExplorerToolbarContext {\n\tworkspaceRoot: PluginWorkspaceRoot;\n\tselection: readonly PluginFileExplorerEntry[];\n}\n\nexport interface PluginFileExplorerToolbarContribution {\n\tid: string;\n\tlabel: string;\n\ticon?: ReactNode;\n\t/** Lower values render first. Defaults to 100. */\n\torder?: number;\n\trun(context: PluginFileExplorerToolbarContext): void | Promise<void>;\n}\n\nexport interface PluginFileExplorerDecoration {\n\t/** Replaces the host's default file/folder icon. */\n\ticon?: ReactNode;\n\t/** Compact status text rendered after the filename. Keep to one or two characters. */\n\tbadge?: string;\n\ttooltip?: string;\n}\n\nexport interface PluginFileExplorerDecorationProvider {\n\tid: string;\n\twhen?: PluginFileExplorerWhen;\n\t/** Higher values win when multiple providers return a decoration. Defaults to 0. */\n\tpriority?: number;\n\tprovideDecoration(\n\t\tentry: PluginFileExplorerEntry,\n\t): PluginFileExplorerDecoration | null;\n}\n\nexport type PluginFileExplorerChange =\n\t| { type: \"changed\" | \"created\" | \"deleted\"; path: string }\n\t| { type: \"moved\"; path: string; oldPath: string };\n\nexport interface PluginFileExplorerRevealOptions {\n\t/** Select the revealed entry. Defaults to true. */\n\tselect?: boolean;\n\t/** Move DOM focus to the row after revealing it. Defaults to false. */\n\tfocus?: boolean;\n}\n\nexport interface PluginFileExplorerApi {\n\tgetWorkspaceRoots(): readonly PluginWorkspaceRoot[];\n\tgetSelection(): readonly PluginFileExplorerEntry[];\n\treveal(path: string, options?: PluginFileExplorerRevealOptions): Promise<void>;\n\trefresh(path?: string): Promise<void>;\n\tonDidChangeSelection(listener: (selection: readonly PluginFileExplorerEntry[]) => void): Disposable;\n\tonDidChangeFiles(listener: (changes: readonly PluginFileExplorerChange[]) => void): Disposable;\n\tregisterContextMenuAction(contribution: PluginFileExplorerContextMenuContribution): Disposable;\n\tregisterToolbarAction(contribution: PluginFileExplorerToolbarContribution): Disposable;\n\tregisterDecorationProvider(contribution: PluginFileExplorerDecorationProvider): Disposable;\n}\n"]}
package/dist/fs.d.ts CHANGED
@@ -19,9 +19,23 @@ export interface PluginFsReadResult {
19
19
  content: string;
20
20
  encoding: "utf8" | "base64";
21
21
  }
22
+ export interface PluginFsBinaryReadResult {
23
+ data: string;
24
+ mimeType: string;
25
+ size: number;
26
+ }
27
+ export interface PluginFsSaveAsOptions {
28
+ title?: string;
29
+ /** Defaults to a single filter derived from the default file name's extension. */
30
+ filters?: Array<{
31
+ name: string;
32
+ extensions: string[];
33
+ }>;
34
+ }
22
35
  export interface PluginFsApi {
23
36
  readDir(dirPath: string): Promise<PluginFsEntry[]>;
24
37
  readFile(filePath: string): Promise<PluginFsReadResult>;
38
+ readBinaryFile(filePath: string): Promise<PluginFsBinaryReadResult>;
25
39
  /** Pass `encoding: "base64"` to write binary payloads (decoded from base64 text). */
26
40
  writeFile(filePath: string, content: string, encoding?: "utf8" | "base64"): Promise<void>;
27
41
  stat(filePath: string): Promise<PluginFsStatResult | null>;
@@ -30,5 +44,16 @@ export interface PluginFsApi {
30
44
  move(sourcePath: string, destDir: string): Promise<void>;
31
45
  createDirectory(dirPath: string): Promise<void>;
32
46
  listFilesRecursive(rootPath: string): Promise<PluginFsFileRef[]>;
47
+ /**
48
+ * Write bytes to a path the user picks in the host's native save dialog.
49
+ * Unlike {@link writeFile} the destination is not restricted to project
50
+ * roots — the user chooses it, so nothing lands on disk without an explicit
51
+ * confirmation. Resolves to the saved path, or `null` if the user cancels.
52
+ * Requires `fs.write`.
53
+ */
54
+ saveAs(defaultFileName: string, content: string, encoding?: "utf8" | "base64", options?: PluginFsSaveAsOptions): Promise<string | null>;
55
+ /** Watch one directory for host-debounced changes. Requires `fs.read`. */
56
+ watchDirectory(dirPath: string, listener: (changedPath: string) => void): Disposable;
33
57
  }
58
+ import type { Disposable } from "./disposable.js";
34
59
  //# sourceMappingURL=fs.d.ts.map
package/dist/fs.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD,qFAAqF;IACrF,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACjE","sourcesContent":["export interface PluginFsEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginFsFileRef {\n\tname: string;\n\tpath: string;\n\trelPath: string;\n}\n\nexport interface PluginFsStatResult {\n\tsize: number;\n\tmodifiedAt: number;\n\tcreatedAt: number;\n}\n\nexport interface PluginFsReadResult {\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\nexport interface PluginFsApi {\n\treadDir(dirPath: string): Promise<PluginFsEntry[]>;\n\treadFile(filePath: string): Promise<PluginFsReadResult>;\n\t/** Pass `encoding: \"base64\"` to write binary payloads (decoded from base64 text). */\n\twriteFile(filePath: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n\tstat(filePath: string): Promise<PluginFsStatResult | null>;\n\trename(oldPath: string, newPath: string): Promise<void>;\n\tdelete(targetPath: string): Promise<void>;\n\tmove(sourcePath: string, destDir: string): Promise<void>;\n\tcreateDirectory(dirPath: string): Promise<void>;\n\tlistFilesRecursive(rootPath: string): Promise<PluginFsFileRef[]>;\n}\n"]}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACpE,qFAAqF;IACrF,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACjE;;;;;;OAMG;IACH,MAAM,CACL,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,EAC5B,OAAO,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1B,0EAA0E;IAC1E,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;CACrF;AACD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export interface PluginFsEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginFsFileRef {\n\tname: string;\n\tpath: string;\n\trelPath: string;\n}\n\nexport interface PluginFsStatResult {\n\tsize: number;\n\tmodifiedAt: number;\n\tcreatedAt: number;\n}\n\nexport interface PluginFsReadResult {\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\nexport interface PluginFsBinaryReadResult {\n\tdata: string;\n\tmimeType: string;\n\tsize: number;\n}\n\nexport interface PluginFsSaveAsOptions {\n\ttitle?: string;\n\t/** Defaults to a single filter derived from the default file name's extension. */\n\tfilters?: Array<{ name: string; extensions: string[] }>;\n}\n\nexport interface PluginFsApi {\n\treadDir(dirPath: string): Promise<PluginFsEntry[]>;\n\treadFile(filePath: string): Promise<PluginFsReadResult>;\n\treadBinaryFile(filePath: string): Promise<PluginFsBinaryReadResult>;\n\t/** Pass `encoding: \"base64\"` to write binary payloads (decoded from base64 text). */\n\twriteFile(filePath: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n\tstat(filePath: string): Promise<PluginFsStatResult | null>;\n\trename(oldPath: string, newPath: string): Promise<void>;\n\tdelete(targetPath: string): Promise<void>;\n\tmove(sourcePath: string, destDir: string): Promise<void>;\n\tcreateDirectory(dirPath: string): Promise<void>;\n\tlistFilesRecursive(rootPath: string): Promise<PluginFsFileRef[]>;\n\t/**\n\t * Write bytes to a path the user picks in the host's native save dialog.\n\t * Unlike {@link writeFile} the destination is not restricted to project\n\t * roots — the user chooses it, so nothing lands on disk without an explicit\n\t * confirmation. Resolves to the saved path, or `null` if the user cancels.\n\t * Requires `fs.write`.\n\t */\n\tsaveAs(\n\t\tdefaultFileName: string,\n\t\tcontent: string,\n\t\tencoding?: \"utf8\" | \"base64\",\n\t\toptions?: PluginFsSaveAsOptions,\n\t): Promise<string | null>;\n\t/** Watch one directory for host-debounced changes. Requires `fs.read`. */\n\twatchDirectory(dirPath: string, listener: (changedPath: string) => void): Disposable;\n}\nimport type { Disposable } from \"./disposable.js\";\n"]}
package/dist/fs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"","sourcesContent":["export interface PluginFsEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginFsFileRef {\n\tname: string;\n\tpath: string;\n\trelPath: string;\n}\n\nexport interface PluginFsStatResult {\n\tsize: number;\n\tmodifiedAt: number;\n\tcreatedAt: number;\n}\n\nexport interface PluginFsReadResult {\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\nexport interface PluginFsApi {\n\treadDir(dirPath: string): Promise<PluginFsEntry[]>;\n\treadFile(filePath: string): Promise<PluginFsReadResult>;\n\t/** Pass `encoding: \"base64\"` to write binary payloads (decoded from base64 text). */\n\twriteFile(filePath: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n\tstat(filePath: string): Promise<PluginFsStatResult | null>;\n\trename(oldPath: string, newPath: string): Promise<void>;\n\tdelete(targetPath: string): Promise<void>;\n\tmove(sourcePath: string, destDir: string): Promise<void>;\n\tcreateDirectory(dirPath: string): Promise<void>;\n\tlistFilesRecursive(rootPath: string): Promise<PluginFsFileRef[]>;\n}\n"]}
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"","sourcesContent":["export interface PluginFsEntry {\n\tname: string;\n\tpath: string;\n\tisDirectory: boolean;\n\tsize: number;\n\tmodifiedAt: number;\n}\n\nexport interface PluginFsFileRef {\n\tname: string;\n\tpath: string;\n\trelPath: string;\n}\n\nexport interface PluginFsStatResult {\n\tsize: number;\n\tmodifiedAt: number;\n\tcreatedAt: number;\n}\n\nexport interface PluginFsReadResult {\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\nexport interface PluginFsBinaryReadResult {\n\tdata: string;\n\tmimeType: string;\n\tsize: number;\n}\n\nexport interface PluginFsSaveAsOptions {\n\ttitle?: string;\n\t/** Defaults to a single filter derived from the default file name's extension. */\n\tfilters?: Array<{ name: string; extensions: string[] }>;\n}\n\nexport interface PluginFsApi {\n\treadDir(dirPath: string): Promise<PluginFsEntry[]>;\n\treadFile(filePath: string): Promise<PluginFsReadResult>;\n\treadBinaryFile(filePath: string): Promise<PluginFsBinaryReadResult>;\n\t/** Pass `encoding: \"base64\"` to write binary payloads (decoded from base64 text). */\n\twriteFile(filePath: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n\tstat(filePath: string): Promise<PluginFsStatResult | null>;\n\trename(oldPath: string, newPath: string): Promise<void>;\n\tdelete(targetPath: string): Promise<void>;\n\tmove(sourcePath: string, destDir: string): Promise<void>;\n\tcreateDirectory(dirPath: string): Promise<void>;\n\tlistFilesRecursive(rootPath: string): Promise<PluginFsFileRef[]>;\n\t/**\n\t * Write bytes to a path the user picks in the host's native save dialog.\n\t * Unlike {@link writeFile} the destination is not restricted to project\n\t * roots — the user chooses it, so nothing lands on disk without an explicit\n\t * confirmation. Resolves to the saved path, or `null` if the user cancels.\n\t * Requires `fs.write`.\n\t */\n\tsaveAs(\n\t\tdefaultFileName: string,\n\t\tcontent: string,\n\t\tencoding?: \"utf8\" | \"base64\",\n\t\toptions?: PluginFsSaveAsOptions,\n\t): Promise<string | null>;\n\t/** Watch one directory for host-debounced changes. Requires `fs.read`. */\n\twatchDirectory(dirPath: string, listener: (changedPath: string) => void): Disposable;\n}\nimport type { Disposable } from \"./disposable.js\";\n"]}
package/dist/hooks.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ConversationMessage, ConversationState } from "./conversation.js";
2
2
  import type { PluginLocales, PluginTranslate } from "./i18n.js";
3
- import type { PluginImageRef } from "./images.js";
3
+ import type { PluginPromptAttachment } from "./prompt-attachment.js";
4
4
  export interface PluginI18nContextValue {
5
5
  /** This plugin's catalogs, keyed by locale code. */
6
6
  locales: PluginLocales;
@@ -30,10 +30,8 @@ export declare function useActiveConversation(): ConversationState;
30
30
  /** Reactive: the active conversation's messages. */
31
31
  export declare function useConversationMessages(): ConversationMessage[];
32
32
  /**
33
- * Reactive: the image currently bound as the edit target via
34
- * `ui.setEditImageAttachment` (or null). Single source of truth for the
35
- * "selected for edit" highlight — clears automatically when the host drops the
36
- * attachment (send, capsule close, or session switch).
33
+ * Reactive: the plugin-owned one-shot context attached to the next prompt.
34
+ * Clears automatically after send, capsule close, or session switch.
37
35
  */
38
- export declare function useEditImageAttachment(): PluginImageRef | null;
36
+ export declare function usePromptAttachment(): PluginPromptAttachment | null;
39
37
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEhF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,sBAAsB;IACtC,oDAAoD;IACpD,OAAO,EAAE,aAAa,CAAC;IACvB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iDAG9B,CAAC;AAEH,MAAM,WAAW,iBAAiB;IACjC,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,CAAC,EAAE,eAAe,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,IAAI,iBAAiB,CAEzD;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,IAAI,mBAAmB,EAAE,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,GAAG,IAAI,CAE9D","sourcesContent":["import { createContext, useCallback, useContext } from \"react\";\nimport type { ConversationMessage, ConversationState } from \"./conversation.js\";\nimport { requireBridge } from \"./host-bridge.js\";\nimport type { PluginLocales, PluginTranslate } from \"./i18n.js\";\nimport { resolveCatalogKey } from \"./i18n.js\";\nimport type { PluginImageRef } from \"./images.js\";\n\n// ─── i18n context (host-provided, per plugin) ───\n\nexport interface PluginI18nContextValue {\n\t/** This plugin's catalogs, keyed by locale code. */\n\tlocales: PluginLocales;\n\t/** Fallback locale when a key is missing in the current locale. */\n\tdefaultLocale: string;\n}\n\n/**\n * Internal: the host wraps plugin-rendered components in this context's Provider,\n * carrying THIS plugin's catalogs. Module Federation shares this single SDK\n * instance, so the value the host provides is visible to {@link useTranslation}.\n */\nexport const __PluginI18nContext = createContext<PluginI18nContextValue>({\n\tlocales: {},\n\tdefaultLocale: \"zh\",\n});\n\nexport interface PluginTranslation {\n\t/** The host's current locale code (e.g. \"zh\"). */\n\tlocale: string;\n\t/** Resolve a bare catalog key at the current locale, with optional `{{params}}`. */\n\tt: PluginTranslate;\n}\n\n/**\n * Reactive translation for plugin React components — re-renders when the host\n * language changes. `t` resolves a BARE catalog key (no `%...%` wrapper) against\n * THIS plugin's catalogs; the host provides them via __PluginI18nContext.\n */\nexport function useTranslation(): PluginTranslation {\n\tconst locale = requireBridge().useLocale();\n\tconst { locales, defaultLocale } = useContext(__PluginI18nContext);\n\tconst t = useCallback<PluginTranslate>(\n\t\t(key, params) => resolveCatalogKey(key, locales, locale, defaultLocale, params),\n\t\t[locales, locale, defaultLocale],\n\t);\n\treturn { locale, t };\n}\n\n/** Reactive: the currently-active conversation's state. */\nexport function useActiveConversation(): ConversationState {\n\treturn requireBridge().useActiveConversation();\n}\n\n/** Reactive: the active conversation's messages. */\nexport function useConversationMessages(): ConversationMessage[] {\n\treturn requireBridge().useConversationMessages();\n}\n\n/**\n * Reactive: the image currently bound as the edit target via\n * `ui.setEditImageAttachment` (or null). Single source of truth for the\n * \"selected for edit\" highlight — clears automatically when the host drops the\n * attachment (send, capsule close, or session switch).\n */\nexport function useEditImageAttachment(): PluginImageRef | null {\n\treturn requireBridge().useEditImageAttachment();\n}\n"]}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEhF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAIrE,MAAM,WAAW,sBAAsB;IACtC,oDAAoD;IACpD,OAAO,EAAE,aAAa,CAAC;IACvB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iDAG9B,CAAC;AAEH,MAAM,WAAW,iBAAiB;IACjC,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,CAAC,EAAE,eAAe,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,IAAI,iBAAiB,CAEzD;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,IAAI,mBAAmB,EAAE,CAE/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,sBAAsB,GAAG,IAAI,CAEnE","sourcesContent":["import { createContext, useCallback, useContext } from \"react\";\nimport type { ConversationMessage, ConversationState } from \"./conversation.js\";\nimport { requireBridge } from \"./host-bridge.js\";\nimport type { PluginLocales, PluginTranslate } from \"./i18n.js\";\nimport { resolveCatalogKey } from \"./i18n.js\";\nimport type { PluginPromptAttachment } from \"./prompt-attachment.js\";\n\n// ─── i18n context (host-provided, per plugin) ───\n\nexport interface PluginI18nContextValue {\n\t/** This plugin's catalogs, keyed by locale code. */\n\tlocales: PluginLocales;\n\t/** Fallback locale when a key is missing in the current locale. */\n\tdefaultLocale: string;\n}\n\n/**\n * Internal: the host wraps plugin-rendered components in this context's Provider,\n * carrying THIS plugin's catalogs. Module Federation shares this single SDK\n * instance, so the value the host provides is visible to {@link useTranslation}.\n */\nexport const __PluginI18nContext = createContext<PluginI18nContextValue>({\n\tlocales: {},\n\tdefaultLocale: \"zh\",\n});\n\nexport interface PluginTranslation {\n\t/** The host's current locale code (e.g. \"zh\"). */\n\tlocale: string;\n\t/** Resolve a bare catalog key at the current locale, with optional `{{params}}`. */\n\tt: PluginTranslate;\n}\n\n/**\n * Reactive translation for plugin React components — re-renders when the host\n * language changes. `t` resolves a BARE catalog key (no `%...%` wrapper) against\n * THIS plugin's catalogs; the host provides them via __PluginI18nContext.\n */\nexport function useTranslation(): PluginTranslation {\n\tconst locale = requireBridge().useLocale();\n\tconst { locales, defaultLocale } = useContext(__PluginI18nContext);\n\tconst t = useCallback<PluginTranslate>(\n\t\t(key, params) => resolveCatalogKey(key, locales, locale, defaultLocale, params),\n\t\t[locales, locale, defaultLocale],\n\t);\n\treturn { locale, t };\n}\n\n/** Reactive: the currently-active conversation's state. */\nexport function useActiveConversation(): ConversationState {\n\treturn requireBridge().useActiveConversation();\n}\n\n/** Reactive: the active conversation's messages. */\nexport function useConversationMessages(): ConversationMessage[] {\n\treturn requireBridge().useConversationMessages();\n}\n\n/**\n * Reactive: the plugin-owned one-shot context attached to the next prompt.\n * Clears automatically after send, capsule close, or session switch.\n */\nexport function usePromptAttachment(): PluginPromptAttachment | null {\n\treturn requireBridge().usePromptAttachment();\n}\n"]}
package/dist/hooks.js CHANGED
@@ -30,12 +30,10 @@ export function useConversationMessages() {
30
30
  return requireBridge().useConversationMessages();
31
31
  }
32
32
  /**
33
- * Reactive: the image currently bound as the edit target via
34
- * `ui.setEditImageAttachment` (or null). Single source of truth for the
35
- * "selected for edit" highlight — clears automatically when the host drops the
36
- * attachment (send, capsule close, or session switch).
33
+ * Reactive: the plugin-owned one-shot context attached to the next prompt.
34
+ * Clears automatically after send, capsule close, or session switch.
37
35
  */
38
- export function useEditImageAttachment() {
39
- return requireBridge().useEditImageAttachment();
36
+ export function usePromptAttachment() {
37
+ return requireBridge().usePromptAttachment();
40
38
  }
41
39
  //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAY9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAyB;IACxE,OAAO,EAAE,EAAE;IACX,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AASH;;;;GAIG;AACH,MAAM,UAAU,cAAc,GAAsB;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC,SAAS,EAAE,CAAC;IAC3C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,CAAC,GAAG,WAAW,CACpB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAC/E,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAChC,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAAA,CACrB;AAED,2DAA2D;AAC3D,MAAM,UAAU,qBAAqB,GAAsB;IAC1D,OAAO,aAAa,EAAE,CAAC,qBAAqB,EAAE,CAAC;AAAA,CAC/C;AAED,oDAAoD;AACpD,MAAM,UAAU,uBAAuB,GAA0B;IAChE,OAAO,aAAa,EAAE,CAAC,uBAAuB,EAAE,CAAC;AAAA,CACjD;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,GAA0B;IAC/D,OAAO,aAAa,EAAE,CAAC,sBAAsB,EAAE,CAAC;AAAA,CAChD","sourcesContent":["import { createContext, useCallback, useContext } from \"react\";\nimport type { ConversationMessage, ConversationState } from \"./conversation.js\";\nimport { requireBridge } from \"./host-bridge.js\";\nimport type { PluginLocales, PluginTranslate } from \"./i18n.js\";\nimport { resolveCatalogKey } from \"./i18n.js\";\nimport type { PluginImageRef } from \"./images.js\";\n\n// ─── i18n context (host-provided, per plugin) ───\n\nexport interface PluginI18nContextValue {\n\t/** This plugin's catalogs, keyed by locale code. */\n\tlocales: PluginLocales;\n\t/** Fallback locale when a key is missing in the current locale. */\n\tdefaultLocale: string;\n}\n\n/**\n * Internal: the host wraps plugin-rendered components in this context's Provider,\n * carrying THIS plugin's catalogs. Module Federation shares this single SDK\n * instance, so the value the host provides is visible to {@link useTranslation}.\n */\nexport const __PluginI18nContext = createContext<PluginI18nContextValue>({\n\tlocales: {},\n\tdefaultLocale: \"zh\",\n});\n\nexport interface PluginTranslation {\n\t/** The host's current locale code (e.g. \"zh\"). */\n\tlocale: string;\n\t/** Resolve a bare catalog key at the current locale, with optional `{{params}}`. */\n\tt: PluginTranslate;\n}\n\n/**\n * Reactive translation for plugin React components — re-renders when the host\n * language changes. `t` resolves a BARE catalog key (no `%...%` wrapper) against\n * THIS plugin's catalogs; the host provides them via __PluginI18nContext.\n */\nexport function useTranslation(): PluginTranslation {\n\tconst locale = requireBridge().useLocale();\n\tconst { locales, defaultLocale } = useContext(__PluginI18nContext);\n\tconst t = useCallback<PluginTranslate>(\n\t\t(key, params) => resolveCatalogKey(key, locales, locale, defaultLocale, params),\n\t\t[locales, locale, defaultLocale],\n\t);\n\treturn { locale, t };\n}\n\n/** Reactive: the currently-active conversation's state. */\nexport function useActiveConversation(): ConversationState {\n\treturn requireBridge().useActiveConversation();\n}\n\n/** Reactive: the active conversation's messages. */\nexport function useConversationMessages(): ConversationMessage[] {\n\treturn requireBridge().useConversationMessages();\n}\n\n/**\n * Reactive: the image currently bound as the edit target via\n * `ui.setEditImageAttachment` (or null). Single source of truth for the\n * \"selected for edit\" highlight — clears automatically when the host drops the\n * attachment (send, capsule close, or session switch).\n */\nexport function useEditImageAttachment(): PluginImageRef | null {\n\treturn requireBridge().useEditImageAttachment();\n}\n"]}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAY9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAyB;IACxE,OAAO,EAAE,EAAE;IACX,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AASH;;;;GAIG;AACH,MAAM,UAAU,cAAc,GAAsB;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC,SAAS,EAAE,CAAC;IAC3C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,CAAC,GAAG,WAAW,CACpB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAC/E,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAChC,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAAA,CACrB;AAED,2DAA2D;AAC3D,MAAM,UAAU,qBAAqB,GAAsB;IAC1D,OAAO,aAAa,EAAE,CAAC,qBAAqB,EAAE,CAAC;AAAA,CAC/C;AAED,oDAAoD;AACpD,MAAM,UAAU,uBAAuB,GAA0B;IAChE,OAAO,aAAa,EAAE,CAAC,uBAAuB,EAAE,CAAC;AAAA,CACjD;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,GAAkC;IACpE,OAAO,aAAa,EAAE,CAAC,mBAAmB,EAAE,CAAC;AAAA,CAC7C","sourcesContent":["import { createContext, useCallback, useContext } from \"react\";\nimport type { ConversationMessage, ConversationState } from \"./conversation.js\";\nimport { requireBridge } from \"./host-bridge.js\";\nimport type { PluginLocales, PluginTranslate } from \"./i18n.js\";\nimport { resolveCatalogKey } from \"./i18n.js\";\nimport type { PluginPromptAttachment } from \"./prompt-attachment.js\";\n\n// ─── i18n context (host-provided, per plugin) ───\n\nexport interface PluginI18nContextValue {\n\t/** This plugin's catalogs, keyed by locale code. */\n\tlocales: PluginLocales;\n\t/** Fallback locale when a key is missing in the current locale. */\n\tdefaultLocale: string;\n}\n\n/**\n * Internal: the host wraps plugin-rendered components in this context's Provider,\n * carrying THIS plugin's catalogs. Module Federation shares this single SDK\n * instance, so the value the host provides is visible to {@link useTranslation}.\n */\nexport const __PluginI18nContext = createContext<PluginI18nContextValue>({\n\tlocales: {},\n\tdefaultLocale: \"zh\",\n});\n\nexport interface PluginTranslation {\n\t/** The host's current locale code (e.g. \"zh\"). */\n\tlocale: string;\n\t/** Resolve a bare catalog key at the current locale, with optional `{{params}}`. */\n\tt: PluginTranslate;\n}\n\n/**\n * Reactive translation for plugin React components — re-renders when the host\n * language changes. `t` resolves a BARE catalog key (no `%...%` wrapper) against\n * THIS plugin's catalogs; the host provides them via __PluginI18nContext.\n */\nexport function useTranslation(): PluginTranslation {\n\tconst locale = requireBridge().useLocale();\n\tconst { locales, defaultLocale } = useContext(__PluginI18nContext);\n\tconst t = useCallback<PluginTranslate>(\n\t\t(key, params) => resolveCatalogKey(key, locales, locale, defaultLocale, params),\n\t\t[locales, locale, defaultLocale],\n\t);\n\treturn { locale, t };\n}\n\n/** Reactive: the currently-active conversation's state. */\nexport function useActiveConversation(): ConversationState {\n\treturn requireBridge().useActiveConversation();\n}\n\n/** Reactive: the active conversation's messages. */\nexport function useConversationMessages(): ConversationMessage[] {\n\treturn requireBridge().useConversationMessages();\n}\n\n/**\n * Reactive: the plugin-owned one-shot context attached to the next prompt.\n * Clears automatically after send, capsule close, or session switch.\n */\nexport function usePromptAttachment(): PluginPromptAttachment | null {\n\treturn requireBridge().usePromptAttachment();\n}\n"]}