@lapis-notes/ai 0.1.0

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 (266) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE.md +8 -0
  3. package/README.md +20 -0
  4. package/dist/ai-plugin.d.ts +88 -0
  5. package/dist/ai-plugin.js +742 -0
  6. package/dist/bootstrap/build.d.ts +15 -0
  7. package/dist/bootstrap/build.js +28 -0
  8. package/dist/bootstrap/folder-instructions.d.ts +4 -0
  9. package/dist/bootstrap/folder-instructions.js +49 -0
  10. package/dist/bootstrap/format.d.ts +2 -0
  11. package/dist/bootstrap/format.js +46 -0
  12. package/dist/bootstrap/instructions.d.ts +1 -0
  13. package/dist/bootstrap/instructions.js +8 -0
  14. package/dist/bootstrap/types.d.ts +36 -0
  15. package/dist/bootstrap/types.js +3 -0
  16. package/dist/catalog/ai-catalog-panel.svelte +742 -0
  17. package/dist/catalog/ai-catalog-panel.svelte.d.ts +13 -0
  18. package/dist/catalog/ai-catalog-view-type.d.ts +1 -0
  19. package/dist/catalog/ai-catalog-view-type.js +1 -0
  20. package/dist/catalog/ai-catalog-view.d.ts +22 -0
  21. package/dist/catalog/ai-catalog-view.js +48 -0
  22. package/dist/catalog/filter.d.ts +3 -0
  23. package/dist/catalog/filter.js +24 -0
  24. package/dist/catalog/inventory.d.ts +21 -0
  25. package/dist/catalog/inventory.js +255 -0
  26. package/dist/catalog/tree.d.ts +12 -0
  27. package/dist/catalog/tree.js +60 -0
  28. package/dist/catalog/types.d.ts +44 -0
  29. package/dist/catalog/types.js +1 -0
  30. package/dist/chat/ai-approval-card.svelte +54 -0
  31. package/dist/chat/ai-approval-card.svelte.d.ts +9 -0
  32. package/dist/chat/ai-chat-panel.svelte +1288 -0
  33. package/dist/chat/ai-chat-panel.svelte.d.ts +50 -0
  34. package/dist/chat/ai-inventory-result.css +55 -0
  35. package/dist/chat/ai-inventory-result.svelte +63 -0
  36. package/dist/chat/ai-inventory-result.svelte.d.ts +5 -0
  37. package/dist/chat/ai-question-card.svelte +132 -0
  38. package/dist/chat/ai-question-card.svelte.d.ts +9 -0
  39. package/dist/chat/ai-view-bootstrap.d.ts +13 -0
  40. package/dist/chat/ai-view-bootstrap.js +86 -0
  41. package/dist/chat/ai-view-panel.svelte +89 -0
  42. package/dist/chat/ai-view-panel.svelte.d.ts +13 -0
  43. package/dist/chat/ai-view-type.d.ts +1 -0
  44. package/dist/chat/ai-view-type.js +1 -0
  45. package/dist/chat/ai-view.d.ts +60 -0
  46. package/dist/chat/ai-view.js +121 -0
  47. package/dist/chat/chat-controller.svelte.d.ts +82 -0
  48. package/dist/chat/chat-controller.svelte.js +1926 -0
  49. package/dist/chat/chat-items.d.ts +88 -0
  50. package/dist/chat/chat-items.js +9 -0
  51. package/dist/chat/chat-mentions.d.ts +15 -0
  52. package/dist/chat/chat-mentions.js +77 -0
  53. package/dist/chat/chat-result-views.d.ts +5 -0
  54. package/dist/chat/chat-result-views.js +15 -0
  55. package/dist/chat/chat-session.d.ts +28 -0
  56. package/dist/chat/chat-session.js +50 -0
  57. package/dist/chat/chat-status.d.ts +1 -0
  58. package/dist/chat/chat-status.js +3 -0
  59. package/dist/chat/chat-time.d.ts +18 -0
  60. package/dist/chat/chat-time.js +90 -0
  61. package/dist/chat/chat-tool-display.d.ts +17 -0
  62. package/dist/chat/chat-tool-display.js +213 -0
  63. package/dist/chat/chat-tool-identity.d.ts +4 -0
  64. package/dist/chat/chat-tool-identity.js +42 -0
  65. package/dist/chat/chat-trace.d.ts +6 -0
  66. package/dist/chat/chat-trace.js +256 -0
  67. package/dist/chat/live-runtime-unavailable.d.ts +1 -0
  68. package/dist/chat/live-runtime-unavailable.js +1 -0
  69. package/dist/commands/agent.d.ts +8 -0
  70. package/dist/commands/agent.js +38 -0
  71. package/dist/commands/catalog.d.ts +18 -0
  72. package/dist/commands/catalog.js +115 -0
  73. package/dist/commands/discovery.d.ts +36 -0
  74. package/dist/commands/discovery.js +151 -0
  75. package/dist/commands/groups.d.ts +16 -0
  76. package/dist/commands/groups.js +121 -0
  77. package/dist/commands/inspect.d.ts +18 -0
  78. package/dist/commands/inspect.js +29 -0
  79. package/dist/commands/markdown.d.ts +21 -0
  80. package/dist/commands/markdown.js +117 -0
  81. package/dist/commands/parser.d.ts +4 -0
  82. package/dist/commands/parser.js +24 -0
  83. package/dist/commands/reserved.d.ts +4 -0
  84. package/dist/commands/reserved.js +107 -0
  85. package/dist/commands/router.d.ts +17 -0
  86. package/dist/commands/router.js +170 -0
  87. package/dist/commands/seed.d.ts +4 -0
  88. package/dist/commands/seed.js +8 -0
  89. package/dist/commands/types.d.ts +54 -0
  90. package/dist/commands/types.js +1 -0
  91. package/dist/commands/user-agents-node.d.ts +3 -0
  92. package/dist/commands/user-agents-node.js +52 -0
  93. package/dist/commands/user-agents.d.ts +22 -0
  94. package/dist/commands/user-agents.js +40 -0
  95. package/dist/conversations/approval-grants.d.ts +20 -0
  96. package/dist/conversations/approval-grants.js +75 -0
  97. package/dist/conversations/binding-state.d.ts +6 -0
  98. package/dist/conversations/binding-state.js +35 -0
  99. package/dist/conversations/context-handoff.d.ts +25 -0
  100. package/dist/conversations/context-handoff.js +207 -0
  101. package/dist/conversations/conversation-index-coordinator.d.ts +18 -0
  102. package/dist/conversations/conversation-index-coordinator.js +81 -0
  103. package/dist/conversations/conversation-index.d.ts +16 -0
  104. package/dist/conversations/conversation-index.js +125 -0
  105. package/dist/conversations/conversation-locator.d.ts +2 -0
  106. package/dist/conversations/conversation-locator.js +20 -0
  107. package/dist/conversations/conversation-palette.d.ts +18 -0
  108. package/dist/conversations/conversation-palette.js +29 -0
  109. package/dist/conversations/conversation-repository.d.ts +39 -0
  110. package/dist/conversations/conversation-repository.js +213 -0
  111. package/dist/conversations/handoff-summary.d.ts +48 -0
  112. package/dist/conversations/handoff-summary.js +269 -0
  113. package/dist/conversations/hashes.d.ts +5 -0
  114. package/dist/conversations/hashes.js +40 -0
  115. package/dist/conversations/history-creation-scope.d.ts +12 -0
  116. package/dist/conversations/history-creation-scope.js +44 -0
  117. package/dist/conversations/jsonl.d.ts +10 -0
  118. package/dist/conversations/jsonl.js +41 -0
  119. package/dist/conversations/memory-transcript-store.d.ts +15 -0
  120. package/dist/conversations/memory-transcript-store.js +119 -0
  121. package/dist/conversations/paths.d.ts +14 -0
  122. package/dist/conversations/paths.js +92 -0
  123. package/dist/conversations/redaction.d.ts +13 -0
  124. package/dist/conversations/redaction.js +94 -0
  125. package/dist/conversations/reveal-scope.d.ts +3 -0
  126. package/dist/conversations/reveal-scope.js +8 -0
  127. package/dist/conversations/scope-resolver.d.ts +11 -0
  128. package/dist/conversations/scope-resolver.js +18 -0
  129. package/dist/conversations/scope-tree.d.ts +10 -0
  130. package/dist/conversations/scope-tree.js +71 -0
  131. package/dist/conversations/transcript-projection.d.ts +9 -0
  132. package/dist/conversations/transcript-projection.js +409 -0
  133. package/dist/conversations/transcript-store.d.ts +24 -0
  134. package/dist/conversations/transcript-store.js +27 -0
  135. package/dist/conversations/types.d.ts +224 -0
  136. package/dist/conversations/types.js +12 -0
  137. package/dist/conversations/validation.d.ts +4 -0
  138. package/dist/conversations/validation.js +383 -0
  139. package/dist/conversations/vault-transcript-store.d.ts +22 -0
  140. package/dist/conversations/vault-transcript-store.js +219 -0
  141. package/dist/core/event-queue.d.ts +6 -0
  142. package/dist/core/event-queue.js +39 -0
  143. package/dist/core/types.d.ts +241 -0
  144. package/dist/core/types.js +50 -0
  145. package/dist/history/ai-history-panel.svelte +937 -0
  146. package/dist/history/ai-history-panel.svelte.d.ts +17 -0
  147. package/dist/history/ai-history-view-type.d.ts +1 -0
  148. package/dist/history/ai-history-view-type.js +1 -0
  149. package/dist/history/ai-history-view.d.ts +26 -0
  150. package/dist/history/ai-history-view.js +51 -0
  151. package/dist/history/conversation-history-tree.d.ts +15 -0
  152. package/dist/history/conversation-history-tree.js +71 -0
  153. package/dist/host/agent-workspace.d.ts +6 -0
  154. package/dist/host/agent-workspace.js +16 -0
  155. package/dist/host/create-host-runtimes.d.ts +2 -0
  156. package/dist/host/create-host-runtimes.js +14 -0
  157. package/dist/host/desktop-process-host.d.ts +6 -0
  158. package/dist/host/desktop-process-host.js +74 -0
  159. package/dist/host/host-runtime-availability.d.ts +1 -0
  160. package/dist/host/host-runtime-availability.js +3 -0
  161. package/dist/host/process-host.d.ts +31 -0
  162. package/dist/host/process-host.js +6 -0
  163. package/dist/index.d.ts +69 -0
  164. package/dist/index.js +49 -0
  165. package/dist/jsonl/ai-jsonl-preview.d.ts +27 -0
  166. package/dist/jsonl/ai-jsonl-preview.js +68 -0
  167. package/dist/jsonl/ai-jsonl-view-type.d.ts +1 -0
  168. package/dist/jsonl/ai-jsonl-view-type.js +1 -0
  169. package/dist/jsonl/ai-jsonl-view.d.ts +16 -0
  170. package/dist/jsonl/ai-jsonl-view.js +57 -0
  171. package/dist/jsonl/ai-jsonl-view.svelte +260 -0
  172. package/dist/jsonl/ai-jsonl-view.svelte.d.ts +9 -0
  173. package/dist/memory/candidate-extractor.d.ts +25 -0
  174. package/dist/memory/candidate-extractor.js +191 -0
  175. package/dist/memory/forget-confirmation.d.ts +3 -0
  176. package/dist/memory/forget-confirmation.js +45 -0
  177. package/dist/memory/hashes.d.ts +5 -0
  178. package/dist/memory/hashes.js +37 -0
  179. package/dist/memory/memory-ingestion-coordinator.d.ts +19 -0
  180. package/dist/memory/memory-ingestion-coordinator.js +108 -0
  181. package/dist/memory/memory-record-store.d.ts +62 -0
  182. package/dist/memory/memory-record-store.js +369 -0
  183. package/dist/memory/memory-scheduler.d.ts +21 -0
  184. package/dist/memory/memory-scheduler.js +143 -0
  185. package/dist/memory/memory-tools.d.ts +61 -0
  186. package/dist/memory/memory-tools.js +99 -0
  187. package/dist/memory/native-memory-service.d.ts +72 -0
  188. package/dist/memory/native-memory-service.js +1256 -0
  189. package/dist/memory/paths.d.ts +13 -0
  190. package/dist/memory/paths.js +60 -0
  191. package/dist/memory/runtime-consolidation-provider.d.ts +18 -0
  192. package/dist/memory/runtime-consolidation-provider.js +154 -0
  193. package/dist/memory/types.d.ts +139 -0
  194. package/dist/memory/types.js +1 -0
  195. package/dist/providers/acp-model-provider.d.ts +11 -0
  196. package/dist/providers/acp-model-provider.js +99 -0
  197. package/dist/providers/codex-model-catalog.d.ts +7 -0
  198. package/dist/providers/codex-model-catalog.js +179 -0
  199. package/dist/providers/codex-model-provider.d.ts +12 -0
  200. package/dist/providers/codex-model-provider.js +42 -0
  201. package/dist/providers/model-provider.d.ts +26 -0
  202. package/dist/providers/model-provider.js +26 -0
  203. package/dist/public-components.d.ts +3 -0
  204. package/dist/public-components.js +3 -0
  205. package/dist/registry/runtime-registry.d.ts +11 -0
  206. package/dist/registry/runtime-registry.js +71 -0
  207. package/dist/registry/select-runtime.d.ts +9 -0
  208. package/dist/registry/select-runtime.js +31 -0
  209. package/dist/runtime-adapters.d.ts +16 -0
  210. package/dist/runtime-adapters.js +9 -0
  211. package/dist/runtimes/acp/acp-event-mapper.d.ts +56 -0
  212. package/dist/runtimes/acp/acp-event-mapper.js +237 -0
  213. package/dist/runtimes/acp/acp-runtime.d.ts +46 -0
  214. package/dist/runtimes/acp/acp-runtime.js +165 -0
  215. package/dist/runtimes/acp/desktop-acp-backend.d.ts +16 -0
  216. package/dist/runtimes/acp/desktop-acp-backend.js +243 -0
  217. package/dist/runtimes/codex/app-server-protocol.d.ts +28 -0
  218. package/dist/runtimes/codex/app-server-protocol.js +274 -0
  219. package/dist/runtimes/codex/codex-runtime.d.ts +24 -0
  220. package/dist/runtimes/codex/codex-runtime.js +318 -0
  221. package/dist/runtimes/fake/fake-runtime.d.ts +51 -0
  222. package/dist/runtimes/fake/fake-runtime.js +257 -0
  223. package/dist/sessions/plugin-data.d.ts +8 -0
  224. package/dist/sessions/plugin-data.js +29 -0
  225. package/dist/sessions/session-store.d.ts +47 -0
  226. package/dist/sessions/session-store.js +117 -0
  227. package/dist/settings/acp-agents.d.ts +8 -0
  228. package/dist/settings/acp-agents.js +11 -0
  229. package/dist/settings/ai-settings-tab.d.ts +8 -0
  230. package/dist/settings/ai-settings-tab.js +249 -0
  231. package/dist/settings/ai-settings.d.ts +43 -0
  232. package/dist/settings/ai-settings.js +147 -0
  233. package/dist/settings/app-tool-setting-rows.d.ts +16 -0
  234. package/dist/settings/app-tool-setting-rows.js +30 -0
  235. package/dist/settings/register-ai-settings.d.ts +3 -0
  236. package/dist/settings/register-ai-settings.js +393 -0
  237. package/dist/skills/activation.d.ts +2 -0
  238. package/dist/skills/activation.js +20 -0
  239. package/dist/skills/bundled/lapis-notes.d.ts +3 -0
  240. package/dist/skills/bundled/lapis-notes.js +52 -0
  241. package/dist/skills/bundled/research.d.ts +6 -0
  242. package/dist/skills/bundled/research.js +29 -0
  243. package/dist/skills/discovery.d.ts +21 -0
  244. package/dist/skills/discovery.js +227 -0
  245. package/dist/skills/manifest.d.ts +3 -0
  246. package/dist/skills/manifest.js +39 -0
  247. package/dist/skills/parser.d.ts +12 -0
  248. package/dist/skills/parser.js +124 -0
  249. package/dist/skills/registry.d.ts +21 -0
  250. package/dist/skills/registry.js +89 -0
  251. package/dist/skills/seed.d.ts +5 -0
  252. package/dist/skills/seed.js +18 -0
  253. package/dist/skills/skill-tools.d.ts +8 -0
  254. package/dist/skills/skill-tools.js +113 -0
  255. package/dist/skills/types.d.ts +67 -0
  256. package/dist/skills/types.js +1 -0
  257. package/dist/styles.css +514 -0
  258. package/dist/tools/app-tool-host.d.ts +47 -0
  259. package/dist/tools/app-tool-host.js +419 -0
  260. package/dist/tools/desktop-app-tool-bridge.d.ts +23 -0
  261. package/dist/tools/desktop-app-tool-bridge.js +223 -0
  262. package/dist/tools/mcp-server-registry.d.ts +7 -0
  263. package/dist/tools/mcp-server-registry.js +30 -0
  264. package/manifest.json +34 -0
  265. package/package.json +83 -0
  266. package/styles.css +1 -0
