@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,50 @@
1
+ import type { App, WorkspaceLeaf } from "@lapis-notes/api";
2
+ import type { ComposerSearchSource } from "@lapismd/design-core/ai/chat";
3
+ import type { AgentRequest, AgentRuntime, ModelRef, McpServerContribution } from "../core/types";
4
+ import type { AgentSessionStore } from "../sessions/session-store";
5
+ import type { ConversationRepository, CreateConversationInput } from "../conversations/conversation-repository";
6
+ import type { ConversationLocation } from "../conversations/types";
7
+ import { type AiPluginSettings } from "../settings/ai-settings";
8
+ import type { AppToolBridgeCoordinator } from "../tools/desktop-app-tool-bridge";
9
+ import type { SkillRegistry, SkillSnapshotStore } from "../skills/registry";
10
+ import type { SkillDiscoveryContext } from "../skills/types";
11
+ import type { SlashCommandRouter } from "../commands/router";
12
+ import type { AppToolHost } from "../tools/app-tool-host";
13
+ import type { AutomaticMemoryRecall } from "../memory/types";
14
+ import type { HandoffSummaryCoordinator } from "../conversations/handoff-summary";
15
+ type $$ComponentProps = {
16
+ app?: App;
17
+ runtime: AgentRuntime;
18
+ selectRuntime?: (request: AgentRequest) => Promise<AgentRuntime>;
19
+ unavailableReason?: string | null;
20
+ initializing?: boolean;
21
+ workspace?: string;
22
+ mcpServers?: McpServerContribution[];
23
+ appToolBridge?: AppToolBridgeCoordinator;
24
+ skills?: SkillRegistry;
25
+ skillSnapshots?: SkillSnapshotStore;
26
+ slashRouter?: SlashCommandRouter;
27
+ appToolHost?: AppToolHost;
28
+ memoryRecall?: AutomaticMemoryRecall;
29
+ handoffSummaries?: Pick<HandoffSummaryCoordinator, "afterTerminal">;
30
+ skillContext?: () => SkillDiscoveryContext;
31
+ sessionStore?: AgentSessionStore;
32
+ sessionId?: string;
33
+ repository?: ConversationRepository;
34
+ initialLocation?: ConversationLocation | null;
35
+ createConversation?: (explicitFolder?: string) => CreateConversationInput;
36
+ subscribeConversationMoves?: (listener: (oldPath: string, newPath: string) => void) => () => void;
37
+ onRevealHistory?: () => void | Promise<void>;
38
+ onConversationLocationChange?: (location: ConversationLocation | null) => void;
39
+ currentConversationScope?: () => string;
40
+ listConversationFolders?: () => string[];
41
+ workspaceLeaf?: WorkspaceLeaf;
42
+ fileSearch?: ComposerSearchSource;
43
+ models?: ModelRef[];
44
+ modelCatalogError?: string | null;
45
+ settings?: Partial<AiPluginSettings>;
46
+ onSettingsChange?: (patch: Partial<AiPluginSettings>) => void | Promise<void>;
47
+ };
48
+ declare const AiChatPanel: import("svelte").Component<$$ComponentProps, {}, "">;
49
+ type AiChatPanel = ReturnType<typeof AiChatPanel>;
50
+ export default AiChatPanel;
@@ -0,0 +1,55 @@
1
+ [data-ui-component="ai-inventory-result"] {
2
+ display: flex;
3
+ width: 100%;
4
+ min-width: 0;
5
+ flex-direction: column;
6
+ gap: 0.25rem;
7
+ }
8
+
9
+ [data-ui-component="ai-inventory-result"] [data-ui-part="empty"] {
10
+ padding: 0.375rem;
11
+ color: var(--muted-foreground);
12
+ font-size: 0.8125rem;
13
+ }
14
+
15
+ [data-ui-component="ai-inventory-result"] [data-ui-part="item"] {
16
+ display: flex;
17
+ min-width: 0;
18
+ align-items: flex-start;
19
+ justify-content: space-between;
20
+ gap: 0.5rem;
21
+ border-radius: var(--ui-workspace-radius-small, 0.25rem);
22
+ padding: 0.375rem 0.5rem;
23
+ }
24
+
25
+ [data-ui-component="ai-inventory-result"] [data-ui-part="item"]:hover,
26
+ [data-ui-component="ai-inventory-result"] [data-ui-part="item"]:focus-within {
27
+ background: var(
28
+ --ui-workspace-explorer-row-hover-background,
29
+ var(--sidebar-accent)
30
+ );
31
+ }
32
+
33
+ [data-ui-component="ai-inventory-result"] [data-ui-part="body"] {
34
+ display: flex;
35
+ min-width: 0;
36
+ flex: 1 1 auto;
37
+ flex-direction: column;
38
+ gap: 0.125rem;
39
+ }
40
+
41
+ [data-ui-component="ai-inventory-result"] [data-ui-part="name"] {
42
+ overflow: hidden;
43
+ font-weight: 600;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ }
47
+
48
+ [data-ui-component="ai-inventory-result"] [data-ui-part="description"] {
49
+ color: var(--muted-foreground);
50
+ font-size: 0.75rem;
51
+ }
52
+
53
+ [data-ui-component="ai-inventory-result"] [data-ui-part="open"] {
54
+ flex: 0 0 auto;
55
+ }
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import type { AgentResultViewProps, App } from "@lapis-notes/api";
3
+ import { Button } from "@lapismd/design-core/shadcn/button";
4
+ import SquareArrowOutUpRightIcon from "@lucide/svelte/icons/square-arrow-out-up-right";
5
+ import type { AiChatInventory, AiChatInventoryItem } from "./chat-items";
6
+ import "./ai-inventory-result.css";
7
+
8
+ let {
9
+ app,
10
+ output,
11
+ }: Partial<AgentResultViewProps<App>> = $props();
12
+
13
+ const inventory = $derived.by((): AiChatInventory | undefined => {
14
+ if (!output || typeof output !== "object" || Array.isArray(output)) {
15
+ return undefined;
16
+ }
17
+ const record = output as Partial<AiChatInventory>;
18
+ if (record.kind !== "skills" && record.kind !== "tools") return undefined;
19
+ if (!Array.isArray(record.items)) return undefined;
20
+ return record as AiChatInventory;
21
+ });
22
+
23
+ async function openItem(item: AiChatInventoryItem): Promise<void> {
24
+ if (!item.path || !app) return;
25
+ await app.workspace.openLinkText(item.path, "");
26
+ }
27
+ </script>
28
+
29
+ <div
30
+ data-ui-component="ai-inventory-result"
31
+ data-kind={inventory?.kind}
32
+ >
33
+ {#if !inventory || inventory.items.length === 0}
34
+ <p data-ui-part="empty">
35
+ {inventory?.kind === "tools"
36
+ ? "No application tools are available."
37
+ : "No skills are available."}
38
+ </p>
39
+ {:else}
40
+ {#each inventory.items as item (`${item.kind}:${item.name}:${item.path ?? ""}`)}
41
+ <div data-ui-part="item">
42
+ <div data-ui-part="body">
43
+ <span data-ui-part="name">{item.name}</span>
44
+ {#if item.description}
45
+ <span data-ui-part="description">{item.description}</span>
46
+ {/if}
47
+ </div>
48
+ {#if item.path && app}
49
+ <Button
50
+ type="button"
51
+ size="icon-xs"
52
+ variant="ghost"
53
+ data-ui-part="open"
54
+ aria-label={`Open ${item.name}`}
55
+ onclick={() => void openItem(item)}
56
+ >
57
+ <SquareArrowOutUpRightIcon aria-hidden="true" />
58
+ </Button>
59
+ {/if}
60
+ </div>
61
+ {/each}
62
+ {/if}
63
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { AgentResultViewProps, App } from "@lapis-notes/api";
2
+ import "./ai-inventory-result.css";
3
+ declare const AiInventoryResult: import("svelte").Component<Partial<AgentResultViewProps<App>>, {}, "">;
4
+ type AiInventoryResult = ReturnType<typeof AiInventoryResult>;
5
+ export default AiInventoryResult;
@@ -0,0 +1,132 @@
1
+ <script lang="ts">
2
+ import { Badge } from "@lapismd/design-core/shadcn/badge";
3
+ import { Button } from "@lapismd/design-core/shadcn/button";
4
+ import type {
5
+ UserInputAnswers,
6
+ UserInputQuestion,
7
+ UserInputRequest,
8
+ } from "../core/types";
9
+
10
+ let {
11
+ request,
12
+ disabled = false,
13
+ onRespond,
14
+ }: {
15
+ request: UserInputRequest;
16
+ disabled?: boolean;
17
+ onRespond(answers: UserInputAnswers): void;
18
+ } = $props();
19
+
20
+ let answers = $state<Record<string, string>>({});
21
+ let otherSelected = $state<Record<string, boolean>>({});
22
+ const complete = $derived(
23
+ request.questions.every((question) =>
24
+ Boolean(answers[question.id]?.trim()),
25
+ ),
26
+ );
27
+
28
+ function answer(question: UserInputQuestion, value: string): void {
29
+ answers = { ...answers, [question.id]: value };
30
+ otherSelected = { ...otherSelected, [question.id]: false };
31
+ }
32
+
33
+ function chooseOther(question: UserInputQuestion): void {
34
+ answers = { ...answers, [question.id]: "" };
35
+ otherSelected = { ...otherSelected, [question.id]: true };
36
+ }
37
+
38
+ function updateInput(question: UserInputQuestion, value: string): void {
39
+ answers = { ...answers, [question.id]: value };
40
+ }
41
+
42
+ function submit(): void {
43
+ if (disabled || !complete) return;
44
+ onRespond(
45
+ Object.fromEntries(
46
+ request.questions.map((question) => [
47
+ question.id,
48
+ [answers[question.id]?.trim() ?? ""],
49
+ ]),
50
+ ),
51
+ );
52
+ }
53
+ </script>
54
+
55
+ <form
56
+ class="ai-agent-request"
57
+ data-ui-component="ai-agent-request"
58
+ data-kind="question"
59
+ data-testid="ai-question-card"
60
+ onsubmit={(event) => {
61
+ event.preventDefault();
62
+ submit();
63
+ }}
64
+ >
65
+ {#each request.questions as question (question.id)}
66
+ <fieldset>
67
+ <legend>{question.header}</legend>
68
+ <strong>{question.prompt}</strong>
69
+ {#if question.options?.length}
70
+ <div data-ui-part="options">
71
+ {#each question.options as option, index (option.id)}
72
+ <button
73
+ type="button"
74
+ data-ui-part="feedback-option"
75
+ data-selected={!otherSelected[question.id] &&
76
+ answers[question.id] === option.label}
77
+ disabled={disabled}
78
+ onclick={() => answer(question, option.label)}
79
+ >
80
+ <Badge
81
+ variant={!otherSelected[question.id] &&
82
+ answers[question.id] === option.label
83
+ ? "default"
84
+ : "secondary"}
85
+ >{String.fromCharCode(65 + index)}</Badge
86
+ >
87
+ <span>
88
+ <span>{option.label}</span>
89
+ {#if option.description}
90
+ <small>{option.description}</small>
91
+ {/if}
92
+ </span>
93
+ </button>
94
+ {/each}
95
+ {#if question.allowOther}
96
+ <button
97
+ type="button"
98
+ data-ui-part="feedback-option"
99
+ data-selected={otherSelected[question.id] === true}
100
+ disabled={disabled}
101
+ onclick={() => chooseOther(question)}
102
+ >
103
+ <Badge
104
+ variant={otherSelected[question.id]
105
+ ? "default"
106
+ : "secondary"}
107
+ >{String.fromCharCode(65 + question.options.length)}</Badge
108
+ >
109
+ <span>Other</span>
110
+ </button>
111
+ {/if}
112
+ </div>
113
+ {/if}
114
+ {#if !question.options?.length || otherSelected[question.id]}
115
+ <input
116
+ type={question.secret ? "password" : "text"}
117
+ aria-label={`${question.header} answer`}
118
+ autocomplete="off"
119
+ value={answers[question.id] ?? ""}
120
+ disabled={disabled}
121
+ oninput={(event) =>
122
+ updateInput(question, event.currentTarget.value)}
123
+ />
124
+ {/if}
125
+ </fieldset>
126
+ {/each}
127
+ <div data-ui-part="request-actions">
128
+ <Button type="submit" size="sm" disabled={disabled || !complete}
129
+ >Submit answer</Button
130
+ >
131
+ </div>
132
+ </form>
@@ -0,0 +1,9 @@
1
+ import type { UserInputAnswers, UserInputRequest } from "../core/types";
2
+ type $$ComponentProps = {
3
+ request: UserInputRequest;
4
+ disabled?: boolean;
5
+ onRespond(answers: UserInputAnswers): void;
6
+ };
7
+ declare const AiQuestionCard: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type AiQuestionCard = ReturnType<typeof AiQuestionCard>;
9
+ export default AiQuestionCard;
@@ -0,0 +1,13 @@
1
+ import type { AgentRuntime, ModelRef, McpServerContribution } from "../core/types";
2
+ import type { ConversationLocation } from "../conversations/types";
3
+ import type { AiPluginSettings } from "../settings/ai-settings";
4
+ import type { AiViewHost } from "./ai-view";
5
+ export type AiViewBootstrap = {
6
+ runtime: AgentRuntime;
7
+ settings: AiPluginSettings;
8
+ models: ModelRef[];
9
+ modelCatalogError: string | null;
10
+ unavailableReason: string | null;
11
+ };
12
+ export declare function initialAiViewBootstrap(host: AiViewHost): AiViewBootstrap;
13
+ export declare function prepareAiViewBootstrap(host: AiViewHost, initialLocation: ConversationLocation | null, mcpServers: McpServerContribution[]): Promise<AiViewBootstrap>;
@@ -0,0 +1,86 @@
1
+ import { ACP_AGENT_IDS } from "../settings/acp-agents";
2
+ export function initialAiViewBootstrap(host) {
3
+ return {
4
+ runtime: host.fallbackRuntime(),
5
+ settings: host.getSettings(),
6
+ models: [],
7
+ modelCatalogError: null,
8
+ unavailableReason: null,
9
+ };
10
+ }
11
+ export async function prepareAiViewBootstrap(host, initialLocation, mcpServers) {
12
+ let settings = host.getSettings();
13
+ const conversation = initialLocation
14
+ ? host.conversations.read(initialLocation)
15
+ : Promise.resolve(null);
16
+ const catalogs = ACP_AGENT_IDS.map((agent) => host.models.listModels(agent));
17
+ const [snapshot, settledCatalogs] = await Promise.all([
18
+ conversation.catch(() => null),
19
+ Promise.allSettled(catalogs),
20
+ ]);
21
+ if (snapshot) {
22
+ const binding = snapshot.agents.find((record) => record.type === "binding.created" &&
23
+ record.id === snapshot.metadata.activeAgentBindingId);
24
+ if (binding?.type === "binding.created") {
25
+ const agent = binding.agent === "cursor" ? "cursor" : "codex";
26
+ settings = {
27
+ ...settings,
28
+ acpAgent: agent,
29
+ defaultRuntime: binding.runtime === "codex-native"
30
+ ? "codex-native"
31
+ : binding.runtime === "fake"
32
+ ? "fake"
33
+ : "acp",
34
+ defaultModel: binding.model?.model ?? settings.defaultModels[agent],
35
+ thinking: binding.thinking ?? settings.thinking,
36
+ };
37
+ }
38
+ }
39
+ const models = settledCatalogs.flatMap((catalog) => catalog.status === "fulfilled" ? catalog.value : []);
40
+ let modelCatalogError = null;
41
+ const selectedCatalog = settledCatalogs[ACP_AGENT_IDS.indexOf(settings.acpAgent)];
42
+ const agentModels = models.filter((model) => model.provider === settings.acpAgent);
43
+ if (selectedCatalog?.status === "rejected") {
44
+ modelCatalogError = errorMessage(selectedCatalog.reason);
45
+ }
46
+ else if (!initialLocation &&
47
+ agentModels.length > 0 &&
48
+ !agentModels.some((model) => model.model === settings.defaultModel)) {
49
+ const model = (agentModels.find((entry) => entry.isDefault) ??
50
+ agentModels[0]);
51
+ await host.updateSettings({ defaultModel: model.model });
52
+ settings = host.getSettings();
53
+ }
54
+ let runtime;
55
+ let unavailableReason = null;
56
+ try {
57
+ runtime = await host.selectRuntime({
58
+ prompt: "",
59
+ mcpServers,
60
+ agent: settings.acpAgent,
61
+ model: { provider: settings.acpAgent, model: settings.defaultModel },
62
+ thinking: settings.thinking,
63
+ metadata: settings.defaultRuntime === "auto"
64
+ ? undefined
65
+ : { runtime: settings.defaultRuntime },
66
+ });
67
+ unavailableReason =
68
+ settings.defaultRuntime === "fake"
69
+ ? null
70
+ : host.liveRuntimeUnavailableReason();
71
+ }
72
+ catch (error) {
73
+ runtime = host.fallbackRuntime();
74
+ unavailableReason = errorMessage(error);
75
+ }
76
+ return {
77
+ runtime,
78
+ settings,
79
+ models,
80
+ modelCatalogError,
81
+ unavailableReason,
82
+ };
83
+ }
84
+ function errorMessage(error) {
85
+ return error instanceof Error ? error.message : String(error);
86
+ }
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import { onMount } from "svelte";
3
+ import type { App, WorkspaceLeaf } from "@lapis-notes/api";
4
+ import type { ConversationLocation } from "../conversations/types";
5
+ import AiChatPanel from "./ai-chat-panel.svelte";
6
+ import type { AiViewHost } from "./ai-view";
7
+ import {
8
+ initialAiViewBootstrap,
9
+ prepareAiViewBootstrap,
10
+ type AiViewBootstrap,
11
+ } from "./ai-view-bootstrap";
12
+
13
+ let {
14
+ app,
15
+ host,
16
+ workspaceLeaf,
17
+ initialLocation,
18
+ onConversationLocationChange,
19
+ }: {
20
+ app: App;
21
+ host: AiViewHost;
22
+ workspaceLeaf: WorkspaceLeaf;
23
+ initialLocation: ConversationLocation | null;
24
+ onConversationLocationChange: (
25
+ location: ConversationLocation | null,
26
+ ) => void;
27
+ } = $props();
28
+
29
+ const mcpServers = $derived(host.mcpServers.list());
30
+ const initialBootstrap = $derived(initialAiViewBootstrap(host));
31
+ let preparedBootstrap = $state<AiViewBootstrap | null>(null);
32
+ const bootstrap = $derived(preparedBootstrap ?? initialBootstrap);
33
+ let initializing = $state(true);
34
+
35
+ onMount(() => {
36
+ let disposed = false;
37
+ void prepareAiViewBootstrap(host, initialLocation, mcpServers)
38
+ .then((prepared) => {
39
+ if (disposed) return;
40
+ preparedBootstrap = prepared;
41
+ initializing = false;
42
+ })
43
+ .catch((error) => {
44
+ if (disposed) return;
45
+ preparedBootstrap = {
46
+ ...bootstrap,
47
+ unavailableReason:
48
+ error instanceof Error ? error.message : String(error),
49
+ };
50
+ initializing = false;
51
+ });
52
+ return () => {
53
+ disposed = true;
54
+ };
55
+ });
56
+ </script>
57
+
58
+ <AiChatPanel
59
+ {app}
60
+ runtime={bootstrap.runtime}
61
+ selectRuntime={(request) => host.selectRuntime(request)}
62
+ unavailableReason={bootstrap.unavailableReason}
63
+ {initializing}
64
+ {mcpServers}
65
+ appToolBridge={host.appToolBridge}
66
+ skills={host.skills}
67
+ skillSnapshots={host.skillSnapshots}
68
+ slashRouter={host.slashRouter}
69
+ appToolHost={host.appToolHost}
70
+ memoryRecall={host.memory}
71
+ handoffSummaries={host.handoffSummaries}
72
+ skillContext={host.skillContext}
73
+ workspace={host.workspace}
74
+ repository={host.conversations}
75
+ {initialLocation}
76
+ createConversation={(explicitFolder) =>
77
+ host.createConversationInput(explicitFolder)}
78
+ onRevealHistory={() => host.revealConversationHistory()}
79
+ subscribeConversationMoves={host.subscribeConversationMoves?.bind(host)}
80
+ {onConversationLocationChange}
81
+ currentConversationScope={() => host.currentConversationScope()}
82
+ listConversationFolders={() => host.listConversationFolders()}
83
+ {workspaceLeaf}
84
+ fileSearch={host.searchVaultFiles}
85
+ models={bootstrap.models}
86
+ modelCatalogError={bootstrap.modelCatalogError}
87
+ settings={bootstrap.settings}
88
+ onSettingsChange={(patch) => host.updateSettings(patch)}
89
+ />
@@ -0,0 +1,13 @@
1
+ import type { App, WorkspaceLeaf } from "@lapis-notes/api";
2
+ import type { ConversationLocation } from "../conversations/types";
3
+ import type { AiViewHost } from "./ai-view";
4
+ type $$ComponentProps = {
5
+ app: App;
6
+ host: AiViewHost;
7
+ workspaceLeaf: WorkspaceLeaf;
8
+ initialLocation: ConversationLocation | null;
9
+ onConversationLocationChange: (location: ConversationLocation | null) => void;
10
+ };
11
+ declare const AiViewPanel: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type AiViewPanel = ReturnType<typeof AiViewPanel>;
13
+ export default AiViewPanel;
@@ -0,0 +1 @@
1
+ export declare const AiViewType = "ai";
@@ -0,0 +1 @@
1
+ export const AiViewType = "ai";
@@ -0,0 +1,60 @@
1
+ import { View, type ViewStateResult, type WorkspaceLeaf } from "@lapis-notes/api";
2
+ import type { ComposerSearchSource } from "@lapismd/design-core/ai/chat";
3
+ import type { AgentRequest, AgentRuntime, ModelRef, McpServerContribution } from "../core/types";
4
+ import type { ConversationRepository, CreateConversationInput } from "../conversations/conversation-repository";
5
+ import type { AiPluginSettings } from "../settings/ai-settings";
6
+ import type { AppToolBridgeCoordinator } from "../tools/desktop-app-tool-bridge";
7
+ export { AiViewType } from "./ai-view-type";
8
+ export type AiViewHost = {
9
+ selectRuntime(request: AgentRequest): Promise<AgentRuntime>;
10
+ fallbackRuntime(): AgentRuntime;
11
+ liveRuntimeUnavailableReason(): string | null;
12
+ mcpServers: {
13
+ list(): McpServerContribution[];
14
+ };
15
+ appToolBridge?: AppToolBridgeCoordinator;
16
+ skills?: import("../skills/registry").SkillRegistry;
17
+ skillSnapshots?: import("../skills/registry").SkillSnapshotStore;
18
+ slashRouter?: import("../commands/router").SlashCommandRouter;
19
+ appToolHost?: import("../tools/app-tool-host").AppToolHost;
20
+ memory?: import("../memory/types").AutomaticMemoryRecall;
21
+ handoffSummaries?: Pick<import("../conversations/handoff-summary").HandoffSummaryCoordinator, "afterTerminal">;
22
+ skillContext?: () => import("../skills/types").SkillDiscoveryContext;
23
+ conversations: ConversationRepository;
24
+ createConversationInput(explicitFolder?: string): CreateConversationInput;
25
+ currentConversationScope(): string;
26
+ listConversationFolders(): string[];
27
+ revealConversationHistory(): Promise<void>;
28
+ subscribeConversationMoves?(listener: (oldPath: string, newPath: string) => void): () => void;
29
+ searchVaultFiles: ComposerSearchSource;
30
+ getSettings(): AiPluginSettings;
31
+ updateSettings(patch: Partial<AiPluginSettings>): Promise<void>;
32
+ subscribeSettings?(listener: (patch: Partial<AiPluginSettings>) => void): () => void;
33
+ models: {
34
+ listModels(provider: string): Promise<ModelRef[]>;
35
+ };
36
+ workspace?: string;
37
+ };
38
+ export declare class AiView extends View {
39
+ private component;
40
+ private disposed;
41
+ private mountGeneration;
42
+ private readonly host;
43
+ constructor(leaf: WorkspaceLeaf, host: AiViewHost);
44
+ getViewType(): string;
45
+ getDisplayText(): string;
46
+ getIcon(): string;
47
+ getBreadcrumbFilePath(): string | null;
48
+ getBreadcrumbs(): {
49
+ id: string;
50
+ label: string;
51
+ onSelect: () => void;
52
+ }[];
53
+ protected onOpen(): Promise<void>;
54
+ protected onClose(): Promise<void>;
55
+ onload(): void;
56
+ onunload(): void;
57
+ setState(state: Record<string, unknown>, result?: ViewStateResult): Promise<void>;
58
+ private mountPanel;
59
+ private persistLocationHint;
60
+ }