summaryrefslogtreecommitdiffhomepage
path: root/src/app/views/ExtensionsPane.svelte
blob: d5baa39c8a0c9c5c5927343262ca16a247559ac1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<script lang="ts">
  /**
   * The `extensions` view — the frontend-modules table (aggregated from each
   * feature's public `manifest` so it can't drift from what's actually
   * composed) plus the generic surface list. The backend's "Loaded Extensions"
   * surface is a SEPARATE, backend-owned list. Unkeyed (like today).
   */
  import Table from "../../components/Table.svelte";
  import { manifest as accountUsageManifest } from "../../features/account-usage";
  import { manifest as cacheWarmingManifest } from "../../features/cache-warming";
  import { manifest as chatManifest } from "../../features/chat";
  import { manifest as concurrencyManifest } from "../../features/concurrency";
  import { manifest as conversationCacheManifest } from "../../features/conversation-cache";
  import { manifest as cwdLspManifest } from "../../features/cwd-lsp";
  import { manifest as computerManifest } from "../../features/computer";
  import { manifest as heartbeatManifest } from "../../features/heartbeat";
  import { manifest as layoutManifest } from "../../features/layout";
  import { manifest as markdownManifest } from "../../features/markdown";
  import { manifest as mcpManifest } from "../../features/mcp";
  import { manifest as namedAgentsManifest } from "../../features/named-agents";
  import { manifest as searchSettingsManifest } from "../../features/search-settings";
  import { manifest as settingsManifest } from "../../features/settings";
  import { manifest as smartScrollManifest } from "../../features/smart-scroll";
  import { SurfaceView } from "../../features/surface-host";
  import { manifest as surfaceHostManifest } from "../../features/surface-host";
  import { manifest as systemPromptManifest } from "../../features/system-prompt";
  import { manifest as tabsManifest } from "../../features/tabs";
  import { manifest as viewsManifest } from "../../features/views";
  import { manifest as visionManifest } from "../../features/vision";
  import type { AppViewPorts } from "../view-ports";

  // Surfaces with dedicated renderers elsewhere stay out of the generic list:
  // cache-warming (its own view), message-queue (its own view), todo (the
  // Tasks view). SurfaceView itself stays fully generic (it never switches on
  // a surface id) — the FILTER is this view's data selection.
  const CACHE_WARMING_ID = "cache-warming";
  const MESSAGE_QUEUE_ID = "message-queue";
  const TODO_ID = "todo";

  let { ports }: { ports: AppViewPorts } = $props();
  const store = $derived(ports.store);

  const MODULE_COLUMNS = ["Module", "Description"] as const;
  // FE features are internal units of this single repo, so there is no
  // per-module version — they all share dispatch-web's version.
  const loadedModules: readonly (readonly [string, string])[] = [
    chatManifest,
    tabsManifest,
    surfaceHostManifest,
    viewsManifest,
    layoutManifest,
    conversationCacheManifest,
    markdownManifest,
    cacheWarmingManifest,
    cwdLspManifest,
    mcpManifest,
    computerManifest,
    smartScrollManifest,
    settingsManifest,
    systemPromptManifest,
    heartbeatManifest,
    concurrencyManifest,
    accountUsageManifest,
    visionManifest,
    namedAgentsManifest,
    searchSettingsManifest,
  ].map((m) => [m.name, m.description] as const);
</script>

<section>
  <h3 class="mb-1 text-xs font-semibold uppercase opacity-60">Frontend modules</h3>
  <Table columns={MODULE_COLUMNS} rows={loadedModules} />
</section>
<section class="mt-4 flex flex-col gap-3">
  <h3 class="text-xs font-semibold uppercase opacity-60">Surfaces</h3>
  {#each store.surfaces.filter((s) => s.id !== CACHE_WARMING_ID && s.id !== MESSAGE_QUEUE_ID && s.id !== TODO_ID) as spec (spec.id)}
    <SurfaceView
      {spec}
      onInvoke={(msg) => store.invoke(msg.surfaceId, msg.actionId, msg.payload)}
    />
  {/each}
</section>