@lapis-notes/ai 0.1.1 → 0.1.5

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 (69) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/LICENSE.md +3 -7
  3. package/README.md +1 -1
  4. package/dist/ai-plugin.d.ts +2 -2
  5. package/dist/ai-plugin.js +28 -11
  6. package/dist/catalog/ai-catalog-panel.svelte +20 -3
  7. package/dist/chat/ai-chat-panel.svelte +187 -87
  8. package/dist/chat/ai-chat-panel.svelte.d.ts +2 -0
  9. package/dist/chat/ai-view-bootstrap.d.ts +1 -0
  10. package/dist/chat/ai-view-bootstrap.js +32 -12
  11. package/dist/chat/ai-view-panel.svelte +14 -0
  12. package/dist/chat/ai-view.d.ts +1 -1
  13. package/dist/chat/chat-controller.svelte.d.ts +1 -1
  14. package/dist/chat/chat-controller.svelte.js +94 -29
  15. package/dist/chat/chat-tool-display.d.ts +2 -12
  16. package/dist/chat/chat-tool-display.js +2 -206
  17. package/dist/chat/composer-model-catalog.d.ts +20 -0
  18. package/dist/chat/composer-model-catalog.js +44 -0
  19. package/dist/commands/agent.d.ts +1 -1
  20. package/dist/commands/agent.js +6 -1
  21. package/dist/conversations/context-handoff.d.ts +1 -25
  22. package/dist/conversations/context-handoff.js +1 -207
  23. package/dist/conversations/hashes.d.ts +1 -5
  24. package/dist/conversations/hashes.js +1 -40
  25. package/dist/core/types.d.ts +1 -241
  26. package/dist/core/types.js +1 -50
  27. package/dist/history/ai-history-panel.svelte +4 -1
  28. package/dist/host/controller-connection.d.ts +14 -0
  29. package/dist/host/controller-connection.js +62 -0
  30. package/dist/host/controller-runtime.d.ts +13 -0
  31. package/dist/host/controller-runtime.js +112 -0
  32. package/dist/host/create-host-runtimes.d.ts +2 -1
  33. package/dist/host/create-host-runtimes.js +5 -7
  34. package/dist/index.d.ts +1 -1
  35. package/dist/memory/candidate-extractor.d.ts +2 -25
  36. package/dist/memory/candidate-extractor.js +1 -191
  37. package/dist/memory/hashes.d.ts +1 -5
  38. package/dist/memory/hashes.js +1 -37
  39. package/dist/memory/memory-record-store.d.ts +3 -48
  40. package/dist/memory/memory-record-store.js +16 -220
  41. package/dist/memory/memory-scheduler.d.ts +1 -21
  42. package/dist/memory/memory-scheduler.js +1 -143
  43. package/dist/memory/native-memory-service.d.ts +1 -72
  44. package/dist/memory/native-memory-service.js +1 -1256
  45. package/dist/memory/paths.d.ts +1 -13
  46. package/dist/memory/paths.js +1 -60
  47. package/dist/memory/runtime-consolidation-provider.d.ts +2 -18
  48. package/dist/memory/runtime-consolidation-provider.js +1 -154
  49. package/dist/memory/types.d.ts +1 -139
  50. package/dist/providers/acp-model-provider.d.ts +8 -3
  51. package/dist/providers/acp-model-provider.js +21 -49
  52. package/dist/providers/model-provider.d.ts +3 -2
  53. package/dist/providers/model-provider.js +15 -2
  54. package/dist/runtime-adapters.d.ts +3 -0
  55. package/dist/runtime-adapters.js +2 -0
  56. package/dist/settings/acp-agents.d.ts +4 -1
  57. package/dist/settings/acp-agents.js +5 -1
  58. package/dist/settings/ai-settings-tab.js +8 -6
  59. package/dist/settings/ai-settings.d.ts +4 -4
  60. package/dist/settings/ai-settings.js +5 -3
  61. package/dist/settings/register-ai-settings.js +27 -14
  62. package/dist/tools/app-tool-host.d.ts +22 -2
  63. package/dist/tools/app-tool-host.js +51 -4
  64. package/dist/tools/desktop-app-tool-bridge.d.ts +4 -1
  65. package/dist/tools/desktop-app-tool-bridge.js +94 -157
  66. package/manifest.json +20 -2
  67. package/package.json +20 -7
  68. package/registry-content/overview.md +10 -0
  69. package/registry.json +221 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # AI changelog
2
2
 
