@astrale-os/shell 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.
- package/dist/adapters/iframe.shell-adapter.d.ts +10 -0
- package/dist/adapters/iframe.shell-adapter.d.ts.map +1 -0
- package/dist/adapters/iframe.shell-adapter.js +55 -0
- package/dist/adapters/kernel-client.adapter.d.ts +53 -0
- package/dist/adapters/kernel-client.adapter.d.ts.map +1 -0
- package/dist/adapters/kernel-client.adapter.js +69 -0
- package/dist/adapters/message-port.transport.d.ts +7 -0
- package/dist/adapters/message-port.transport.d.ts.map +1 -0
- package/dist/adapters/message-port.transport.js +42 -0
- package/dist/application/channels/children-channel.d.ts +21 -0
- package/dist/application/channels/children-channel.d.ts.map +1 -0
- package/dist/application/channels/children-channel.js +82 -0
- package/dist/application/channels/observer.d.ts +9 -0
- package/dist/application/channels/observer.d.ts.map +1 -0
- package/dist/application/channels/observer.js +23 -0
- package/dist/application/channels/parent-channel.d.ts +17 -0
- package/dist/application/channels/parent-channel.d.ts.map +1 -0
- package/dist/application/channels/parent-channel.js +21 -0
- package/dist/application/channels/types.d.ts +12 -0
- package/dist/application/channels/types.d.ts.map +1 -0
- package/dist/application/channels/types.js +29 -0
- package/dist/application/intent/pipeline-runner.d.ts +12 -0
- package/dist/application/intent/pipeline-runner.d.ts.map +1 -0
- package/dist/application/intent/pipeline-runner.js +27 -0
- package/dist/application/intent/request.d.ts +34 -0
- package/dist/application/intent/request.d.ts.map +1 -0
- package/dist/application/intent/request.js +70 -0
- package/dist/application/intent/router.d.ts +56 -0
- package/dist/application/intent/router.d.ts.map +1 -0
- package/dist/application/intent/router.js +94 -0
- package/dist/application/kernel-facade.d.ts +33 -0
- package/dist/application/kernel-facade.d.ts.map +1 -0
- package/dist/application/kernel-facade.js +77 -0
- package/dist/application/shell.d.ts +100 -0
- package/dist/application/shell.d.ts.map +1 -0
- package/dist/application/shell.js +256 -0
- package/dist/application/windowing/child-init.d.ts +23 -0
- package/dist/application/windowing/child-init.d.ts.map +1 -0
- package/dist/application/windowing/child-init.js +101 -0
- package/dist/application/windowing/handshake.d.ts +30 -0
- package/dist/application/windowing/handshake.d.ts.map +1 -0
- package/dist/application/windowing/handshake.js +63 -0
- package/dist/application/windowing/lifecycle-controller.d.ts +10 -0
- package/dist/application/windowing/lifecycle-controller.d.ts.map +1 -0
- package/dist/application/windowing/lifecycle-controller.js +30 -0
- package/dist/application/windowing/mount-controller.d.ts +25 -0
- package/dist/application/windowing/mount-controller.d.ts.map +1 -0
- package/dist/application/windowing/mount-controller.js +277 -0
- package/dist/application/windowing/protocol.d.ts +21 -0
- package/dist/application/windowing/protocol.d.ts.map +1 -0
- package/dist/application/windowing/protocol.js +19 -0
- package/dist/application/windowing/token-refresh.d.ts +19 -0
- package/dist/application/windowing/token-refresh.d.ts.map +1 -0
- package/dist/application/windowing/token-refresh.js +60 -0
- package/dist/domain/identity/delegation.d.ts +15 -0
- package/dist/domain/identity/delegation.d.ts.map +1 -0
- package/dist/domain/identity/delegation.js +12 -0
- package/dist/domain/identity/path.d.ts +11 -0
- package/dist/domain/identity/path.d.ts.map +1 -0
- package/dist/domain/identity/path.js +13 -0
- package/dist/domain/identity/resolve-self.d.ts +21 -0
- package/dist/domain/identity/resolve-self.d.ts.map +1 -0
- package/dist/domain/identity/resolve-self.js +36 -0
- package/dist/domain/intent/middleware/capabilities.d.ts +28 -0
- package/dist/domain/intent/middleware/capabilities.d.ts.map +1 -0
- package/dist/domain/intent/middleware/capabilities.js +18 -0
- package/dist/domain/intent/middleware/logging.d.ts +14 -0
- package/dist/domain/intent/middleware/logging.d.ts.map +1 -0
- package/dist/domain/intent/middleware/logging.js +21 -0
- package/dist/domain/intent/middleware/rate-limit.d.ts +20 -0
- package/dist/domain/intent/middleware/rate-limit.d.ts.map +1 -0
- package/dist/domain/intent/middleware/rate-limit.js +33 -0
- package/dist/domain/intent/pipeline.d.ts +3 -0
- package/dist/domain/intent/pipeline.d.ts.map +1 -0
- package/dist/domain/intent/pipeline.js +1 -0
- package/dist/domain/intent/router.d.ts +6 -0
- package/dist/domain/intent/router.d.ts.map +1 -0
- package/dist/domain/intent/router.js +1 -0
- package/dist/domain/message/errors.d.ts +2 -0
- package/dist/domain/message/errors.d.ts.map +1 -0
- package/dist/domain/message/errors.js +1 -0
- package/dist/domain/message/registries.d.ts +145 -0
- package/dist/domain/message/registries.d.ts.map +1 -0
- package/dist/domain/message/registries.js +1 -0
- package/dist/domain/message/types.d.ts +30 -0
- package/dist/domain/message/types.d.ts.map +1 -0
- package/dist/domain/message/types.js +1 -0
- package/dist/domain/window/config.d.ts +26 -0
- package/dist/domain/window/config.d.ts.map +1 -0
- package/dist/domain/window/config.js +1 -0
- package/dist/domain/window/lifecycle.d.ts +27 -0
- package/dist/domain/window/lifecycle.d.ts.map +1 -0
- package/dist/domain/window/lifecycle.js +36 -0
- package/dist/domain/window/window.d.ts +12 -0
- package/dist/domain/window/window.d.ts.map +1 -0
- package/dist/domain/window/window.js +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/ports/kernel-client.d.ts +33 -0
- package/dist/ports/kernel-client.d.ts.map +1 -0
- package/dist/ports/kernel-client.js +1 -0
- package/dist/ports/shell-adapter.d.ts +13 -0
- package/dist/ports/shell-adapter.d.ts.map +1 -0
- package/dist/ports/shell-adapter.js +1 -0
- package/dist/ports/transport.d.ts +7 -0
- package/dist/ports/transport.d.ts.map +1 -0
- package/dist/ports/transport.js +1 -0
- package/package.json +41 -0
- package/src/adapters/iframe.shell-adapter.ts +68 -0
- package/src/adapters/kernel-client.adapter.ts +138 -0
- package/src/adapters/message-port.transport.ts +50 -0
- package/src/application/channels/children-channel.ts +112 -0
- package/src/application/channels/observer.ts +33 -0
- package/src/application/channels/parent-channel.ts +43 -0
- package/src/application/channels/types.ts +41 -0
- package/src/application/intent/pipeline-runner.ts +36 -0
- package/src/application/intent/request.ts +87 -0
- package/src/application/intent/router.ts +161 -0
- package/src/application/kernel-facade.ts +143 -0
- package/src/application/shell.ts +433 -0
- package/src/application/windowing/child-init.ts +137 -0
- package/src/application/windowing/handshake.ts +98 -0
- package/src/application/windowing/lifecycle-controller.ts +40 -0
- package/src/application/windowing/mount-controller.ts +335 -0
- package/src/application/windowing/protocol.ts +37 -0
- package/src/application/windowing/token-refresh.ts +78 -0
- package/src/domain/identity/delegation.ts +25 -0
- package/src/domain/identity/path.ts +14 -0
- package/src/domain/identity/resolve-self.ts +38 -0
- package/src/domain/intent/middleware/capabilities.ts +53 -0
- package/src/domain/intent/middleware/logging.ts +45 -0
- package/src/domain/intent/middleware/rate-limit.ts +54 -0
- package/src/domain/intent/pipeline.ts +3 -0
- package/src/domain/intent/router.ts +6 -0
- package/src/domain/message/errors.ts +9 -0
- package/src/domain/message/registries.ts +76 -0
- package/src/domain/message/types.ts +32 -0
- package/src/domain/window/config.ts +28 -0
- package/src/domain/window/lifecycle.ts +39 -0
- package/src/domain/window/window.ts +13 -0
- package/src/index.ts +103 -0
- package/src/ports/kernel-client.ts +32 -0
- package/src/ports/shell-adapter.ts +11 -0
- package/src/ports/transport.ts +7 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface ViewRef {
|
|
2
|
+
readonly viewId: string
|
|
3
|
+
readonly functionId: string
|
|
4
|
+
readonly label?: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Intent registry — extensible via declaration merging.
|
|
9
|
+
*
|
|
10
|
+
* Consumers extend via:
|
|
11
|
+
* declare module '@astrale-os/shell' {
|
|
12
|
+
* interface IntentRegistry { ... }
|
|
13
|
+
* }
|
|
14
|
+
*/
|
|
15
|
+
export interface IntentRegistry {
|
|
16
|
+
open: { payload: { nodeId: string; viewId?: string }; response: { windowId: string } }
|
|
17
|
+
close: { payload: { windowId: string }; response: void }
|
|
18
|
+
focus: { payload: { nodeId: string }; response: void }
|
|
19
|
+
willClose: { payload: Record<string, never>; response: void }
|
|
20
|
+
closeAck: { payload: Record<string, never>; response: void }
|
|
21
|
+
closeRefuse: { payload: { reason: string }; response: void }
|
|
22
|
+
pickView: { payload: { views: ViewRef[] }; response: { viewId: string } }
|
|
23
|
+
receive: { payload: { data: unknown; sourceIntent: string }; response: void }
|
|
24
|
+
/**
|
|
25
|
+
* Hot-swap — parent pushes a new target node to an already-mounted view
|
|
26
|
+
* without remounting. The child reads `targetNodeId` at handshake time
|
|
27
|
+
* for the initial value; `setTarget` replaces it for the lifetime of the
|
|
28
|
+
* window.
|
|
29
|
+
*/
|
|
30
|
+
setTarget: { payload: { nodeId: string }; response: void }
|
|
31
|
+
/**
|
|
32
|
+
* Child → parent: a view asks the user to grant `perms` (a permission
|
|
33
|
+
* bitmask) on `node` to `identity` (the beneficiary subject). Both `node`
|
|
34
|
+
* and `identity` are bare node ids (e.g. the view's `targetNodeId`, or
|
|
35
|
+
* `whoami().id` for "grant to myself") — the root shell addresses them as
|
|
36
|
+
* `@<id>`. The root shell (GUI) surfaces a modal, computes the delta vs.
|
|
37
|
+
* what the subject already holds, and — on approval — grants only the
|
|
38
|
+
* missing bits under the GUI user's own credential. `reason` is shown to
|
|
39
|
+
* the user. `response.perms` is the bitmask actually granted (0 if
|
|
40
|
+
* declined / nothing was missing).
|
|
41
|
+
*
|
|
42
|
+
* Reaches a handler only from a view mounted as a DIRECT child of the root
|
|
43
|
+
* shell — the default intent policy does not bubble past one hop.
|
|
44
|
+
*/
|
|
45
|
+
requestAccess: {
|
|
46
|
+
payload: { node: string; identity: string; perms: number; reason?: string }
|
|
47
|
+
response: { granted: boolean; perms: number }
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generic correlated reply channel. The default intent transport is
|
|
51
|
+
* fire-and-forget; `requestIntent()` sends an intent carrying a
|
|
52
|
+
* `correlationId` and awaits an `intentReply` whose payload echoes it back
|
|
53
|
+
* with the handler's `result`. Routed to the resolver purely by
|
|
54
|
+
* `correlationId` — it intentionally matches no local handler.
|
|
55
|
+
*/
|
|
56
|
+
intentReply: { payload: { correlationId: string; result: unknown }; response: void }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Control message registry — extensible via declaration merging.
|
|
61
|
+
*/
|
|
62
|
+
export interface CtrlRegistry {
|
|
63
|
+
handshake: {
|
|
64
|
+
data: {
|
|
65
|
+
delegationToken: string
|
|
66
|
+
tokenExpiresAt: number
|
|
67
|
+
windowId: string
|
|
68
|
+
kernelUrl: string
|
|
69
|
+
functionId: string
|
|
70
|
+
targetNodeId?: string
|
|
71
|
+
mintIdentity?: string
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
handshakeAck: { data: { windowId: string } }
|
|
75
|
+
tokenRefresh: { data: { delegationToken: string; tokenExpiresAt: number } }
|
|
76
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ErrorCode } from './errors'
|
|
2
|
+
import type { CtrlRegistry, IntentRegistry } from './registries'
|
|
3
|
+
|
|
4
|
+
export type IntentEnvelope<K extends keyof IntentRegistry = keyof IntentRegistry> = {
|
|
5
|
+
readonly name: K
|
|
6
|
+
readonly payload: IntentRegistry[K]['payload']
|
|
7
|
+
readonly sender: { readonly windowId: string }
|
|
8
|
+
readonly correlationId?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type IntentMessage<K extends keyof IntentRegistry = keyof IntentRegistry> = {
|
|
12
|
+
readonly type: 'intent'
|
|
13
|
+
readonly version: 1
|
|
14
|
+
readonly envelope: IntentEnvelope<K>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type CtrlMessage<K extends keyof CtrlRegistry = keyof CtrlRegistry> = {
|
|
18
|
+
readonly type: 'ctrl'
|
|
19
|
+
readonly version: 1
|
|
20
|
+
readonly action: K
|
|
21
|
+
readonly data: CtrlRegistry[K]['data']
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type ErrorMessage = {
|
|
25
|
+
readonly type: 'error'
|
|
26
|
+
readonly version: 1
|
|
27
|
+
readonly code: ErrorCode
|
|
28
|
+
readonly message: string
|
|
29
|
+
readonly context?: unknown
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ShellMessage = IntentMessage | CtrlMessage | ErrorMessage
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IntentRegistry } from '../message/registries'
|
|
2
|
+
|
|
3
|
+
export interface SandboxProfile {
|
|
4
|
+
readonly allowScripts: boolean
|
|
5
|
+
readonly allowForms: boolean
|
|
6
|
+
readonly allowPopups: boolean
|
|
7
|
+
readonly allowSameOrigin: boolean
|
|
8
|
+
readonly allowModals: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface WindowCapabilities {
|
|
12
|
+
readonly intents: ReadonlyArray<keyof IntentRegistry>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface WindowConfig {
|
|
16
|
+
readonly functionId: string
|
|
17
|
+
readonly isolation: 'sandboxed' | 'shared'
|
|
18
|
+
readonly capabilities: WindowCapabilities
|
|
19
|
+
/**
|
|
20
|
+
* Sandbox profile for the iframe.
|
|
21
|
+
* - `undefined` → adapter default (`DEFAULT_SANDBOX` in iframe.shell-adapter).
|
|
22
|
+
* - `SandboxProfile` → explicit flag set, becomes the `sandbox=…` attribute.
|
|
23
|
+
* - `null` → opt out: no `sandbox` attribute on the iframe at all (the
|
|
24
|
+
* browser's cross-origin policy is the only remaining isolation). Used
|
|
25
|
+
* for first-party trusted views per the GUI allowlist.
|
|
26
|
+
*/
|
|
27
|
+
readonly sandbox?: SandboxProfile | null
|
|
28
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { WindowState } from './window'
|
|
2
|
+
|
|
3
|
+
export type LifecycleEvent =
|
|
4
|
+
| { kind: 'hide' }
|
|
5
|
+
| { kind: 'restore' }
|
|
6
|
+
| { kind: 'requestClose' }
|
|
7
|
+
| { kind: 'closeAck' }
|
|
8
|
+
| { kind: 'closeRefuse' }
|
|
9
|
+
| { kind: 'forceClose' }
|
|
10
|
+
|
|
11
|
+
export type TransitionResult = { ok: true; next: WindowState } | { ok: false; reason: string }
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Pure state-machine transition. Used by the lifecycle controller —
|
|
15
|
+
* no timers, no side effects here.
|
|
16
|
+
*/
|
|
17
|
+
export function transition(state: WindowState, event: LifecycleEvent): TransitionResult {
|
|
18
|
+
switch (state) {
|
|
19
|
+
case 'active':
|
|
20
|
+
if (event.kind === 'hide') return { ok: true, next: 'hidden' }
|
|
21
|
+
if (event.kind === 'requestClose') return { ok: true, next: 'closing' }
|
|
22
|
+
if (event.kind === 'forceClose') return { ok: true, next: 'closed' }
|
|
23
|
+
break
|
|
24
|
+
case 'hidden':
|
|
25
|
+
if (event.kind === 'restore') return { ok: true, next: 'active' }
|
|
26
|
+
if (event.kind === 'requestClose') return { ok: true, next: 'closing' }
|
|
27
|
+
if (event.kind === 'forceClose') return { ok: true, next: 'closed' }
|
|
28
|
+
break
|
|
29
|
+
case 'closing':
|
|
30
|
+
if (event.kind === 'closeAck') return { ok: true, next: 'closed' }
|
|
31
|
+
if (event.kind === 'closeRefuse') return { ok: true, next: 'active' }
|
|
32
|
+
if (event.kind === 'forceClose') return { ok: true, next: 'closed' }
|
|
33
|
+
break
|
|
34
|
+
case 'closed':
|
|
35
|
+
// Terminal — no transitions out.
|
|
36
|
+
break
|
|
37
|
+
}
|
|
38
|
+
return { ok: false, reason: `invalid transition ${state}.${event.kind}` }
|
|
39
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WindowCapabilities } from './config'
|
|
2
|
+
|
|
3
|
+
export type WindowState = 'active' | 'hidden' | 'closing' | 'closed'
|
|
4
|
+
|
|
5
|
+
export interface Window {
|
|
6
|
+
readonly windowId: string
|
|
7
|
+
readonly functionId: string
|
|
8
|
+
readonly targetNodeId?: string
|
|
9
|
+
readonly isolation: 'sandboxed' | 'shared'
|
|
10
|
+
readonly state: WindowState
|
|
11
|
+
readonly delegationToken: string | null
|
|
12
|
+
readonly capabilities: WindowCapabilities
|
|
13
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ─── domain/message ─────────────────────────────────────────────────────────
|
|
2
|
+
export type { ErrorCode } from './domain/message/errors'
|
|
3
|
+
export type { IntentRegistry, CtrlRegistry, ViewRef } from './domain/message/registries'
|
|
4
|
+
export type {
|
|
5
|
+
ShellMessage,
|
|
6
|
+
IntentMessage,
|
|
7
|
+
IntentEnvelope,
|
|
8
|
+
CtrlMessage,
|
|
9
|
+
ErrorMessage,
|
|
10
|
+
} from './domain/message/types'
|
|
11
|
+
|
|
12
|
+
// ─── domain/window ──────────────────────────────────────────────────────────
|
|
13
|
+
export type { WindowConfig, WindowCapabilities, SandboxProfile } from './domain/window/config'
|
|
14
|
+
export type { Window, WindowState } from './domain/window/window'
|
|
15
|
+
export { transition as lifecycleTransition } from './domain/window/lifecycle'
|
|
16
|
+
export type { LifecycleEvent, TransitionResult } from './domain/window/lifecycle'
|
|
17
|
+
|
|
18
|
+
// ─── domain/intent ──────────────────────────────────────────────────────────
|
|
19
|
+
export type { IntentMiddleware } from './domain/intent/pipeline'
|
|
20
|
+
export type { IntentRouter } from './domain/intent/router'
|
|
21
|
+
export { loggingMiddleware } from './domain/intent/middleware/logging'
|
|
22
|
+
export type { LoggingConfig, LoggingEntry, LoggingSink } from './domain/intent/middleware/logging'
|
|
23
|
+
export { capabilitiesMiddleware } from './domain/intent/middleware/capabilities'
|
|
24
|
+
export type {
|
|
25
|
+
CapabilitiesConfig,
|
|
26
|
+
CapabilityLookup,
|
|
27
|
+
CapabilityViolation,
|
|
28
|
+
} from './domain/intent/middleware/capabilities'
|
|
29
|
+
export { rateLimitMiddleware } from './domain/intent/middleware/rate-limit'
|
|
30
|
+
export type { RateLimitConfig, RateLimitViolation } from './domain/intent/middleware/rate-limit'
|
|
31
|
+
|
|
32
|
+
// ─── domain/identity ────────────────────────────────────────────────────────
|
|
33
|
+
export type { DelegationScope, DelegationToken, TokenState } from './domain/identity/delegation'
|
|
34
|
+
export { stateOf, isExpired } from './domain/identity/delegation'
|
|
35
|
+
|
|
36
|
+
// ─── ports ──────────────────────────────────────────────────────────────────
|
|
37
|
+
export type { Transport } from './ports/transport'
|
|
38
|
+
export type { ShellAdapter, WindowHandle } from './ports/shell-adapter'
|
|
39
|
+
export type { KernelClient } from './ports/kernel-client'
|
|
40
|
+
|
|
41
|
+
// ─── adapters ───────────────────────────────────────────────────────────────
|
|
42
|
+
export { createKernelClientAdapter } from './adapters/kernel-client.adapter'
|
|
43
|
+
export type {
|
|
44
|
+
KernelClientAdapter,
|
|
45
|
+
CreateKernelClientAdapterOpts,
|
|
46
|
+
} from './adapters/kernel-client.adapter'
|
|
47
|
+
export { createMessagePortTransport } from './adapters/message-port.transport'
|
|
48
|
+
export type { MessagePortTransportConfig } from './adapters/message-port.transport'
|
|
49
|
+
export { createIframeShellAdapter } from './adapters/iframe.shell-adapter'
|
|
50
|
+
export type { IframeShellAdapterConfig } from './adapters/iframe.shell-adapter'
|
|
51
|
+
|
|
52
|
+
// ─── application ────────────────────────────────────────────────────────────
|
|
53
|
+
export type {
|
|
54
|
+
Shell,
|
|
55
|
+
ShellConfig,
|
|
56
|
+
StandaloneConfig,
|
|
57
|
+
SandboxedConfig,
|
|
58
|
+
MountParams,
|
|
59
|
+
MountedWindow,
|
|
60
|
+
CloseResult,
|
|
61
|
+
ParentChannel,
|
|
62
|
+
ChildrenChannel,
|
|
63
|
+
MessageDirection,
|
|
64
|
+
MessageHandler,
|
|
65
|
+
ObserverHandler,
|
|
66
|
+
} from './application/shell'
|
|
67
|
+
export { createShell } from './application/shell'
|
|
68
|
+
|
|
69
|
+
// ─── application/windowing (advanced / testing) ─────────────────────────────
|
|
70
|
+
export { runParentHandshake } from './application/windowing/handshake'
|
|
71
|
+
export type {
|
|
72
|
+
HandshakeParams,
|
|
73
|
+
HandshakeError,
|
|
74
|
+
HandshakeResult,
|
|
75
|
+
} from './application/windowing/handshake'
|
|
76
|
+
export { performChildInit } from './application/windowing/child-init'
|
|
77
|
+
export type { ChildInitParams, ChildInitResult } from './application/windowing/child-init'
|
|
78
|
+
export { createTokenRefresher } from './application/windowing/token-refresh'
|
|
79
|
+
export type { TokenRefreshConfig, TokenRefresher } from './application/windowing/token-refresh'
|
|
80
|
+
|
|
81
|
+
// ─── application/intent (advanced / testing) ────────────────────────────────
|
|
82
|
+
export { createIntentPipeline } from './application/intent/pipeline-runner'
|
|
83
|
+
export type { IntentPipeline } from './application/intent/pipeline-runner'
|
|
84
|
+
export { createIntentRouter } from './application/intent/router'
|
|
85
|
+
export type {
|
|
86
|
+
IntentRouterController,
|
|
87
|
+
IntentRouterConfig,
|
|
88
|
+
IntentDecision,
|
|
89
|
+
IntentOrigin,
|
|
90
|
+
IntentPolicy,
|
|
91
|
+
IntentContext,
|
|
92
|
+
LocalIntentHandler,
|
|
93
|
+
} from './application/intent/router'
|
|
94
|
+
export { requestIntent, replyToIntent, requestAccess } from './application/intent/request'
|
|
95
|
+
|
|
96
|
+
// ─── Init-request protocol (shared with host pages) ─────────────────────────
|
|
97
|
+
export {
|
|
98
|
+
INIT_REQUEST_TYPE,
|
|
99
|
+
INIT_RESPONSE_TYPE,
|
|
100
|
+
isInitRequest,
|
|
101
|
+
isInitResponse,
|
|
102
|
+
} from './application/windowing/protocol'
|
|
103
|
+
export type { InitRequestMessage, InitResponseMessage } from './application/windowing/protocol'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface KernelClient {
|
|
2
|
+
call(path: string, params: unknown): Promise<unknown>
|
|
3
|
+
/**
|
|
4
|
+
* Produce a credential usable by a child shell.
|
|
5
|
+
*
|
|
6
|
+
* v1: returns a fresh identity credential scoped to the current principal.
|
|
7
|
+
* Future (SDK v2): will accept `{ functionId }` to scope the delegation
|
|
8
|
+
* to a specific Function — tracked in `.dev/todo/shell-sdk-v2-delegation.md`.
|
|
9
|
+
*/
|
|
10
|
+
mintDelegation(): Promise<string>
|
|
11
|
+
/**
|
|
12
|
+
* Return the JWT this shell currently uses to authenticate `call`. Iframes
|
|
13
|
+
* use it to make their own authenticated HTTP requests to the kernel —
|
|
14
|
+
* e.g. when a third-party SDK like Vercel AI's `useChat` issues a raw
|
|
15
|
+
* `fetch()` that can't run through `call()`. Callers form the Authorization
|
|
16
|
+
* header themselves: `Authorization: \`Bearer ${shell.kernel.authToken()}\``.
|
|
17
|
+
*
|
|
18
|
+
* The value is the *current* token; the parent shell auto-refreshes it
|
|
19
|
+
* before expiry, so always read fresh on each request rather than caching.
|
|
20
|
+
*/
|
|
21
|
+
authToken(): string
|
|
22
|
+
/**
|
|
23
|
+
* URL of the kernel this shell talks to. Pair with `authToken()` when an
|
|
24
|
+
* iframe needs to make a raw `fetch()` from a third-party SDK (e.g.
|
|
25
|
+
* Vercel AI's `useChat`): the kernel-issued JWT's `aud` matches the
|
|
26
|
+
* kernel's own issuer, so requests must target the kernel directly. If
|
|
27
|
+
* a sandboxed iframe POSTs to its own `window.location.origin` (the
|
|
28
|
+
* worker hosting the iframe), the worker's audience check rejects the
|
|
29
|
+
* cred with "Credential audience mismatch".
|
|
30
|
+
*/
|
|
31
|
+
readonly url: string
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WindowConfig } from '../domain/window/config'
|
|
2
|
+
|
|
3
|
+
export interface WindowHandle {
|
|
4
|
+
readonly element: HTMLIFrameElement | HTMLElement
|
|
5
|
+
readonly port: MessagePort | null
|
|
6
|
+
readonly origin: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ShellAdapter {
|
|
10
|
+
mount(config: WindowConfig): { handle: WindowHandle; dispose: () => void }
|
|
11
|
+
}
|