@wangmo-bit/ds-link 0.0.0-stage → 0.8.18

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -2
  3. package/TESTING.md +59 -0
  4. package/THIRD_PARTY_NOTICES.md +313 -0
  5. package/assets/icon.svg +7 -0
  6. package/cordis.patch.yml +3 -0
  7. package/dist/client.js +6012 -0
  8. package/package.json +102 -4
  9. package/src/core/constants.js +188 -0
  10. package/src/core/downgrade.js +80 -0
  11. package/src/core/engine.js +4669 -0
  12. package/src/core/errors.js +51 -0
  13. package/src/core/ledger.js +1174 -0
  14. package/src/core/migration.js +741 -0
  15. package/src/core/render.js +61 -0
  16. package/src/core/settings.js +147 -0
  17. package/src/core/validation.js +454 -0
  18. package/src/host/adapter.js +1152 -0
  19. package/src/host/connection.js +113 -0
  20. package/src/host/entry-0.2.0.js +13 -0
  21. package/src/host/entry-0.3.0.js +13 -0
  22. package/src/host/entry-0.4.0.js +13 -0
  23. package/src/host/entry-0.8.10.js +13 -0
  24. package/src/host/entry-0.8.11.js +13 -0
  25. package/src/host/entry-0.8.12.js +13 -0
  26. package/src/host/entry-0.8.13.js +13 -0
  27. package/src/host/entry-0.8.14.js +13 -0
  28. package/src/host/entry-0.8.15.js +13 -0
  29. package/src/host/entry-0.8.16-pre.1.js +13 -0
  30. package/src/host/entry-0.8.16-pre.2.js +13 -0
  31. package/src/host/entry-0.8.16-pre.3.js +13 -0
  32. package/src/host/entry-0.8.16-pre.4.js +13 -0
  33. package/src/host/entry-0.8.16-pre.5.js +13 -0
  34. package/src/host/entry-0.8.18.js +13 -0
  35. package/src/host/entry-0.8.5.js +13 -0
  36. package/src/host/entry-0.8.6.js +13 -0
  37. package/src/host/entry-0.8.7.js +13 -0
  38. package/src/host/entry-0.8.8.js +13 -0
  39. package/src/host/entry-0.8.9.js +13 -0
  40. package/src/host/index.js +74 -0
  41. package/src/host/plugin.js +403 -0
  42. package/src/host/prompt.js +22 -0
  43. package/src/host/tools.js +312 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Authenticated owner control-plane API.