@@ -0,0 +1,393 @@
1
+ import { getWorkspaceHostBinding } from "@lapis-notes/api/workspace-host";
2
+ import { ACP_AGENT_IDS, normalizeAcpAgent, } from "./acp-agents";
3
+ import { APP_TOOL_SETTING_PREFIX, DEFAULT_AI_SETTINGS, applyAppToolEnablement, migrateLegacyCommunityToolOptIns, } from "./ai-settings";
4
+ import { listAppToolSettingRows, registeredAppToolRefs, } from "./app-tool-setting-rows";
5
+ const FIELD_IDS = {
6
+ defaultRuntime: "ai.defaultRuntime",
7
+ acpAgent: "ai.acpAgent",
8
+ defaultModel: "ai.defaultModel",
9
+ thinking: "ai.thinking",
10
+ memoryAutomaticRecall: "ai.memoryAutomaticRecall",
11
+ memoryConsolidationEnabled: "ai.memoryConsolidationEnabled",
12
+ memoryConsolidationRuntime: "ai.memoryConsolidationRuntime",
13
+ memoryConsolidationAgent: "ai.memoryConsolidationAgent",
14
+ memoryConsolidationModel: "ai.memoryConsolidationModel",
15
+ handoffSummariesEnabled: "ai.handoffSummariesEnabled",
16
+ handoffSummaryRuntime: "ai.handoffSummaryRuntime",
17
+ handoffSummaryAgent: "ai.handoffSummaryAgent",
18
+ handoffSummaryModel: "ai.handoffSummaryModel",
19
+ appToolsEnabled: "ai.appToolsEnabled",
20
+ appTools: "ai.appTools",
21
+ };
22
+ export function registerAiSettings(plugin) {
23
+ const binding = getWorkspaceHostBinding(plugin.app.workspace);
24
+ if (!binding)
25
+ return;
26
+ const controller = binding.controller;
27
+ const settings = plugin.getSettings();
28
+ const modelSourceId = (provider) => `ai.models.${provider}`;
29
+ const persistLegacyToolMigration = () => {
30
+ const current = plugin.getSettings();
31
+ const migrated = migrateLegacyCommunityToolOptIns(current, registeredAppToolRefs(plugin.app));
32
+ if (migrated.enabledAppToolNames.join("\0") ===
33
+ current.enabledAppToolNames.join("\0") &&
34
+ migrated.enabledCommunityToolPluginIds.join("\0") ===
35
+ current.enabledCommunityToolPluginIds.join("\0")) {
36
+ return;
37
+ }
38
+ void plugin.updateSettings({
39
+ enabledAppToolNames: migrated.enabledAppToolNames,
40
+ enabledCommunityToolPluginIds: migrated.enabledCommunityToolPluginIds,
41
+ });
42
+ };
43
+ for (const provider of ACP_AGENT_IDS) {
44
+ const dispose = controller.configuration.optionSources.register({
45
+ id: modelSourceId(provider),
46
+ load: async () => {
47
+ const current = plugin.getSettings();
48
+ const saved = current.defaultModels[provider];
49
+ try {
50
+ const models = await plugin.models.listModels(provider);
51
+ if (models.length === 0) {
52
+ return saved
53
+ ? [
54
+ {
55
+ value: saved,
56
+ label: saved,
57
+ description: "Saved model; the provider returned no catalog.",
58
+ },
59
+ ]
60
+ : [];
61
+ }
62
+ const selected = models.some((model) => model.model === saved)
63
+ ? saved
64
+ : (models.find((model) => model.isDefault) ?? models[0])?.model;
65
+ if (selected && selected !== saved) {
66
+ await plugin.updateSettings({
67
+ defaultModels: { ...current.defaultModels, [provider]: selected },
68
+ });
69
+ if (plugin.getSettings().acpAgent === provider) {
70
+ controller.settings.update(FIELD_IDS.defaultModel, selected);
71
+ }
72
+ }
73
+ return models.map((model) => ({
74
+ value: model.model,
75
+ label: model.displayName ?? model.model,
76
+ description: model.badges?.length
77
+ ? model.badges.join(" · ")
78
+ : model.description,
79
+ }));
80
+ }
81
+ catch (error) {
82
+ return saved
83
+ ? [
84
+ {
85
+ value: saved,
86
+ label: saved,
87
+ description: `Saved model; catalog unavailable: ${error instanceof Error ? error.message : String(error)}`,
88
+ },
89
+ ]
90
+ : [];
91
+ }
92
+ },
93
+ });
94
+ plugin.register(dispose);
95
+ }
96
+ const createSection = (current) => ({
97
+ id: "ai",
98
+ title: "AI",
99
+ description: "Agent runtime, model, and thinking defaults.",
100
+ icon: "sparkles",
101
+ order: 35,
102
+ navigationGroupId: "core-plugins",
103
+ sourcePluginId: plugin.id,
104
+ fields: [
105
+ {
106
+ id: FIELD_IDS.defaultRuntime,
107
+ type: "enum",
108
+ title: "Default runtime",
109
+ description: "Capability-based selection stays automatic unless you pin a runtime.",
110
+ default: DEFAULT_AI_SETTINGS.defaultRuntime,
111
+ options: [
112
+ { value: "auto", label: "Automatic" },
113
+ { value: "acp", label: "ACP" },
114
+ { value: "codex-native", label: "Codex native" },
115
+ { value: "fake", label: "Fake (tests)" },
116
+ ],
117
+ },
118
+ {
119
+ id: FIELD_IDS.acpAgent,
120
+ type: "enum",
121
+ title: "ACP agent",
122
+ description: "Built-in ACP agent used when ACP is selected.",
123
+ default: DEFAULT_AI_SETTINGS.acpAgent,
124
+ options: ACP_AGENT_IDS.map((value) => ({
125
+ value,
126
+ label: value === "cursor" ? "Cursor" : "Codex",
127
+ })),
128
+ },
129
+ {
130
+ id: FIELD_IDS.defaultModel,
131
+ type: "string",
132
+ title: "Default model",
133
+ description: "Model reported by the selected agent provider and sent on the next request.",
134
+ default: current.defaultModel,
135
+ optionsSource: modelSourceId(current.acpAgent),
136
+ allowUnknownOptions: false,
137
+ },
138
+ {
139
+ id: FIELD_IDS.thinking,
140
+ type: "enum",
141
+ title: "Thinking",
142
+ description: "How much model reasoning to request on each turn.",
143
+ default: DEFAULT_AI_SETTINGS.thinking,
144
+ options: [
145
+ { value: "off", label: "Off" },
146
+ { value: "low", label: "Low" },
147
+ { value: "medium", label: "Medium" },
148
+ { value: "high", label: "High" },
149
+ ],
150
+ },
151
+ {
152
+ id: FIELD_IDS.memoryAutomaticRecall,
153
+ type: "boolean",
154
+ title: "Automatic memory recall",
155
+ description: "Inject up to three trusted curated memories into a turn. Transcript evidence remains available only through memory tools.",
156
+ default: DEFAULT_AI_SETTINGS.memoryAutomaticRecall,
157
+ },
158
+ {
159
+ id: FIELD_IDS.memoryConsolidationEnabled,
160
+ type: "boolean",
161
+ title: "Automatic memory consolidation",
162
+ description: "Use the separately pinned processor below for bounded background proposals. This may consume provider quota.",
163
+ default: DEFAULT_AI_SETTINGS.memoryConsolidationEnabled,
164
+ },
165
+ {
166
+ id: FIELD_IDS.memoryConsolidationRuntime,
167
+ type: "enum",
168
+ title: "Memory processor runtime",
169
+ description: "Pinned independently from the interactive chat runtime.",
170
+ default: DEFAULT_AI_SETTINGS.memoryConsolidationRuntime,
171
+ options: [
172
+ { value: "acp", label: "ACP" },
173
+ { value: "codex-native", label: "Codex native" },
174
+ ],
175
+ },
176
+ {
177
+ id: FIELD_IDS.memoryConsolidationAgent,
178
+ type: "enum",
179
+ title: "Memory processor agent",
180
+ description: "Pinned independently from the interactive chat agent.",
181
+ default: DEFAULT_AI_SETTINGS.memoryConsolidationAgent,
182
+ options: ACP_AGENT_IDS.map((value) => ({
183
+ value,
184
+ label: value === "cursor" ? "Cursor" : "Codex",
185
+ })),
186
+ },
187
+ {
188
+ id: FIELD_IDS.memoryConsolidationModel,
189
+ type: "string",
190
+ title: "Memory processor model",
191
+ description: "Exact model used only for restricted background consolidation.",
192
+ default: DEFAULT_AI_SETTINGS.memoryConsolidationModel,
193
+ },
194
+ {
195
+ id: FIELD_IDS.handoffSummariesEnabled,
196
+ type: "boolean",
197
+ title: "Background handoff summaries",
198
+ description: "Prepare verified summaries after long turns for future cross-agent switches. This never runs during a switch and may consume provider quota.",
199
+ default: DEFAULT_AI_SETTINGS.handoffSummariesEnabled,
200
+ },
201
+ {
202
+ id: FIELD_IDS.handoffSummaryRuntime,
203
+ type: "enum",
204
+ title: "Handoff summary runtime",
205
+ description: "Pinned independently from the interactive chat runtime.",
206
+ default: DEFAULT_AI_SETTINGS.handoffSummaryRuntime,
207
+ options: [
208
+ { value: "acp", label: "ACP" },
209
+ { value: "codex-native", label: "Codex native" },
210
+ ],
211
+ },
212
+ {
213
+ id: FIELD_IDS.handoffSummaryAgent,
214
+ type: "enum",
215
+ title: "Handoff summary agent",
216
+ description: "Pinned independently from the interactive chat agent.",
217
+ default: DEFAULT_AI_SETTINGS.handoffSummaryAgent,
218
+ options: ACP_AGENT_IDS.map((value) => ({
219
+ value,
220
+ label: value === "cursor" ? "Cursor" : "Codex",
221
+ })),
222
+ },
223
+ {
224
+ id: FIELD_IDS.handoffSummaryModel,
225
+ type: "string",
226
+ title: "Handoff summary model",
227
+ description: "Exact model used only for restricted background summaries.",
228
+ default: DEFAULT_AI_SETTINGS.handoffSummaryModel,
229
+ },
230
+ {
231
+ id: FIELD_IDS.appToolsEnabled,
232
+ type: "boolean",
233
+ title: "Application tools",
234
+ description: "Expose enabled application tools to newly created agent bindings.",
235
+ default: DEFAULT_AI_SETTINGS.appToolsEnabled,
236
+ },
237
+ {
238
+ id: FIELD_IDS.appTools,
239
+ type: "group",
240
+ presentation: "toggle-table",
241
+ title: "Registered tools",
242
+ description: "Enable or disable each currently registered tool for new agent bindings.",
243
+ fields: listAppToolSettingRows(plugin.app, current).map((row) => ({
244
+ id: row.fieldId,
245
+ type: "boolean",
246
+ title: row.name,
247
+ description: row.description,
248
+ default: row.owner.source !== "community",
249
+ })),
250
+ },
251
+ ],
252
+ });
253
+ let disposeSection = controller.registerSettingsSection(createSection(settings));
254
+ plugin.register(() => disposeSection());
255
+ controller.settings.update(FIELD_IDS.defaultRuntime, settings.defaultRuntime);
256
+ controller.settings.update(FIELD_IDS.acpAgent, settings.acpAgent);
257
+ controller.settings.update(FIELD_IDS.defaultModel, settings.defaultModel);
258
+ controller.settings.update(FIELD_IDS.thinking, settings.thinking);
259
+ controller.settings.update(FIELD_IDS.memoryAutomaticRecall, settings.memoryAutomaticRecall);
260
+ controller.settings.update(FIELD_IDS.memoryConsolidationEnabled, settings.memoryConsolidationEnabled);
261
+ controller.settings.update(FIELD_IDS.memoryConsolidationRuntime, settings.memoryConsolidationRuntime);
262
+ controller.settings.update(FIELD_IDS.memoryConsolidationAgent, settings.memoryConsolidationAgent);
263
+ controller.settings.update(FIELD_IDS.memoryConsolidationModel, settings.memoryConsolidationModel);
264
+ controller.settings.update(FIELD_IDS.handoffSummariesEnabled, settings.handoffSummariesEnabled);
265
+ controller.settings.update(FIELD_IDS.handoffSummaryRuntime, settings.handoffSummaryRuntime);
266
+ controller.settings.update(FIELD_IDS.handoffSummaryAgent, settings.handoffSummaryAgent);
267
+ controller.settings.update(FIELD_IDS.handoffSummaryModel, settings.handoffSummaryModel);
268
+ controller.settings.update(FIELD_IDS.appToolsEnabled, settings.appToolsEnabled);
269
+ const syncAppToolValues = (current) => {
270
+ for (const row of listAppToolSettingRows(plugin.app, current)) {
271
+ controller.settings.update(row.fieldId, row.enabled);
272
+ }
273
+ };
274
+ syncAppToolValues(settings);
275
+ persistLegacyToolMigration();
276
+ const refreshSection = (current) => {
277
+ disposeSection();
278
+ disposeSection = controller.registerSettingsSection(createSection(current));
279
+ syncAppToolValues(current);
280
+ };
281
+ const toolRegistryRef = plugin.app.agentTools.on("changed", () => {
282
+ persistLegacyToolMigration();
283
+ refreshSection(plugin.getSettings());
284
+ });
285
+ plugin.register(() => plugin.app.agentTools.offref(toolRegistryRef));
286
+ const changeRef = controller.settings.on("change", (event) => {
287
+ if (!event.id || !event.id.startsWith("ai."))
288
+ return;
289
+ const values = controller.settings.getSnapshot().values;
290
+ if (event.id === FIELD_IDS.acpAgent) {
291
+ void (async () => {
292
+ await plugin.updateSettings({
293
+ acpAgent: normalizeAcpAgent(values[FIELD_IDS.acpAgent]),
294
+ });
295
+ const next = plugin.getSettings();
296
+ refreshSection(next);
297
+ controller.settings.update(FIELD_IDS.defaultModel, next.defaultModel);
298
+ })();
299
+ return;
300
+ }
301
+ if (event.id === FIELD_IDS.defaultModel) {
302
+ void plugin.updateSettings({
303
+ defaultModel: String(values[FIELD_IDS.defaultModel] ?? ""),
304
+ });
305
+ return;
306
+ }
307
+ if (event.id === FIELD_IDS.defaultRuntime) {
308
+ void plugin.updateSettings({
309
+ defaultRuntime: values[FIELD_IDS.defaultRuntime],
310
+ });
311
+ return;
312
+ }
313
+ if (event.id === FIELD_IDS.thinking) {
314
+ void plugin.updateSettings({
315
+ thinking: values[FIELD_IDS.thinking],
316
+ });
317
+ return;
318
+ }
319
+ if (event.id === FIELD_IDS.memoryAutomaticRecall) {
320
+ void plugin.updateSettings({
321
+ memoryAutomaticRecall: values[FIELD_IDS.memoryAutomaticRecall] === true,
322
+ });
323
+ return;
324
+ }
325
+ if (event.id === FIELD_IDS.memoryConsolidationEnabled) {
326
+ void plugin.updateSettings({
327
+ memoryConsolidationEnabled: values[FIELD_IDS.memoryConsolidationEnabled] === true,
328
+ });
329
+ return;
330
+ }
331
+ if (event.id === FIELD_IDS.memoryConsolidationRuntime) {
332
+ void plugin.updateSettings({
333
+ memoryConsolidationRuntime: values[FIELD_IDS.memoryConsolidationRuntime] === "codex-native"
334
+ ? "codex-native"
335
+ : "acp",
336
+ });
337
+ return;
338
+ }
339
+ if (event.id === FIELD_IDS.memoryConsolidationAgent) {
340
+ void plugin.updateSettings({
341
+ memoryConsolidationAgent: normalizeAcpAgent(values[FIELD_IDS.memoryConsolidationAgent]),
342
+ });
343
+ return;
344
+ }
345
+ if (event.id === FIELD_IDS.memoryConsolidationModel) {
346
+ void plugin.updateSettings({
347
+ memoryConsolidationModel: String(values[FIELD_IDS.memoryConsolidationModel] ?? ""),
348
+ });
349
+ return;
350
+ }
351
+ if (event.id === FIELD_IDS.handoffSummariesEnabled) {
352
+ void plugin.updateSettings({
353
+ handoffSummariesEnabled: values[FIELD_IDS.handoffSummariesEnabled] === true,
354
+ });
355
+ return;
356
+ }
357
+ if (event.id === FIELD_IDS.handoffSummaryRuntime) {
358
+ void plugin.updateSettings({
359
+ handoffSummaryRuntime: values[FIELD_IDS.handoffSummaryRuntime] === "codex-native"
360
+ ? "codex-native"
361
+ : "acp",
362
+ });
363
+ return;
364
+ }
365
+ if (event.id === FIELD_IDS.handoffSummaryAgent) {
366
+ void plugin.updateSettings({
367
+ handoffSummaryAgent: normalizeAcpAgent(values[FIELD_IDS.handoffSummaryAgent]),
368
+ });
369
+ return;
370
+ }
371
+ if (event.id === FIELD_IDS.handoffSummaryModel) {
372
+ void plugin.updateSettings({
373
+ handoffSummaryModel: String(values[FIELD_IDS.handoffSummaryModel] ?? ""),
374
+ });
375
+ return;
376
+ }
377
+ if (event.id === FIELD_IDS.appToolsEnabled) {
378
+ void plugin.updateSettings({
379
+ appToolsEnabled: values[FIELD_IDS.appToolsEnabled] !== false,
380
+ });
381
+ return;
382
+ }
383
+ if (event.id.startsWith(APP_TOOL_SETTING_PREFIX) &&
384
+ event.id !== FIELD_IDS.appTools) {
385
+ const toolName = event.id.slice(APP_TOOL_SETTING_PREFIX.length);
386
+ const registered = plugin.app.agentTools.get(toolName);
387
+ if (!registered)
388
+ return;
389
+ void plugin.updateSettings(applyAppToolEnablement(plugin.getSettings(), { name: registered.tool.name, owner: registered.owner }, values[event.id] === true, registeredAppToolRefs(plugin.app)));
390
+ }
391
+ });
392
+ plugin.register(() => controller.settings.offref(changeRef));
393
+ }
@@ -0,0 +1,2 @@
1
+ import type { SkillActivation } from "./types";
2
+ export declare function projectSkillActivationPrompt(text: string, activations?: readonly SkillActivation[]): string;
@@ -0,0 +1,20 @@
1
+ import { hasHostFilesystemPath } from "./manifest";
2
+ export function projectSkillActivationPrompt(text, activations) {
3
+ const activation = activations?.[0];
4
+ if (!activation?.instructions.trim())
5
+ return text;
6
+ if (hasHostFilesystemPath(activation.instructions))
7
+ return text;
8
+ const name = escapeAttribute(activation.skillName);
9
+ const version = escapeAttribute(activation.version);
10
+ return [
11
+ `<skill_activation name="${name}" version="${version}">`,
12
+ activation.instructions.trim(),
13
+ "</skill_activation>",
14
+ "",
15
+ text,
16
+ ].join("\n");
17
+ }
18
+ function escapeAttribute(value) {
19
+ return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;");
20
+ }
@@ -0,0 +1,3 @@
1
+ import type { LoadedAppSkill } from "../types";
2
+ export declare const LAPIS_NOTES_SKILL_MARKDOWN = "---\nname: lapis-notes\ndescription: Guidance for working with notes, folders, search, links, and other Lapis Notes capabilities.\nuser-invocable: false\n---\n\n# Lapis Notes\n\nYou are operating inside Lapis Notes.\n\nPrefer application tools over manually inspecting the notes filesystem.\n\n## Finding information\n\nUse notes_search when the user asks to find, recall, locate, compare, or research information from their notes.\n\nSearch first, then use read on promising results.\n\nDo not guess note paths when search can locate the note.\n\n## Navigating notes\n\nUse notes_list to inspect folder contents when structure matters.\n\nUse related link tools when relationships between notes are relevant and those tools are available.\n\n## Scope\n\nTool access is automatically scoped by Lapis.\n\nDo not attempt to widen that scope using filesystem paths or shell tools.\n\nThe current conversation's scope and launch note are supplied by the host.\n\n## Writing\n\nUse Lapis note mutation tools when they are available instead of editing application-owned note files through generic filesystem tools.\n\nWrites may require user approval.\n\n## Tool availability\n\nThe exact tool set can vary by installed extensions and conversation scope.\n\nUse the tools exposed for the current session rather than assuming a particular extension is installed.\n";
3
+ export declare const BUNDLED_LAPIS_NOTES_SKILL: LoadedAppSkill;
@@ -0,0 +1,52 @@
1
+ import { parseSkillMarkdown } from "../parser";
2
+ export const LAPIS_NOTES_SKILL_MARKDOWN = `---
3
+ name: lapis-notes
4
+ description: Guidance for working with notes, folders, search, links, and other Lapis Notes capabilities.
5
+ user-invocable: false
6
+ ---
7
+
8
+ # Lapis Notes
9
+
10
+ You are operating inside Lapis Notes.
11
+
12
+ Prefer application tools over manually inspecting the notes filesystem.
13
+
14
+ ## Finding information
15
+
16
+ Use notes_search when the user asks to find, recall, locate, compare, or research information from their notes.
17
+
18
+ Search first, then use read on promising results.
19
+
20
+ Do not guess note paths when search can locate the note.
21
+
22
+ ## Navigating notes
23
+
24
+ Use notes_list to inspect folder contents when structure matters.
25
+
26
+ Use related link tools when relationships between notes are relevant and those tools are available.
27
+
28
+ ## Scope
29
+
30
+ Tool access is automatically scoped by Lapis.
31
+
32
+ Do not attempt to widen that scope using filesystem paths or shell tools.
33
+
34
+ The current conversation's scope and launch note are supplied by the host.
35
+
36
+ ## Writing
37
+
38
+ Use Lapis note mutation tools when they are available instead of editing application-owned note files through generic filesystem tools.
39
+
40
+ Writes may require user approval.
41
+
42
+ ## Tool availability
43
+
44
+ The exact tool set can vary by installed extensions and conversation scope.
45
+
46
+ Use the tools exposed for the current session rather than assuming a particular extension is installed.
47
+ `;
48
+ export const BUNDLED_LAPIS_NOTES_SKILL = parseSkillMarkdown(LAPIS_NOTES_SKILL_MARKDOWN, {
49
+ path: "bundled/lapis-notes/SKILL.md",
50
+ source: "bundled",
51
+ root: "bundled/lapis-notes",
52
+ });
@@ -0,0 +1,6 @@
1
+ import type { LoadedAppSkill } from "../types";
2
+ export declare const RESEARCH_SKILL_MARKDOWN = "---\nname: research\ndescription: Research notes in the current folder and synthesize an answer.\nuser-invocable: true\nargument-hint: \"<topic>\"\n---\nResearch the given topic in the current conversation folder.\n\n1. Use notes_search to find relevant notes.\n2. Use read to inspect the best matches.\n3. Follow further searches when needed.\n4. Synthesize a concise answer and cite note paths.\n";
3
+ export declare const BUNDLED_RESEARCH_SKILL: LoadedAppSkill;
4
+ export declare const BUNDLED_APP_SKILLS: readonly LoadedAppSkill[];
5
+ export declare const BUNDLED_SKILL_MARKDOWN: Readonly<Record<string, string>>;
6
+ export declare const BUNDLED_SKILL_NAMES: Set<string>;
@@ -0,0 +1,29 @@
1
+ import { parseSkillMarkdown } from "../parser";
2
+ import { BUNDLED_LAPIS_NOTES_SKILL, LAPIS_NOTES_SKILL_MARKDOWN, } from "./lapis-notes";
3
+ export const RESEARCH_SKILL_MARKDOWN = `---
4
+ name: research
5
+ description: Research notes in the current folder and synthesize an answer.
6
+ user-invocable: true
7
+ argument-hint: "<topic>"
8
+ ---
9
+ Research the given topic in the current conversation folder.
10
+
11
+ 1. Use notes_search to find relevant notes.
12
+ 2. Use read to inspect the best matches.
13
+ 3. Follow further searches when needed.
14
+ 4. Synthesize a concise answer and cite note paths.
15
+ `;
16
+ export const BUNDLED_RESEARCH_SKILL = parseSkillMarkdown(RESEARCH_SKILL_MARKDOWN, {
17
+ path: "bundled/research/SKILL.md",
18
+ source: "bundled",
19
+ root: "bundled/research",
20
+ });
21
+ export const BUNDLED_APP_SKILLS = [
22
+ BUNDLED_LAPIS_NOTES_SKILL,
23
+ BUNDLED_RESEARCH_SKILL,
24
+ ];
25
+ export const BUNDLED_SKILL_MARKDOWN = {
26
+ research: RESEARCH_SKILL_MARKDOWN,
27
+ "lapis-notes": LAPIS_NOTES_SKILL_MARKDOWN,
28
+ };
29
+ export const BUNDLED_SKILL_NAMES = new Set(Object.keys(BUNDLED_SKILL_MARKDOWN));
@@ -0,0 +1,21 @@
1
+ import type { Vault } from "@lapis-notes/api";
2
+ import type { AppSkillRegistry } from "@lapis-notes/api/agent-skills";
3
+ import type { LoadedAppSkill, SkillDiagnostic, SkillDiscoveryContext } from "./types";
4
+ export interface DiscoveredSkills {
5
+ skills: LoadedAppSkill[];
6
+ diagnostics: SkillDiagnostic[];
7
+ }
8
+ export interface SkillDiscoveryOptions {
9
+ vault: Vault;
10
+ appSkills?: AppSkillRegistry;
11
+ bundled?: LoadedAppSkill[];
12
+ extensionFiles?: ReadonlyMap<string, Readonly<Record<string, string>>>;
13
+ extensionRootFor?: (ownerPluginId: string) => string | undefined;
14
+ userPrefix?: string;
15
+ }
16
+ export declare class SkillDiscovery {
17
+ #private;
18
+ private readonly options;
19
+ constructor(options: SkillDiscoveryOptions);
20
+ discover(context: SkillDiscoveryContext): Promise<DiscoveredSkills>;
21
+ }