3
- ## 0.1.1
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#6](https://github.com/lapismd/lapis-plugins/pull/6) [`86f38d2`](https://github.com/lapismd/lapis-plugins/commit/86f38d211bd8beaf4e2e748e65aee8002409f77b) Thanks [@stevejuma](https://github.com/stevejuma)! - Refresh model catalogs when the harness changes in chat or Settings, distinguish native and ACP providers, and discard stale discovery results. Pass the owning vault when checking initial desktop controller readiness.
8
+
9
+ - Updated dependencies [[`cafe5b0`](https://github.com/lapismd/lapis-plugins/commit/cafe5b084ff6579948b99226048691bf36fc7276)]:
10
+ - @lapis-notes/markdown@0.1.6
11
+
12
+ ## 0.1.4
13
+
14
+ ### Patch Changes
15
+
16
+ - Add official author avatars and deterministic split, light, and dark registry media for plugin banners, overviews, and galleries.
17
+
18
+ - Updated dependencies []:
19
+ - @lapis-notes/markdown@0.1.5
20
+
21
+ ## 0.1.3
22
+
23
+ ### Patch Changes
24
+
25
+ - [`8c23b79`](https://github.com/lapismd/lapis-plugins/commit/8c23b7911798fd73abba74e0ece91ef8745b49a2) Thanks [@stevejuma](https://github.com/stevejuma)! - Refresh the AI catalog when the active workspace leaf changes its folder scope.
26
+
27
+ ## 0.1.2
4
28
 
5
29
  - Initial independent public package extracted from Lapis Notes without changing
6
30
  the runtime plugin ID.
package/LICENSE.md CHANGED
@@ -1,8 +1,4 @@
1
- # License
1
+ Apache-2.0
2
2
 
3
- Copyright (c) LapisMD contributors.
4
-
5
- This software is licensed under the GNU Affero General Public License, version
6
- 3 or (at your option) any later version (`AGPL-3.0-or-later`). The complete
7
- license text is available from the
8
- [GNU Project](https://www.gnu.org/licenses/agpl-3.0.html).
3
+ This project is licensed under the Apache License 2.0.
4
+ See <https://www.apache.org/licenses/LICENSE-2.0>.
package/README.md CHANGED
@@ -13,7 +13,7 @@ Register the exported plugin class in the application's `PluginProfile`. Import
13
13
  registration so the host owns its lifecycle.
14
14
 
15
15
  The runtime plugin ID is `ai`. A matching signed
16
- `ai-0.1.1.lapis-plugin` archive is attached to the
16
+ `ai-0.1.5.lapis-plugin` archive is attached to the
17
17
  package-scoped GitHub release for manual or registry installation.
18
18
 
19
19
  See the [repository README](https://github.com/lapismd/lapis-plugins#readme) for
@@ -3,7 +3,7 @@ import type { ComposerTriggerItem } from "@lapismd/design-core/ai/chat";
3
3
  import type { CatalogGroup, CatalogToolRow } from "./catalog/types";
4
4
  import type { ConversationLocation } from "./conversations/types";
5
5
  import type { AgentRequest, AgentRuntime } from "./core/types";
6
- import type { AgentProcessHost } from "./host/process-host";
6
+ import { ControllerConnectionPool } from "./host/controller-connection";
7
7
  import { ModelProviderRegistry } from "./providers/model-provider";
8
8
  import { type AgentRuntimeRegistry } from "./registry/runtime-registry";
9
9
  import { FakeAgentRuntime } from "./runtimes/fake/fake-runtime";
@@ -28,7 +28,7 @@ import { type UserAgentsCommandStore } from "./commands/user-agents";
28
28
  export declare class AiPlugin extends Plugin {
29
29
  #private;
30
30
  private data;
31
- readonly processHost: AgentProcessHost;
31
+ readonly controllerConnections: ControllerConnectionPool;
32
32
  readonly registry: AgentRuntimeRegistry;
33
33
  readonly models: ModelProviderRegistry;
34
34
  readonly mcpServers: import(".").McpServerContributionRegistry;
package/dist/ai-plugin.js CHANGED
@@ -9,7 +9,7 @@ import { AiHistoryView, AiHistoryViewType } from "./history/ai-history-view";
9
9
  import { AiJsonlView, AiJsonlViewType } from "./jsonl/ai-jsonl-view";
10
10
  import { formatFileMention, searchVaultFiles } from "./chat/chat-mentions";
11
11
  import { createHostAgentRuntimes } from "./host/create-host-runtimes";
12
- import { createAgentProcessHost } from "./host/desktop-process-host";
12
+ import { ControllerConnectionPool } from "./host/controller-connection";
13
13
  import { resolveAgentWorkspace } from "./host/agent-workspace";
14
14
  import { AcpModelProvider } from "./providers/acp-model-provider";
15
15
  import { ModelProviderRegistry } from "./providers/model-provider";
@@ -56,7 +56,7 @@ export class AiPlugin extends Plugin {
56
56
  settings: DEFAULT_AI_SETTINGS,
57
57
  source: {},
58
58
  };
59
- processHost;
59
+ controllerConnections = new ControllerConnectionPool();
60
60
  registry;
61
61
  models;
62
62
  mcpServers = createMcpServerContributionRegistry();
@@ -91,7 +91,7 @@ export class AiPlugin extends Plugin {
91
91
  this.conversationIndex = new AiConversationIndex(this.conversations, app.appDatabase);
92
92
  this.conversationIndexCoordinator = new ConversationIndexCoordinator(this.conversationIndex, (operation, location, error) => this.app.logger.warn(`Unable to ${operation} the AI conversation index for ${location.conversationId}`, error));
93
93
  this.appToolHost = new AppToolHost(app.agentTools, () => this.getSettings());
94
- this.appToolBridge = new DesktopAppToolBridge(this.appToolHost);
94
+ this.appToolBridge = new DesktopAppToolBridge(this.appToolHost, () => this.controllerConnections.get(this.workspace));
95
95
  this.skillRegistry = new SkillRegistry({
96
96
  vault: app.vault,
97
97
  appSkills: app.agentSkills,
@@ -104,15 +104,28 @@ export class AiPlugin extends Plugin {
104
104
  this.register(() => {
105
105
  void this.appToolBridge.close().finally(() => this.appToolHost.close());
106
106
  });
107
- this.processHost = createAgentProcessHost();
107
+ this.register(() => this.controllerConnections.close());
108
108
  const workspace = this.workspace;
109
109
  this.models = new ModelProviderRegistry([
110
- new AcpModelProvider("codex", { workspace }),
111
- new AcpModelProvider("cursor", { workspace }),
110
+ new AcpModelProvider("codex", {
111
+ connection: () => this.controllerConnections.get(workspace),
112
+ }),
113
+ new AcpModelProvider("cursor", {
114
+ connection: () => this.controllerConnections.get(workspace),
115
+ }),
116
+ new AcpModelProvider("opencode", {
117
+ connection: () => this.controllerConnections.get(workspace),
118
+ }),
119
+ new AcpModelProvider("codex-native", {
120
+ connection: () => this.controllerConnections.get(workspace),
121
+ }),
122
+ new AcpModelProvider("opencode-native", {
123
+ connection: () => this.controllerConnections.get(workspace),
124
+ }),
112
125
  ]);
113
126
  this.registry = createAgentRuntimeRegistry([
114
127
  this.fakeRuntime,
115
- ...createHostAgentRuntimes(),
128
+ ...createHostAgentRuntimes(this.controllerConnections),
116
129
  ]);
117
130
  this.memoryConsolidationProvider = new RuntimeMemoryConsolidationProvider({
118
131
  configuration: () => {
@@ -231,7 +244,7 @@ export class AiPlugin extends Plugin {
231
244
  return () => this.#conversationMoveListeners.delete(listener);
232
245
  }
233
246
  refreshHostRuntimes() {
234
- for (const runtime of createHostAgentRuntimes()) {
247
+ for (const runtime of createHostAgentRuntimes(this.controllerConnections)) {
235
248
  this.registry.register(runtime);
236
249
  }
237
250
  }
@@ -453,7 +466,9 @@ export class AiPlugin extends Plugin {
453
466
  this.app.appDatabase.queryMemoryCandidates({ limit: 10_000 }),
454
467
  this.app.appDatabase.listMemoryJobs(),
455
468
  ]);
456
- new Notice(`Memory: ${sources.length} conversation source${sources.length === 1 ? "" : "s"}, ${candidates.length} candidate${candidates.length === 1 ? "" : "s"}, ${jobs.filter((job) => job.status === "running").length} active job${jobs.filter((job) => job.status === "running").length === 1 ? "" : "s"}`);
469
+ new Notice(`Memory: ${sources.length} conversation source${sources.length === 1 ? "" : "s"}, ${candidates.length} candidate${candidates.length === 1 ? "" : "s"}, ${jobs.filter((job) => job.status === "running").length} active job${jobs.filter((job) => job.status === "running").length === 1
470
+ ? ""
471
+ : "s"}`);
457
472
  },
458
473
  });
459
474
  this.addCommand({
@@ -536,7 +551,9 @@ export class AiPlugin extends Plugin {
536
551
  this.register(() => this.memoryScheduler.dispose());
537
552
  this.memoryIngestionCoordinator.startCatchUp();
538
553
  this.memoryScheduler.start();
539
- this.registerView(AiJsonlViewType, (leaf) => new AiJsonlView(leaf), { kind: "file" });
554
+ this.registerView(AiJsonlViewType, (leaf) => new AiJsonlView(leaf), {
555
+ kind: "file",
556
+ });
540
557
  this.registerEditorView({
541
558
  id: AiJsonlViewType,
542
559
  viewType: AiJsonlViewType,
@@ -651,7 +668,7 @@ export class AiPlugin extends Plugin {
651
668
  settings: this.getSettings(),
652
669
  pluginLabel: (pluginId) => contributingPluginLabel(this.app, pluginId),
653
670
  userAgents: this.userAgents,
654
- scopeDir: this.createConversationInput().scopeDir,
671
+ scopeDir: this.currentConversationScope(),
655
672
  });
656
673
  }
657
674
  async setCatalogToolEnabled(tool, enabled) {
@@ -61,6 +61,8 @@
61
61
  let openKeys = new SvelteSet<string>();
62
62
  let openedCatalogPath = $state<string | null>(null);
63
63
  let defaultsApplied = false;
64
+ let refreshGeneration = 0;
65
+ let groupsSignature = "";
64
66
 
65
67
  const visibleGroups = $derived(filterCatalogGroups(groups, query));
66
68
  const filtering = $derived(query.trim().length > 0);
@@ -95,7 +97,13 @@
95
97
  }
96
98
 
97
99
  async function refresh(): Promise<void> {
98
- groups = await loadCatalog();
100
+ const generation = ++refreshGeneration;
101
+ const nextGroups = await loadCatalog();
102
+ if (generation !== refreshGeneration) return;
103
+ const nextSignature = JSON.stringify(nextGroups);
104
+ if (nextSignature === groupsSignature) return;
105
+ groupsSignature = nextSignature;
106
+ groups = nextGroups;
99
107
  if (!defaultsApplied) {
100
108
  openKeys.clear();
101
109
  for (const key of collectCatalogFolderKeys(groups)) {
@@ -106,6 +114,7 @@
106
114
  }
107
115
 
108
116
  onMount(() => {
117
+ const layout = app.workspace.on("layout-ready", () => void refresh());
109
118
  const tools = app.agentTools.on("changed", () => void refresh());
110
119
  const commands = app.agentSlashCommands.on("changed", () => void refresh());
111
120
  const skills = app.agentSkills.on("changed", () => void refresh());
@@ -113,9 +122,13 @@
113
122
  const deleted = app.vault.on("delete", () => void refresh());
114
123
  const modified = app.vault.on("modify", () => void refresh());
115
124
  const renamed = app.vault.on("rename", () => void refresh());
125
+ const activeLeaf = app.workspace.on("active-leaf-change", () =>
126
+ void refresh(),
127
+ );
116
128
  const unsubscribeSettings = subscribeSettings?.(() => void refresh());
117
- void refresh();
129
+ if (app.workspace.layoutReady) void refresh();
118
130
  return () => {
131
+ app.workspace.offref(layout);
119
132
  app.agentTools.offref(tools);
120
133
  app.agentSlashCommands.offref(commands);
121
134
  app.agentSkills.offref(skills);
@@ -123,6 +136,7 @@
123
136
  app.vault.offref(deleted);
124
137
  app.vault.offref(modified);
125
138
  app.vault.offref(renamed);
139
+ app.workspace.offref(activeLeaf);
126
140
  unsubscribeSettings?.();
127
141
  };
128
142
  });
@@ -733,7 +747,10 @@
733
747
 
734
748
  :global(.ai-catalog .suggestion-highlight) {
735
749
  border-radius: 0.125rem;
736
- color: var(--ui-search-highlight-foreground, inherit);
750
+ color: var(
751
+ --ui-search-highlight-foreground,
752
+ var(--ui-workspace-foreground, var(--foreground))
753
+ );
737
754
  background: var(
738
755
  --ui-search-highlight-background,
739
756
  color-mix(in srgb, var(--primary) 22%, transparent)