3
+ *
4
+ * The route is registered through `ctx.connection.fetch`, so rc.5 applies its
5
+ * Host/Origin fence and owner-only principal gate before this handler runs.
6
+ * No cookie parsing, invocation object, or raw webServer route is used.
7
+ */
8
+
9
+ import { fail, errorPayload } from '../core/errors.js'
10
+ import { assertAllowedKeys, assertPlainObject, requiredString } from '../core/validation.js'
11
+
12
+ export const CONNECTION_PATH = '/api/session-link/api'
13
+ export const CONNECTION_METHODS = Object.freeze(['POST'])
14
+ const MAX_BODY_BYTES = 1024 * 1024
15
+
16
+ /**
17
+ * @param {Record<string, any>} service
18
+ * @returns {(request: Request) => Promise<Response>}
19
+ */
20
+ export function createConnectionHandler(service) {
21
+ return async (request) => {
22
+ if (request.method !== 'POST') return envelope(null, 405, 'method_not_allowed', 'POST only')
23
+ const contentType = request.headers.get('content-type')?.split(';', 1)[0]?.trim().toLowerCase()
24
+ if (contentType !== 'application/json') {
25
+ return envelope(null, 415, 'unsupported_media_type', 'content-type must be application/json')
26
+ }
27
+ let text
28
+ try {
29
+ text = await request.text()
30
+ } catch {
31
+ return envelope(null, 400, 'bad_request', 'request body could not be read')
32
+ }
33
+ if (Buffer.byteLength(text, 'utf8') > MAX_BODY_BYTES) {
34
+ return envelope(null, 413, 'payload_too_large', 'request body is too large')
35
+ }
36
+ let body
37
+ try {
38
+ body = JSON.parse(text)
39
+ } catch {
40
+ return envelope(null, 400, 'bad_request', 'body is not JSON')
41
+ }
42
+ try {
43
+ const value = await dispatchRpc(service, body)
44
+ return jsonResponse({ ok: true, value })
45
+ } catch (error) {
46
+ return jsonResponse({ ok: false, error: errorPayload(error) })
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * @param {Record<string, any>} service
53
+ * @param {unknown} body
54
+ * @returns {Promise<unknown>}
55
+ */
56
+ export async function dispatchRpc(service, body) {
57
+ const object = assertPlainObject(body, 'request body', 'bad_request')
58
+ assertAllowedKeys(object, ['action', 'payload'], 'request body', 'bad_request')
59
+ const action = requiredString(object.action, 'action', { max: 64, code: 'bad_request' })
60
+ const payload = object.payload === undefined ? {} : assertPlainObject(object.payload, 'payload', 'bad_request')
61
+ if (action === 'snapshot') return service.engine.snapshot(payload)
62
+ if (action === 'settings') return service.engine.updateSettings(payload)
63
+ if (action === 'control') return service.engine.ownerControl(payload)
64
+ // Owner-only bounded card lookup: the rc.5 Host/Origin fence and owner
65
+ // principal gate run before this handler; the engine then returns only
66
+ // minimal fields for messages that participate in the requested session.
67
+ if (action === 'card_lookup') return service.engine.cardLookup(payload)
68
+ throw fail('invalid_argument', `unknown action ${action}`)
69
+ }
70
+
71
+ /**
72
+ * Register the exact fetch route on the shared authenticated channel.
73
+ * @param {Record<string, any>} ctx
74
+ * @param {(request: Request) => Promise<Response>} handler
75
+ * @returns {Promise<() => Promise<void>>}
76
+ */
77
+ export async function registerConnectionRoute(ctx, handler) {
78
+ const fetch = ctx.connection?.fetch
79
+ if (fetch === undefined || typeof fetch.register !== 'function') {
80
+ throw fail(
81
+ 'unsupported_host',
82
+ 'target Host does not expose the authenticated exact Fetch API; refusing to mount an insecure control plane',
83
+ )
84
+ }
85
+ return fetch.register({
86
+ path: CONNECTION_PATH,
87
+ methods: [...CONNECTION_METHODS],
88
+ requestBody: 'buffered',
89
+ fetch: handler,
90
+ })
91
+ }
92
+
93
+ /**
94
+ * @param {unknown} value
95
+ * @param {number} status
96
+ * @param {string} code
97
+ * @param {string} message
98
+ * @returns {Response}
99
+ */
100
+ function envelope(value, status, code, message) {
101
+ return jsonResponse(status >= 400 ? { ok: false, error: { code, message } } : { ok: true, value }, status)
102
+ }
103
+
104
+ /** @param {unknown} body @param {number} [status] @returns {Response} */
105
+ function jsonResponse(body, status = 200) {
106
+ return new Response(JSON.stringify(body), {
107
+ status,
108
+ headers: {
109
+ 'content-type': 'application/json; charset=utf-8',
110
+ 'cache-control': 'no-store',
111
+ },
112
+ })
113
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry: do not reuse an older index.js callback during rc.5 HMR. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export { inject } from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo-bit/ds-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo-bit/ds-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo-bit/ds-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo-bit/ds-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,13 @@
1
+ /** Exact-version physical entry; service/state identity stays unversioned. */
2
+ import { createSessionLinkPlugin } from './plugin.js'
3
+ export * from './index.js'
4
+ export const name = 'session-link'
5
+ let builder
6
+ export async function apply(ctx, config) {
7
+ if (builder === undefined) {
8
+ const sdk = await import('@deepseek-ai/dsh-llm')
9
+ if (typeof sdk.createUserMessage !== 'function') throw new Error('@wangmo/dsh-session-link: Host createUserMessage is unavailable')
10
+ builder = sdk.createUserMessage
11
+ }
12
+ await createSessionLinkPlugin(ctx, config, { createUserMessage: builder })
13
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Package entry. Only this module imports a Host value: the public
3
+ * `createUserMessage` builder. Everything else is injected so tests can run
4
+ * against a mock Host without private package internals.
5
+ */
6
+
7
+ import { SessionLinkService, createSessionLinkPlugin, normalizeConfig, resolveStateRoot } from './plugin.js'
8
+
9
+ let hostBuilder
10
+
11
+ /**
12
+ * Load the only Host value import lazily. This keeps every source module
13
+ * importable in tests without a production Harness install, while a real
14
+ * profile still must provide the exact peer package at apply time.
15
+ * @returns {Promise<(input: Record<string, any>) => Record<string, any>>}
16
+ */
17
+ async function createUserMessageBuilder() {
18
+ if (hostBuilder !== undefined) return hostBuilder
19
+ let module
20
+ try {
21
+ module = await import('@deepseek-ai/dsh-llm')
22
+ } catch (error) {
23
+ throw new Error(
24
+ '@wangmo-bit/ds-link: @deepseek-ai/dsh-llm must be resolvable from this package (peer 0.2.1-rc.5 || 0.2.2-rc.1)',
25
+ { cause: error },
26
+ )
27
+ }
28
+ if (typeof module.createUserMessage !== 'function') {
29
+ throw new Error('@wangmo-bit/ds-link: @deepseek-ai/dsh-llm does not export createUserMessage')
30
+ }
31
+ hostBuilder = module.createUserMessage
32
+ return hostBuilder
33
+ }
34
+
35
+ export const name = 'session-link'
36
+
37
+ /**
38
+ * Public Host services this plugin requires. The loader activates the plugin
39
+ * only after all of them exist; a Host without the authenticated exact Fetch
40
+ * API is rejected in open() instead of falling back to an unauthenticated
41
+ * raw webServer route.
42
+ */
43
+ export const inject = [
44
+ 'sessions',
45
+ 'agents',
46
+ 'sessionController',
47
+ 'workspaceRegistry',
48
+ 'sessionQuery',
49
+ 'connection',
50
+ 'tools',
51
+ 'systemPrompt',
52
+ ]
53
+
54
+ /**
55
+ * @param {Record<string, any>} ctx
56
+ * @param {Record<string, unknown>|undefined} config
57
+ * @returns {Promise<SessionLinkService>}
58
+ */
59
+ export async function apply(ctx, config) {
60
+ const createUserMessage = await createUserMessageBuilder()
61
+ // Cordis accepts only void or an effect disposer from apply; the service is
62
+ // registered through ctx.provide and tied to the plugin's lifecycle effect.
63
+ await createSessionLinkPlugin(ctx, config, { createUserMessage })
64
+ }
65
+
66
+ export { SessionLinkService, createSessionLinkPlugin, normalizeConfig, resolveStateRoot }
67
+ export { Ledger } from '../core/ledger.js'
68
+ export { rollbackPreflight, validateV1State, v3ToV2Preflight } from '../core/migration.js'
69
+ export { v04DowngradePreflight } from '../core/downgrade.js'
70
+ export { SessionLinkEngine } from '../core/engine.js'
71
+ export { HostAdapter } from './adapter.js'
72
+ export { createToolDefinitions } from './tools.js'
73
+ export { CONNECTION_PATH, createConnectionHandler, dispatchRpc, registerConnectionRoute } from './connection.js'
74
+ export { PROMPT_SECTION_NAME, SESSION_LINK_GUIDANCE } from './prompt.js'