diff --git a/alias.ts b/alias.ts index 8a5893640..6e2d67173 100644 --- a/alias.ts +++ b/alias.ts @@ -74,10 +74,8 @@ export const alias = { '@devframes/json-render/hub': r('json-render/src/hub.ts'), '@devframes/json-render/node': r('json-render/src/node/index.ts'), '@devframes/json-render': r('json-render/src/index.ts'), - '@devframes/json-render-ui/components': r('json-render-ui/src/components/index.ts'), '@devframes/json-render-ui/hub': r('json-render-ui/src/hub.ts'), '@devframes/json-render-ui/spa': r('json-render-ui/src/spa.ts'), - '@devframes/json-render-ui': r('json-render-ui/src/index.ts'), 'json-render/dashboard': fileURLToPath(new URL('./examples/json-render/src/node/dashboard.ts', import.meta.url)), '@devframes/plugin-code-server/node': p('code-server/src/node/setup.ts'), '@devframes/plugin-code-server/constants': p('code-server/src/node/constants.ts'), diff --git a/knip.jsonc b/knip.jsonc index 9ccebfac9..b664838e7 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -180,9 +180,8 @@ // Published node-safe entries are `spa.ts`/`hub.ts`; the browser // renderer ships only as self-contained Vite bundles (the standalone // SPA and the prebuilt renderer module, consumed at runtime via the - // hub's renderer manifest). `src/index.ts` stays as the source barrel - // those Vite/Storybook builds resolve, so it's declared as an entry too. - "entry": ["src/{index,spa,hub}.ts", "src/renderer-module/index.ts"], + // hub's renderer manifest). + "entry": ["src/{spa,hub}.ts", "src/renderer-module/index.ts"], // The standalone SPA's own Vite config (`src/spa/vite.config.ts`) // mounts `unocss/vite` with no explicit config path, so UnoCSS // discovers this nested `uno.config.ts` by directory proximity to diff --git a/packages/devframe/src/adapters/mcp/__tests__/to-json-schema.test.ts b/packages/devframe/src/adapters/mcp/__tests__/to-json-schema.test.ts index 132f95dff..f7e572727 100644 --- a/packages/devframe/src/adapters/mcp/__tests__/to-json-schema.test.ts +++ b/packages/devframe/src/adapters/mcp/__tests__/to-json-schema.test.ts @@ -22,18 +22,17 @@ function withJsonSchema(json: Record): StandardSchemaV1 { describe('argsToJsonSchema', () => { it('returns an empty object schema when no args', () => { - const { schema, unwrapped } = argsToJsonSchema(undefined) - expect(unwrapped).toBe(false) + const schema = argsToJsonSchema(undefined) expect(schema).toEqual({ type: 'object', properties: {} }) }) it('uses the schema\'s own Standard JSON Schema converter when present', () => { - const { schema } = argsToJsonSchema([withJsonSchema({ type: 'string' })]) + const schema = argsToJsonSchema([withJsonSchema({ type: 'string' })]) expect((schema as any).properties.arg0).toEqual({ type: 'string' }) }) it('falls back to a permissive object for validators without a native converter (valibot)', () => { - const { schema } = argsToJsonSchema([v.string(), v.number()]) + const schema = argsToJsonSchema([v.string(), v.number()]) expect((schema as any).properties.arg0).toEqual(PERMISSIVE) expect((schema as any).properties.arg1).toEqual(PERMISSIVE) expect(schema).toMatchObject({ type: 'object', required: ['arg0', 'arg1'], additionalProperties: false }) diff --git a/packages/devframe/src/adapters/mcp/build-server.ts b/packages/devframe/src/adapters/mcp/build-server.ts index d3d1f4327..2ca735d80 100644 --- a/packages/devframe/src/adapters/mcp/build-server.ts +++ b/packages/devframe/src/adapters/mcp/build-server.ts @@ -428,14 +428,14 @@ function projectTool(name: string, tool: AgentTool, ctx: DevframeNodeContext): T function computeInputSchema(tool: AgentTool, ctx: DevframeNodeContext): unknown { if (tool.kind === 'tool') - return argsToJsonSchema(tool.args).schema + return argsToJsonSchema(tool.args) if (tool.kind !== 'rpc' || !tool.rpcName) return { type: 'object', properties: {} } const def = ctx.rpc.definitions.get(tool.rpcName) as RpcFunctionDefinitionAnyWithContext | undefined if (!def) return { type: 'object', properties: {} } const args = def.args as readonly StandardSchemaV1[] | undefined - return argsToJsonSchema(args).schema + return argsToJsonSchema(args) } function computeOutputSchema(tool: AgentTool, ctx: DevframeNodeContext): unknown { diff --git a/packages/devframe/src/adapters/mcp/to-json-schema.ts b/packages/devframe/src/adapters/mcp/to-json-schema.ts index 765e1a6d3..7f7b4b4a7 100644 --- a/packages/devframe/src/adapters/mcp/to-json-schema.ts +++ b/packages/devframe/src/adapters/mcp/to-json-schema.ts @@ -48,9 +48,9 @@ export function returnToJsonSchema(schema: StandardSchemaV1 | undefined): unknow */ export function argsToJsonSchema( args: readonly StandardSchemaV1[] | undefined, -): { schema: unknown, unwrapped: boolean } { +): unknown { if (!args || args.length === 0) - return { schema: { type: 'object', properties: {} }, unwrapped: false } + return { type: 'object', properties: {} } const properties: Record = {} const required: string[] = [] @@ -61,12 +61,9 @@ export function argsToJsonSchema( } return { - schema: { - type: 'object', - properties, - required, - additionalProperties: false, - }, - unwrapped: false, + type: 'object', + properties, + required, + additionalProperties: false, } } diff --git a/packages/devframe/src/client/rpc-live.ts b/packages/devframe/src/client/rpc-live.ts index 81646f0af..8f907e8ce 100644 --- a/packages/devframe/src/client/rpc-live.ts +++ b/packages/devframe/src/client/rpc-live.ts @@ -4,7 +4,6 @@ import type { DevframeConnectionStatus } from './connection' import type { DevframeClientRpcHost, DevframeRpcClientMode, DevframeRpcClientOptions, RpcClientEvents } from './rpc' import { createRpcClient } from 'devframe/rpc/client' import { DEVFRAME_EVENTS } from '../events' -import { promiseWithResolver } from '../utils/promise' import { DevframeConnectionError } from './connection' /** What a live transport's channel factory receives from the shared mode. */ @@ -53,7 +52,7 @@ export function createLiveRpcClientMode( let isTrusted = false let status: DevframeConnectionStatus = 'connecting' let connectionError: Error | null = null - const trustedPromise = promiseWithResolver() + const trustedPromise = Promise.withResolvers() // ── connection status ──────────────────────────────────────────────────── diff --git a/packages/devframe/src/client/settings.ts b/packages/devframe/src/client/settings.ts index 75b32e07a..b00bf1bb3 100644 --- a/packages/devframe/src/client/settings.ts +++ b/packages/devframe/src/client/settings.ts @@ -1,6 +1,7 @@ import type { DevframeSettings, DevframeSettingsStore } from 'devframe/types' import type { SharedState } from 'devframe/utils/shared-state' import type { DevframeRpcClient } from './rpc' +import { createSettingsStore } from '../settings-store' function createClientSettingsStore>( rpc: DevframeRpcClient, @@ -21,27 +22,7 @@ function createClientSettingsStore>( return statePromise } - return { - async get(key) { - return ((await store()).value() as T)[key] - }, - async set(key, value) { - ;(await store()).mutate((draft) => { - ;(draft as T)[key] = value - }) - }, - async delete(key) { - ;(await store()).mutate((draft) => { - delete (draft as T)[key] - }) - }, - async all() { - return (await store()).value() as Readonly - }, - async onChange(fn) { - return (await store()).on('updated', full => fn(full as Readonly)) - }, - } + return createSettingsStore(store) } /** diff --git a/packages/devframe/src/node/settings.ts b/packages/devframe/src/node/settings.ts index 203797877..ce2a12ffb 100644 --- a/packages/devframe/src/node/settings.ts +++ b/packages/devframe/src/node/settings.ts @@ -1,6 +1,7 @@ import type { DevframeNodeContext, DevframeRpcSharedStates, DevframeSettings, DevframeSettingsStore } from 'devframe/types' import type { SharedState } from 'devframe/utils/shared-state' import { join } from 'pathe' +import { createSettingsStore } from '../settings-store' import { createStorage } from './storage' // Map a settings scope to the host storage scope it persists under. @@ -32,27 +33,7 @@ function createNodeSettingsStore>( return statePromise } - return { - async get(key) { - return ((await store()).value() as T)[key] - }, - async set(key, value) { - ;(await store()).mutate((draft) => { - ;(draft as T)[key] = value - }) - }, - async delete(key) { - ;(await store()).mutate((draft) => { - delete (draft as T)[key] - }) - }, - async all() { - return (await store()).value() as Readonly - }, - async onChange(fn) { - return (await store()).on('updated', full => fn(full as Readonly)) - }, - } + return createSettingsStore(store) } /** diff --git a/packages/devframe/src/rpc/types.test.ts b/packages/devframe/src/rpc/types.test.ts index 5d690b806..6e6a86dbb 100644 --- a/packages/devframe/src/rpc/types.test.ts +++ b/packages/devframe/src/rpc/types.test.ts @@ -4,11 +4,15 @@ import type { RpcDefinitionsToFunctions, RpcFunctionDefinitionToFunction, } from '.' -import type { AssertEqual } from './utils' import * as v from 'valibot' import { describe, it } from 'vitest' import { defineRpcFunction } from '.' +/** Type-level assertion that two types are equal. */ +type AssertEqual + = (() => T extends X ? 1 : 2) extends + (() => T extends Y ? 1 : 2) ? true : never + /** Fake a typed Standard Schema from a non-valibot vendor. */ function schema(): StandardSchemaV1 { return { diff --git a/packages/devframe/src/rpc/utils.ts b/packages/devframe/src/rpc/utils.ts index 16f2323eb..4dabcd8ae 100644 --- a/packages/devframe/src/rpc/utils.ts +++ b/packages/devframe/src/rpc/utils.ts @@ -1,11 +1,6 @@ import type { StandardSchemaV1 } from '@standard-schema/spec' import type { RpcArgsSchema, RpcReturnSchema } from './types' -/** Type-level assertion that two types are equal */ -export type AssertEqual - = (() => T extends X ? 1 : 2) extends - (() => T extends Y ? 1 : 2) ? true : never - /** Infers a TypeScript argument tuple from a Standard Schema array */ export type InferArgsType = S extends readonly [] ? [] diff --git a/packages/devframe/src/settings-store.ts b/packages/devframe/src/settings-store.ts new file mode 100644 index 000000000..5841a92d4 --- /dev/null +++ b/packages/devframe/src/settings-store.ts @@ -0,0 +1,34 @@ +import type { DevframeSettingsStore } from 'devframe/types' +import type { SharedState } from 'devframe/utils/shared-state' + +/** + * The key-value store surface over a lazily-resolved shared state, shared by + * the node-side (file-backed) and client-side (RPC-mirrored) settings stores. + * Each side supplies its own `store()` resolver; the read/write/subscribe + * behavior on top of it is identical. + */ +export function createSettingsStore>( + store: () => Promise>, +): DevframeSettingsStore { + return { + async get(key) { + return ((await store()).value() as T)[key] + }, + async set(key, value) { + ;(await store()).mutate((draft) => { + ;(draft as T)[key] = value + }) + }, + async delete(key) { + ;(await store()).mutate((draft) => { + delete (draft as T)[key] + }) + }, + async all() { + return (await store()).value() as Readonly + }, + async onChange(fn) { + return (await store()).on('updated', full => fn(full as Readonly)) + }, + } +} diff --git a/packages/devframe/src/utils/promise.ts b/packages/devframe/src/utils/promise.ts deleted file mode 100644 index 87bef2eec..000000000 --- a/packages/devframe/src/utils/promise.ts +++ /dev/null @@ -1,17 +0,0 @@ -export function promiseWithResolver(): { - promise: Promise - resolve: (value: T) => void - reject: (error: Error) => void -} { - let resolve: (value: T) => void | undefined - let reject: (error: Error) => void | undefined - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve - reject = _reject - }) - return { - promise, - resolve: resolve!, - reject: reject!, - } -} diff --git a/packages/hub-ui/src/client/state/context.ts b/packages/hub-ui/src/client/state/context.ts index 202554aba..4ded43869 100644 --- a/packages/hub-ui/src/client/state/context.ts +++ b/packages/hub-ui/src/client/state/context.ts @@ -238,7 +238,6 @@ export async function createDocksContext( ...toRefs(docksContext) as any, current: dockEntryStateMap.get(entry.id)!, messages: messagesClient, - logs: messagesClient, }) await executeSetupScript(entry, scriptContext) } diff --git a/packages/hub/src/node/install-devframe.ts b/packages/hub/src/node/install-devframe.ts index 90e836ceb..874dd0d42 100644 --- a/packages/hub/src/node/install-devframe.ts +++ b/packages/hub/src/node/install-devframe.ts @@ -62,29 +62,6 @@ async function resolvePageScriptClientScript( return { ...clientScript, importFrom: joinURL(scriptBase, basename(importFrom)) } } -/** - * Framework-neutral primitive backing {@link DevframeHubContext.install} - - * installs a {@link DevframeDefinition} as a dock inside a hub-aware context: - * serves the devframe's SPA at the resolved base path, synthesizes an iframe - * dock entry from the definition's metadata, and runs the definition's - * `setup(ctx)`. Reach for it through `ctx.install(devframe)` rather than - * calling it directly. - * - * Framework kits wrap `ctx.install` with their own plugin/middleware - * machinery, e.g. `@vitejs/devtools-kit`'s `createPluginFromDevframe` - * returns a Vite `Plugin` whose `devtools.setup` ultimately delegates here. - */ -/** - * Phase one of an install: run the duplication guard, serve the SPA + meta, - * register the iframe dock, and queue the definition's declarative wire - * services, everything up to (but not including) `setup(ctx)`. Returns a - * deferred setup thunk, or `null` when the devframe was deduplicated. - * - * The hub's initial batch uses this to collect every devframe's services - * across the whole hub, `ready()` them once, and only then run the setups, - * so services are ready before any setup, and a plugin can consume a service - * another plugin declared regardless of mount order. - */ /** * Serve a devframe's SPA (and the hub's connection meta) under `base`, if the * definition ships client assets. diff --git a/packages/json-render-ui/src/action-bridge.ts b/packages/json-render-ui/src/action-bridge.ts index fbddb15f7..a31a19249 100644 --- a/packages/json-render-ui/src/action-bridge.ts +++ b/packages/json-render-ui/src/action-bridge.ts @@ -5,7 +5,7 @@ export interface ActionBridgeRpc { call: (method: string, ...args: unknown[]) => Promise } -export interface JsonRenderActionError { +interface JsonRenderActionError { action: string error: unknown } diff --git a/packages/json-render-ui/src/components/index.ts b/packages/json-render-ui/src/components/index.ts index 8adfc2d63..12f6681ff 100644 --- a/packages/json-render-ui/src/components/index.ts +++ b/packages/json-render-ui/src/components/index.ts @@ -1,5 +1,3 @@ -export type { JrComponent } from './_shared' - export { Badge } from './Badge' export { Button } from './Button' export { Card } from './Card' diff --git a/packages/json-render-ui/src/dock-renderer.ts b/packages/json-render-ui/src/dock-renderer.ts index b58e38ca5..4bf497563 100644 --- a/packages/json-render-ui/src/dock-renderer.ts +++ b/packages/json-render-ui/src/dock-renderer.ts @@ -6,7 +6,7 @@ import { createApp, h, shallowRef } from 'vue' import { baseRegistry } from './registry' import { JsonRenderView } from './renderer' -export type { JsonRenderDockMountOptions, JsonRenderDockRenderer } from '@devframes/json-render/hub' +export type { JsonRenderDockRenderer } from '@devframes/json-render/hub' export interface JsonRenderDockRendererOptions { /** Registry to render with. Defaults to the base registry. */ diff --git a/packages/json-render-ui/src/index.ts b/packages/json-render-ui/src/index.ts deleted file mode 100644 index de27ed1ba..000000000 --- a/packages/json-render-ui/src/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export { createActionBridge } from './action-bridge' -export type { ActionBridgeRpc, JsonRenderActionBridge, JsonRenderActionError } from './action-bridge' - -export * from './components' -export { createJsonRenderDockRenderer } from './dock-renderer' -export type { - JsonRenderDockMountOptions, - JsonRenderDockRenderer, - JsonRenderDockRendererOptions, -} from './dock-renderer' - -export { baseRegistry, ERROR_COMPONENT_TYPE, UNSUPPORTED_COMPONENT_TYPE } from './registry' -export { createRenderer, JsonRenderView, sanitizeSpec } from './renderer' -export type { CreateRendererOptions } from './renderer' diff --git a/packages/json-render-ui/src/renderer.ts b/packages/json-render-ui/src/renderer.ts index 28ee85b08..cd05a991d 100644 --- a/packages/json-render-ui/src/renderer.ts +++ b/packages/json-render-ui/src/renderer.ts @@ -1,6 +1,6 @@ import type { Spec } from '@devframes/json-render' import type { ComponentRegistry } from '@json-render/vue' -import type { Component, PropType } from 'vue' +import type { PropType } from 'vue' import type { ActionBridgeRpc } from './action-bridge' import { basePropSchemas } from '@devframes/json-render' import { JSONUIProvider, Renderer } from '@json-render/vue' @@ -126,26 +126,3 @@ export const JsonRenderView = defineComponent({ } }, }) - -/** Options for {@link createRenderer}. */ -export interface CreateRendererOptions { - /** Component registry to render with. Defaults to the base registry. */ - registry?: ComponentRegistry -} - -/** - * Create a configured renderer component bound to a registry. The returned - * component is {@link JsonRenderView} with the registry defaulted, so a host - * can `createRenderer({ registry: myRegistry })` to swap the whole registry. - */ -export function createRenderer(options: CreateRendererOptions = {}) { - const registry = options.registry ?? baseRegistry - return defineComponent({ - name: 'ConfiguredJsonRenderView', - inheritAttrs: false, - setup(_props, { attrs }) { - // Default the registry; every other prop flows through via attrs. - return () => h(JsonRenderView as Component, { registry, ...attrs }) - }, - }) -} diff --git a/packages/next/src/handler.ts b/packages/next/src/handler.ts index 831aed1e4..d245448d8 100644 --- a/packages/next/src/handler.ts +++ b/packages/next/src/handler.ts @@ -4,7 +4,7 @@ import { homedir } from 'node:os' import { join } from 'node:path' import process from 'node:process' import { initDevframe } from 'devframe/initiate' -import { resolveClientAssets } from 'devframe/internal' +import { normalizeBasePath, resolveBasePath, resolveClientAssets } from 'devframe/internal' export interface CreateDevframeNextHandlerOptions { /** @@ -71,11 +71,6 @@ export interface DevframeNextHandler { close: () => Promise } -/** Ensure a mount base has a single leading and trailing slash. */ -function normalizeBase(base: string): string { - return `/${base}/`.replace(/\/{2,}/g, '/') -} - const REGISTRY_KEY = Symbol.for('@devframes/next:handler-registry') /** @@ -130,7 +125,7 @@ export function createDevframeNextHandler( ) } - const base = normalizeBase(options.base ?? def.basePath ?? `/__${def.id}/`) + const base = options.base ? normalizeBasePath(options.base) : resolveBasePath(def, 'hosted') const key = options.key ?? `@devframes/next:${def.id}:${base}` const registry = handlerRegistry() const memoized = registry.get(key) diff --git a/packages/nuxt/src/hub.ts b/packages/nuxt/src/hub.ts index 2a7df78a3..82abc7005 100644 --- a/packages/nuxt/src/hub.ts +++ b/packages/nuxt/src/hub.ts @@ -1,7 +1,7 @@ import type { ViteDevframeHubOptions } from '@devframes/vite/hub' import { DEVFRAMES_HUB_BASE, normalizeHubBase } from '@devframes/hub/constants' import { viteDevframeHub } from '@devframes/vite/hub' -import { addVitePlugin, createResolver, defineNuxtModule } from '@nuxt/kit' +import { addVitePlugin, defineNuxtModule } from '@nuxt/kit' export interface DevframeNuxtHubOptions extends Omit { /** @@ -68,8 +68,6 @@ export default defineNuxtModule({ if (!nuxt.options.dev) return - createResolver(import.meta.url) - const base = normalizeHubBase(options.base ?? DEVFRAMES_HUB_BASE) const { injectEmbedded, quiet: _quiet, ...hubOptions } = options diff --git a/packages/nuxt/src/single.ts b/packages/nuxt/src/single.ts index e43ed1a0d..394d1f638 100644 --- a/packages/nuxt/src/single.ts +++ b/packages/nuxt/src/single.ts @@ -112,10 +112,7 @@ export default defineNuxtModule({ const publicConfig = nuxt.options.runtimeConfig.public as Record // override baseURL - publicConfig.devframe ??= {} - Object.assign(publicConfig.devframe, publicConfig.devframe ?? {}, { - baseURL: options.baseURL, - }) + publicConfig.devframe = { ...publicConfig.devframe, baseURL: options.baseURL } const runtimeDir = resolve('./runtime') @@ -132,9 +129,7 @@ export default defineNuxtModule({ // user opts out; `apply: 'serve'` on the inner Vite plugin is a // second guard against accidental activation during build. if (options.devframe && options.devMiddleware !== false && nuxt.options.dev) { - const mw = options.devMiddleware === true || options.devMiddleware === undefined - ? {} - : options.devMiddleware + const mw = typeof options.devMiddleware === 'object' ? options.devMiddleware : {} const host = mw.host ?? (nuxt.options.devServer as any)?.host ?? options.devframe.cli?.host diff --git a/plugins/assets/app/app/composables/useAssets.ts b/plugins/assets/app/app/composables/useAssets.ts index 75e874f74..31d8c87ff 100644 --- a/plugins/assets/app/app/composables/useAssets.ts +++ b/plugins/assets/app/app/composables/useAssets.ts @@ -2,8 +2,8 @@ import type { AssetsCapabilities } from '@devframes/plugin-assets/rpc' import type { DevframeConnectionStatus, DevframeRpcClient } from 'devframe/client' import type { Ref } from 'vue' import type { AssetInfo } from '../connect' +import { connectDevframe } from 'devframe/client' import { shallowRef } from 'vue' -import { connectAssets } from '../connect' const CHANGED_EVENT = 'devframes:plugin:assets:changed' @@ -56,7 +56,7 @@ export function useAssets(): UseAssetsResult { } async function connect(): Promise { - const client = await connectAssets() + const client = await connectDevframe() rpc.value = client isStatic.value = client.connectionMeta.backend === 'static' status.value = client.status diff --git a/plugins/assets/app/app/connect.ts b/plugins/assets/app/app/connect.ts index 9df059654..89f9c0ad3 100644 --- a/plugins/assets/app/app/connect.ts +++ b/plugins/assets/app/app/connect.ts @@ -1,8 +1 @@ -import type { DevframeRpcClientOptions } from 'devframe/client' -import { connectDevframe } from 'devframe/client' - export type { AssetImageMeta, AssetInfo, AssetType, CodeSnippet } from '../../src/node/types' - -export function connectAssets(options?: DevframeRpcClientOptions) { - return connectDevframe(options) -} diff --git a/plugins/assets/src/node/rpc/functions/capabilities.ts b/plugins/assets/src/node/rpc/functions/capabilities.ts index 8c7e70c4a..44bc7b116 100644 --- a/plugins/assets/src/node/rpc/functions/capabilities.ts +++ b/plugins/assets/src/node/rpc/functions/capabilities.ts @@ -1,10 +1,7 @@ -import type { DevframeNodeContext } from 'devframe' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { getAssetsContext } from '../../context' -const defineAssetsRpc = createDefineWrapperWithContext() - export interface AssetsCapabilities { write: boolean uploadExtensions: readonly string[] | '*' @@ -16,7 +13,7 @@ export interface AssetsCapabilities { * instead of letting the user hit a "method not found" error, the same * `canWrite`-gating idea the git plugin's `GitStatus.canWrite` follows. */ -export const capabilities = defineAssetsRpc({ +export const capabilities = defineRpcFunction({ name: 'devframes:plugin:assets:capabilities', type: 'query', snapshot: true, diff --git a/plugins/assets/src/node/rpc/functions/delete.ts b/plugins/assets/src/node/rpc/functions/delete.ts index c27df8087..c6545ec2d 100644 --- a/plugins/assets/src/node/rpc/functions/delete.ts +++ b/plugins/assets/src/node/rpc/functions/delete.ts @@ -1,14 +1,11 @@ -import type { DevframeNodeContext } from 'devframe' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { getAssetsContext } from '../../context' import { assertAssetMutationPath } from '../../paths' -const defineAssetsRpc = createDefineWrapperWithContext() - /** One request covers both single- and multi-select delete. */ -export const deleteAssets = defineAssetsRpc({ +export const deleteAssets = defineRpcFunction({ name: 'devframes:plugin:assets:delete', type: 'action', jsonSerializable: true, diff --git a/plugins/assets/src/node/rpc/functions/list.ts b/plugins/assets/src/node/rpc/functions/list.ts index 9ed94f5cf..8e4bb9ea0 100644 --- a/plugins/assets/src/node/rpc/functions/list.ts +++ b/plugins/assets/src/node/rpc/functions/list.ts @@ -1,12 +1,9 @@ -import type { DevframeNodeContext } from 'devframe' import type { AssetInfo } from '../../types' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { getAssetsContext } from '../../context' import { scanAssets } from '../../scanner' -const defineAssetsRpc = createDefineWrapperWithContext() - export const assetInfoSchema = s.object({ path: s.string(), type: s.picklist(['image', 'font', 'video', 'audio', 'text', 'other']), @@ -16,7 +13,7 @@ export const assetInfoSchema = s.object({ fsPath: s.optional(s.string()), }) -export const list = defineAssetsRpc({ +export const list = defineRpcFunction({ name: 'devframes:plugin:assets:list', type: 'query', snapshot: true, diff --git a/plugins/assets/src/node/rpc/functions/mkdir.ts b/plugins/assets/src/node/rpc/functions/mkdir.ts index 73615eee4..6426059c8 100644 --- a/plugins/assets/src/node/rpc/functions/mkdir.ts +++ b/plugins/assets/src/node/rpc/functions/mkdir.ts @@ -1,14 +1,11 @@ -import type { DevframeNodeContext } from 'devframe' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { getAssetsContext } from '../../context' import { diagnostics } from '../../diagnostics' import { assertAssetMutationPath } from '../../paths' -const defineAssetsRpc = createDefineWrapperWithContext() - -export const mkdir = defineAssetsRpc({ +export const mkdir = defineRpcFunction({ name: 'devframes:plugin:assets:mkdir', type: 'action', jsonSerializable: true, diff --git a/plugins/assets/src/node/rpc/functions/read-image-meta.ts b/plugins/assets/src/node/rpc/functions/read-image-meta.ts index d313717a0..285b95798 100644 --- a/plugins/assets/src/node/rpc/functions/read-image-meta.ts +++ b/plugins/assets/src/node/rpc/functions/read-image-meta.ts @@ -1,15 +1,12 @@ -import type { DevframeNodeContext } from 'devframe' import type { AssetImageMeta } from '../../types' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { imageMeta } from 'image-meta' import { getAssetsContext } from '../../context' import { resolveAssetReadPath } from '../../paths' -const defineAssetsRpc = createDefineWrapperWithContext() - -export const readImageMeta = defineAssetsRpc({ +export const readImageMeta = defineRpcFunction({ name: 'devframes:plugin:assets:read-image-meta', type: 'query', jsonSerializable: true, diff --git a/plugins/assets/src/node/rpc/functions/read-text.ts b/plugins/assets/src/node/rpc/functions/read-text.ts index a6b255885..9792ae61f 100644 --- a/plugins/assets/src/node/rpc/functions/read-text.ts +++ b/plugins/assets/src/node/rpc/functions/read-text.ts @@ -1,15 +1,12 @@ -import type { DevframeNodeContext } from 'devframe' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { getAssetsContext } from '../../context' import { resolveAssetReadPath } from '../../paths' -const defineAssetsRpc = createDefineWrapperWithContext() - const DEFAULT_LIMIT = 5000 -export const readText = defineAssetsRpc({ +export const readText = defineRpcFunction({ name: 'devframes:plugin:assets:read-text', type: 'query', jsonSerializable: true, diff --git a/plugins/assets/src/node/rpc/functions/rename.ts b/plugins/assets/src/node/rpc/functions/rename.ts index 278188a97..9d34d776f 100644 --- a/plugins/assets/src/node/rpc/functions/rename.ts +++ b/plugins/assets/src/node/rpc/functions/rename.ts @@ -1,7 +1,6 @@ -import type { DevframeNodeContext } from 'devframe' import type { AssetInfo } from '../../types' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { dirname, extname } from 'pathe' import { getAssetsContext } from '../../context' @@ -10,8 +9,6 @@ import { assertAssetMutationPath } from '../../paths' import { statToAssetInfo } from '../../scanner' import { assetInfoSchema } from './list' -const defineAssetsRpc = createDefineWrapperWithContext() - export interface RenameArgs { /** Root-relative path of the asset to rename. */ path: string @@ -24,7 +21,7 @@ export interface RenameArgs { newName: string } -export const rename = defineAssetsRpc({ +export const rename = defineRpcFunction({ name: 'devframes:plugin:assets:rename', type: 'action', jsonSerializable: true, diff --git a/plugins/assets/src/node/rpc/functions/upload.ts b/plugins/assets/src/node/rpc/functions/upload.ts index 7714abcfc..e8756cecc 100644 --- a/plugins/assets/src/node/rpc/functions/upload.ts +++ b/plugins/assets/src/node/rpc/functions/upload.ts @@ -1,15 +1,12 @@ -import type { DevframeNodeContext } from 'devframe' import { createWriteStream } from 'node:fs' import fsp from 'node:fs/promises' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { dirname, extname } from 'pathe' import { getAssetsContext } from '../../context' import { diagnostics } from '../../diagnostics' import { assertAssetMutationPath } from '../../paths' -const defineAssetsRpc = createDefineWrapperWithContext() - /** Streaming channel name, namespaced like every other RPC name in this plugin. */ export const UPLOAD_CHANNEL = 'devframes:plugin:assets:upload' @@ -25,7 +22,7 @@ function isExtensionAllowed(path: string, allowed: readonly string[] | '*'): boo * the `upload` channel opened in `setupAssets`; see the client-side * `useUpload` hook for the matching `rpc.streaming.upload()` call. */ -export const upload = defineAssetsRpc({ +export const upload = defineRpcFunction({ name: 'devframes:plugin:assets:upload', type: 'action', jsonSerializable: true, diff --git a/plugins/code-server/app/composables/rpc.ts b/plugins/code-server/app/composables/rpc.ts index 244c0bdf7..f3486e2c8 100644 --- a/plugins/code-server/app/composables/rpc.ts +++ b/plugins/code-server/app/composables/rpc.ts @@ -1,6 +1,6 @@ import type { ConnectionMeta, DevframeConnectionStatus, DevframeRpcClient } from '../connect' +import { connectDevframe } from 'devframe/client' import { reactive, shallowRef } from 'vue' -import { connectCodeServer } from '../connect' export const connection = reactive<{ connected: boolean @@ -25,7 +25,7 @@ function applyStatus(client: DevframeRpcClient): void { /** Establish the devframe connection and keep `connection` in sync with it. */ export async function connect(): Promise { try { - const client = await connectCodeServer() + const client = await connectDevframe() rpcRef.value = client connection.backend = client.connectionMeta.backend applyStatus(client) diff --git a/plugins/code-server/app/connect.ts b/plugins/code-server/app/connect.ts index 77b856484..a76f7fbd3 100644 --- a/plugins/code-server/app/connect.ts +++ b/plugins/code-server/app/connect.ts @@ -1,6 +1,5 @@ -import type { DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientOptions } from 'devframe/client' +import type { DevframeConnectionStatus, DevframeRpcClient } from 'devframe/client' import type { ConnectionMeta } from 'devframe/types' -import { connectDevframe } from 'devframe/client' export { STATE_KEY } from '../src/node/constants' export type { ConnectionMeta, DevframeConnectionStatus, DevframeRpcClient } @@ -11,12 +10,3 @@ export type { CodeServerSharedState, CodeServerStatusResult, } from '../src/node/types' - -/** - * Connect to the code-server plugin's devframe backend. A thin, typed wrapper - * around devframe's {@link connectDevframe}; the SPA derives its base from - * `document.baseURI`, so no options are required in the common case. - */ -export function connectCodeServer(options?: DevframeRpcClientOptions): Promise { - return connectDevframe(options) -} diff --git a/plugins/data-inspector/src/node/rpc/functions/_define.ts b/plugins/data-inspector/src/node/rpc/functions/_define.ts index 226906cb2..356fa022d 100644 --- a/plugins/data-inspector/src/node/rpc/functions/_define.ts +++ b/plugins/data-inspector/src/node/rpc/functions/_define.ts @@ -1,7 +1,2 @@ -import type { DevframeNodeContext } from 'devframe' -import { createDefineWrapperWithContext } from 'devframe/rpc' - -export const defineDataInspectorRpc = createDefineWrapperWithContext() - /** RPC namespace, the plugin id. */ export const NS = 'devframes:plugin:data-inspector' diff --git a/plugins/data-inspector/src/node/rpc/functions/query-path.ts b/plugins/data-inspector/src/node/rpc/functions/query-path.ts index 842cdce35..719b8a05b 100644 --- a/plugins/data-inspector/src/node/rpc/functions/query-path.ts +++ b/plugins/data-inspector/src/node/rpc/functions/query-path.ts @@ -1,7 +1,8 @@ import type { FilterOptions, NodePath, QueryOutcome } from '../../engine/contract' +import { defineRpcFunction } from 'devframe' import { runQueryAtPath } from '../../engine/query-engine' import { getDataSource, resolveSourceData } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** * Lazily expand a depth-truncated node. Re-runs the base jora query against @@ -10,7 +11,7 @@ import { defineDataInspectorRpc, NS } from './_define' * returns just that subtree normalized with a fresh depth budget, so huge * graphs load a level at a time instead of all at once. */ -export const queryPath = defineDataInspectorRpc({ +export const queryPath = defineRpcFunction({ name: `${NS}:queryPath`, type: 'query', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/query.ts b/plugins/data-inspector/src/node/rpc/functions/query.ts index 795db0af9..d355a2dd7 100644 --- a/plugins/data-inspector/src/node/rpc/functions/query.ts +++ b/plugins/data-inspector/src/node/rpc/functions/query.ts @@ -1,14 +1,15 @@ import type { FilterOptions, QueryOutcome } from '../../engine/contract' +import { defineRpcFunction } from 'devframe' import { runQuery } from '../../engine/query-engine' import { getDataSource, resolveSourceData } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** * Execute a jora query against a registered source. Runs in-process against * the live object; the result is normalized to strict JSON (circulars -> * `$ref`, exotic types tagged, depth/entry caps) before it rides the wire. */ -export const query = defineDataInspectorRpc({ +export const query = defineRpcFunction({ name: `${NS}:query`, type: 'query', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/saved.ts b/plugins/data-inspector/src/node/rpc/functions/saved.ts index 72c828e4e..e0a1c0cb3 100644 --- a/plugins/data-inspector/src/node/rpc/functions/saved.ts +++ b/plugins/data-inspector/src/node/rpc/functions/saved.ts @@ -1,8 +1,9 @@ import type { SavedQueryScope, SaveQueryInput } from '../../engine/contract' +import { defineRpcFunction } from 'devframe' import { deleteSavedQuery, listSavedQueries, saveQuery } from '../../saved-queries' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' -export const savedList = defineDataInspectorRpc({ +export const savedList = defineRpcFunction({ name: `${NS}:saved:list`, type: 'query', jsonSerializable: true, @@ -11,7 +12,7 @@ export const savedList = defineDataInspectorRpc({ }), }) -export const savedSave = defineDataInspectorRpc({ +export const savedSave = defineRpcFunction({ name: `${NS}:saved:save`, type: 'action', jsonSerializable: true, @@ -20,7 +21,7 @@ export const savedSave = defineDataInspectorRpc({ }), }) -export const savedDelete = defineDataInspectorRpc({ +export const savedDelete = defineRpcFunction({ name: `${NS}:saved:delete`, type: 'action', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/skeleton.ts b/plugins/data-inspector/src/node/rpc/functions/skeleton.ts index 467185e87..8f436c246 100644 --- a/plugins/data-inspector/src/node/rpc/functions/skeleton.ts +++ b/plugins/data-inspector/src/node/rpc/functions/skeleton.ts @@ -1,10 +1,11 @@ import type { FilterOptions, SkeletonOutcome } from '../../engine/contract' +import { defineRpcFunction } from 'devframe' import { skeletonOf } from '../../engine/skeleton' import { getDataSource, resolveSourceData } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** The type skeleton of a source ("what data are available"), query-independent. */ -export const skeleton = defineDataInspectorRpc({ +export const skeleton = defineRpcFunction({ name: `${NS}:skeleton`, type: 'query', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/sources.ts b/plugins/data-inspector/src/node/rpc/functions/sources.ts index 55585d423..b5fd910f0 100644 --- a/plugins/data-inspector/src/node/rpc/functions/sources.ts +++ b/plugins/data-inspector/src/node/rpc/functions/sources.ts @@ -1,8 +1,9 @@ +import { defineRpcFunction } from 'devframe' import { listDataSources } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** Every registered data source (meta only, no data). */ -export const sources = defineDataInspectorRpc({ +export const sources = defineRpcFunction({ name: `${NS}:sources`, type: 'query', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/suggest.ts b/plugins/data-inspector/src/node/rpc/functions/suggest.ts index eb1a38d6b..79daf825d 100644 --- a/plugins/data-inspector/src/node/rpc/functions/suggest.ts +++ b/plugins/data-inspector/src/node/rpc/functions/suggest.ts @@ -1,10 +1,11 @@ import type { SuggestOutcome } from '../../engine/contract' +import { defineRpcFunction } from 'devframe' import { suggest as suggestQuery } from '../../engine/query-engine' import { getDataSource, resolveSourceData } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** Autocomplete: jora stat-mode suggestions at a cursor position. */ -export const suggest = defineDataInspectorRpc({ +export const suggest = defineRpcFunction({ name: `${NS}:suggest`, type: 'query', jsonSerializable: true, diff --git a/plugins/data-inspector/src/node/rpc/functions/write.ts b/plugins/data-inspector/src/node/rpc/functions/write.ts index 5dfa84a43..1952e3e18 100644 --- a/plugins/data-inspector/src/node/rpc/functions/write.ts +++ b/plugins/data-inspector/src/node/rpc/functions/write.ts @@ -1,8 +1,9 @@ import type { WriteOutcome, WriteRequest } from '../../engine/contract' import type { WriteApplyOptions } from '../../engine/write' +import { defineRpcFunction } from 'devframe' import { applyWrite } from '../../engine/write' import { getDataSource, isWritableEntry, notifyDataSourceChanged, resolveSourceData } from '../../registry/index' -import { defineDataInspectorRpc, NS } from './_define' +import { NS } from './_define' /** * Mutate a writable source's live object in place. Only sources that opted @@ -11,7 +12,7 @@ import { defineDataInspectorRpc, NS } from './_define' * must be threaded through so array indices line up. Broadcasts * `data:changed` on success so every connected client refreshes. */ -export const write = defineDataInspectorRpc({ +export const write = defineRpcFunction({ name: `${NS}:write`, type: 'action', jsonSerializable: true, diff --git a/plugins/git/app/components/rpc-provider.tsx b/plugins/git/app/components/rpc-provider.tsx index 234e6a21f..33e7e48e2 100644 --- a/plugins/git/app/components/rpc-provider.tsx +++ b/plugins/git/app/components/rpc-provider.tsx @@ -13,11 +13,7 @@ export interface ConnectionState { error: string | null } -/** - * Exported so tests and Storybook can supply a mock connection (e.g. a stubbed - * shiki service) through the same context the components read. - */ -export const RpcContext = createContext({ rpc: null, status: 'connecting', error: null }) +const RpcContext = createContext({ rpc: null, status: 'connecting', error: null }) export function useRpc(): ConnectionState { return use(RpcContext) diff --git a/plugins/git/app/components/views/branches-panel-view.stories.tsx b/plugins/git/app/components/views/branches-panel-view.stories.tsx deleted file mode 100644 index 3f02fe3e8..000000000 --- a/plugins/git/app/components/views/branches-panel-view.stories.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import type { GitBranches } from '@devframes/service-git' -import type { Meta, StoryObj } from '@storybook/react-vite' -import { BranchesPanelView } from './branches-panel-view' - -const data: GitBranches = { - isRepo: true, - current: 'feat/plugin-git', - branches: [ - { name: 'feat/plugin-git', current: true, sha: 'af39698', upstream: 'origin/feat/plugin-git', subject: 'GitLens-style commit graph and log', ahead: 2, behind: 0, gone: false }, - { name: 'main', current: false, sha: '524c6b6', upstream: 'origin/main', subject: 'add dock switcher UI to minimal hub examples', ahead: 0, behind: 12, gone: false }, - { name: 'feature/onboard', current: false, sha: 'c03c3d4', upstream: 'origin/feature/onboard', subject: 'Fixes stash node icon alignment', ahead: 3, behind: 1, gone: false }, - { name: 'bug/error-log', current: false, sha: 'c08b809', upstream: null, subject: 'Log error instead of throwing', ahead: 0, behind: 0, gone: false }, - { name: 'feature/icons', current: false, sha: 'c10d0ab', upstream: 'origin/feature/icons', subject: 'Add file-diff icons, bump component version', ahead: 0, behind: 0, gone: true }, - ], -} - -const meta = { - title: 'Panels/Branches', - component: BranchesPanelView, - args: { - data, - loading: false, - onRefresh: () => undefined, - }, -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = {} -export const Loading: Story = { args: { data: null, loading: true } } -export const NotARepo: Story = { args: { data: { isRepo: false, current: null, branches: [] } } } diff --git a/plugins/git/app/components/views/branches-panel-view.tsx b/plugins/git/app/components/views/branches-panel-view.tsx deleted file mode 100644 index 82e8e7089..000000000 --- a/plugins/git/app/components/views/branches-panel-view.tsx +++ /dev/null @@ -1,85 +0,0 @@ -'use client' - -import type { Branch, GitBranches } from '@devframes/service-git' -import { Badge } from '../ui/badge' -import { IconButton } from '../ui/button' -import { Icon } from '../ui/icon' -import { ScrollArea } from '../ui/scroll-area' -import { Skeleton } from '../ui/skeleton' - -export interface BranchesPanelViewProps { - data: GitBranches | null - loading: boolean - onRefresh: () => void | Promise -} - -function BranchRow({ branch }: { branch: Branch }) { - return ( -
  • - -
    -
    - - {branch.name} - - {branch.current && ( - - - current - - )} - {branch.gone && upstream gone} -
    - {branch.subject &&

    {branch.subject}

    } -
    -
    - {branch.ahead > 0 && ( - - - {branch.ahead} - - )} - {branch.behind > 0 && ( - - - {branch.behind} - - )} - {branch.sha} -
    -
  • - ) -} - -export function BranchesPanelView({ data, loading, onRefresh }: BranchesPanelViewProps) { - return ( -
    -
    - - {data?.isRepo ? `${data.branches.length} branches` : ' '} - - - - -
    - - {!data && ( -
    - {Array.from({ length: 4 }).map((_, i) => )} -
    - )} - - {data && !data.isRepo && ( -

    The working directory is not a git repository.

    - )} - - {data?.isRepo && data.branches.length > 0 && ( - -
      - {data.branches.map(branch => )} -
    -
    - )} -
    - ) -} diff --git a/plugins/git/app/components/views/diff-panel-view.stories.tsx b/plugins/git/app/components/views/diff-panel-view.stories.tsx deleted file mode 100644 index 50624b13f..000000000 --- a/plugins/git/app/components/views/diff-panel-view.stories.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import type { GitDiff } from '@devframes/service-git' -import type { Meta, StoryObj } from '@storybook/react-vite' -import type { ReactNode } from 'react' -import type { BundledLanguage } from 'shiki' -import type { ConnectionState } from '../rpc-provider' -import { useState } from 'react' -import { codeToTokens } from 'shiki' -import { DiffPatchView } from '../diff/diff-view' -import { RpcContext } from '../rpc-provider' -import { DiffPanelView } from './diff-panel-view' - -const PATCH = `diff --git a/src/rpc/functions/log.ts b/src/rpc/functions/log.ts -index 1234567..89abcde 100644 ---- a/src/rpc/functions/log.ts -+++ b/src/rpc/functions/log.ts -@@ -72,4 +72,4 @@ export const log = defineRpcFunction({ - name: 'devframes:service:git:log', - type: 'query', -- snapshot: true, -+ dump: async (_ctx, handler) => { /* bake head of history */ }, - jsonSerializable: true,` - -// Storybook has no host, so stand up a mock `@devframes/service-shiki` handle -// that highlights in-browser with the real Shiki, so the diff stories then render -// true syntax colors through the same code path production uses. -async function mockCodeToTokens({ code, lang, themes }: { code: string, lang?: string, themes?: { light: string, dark: string } }) { - const pair = themes ?? { light: 'vitesse-light', dark: 'vitesse-dark' } - try { - return await codeToTokens(code, { lang: (lang ?? 'text') as BundledLanguage, themes: pair }) - } - catch { - return await codeToTokens(code, { lang: 'text' as BundledLanguage, themes: pair }) - } -} - -// Storybook mock: only the shiki service handle off `rpc.services` is exercised, -// so the full DevframeRpcClient surface is intentionally stubbed out. -// eslint-disable-next-line slop/no-chained-type-assertions -- minimal RPC mock for a story -const mockConnection = { - rpc: { - services: { - has: () => true, - get: (pkg: string) => (pkg === '@devframes/service-shiki' - ? { scope: 'devframes:service:shiki', rpc: { call: (_name: string, input: Parameters[0]) => mockCodeToTokens(input) } } - : undefined), - }, - }, - status: 'connected', - error: null, -} as unknown as ConnectionState - -function WithMockRpc({ children }: { children: ReactNode }) { - return {children} -} - -const data: GitDiff = { - isRepo: true, - staged: false, - path: null, - files: [ - { path: 'src/rpc/functions/log.ts', additions: 14, deletions: 3, binary: false }, - { path: 'src/client/components/views/log-panel-view.tsx', additions: 162, deletions: 40, binary: false }, - { path: 'src/client/lib/refs.ts', additions: 71, deletions: 0, binary: false }, - { path: 'public/preview.png', additions: 0, deletions: 0, binary: true }, - ], - totalAdditions: 247, - totalDeletions: 43, - patch: null, - truncated: false, -} - -// Wire the scope toggle + file selection so the panel is interactive, and feed -// the selected file's patch through the `DiffPatchView` slot. -function Harness(props: Partial>) { - const [staged, setStaged] = useState(false) - const [selected, setSelected] = useState('src/rpc/functions/log.ts') - return ( - - undefined} - patchSlot={} - {...props} - /> - - ) -} - -const meta = { - title: 'Panels/Diff', - component: Harness, -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = {} -export const NoSelection: Story = { args: { selected: null } } -export const Loading: Story = { args: { data: null, loading: true } } -export const NoChanges: Story = { args: { data: { ...data, files: [], totalAdditions: 0, totalDeletions: 0 } } } -export const NotARepo: Story = { args: { data: { ...data, isRepo: false } } } diff --git a/plugins/git/app/components/views/diff-panel-view.tsx b/plugins/git/app/components/views/diff-panel-view.tsx deleted file mode 100644 index 0610d18b3..000000000 --- a/plugins/git/app/components/views/diff-panel-view.tsx +++ /dev/null @@ -1,128 +0,0 @@ -'use client' - -import type { GitDiff } from '@devframes/service-git' -import type { ReactNode } from 'react' -import { cn } from '../../lib/utils' -import { Badge } from '../ui/badge' -import { IconButton } from '../ui/button' -import { Icon } from '../ui/icon' -import { ScrollArea } from '../ui/scroll-area' -import { Skeleton } from '../ui/skeleton' - -export interface DiffPanelViewProps { - data: GitDiff | null - loading: boolean - staged: boolean - selected: string | null - onSelectScope: (staged: boolean) => void - onSelectFile: (path: string) => void - onRefresh: () => void | Promise - /** Rendered below the file list when a file is selected (the patch viewer). */ - patchSlot?: ReactNode -} - -export function DiffPanelView(props: DiffPanelViewProps) { - const { data, loading, staged, selected, onSelectScope, onSelectFile, onRefresh, patchSlot } = props - return ( -
    -
    -
    - {([['Working tree', false], ['Staged', true]] as const).map(([label, value]) => ( - - ))} -
    -
    - {data?.isRepo && ( - - - + - {data.totalAdditions} - - {' '} - - − - {data.totalDeletions} - - - )} - - - -
    -
    - - {!data && ( -
    - {Array.from({ length: 3 }).map((_, i) => )} -
    - )} - - {data && !data.isRepo && ( -

    The working directory is not a git repository.

    - )} - - {data?.isRepo && data.files.length === 0 && ( -

    - No - {staged ? ' staged' : ' unstaged'} - {' '} - changes. -

    - )} - - {data?.isRepo && data.files.length > 0 && ( - <> - -
      - {data.files.map(file => ( -
    • - -
    • - ))} -
    -
    - - {selected && ( -
    - {patchSlot} -
    - )} - - )} -
    - ) -} diff --git a/plugins/git/package.json b/plugins/git/package.json index 02f9ee35e..34ec7f85c 100644 --- a/plugins/git/package.json +++ b/plugins/git/package.json @@ -83,7 +83,6 @@ "next": "catalog:frontend", "react": "catalog:frontend", "react-dom": "catalog:frontend", - "shiki": "catalog:deps", "storybook": "catalog:storybook", "tailwind-merge": "catalog:frontend", "tsdown": "catalog:build", diff --git a/plugins/inspect/app/composables/rpc.ts b/plugins/inspect/app/composables/rpc.ts index 3d0385498..df1f0995e 100644 --- a/plugins/inspect/app/composables/rpc.ts +++ b/plugins/inspect/app/composables/rpc.ts @@ -1,6 +1,6 @@ import type { DevframeConnectionStatus, DevframeRpcClient } from '../connect' +import { connectDevframe } from 'devframe/client' import { reactive, shallowRef } from 'vue' -import { connectInspect } from '../connect' import { addHistoryRecord } from './history' export const connection = reactive<{ @@ -74,7 +74,7 @@ function applyStatus(client: DevframeRpcClient): void { export async function connect(): Promise { try { - const client = await connectInspect() + const client = await connectDevframe() setupHistoryHooks(client) rpcRef.value = client connection.backend = client.connectionMeta.backend diff --git a/plugins/inspect/app/connect.ts b/plugins/inspect/app/connect.ts index 02fe3983d..28087ff79 100644 --- a/plugins/inspect/app/connect.ts +++ b/plugins/inspect/app/connect.ts @@ -1,14 +1,4 @@ -import type { DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientOptions } from 'devframe/client' -import { connectDevframe } from 'devframe/client' +import type { DevframeConnectionStatus, DevframeRpcClient } from 'devframe/client' export type { DevframeConnectionStatus, DevframeRpcClient } export type { AgentManifest, DevframeInspectCommandInfo, DevframeInspectInstanceInfo, InvokeResult, RpcFunctionInfo } from '../src/node/types' - -/** - * Connect to the inspector's devframe backend. A thin, typed wrapper - * around devframe's {@link connectDevframe}; the SPA derives its base - * from `document.baseURI`, so no options are required in the common case. - */ -export function connectInspect(options?: DevframeRpcClientOptions): Promise { - return connectDevframe(options) -} diff --git a/plugins/inspect/src/node/rpc/functions/_define.ts b/plugins/inspect/src/node/rpc/functions/_define.ts deleted file mode 100644 index b4b3c7213..000000000 --- a/plugins/inspect/src/node/rpc/functions/_define.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { DevframeNodeContext } from 'devframe' -import { createDefineWrapperWithContext } from 'devframe/rpc' - -/** - * `defineRpcFunction` pre-bound to the framework-neutral - * {@link DevframeNodeContext}, so each inspector function's `setup(ctx)` - * receives the typed node context (`ctx.rpc`, `ctx.agent`, …) instead of - * the default `undefined` context. - */ -export const defineInspectRpc = createDefineWrapperWithContext() diff --git a/plugins/inspect/src/node/rpc/functions/describe-agent.ts b/plugins/inspect/src/node/rpc/functions/describe-agent.ts index d8dee4e13..7666152dd 100644 --- a/plugins/inspect/src/node/rpc/functions/describe-agent.ts +++ b/plugins/inspect/src/node/rpc/functions/describe-agent.ts @@ -1,5 +1,5 @@ import type { AgentManifest } from 'devframe' -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' /** * Surface the agent-exposed surface of the connection: the unified @@ -7,7 +7,7 @@ import { defineInspectRpc } from './_define' * host-registered tools) and readable resources. `snapshot: true` bakes * the manifest into the static dump for `build`/`spa` mode. */ -export const describeAgent = defineInspectRpc({ +export const describeAgent = defineRpcFunction({ name: 'devframes:plugin:inspect:describe-agent', type: 'query', jsonSerializable: true, diff --git a/plugins/inspect/src/node/rpc/functions/execute-command.ts b/plugins/inspect/src/node/rpc/functions/execute-command.ts index 7462fad41..f2de30672 100644 --- a/plugins/inspect/src/node/rpc/functions/execute-command.ts +++ b/plugins/inspect/src/node/rpc/functions/execute-command.ts @@ -1,6 +1,6 @@ import type { InvokeResult } from '../../types' +import { defineRpcFunction } from 'devframe' import { diagnostics } from '../../diagnostics' -import { defineInspectRpc } from './_define' import { resolveHubCommands } from './_hub-commands' /** @@ -15,7 +15,7 @@ import { resolveHubCommands } from './_hub-commands' * group-only command with no handler, surfaces as `{ ok: false, error }` * from the hub's own `commands.execute()` instead of throwing. */ -export const executeCommand = defineInspectRpc({ +export const executeCommand = defineRpcFunction({ name: 'devframes:plugin:inspect:execute-command', type: 'action', setup: ctx => ({ diff --git a/plugins/inspect/src/node/rpc/functions/invoke-agent-tool.ts b/plugins/inspect/src/node/rpc/functions/invoke-agent-tool.ts index 6907907df..a10228860 100644 --- a/plugins/inspect/src/node/rpc/functions/invoke-agent-tool.ts +++ b/plugins/inspect/src/node/rpc/functions/invoke-agent-tool.ts @@ -1,7 +1,7 @@ import type { InvokeResult } from '../../types' -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' -export const invokeAgentTool = defineInspectRpc({ +export const invokeAgentTool = defineRpcFunction({ name: 'devframes:plugin:inspect:invoke-agent-tool', type: 'action', setup: ctx => ({ diff --git a/plugins/inspect/src/node/rpc/functions/invoke.ts b/plugins/inspect/src/node/rpc/functions/invoke.ts index 3f0c8082d..12d03fc8c 100644 --- a/plugins/inspect/src/node/rpc/functions/invoke.ts +++ b/plugins/inspect/src/node/rpc/functions/invoke.ts @@ -1,6 +1,6 @@ import type { InvokeResult } from '../../types' +import { defineRpcFunction } from 'devframe' import { diagnostics } from '../../diagnostics' -import { defineInspectRpc } from './_define' const INVOKABLE_TYPES = new Set(['query', 'static']) @@ -13,7 +13,7 @@ const INVOKABLE_TYPES = new Set(['query', 'static']) * (default) so arbitrary return values round-trip without the strict-JSON * constraints that `jsonSerializable: true` would impose. */ -export const invoke = defineInspectRpc({ +export const invoke = defineRpcFunction({ name: 'devframes:plugin:inspect:invoke', type: 'action', setup: ctx => ({ diff --git a/plugins/inspect/src/node/rpc/functions/list-commands.ts b/plugins/inspect/src/node/rpc/functions/list-commands.ts index be30e6275..ac44fbe45 100644 --- a/plugins/inspect/src/node/rpc/functions/list-commands.ts +++ b/plugins/inspect/src/node/rpc/functions/list-commands.ts @@ -1,5 +1,5 @@ import type { DevframeInspectCommandInfo } from '../../types' -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' import { projectCommand, resolveHubCommands } from './_hub-commands' /** @@ -11,7 +11,7 @@ import { projectCommand, resolveHubCommands } from './_hub-commands' * `snapshot: true` bakes the (possibly empty) list into the static dump so * the inspector still lists commands in `build`/`spa` mode. */ -export const listCommands = defineInspectRpc({ +export const listCommands = defineRpcFunction({ name: 'devframes:plugin:inspect:list-commands', type: 'query', jsonSerializable: true, diff --git a/plugins/inspect/src/node/rpc/functions/list-functions.ts b/plugins/inspect/src/node/rpc/functions/list-functions.ts index 0a42d943b..3407451e6 100644 --- a/plugins/inspect/src/node/rpc/functions/list-functions.ts +++ b/plugins/inspect/src/node/rpc/functions/list-functions.ts @@ -1,5 +1,5 @@ import type { RpcFunctionAgentInfo, RpcFunctionInfo } from '../../types' -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' import { argsSchemaToJson, returnSchemaToJson } from './_schema' const INVOKABLE_TYPES = new Set(['query', 'static']) @@ -10,7 +10,7 @@ const INVOKABLE_TYPES = new Set(['query', 'static']) * `snapshot: true` bakes the registry into the static dump so the * inspector still lists functions in `build`/`spa` mode. */ -export const listFunctions = defineInspectRpc({ +export const listFunctions = defineRpcFunction({ name: 'devframes:plugin:inspect:list-functions', type: 'query', jsonSerializable: true, diff --git a/plugins/inspect/src/node/rpc/functions/list-instances.ts b/plugins/inspect/src/node/rpc/functions/list-instances.ts index 699055cb1..3d86acf12 100644 --- a/plugins/inspect/src/node/rpc/functions/list-instances.ts +++ b/plugins/inspect/src/node/rpc/functions/list-instances.ts @@ -1,7 +1,7 @@ import type { DevframeInspectInstanceInfo } from '../../types' import process from 'node:process' +import { defineRpcFunction } from 'devframe' import { listLiveDevframeInstances } from 'devframe/internal' -import { defineInspectRpc } from './_define' /** * Enumerate every devframe dev server currently running on this machine, @@ -15,7 +15,7 @@ import { defineInspectRpc } from './_define' * instance discovery to agents over MCP, so exposing it here would duplicate * that surface). */ -export const listInstances = defineInspectRpc({ +export const listInstances = defineRpcFunction({ name: 'devframes:plugin:inspect:list-instances', type: 'query', jsonSerializable: true, diff --git a/plugins/inspect/src/node/rpc/functions/list-state-keys.ts b/plugins/inspect/src/node/rpc/functions/list-state-keys.ts index a99cb3d9a..05ddcc1c8 100644 --- a/plugins/inspect/src/node/rpc/functions/list-state-keys.ts +++ b/plugins/inspect/src/node/rpc/functions/list-state-keys.ts @@ -1,4 +1,4 @@ -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' /** * Enumerate the keys of every shared-state entry published on the @@ -7,7 +7,7 @@ import { defineInspectRpc } from './_define' * returns the key list. `snapshot: true` keeps it listable in static * `build`/`spa` mode. */ -export const listStateKeys = defineInspectRpc({ +export const listStateKeys = defineRpcFunction({ name: 'devframes:plugin:inspect:list-state-keys', type: 'query', jsonSerializable: true, diff --git a/plugins/inspect/src/node/rpc/functions/read-agent-resource.ts b/plugins/inspect/src/node/rpc/functions/read-agent-resource.ts index 3ae7e86f9..020445a59 100644 --- a/plugins/inspect/src/node/rpc/functions/read-agent-resource.ts +++ b/plugins/inspect/src/node/rpc/functions/read-agent-resource.ts @@ -1,7 +1,7 @@ import type { InvokeResult } from '../../types' -import { defineInspectRpc } from './_define' +import { defineRpcFunction } from 'devframe' -export const readAgentResource = defineInspectRpc({ +export const readAgentResource = defineRpcFunction({ name: 'devframes:plugin:inspect:read-agent-resource', type: 'action', setup: ctx => ({ diff --git a/plugins/messages/src/node/rpc/functions/_define.ts b/plugins/messages/src/node/rpc/functions/_define.ts index a6d4efc94..61d8df0e9 100644 --- a/plugins/messages/src/node/rpc/functions/_define.ts +++ b/plugins/messages/src/node/rpc/functions/_define.ts @@ -1,13 +1,5 @@ import type { DevframeMessagesHost } from '@devframes/hub/types' import type { DevframeNodeContext } from 'devframe' -import { createDefineWrapperWithContext } from 'devframe/rpc' - -/** - * `defineRpcFunction` pre-bound to the framework-neutral - * {@link DevframeNodeContext}, so each function's `setup(ctx)` receives the - * typed node context instead of the default `undefined` context. - */ -export const defineMessagesRpc = createDefineWrapperWithContext() /** * Read the hub-attached messages host off a node context, if present. The diff --git a/plugins/messages/src/node/rpc/functions/add.ts b/plugins/messages/src/node/rpc/functions/add.ts index 10dbe6cbd..71a38bfad 100644 --- a/plugins/messages/src/node/rpc/functions/add.ts +++ b/plugins/messages/src/node/rpc/functions/add.ts @@ -1,5 +1,6 @@ import type { DevframeMessageEntry, DevframeMessageEntryInput } from '@devframes/hub/types' -import { defineMessagesRpc, getMessagesHost } from './_define' +import { defineRpcFunction } from 'devframe' +import { getMessagesHost } from './_define' /** * Add a message entry from a browser client. The origin is force-stamped @@ -7,7 +8,7 @@ import { defineMessagesRpc, getMessagesHost } from './_define' * server. Returns the stored entry (with generated id/timestamp), or `null` * when no messages host is attached. */ -export const messagesAdd = defineMessagesRpc({ +export const messagesAdd = defineRpcFunction({ name: 'devframes:plugin:messages:add', type: 'action', jsonSerializable: true, diff --git a/plugins/messages/src/node/rpc/functions/clear.ts b/plugins/messages/src/node/rpc/functions/clear.ts index a4b2081a2..b965149b2 100644 --- a/plugins/messages/src/node/rpc/functions/clear.ts +++ b/plugins/messages/src/node/rpc/functions/clear.ts @@ -1,7 +1,8 @@ -import { defineMessagesRpc, getMessagesHost } from './_define' +import { defineRpcFunction } from 'devframe' +import { getMessagesHost } from './_define' /** Clear the whole message feed. */ -export const messagesClear = defineMessagesRpc({ +export const messagesClear = defineRpcFunction({ name: 'devframes:plugin:messages:clear', type: 'action', jsonSerializable: true, diff --git a/plugins/messages/src/node/rpc/functions/list.ts b/plugins/messages/src/node/rpc/functions/list.ts index 6ce0aa6b5..8a3d8e88b 100644 --- a/plugins/messages/src/node/rpc/functions/list.ts +++ b/plugins/messages/src/node/rpc/functions/list.ts @@ -1,5 +1,6 @@ import type { DevframeMessagesListDelta } from '@devframes/hub/types' -import { defineMessagesRpc, getMessagesHost } from './_define' +import { defineRpcFunction } from 'devframe' +import { getMessagesHost } from './_define' /** * Read the message list incrementally. Pass the `version` from the previous @@ -9,7 +10,7 @@ import { defineMessagesRpc, getMessagesHost } from './_define' * `snapshot: true` bakes the full list into static builds, so the panel * renders the last captured feed without a live server. */ -export const messagesList = defineMessagesRpc({ +export const messagesList = defineRpcFunction({ name: 'devframes:plugin:messages:list', type: 'query', jsonSerializable: true, diff --git a/plugins/messages/src/node/rpc/functions/remove.ts b/plugins/messages/src/node/rpc/functions/remove.ts index 67002f92a..2caa1d726 100644 --- a/plugins/messages/src/node/rpc/functions/remove.ts +++ b/plugins/messages/src/node/rpc/functions/remove.ts @@ -1,7 +1,8 @@ -import { defineMessagesRpc, getMessagesHost } from './_define' +import { defineRpcFunction } from 'devframe' +import { getMessagesHost } from './_define' /** Remove (dismiss) a single message entry by id. */ -export const messagesRemove = defineMessagesRpc({ +export const messagesRemove = defineRpcFunction({ name: 'devframes:plugin:messages:remove', type: 'action', jsonSerializable: true, diff --git a/plugins/messages/src/node/rpc/functions/update.ts b/plugins/messages/src/node/rpc/functions/update.ts index 75573c162..6101f1404 100644 --- a/plugins/messages/src/node/rpc/functions/update.ts +++ b/plugins/messages/src/node/rpc/functions/update.ts @@ -1,5 +1,6 @@ import type { DevframeMessageEntry, DevframeMessageEntryInput } from '@devframes/hub/types' -import { defineMessagesRpc, getMessagesHost } from './_define' +import { defineRpcFunction } from 'devframe' +import { getMessagesHost } from './_define' /** * Partially update an existing message entry by id, e.g. the panel resets @@ -7,7 +8,7 @@ import { defineMessagesRpc, getMessagesHost } from './_define' * the updated entry, or `null` when the id is unknown or no messages host is * attached. */ -export const messagesUpdate = defineMessagesRpc({ +export const messagesUpdate = defineRpcFunction({ name: 'devframes:plugin:messages:update', type: 'action', jsonSerializable: true, diff --git a/plugins/og/app/app/composables/useOgViewer.ts b/plugins/og/app/app/composables/useOgViewer.ts index 112bf7fbd..e19cb29c5 100644 --- a/plugins/og/app/app/composables/useOgViewer.ts +++ b/plugins/og/app/app/composables/useOgViewer.ts @@ -1,7 +1,7 @@ import type { DevframeRpcClient } from 'devframe/client' import type { OgSnapshot } from '../connect' +import { connectDevframe } from 'devframe/client' import { computed, readonly, shallowRef } from 'vue' -import { connectOg } from '../connect' export function useOgViewer() { const rpc = shallowRef(null) @@ -19,7 +19,7 @@ export function useOgViewer() { loading.value = true error.value = null try { - rpc.value ??= await connectOg() + rpc.value ??= await connectDevframe() await rpc.value.ensureTrusted() const result = await rpc.value.call('devframes:plugin:og:resolve-metadata', { url: target.value }) snapshot.value = result diff --git a/plugins/og/app/app/connect.ts b/plugins/og/app/app/connect.ts index db3ae7efa..c812f7060 100644 --- a/plugins/og/app/app/connect.ts +++ b/plugins/og/app/app/connect.ts @@ -1,8 +1 @@ -import type { DevframeRpcClientOptions } from 'devframe/client' -import { connectDevframe } from 'devframe/client' - export type { OgHeadTag, OgSnapshot } from '../../src/node/types' - -export function connectOg(options?: DevframeRpcClientOptions) { - return connectDevframe(options) -} diff --git a/plugins/og/src/node/rpc/functions/resolve-metadata.ts b/plugins/og/src/node/rpc/functions/resolve-metadata.ts index 7bf2ecf38..40cd67c22 100644 --- a/plugins/og/src/node/rpc/functions/resolve-metadata.ts +++ b/plugins/og/src/node/rpc/functions/resolve-metadata.ts @@ -1,6 +1,5 @@ -import type { DevframeNodeContext } from 'devframe' import type { OgFetch, OgSnapshot } from '../../types' -import { createDefineWrapperWithContext } from 'devframe/rpc' +import { defineRpcFunction } from 'devframe' import { s } from 'devframe/utils/simple-schema' import { diagnostics } from '../../diagnostics' import { fetchOgMetadata } from '../../metadata' @@ -32,10 +31,8 @@ const snapshotSchema = s.object({ tags: s.array(tagSchema), }) -const defineOgRpc = createDefineWrapperWithContext() - export function createResolveMetadataRpc(options: ResolveMetadataOptions = {}) { - return defineOgRpc({ + return defineRpcFunction({ name: 'devframes:plugin:og:resolve-metadata', type: 'query', jsonSerializable: true, diff --git a/plugins/terminals/src/node/rpc/functions/list.ts b/plugins/terminals/src/node/rpc/functions/list.ts index 73d13bc69..beb763972 100644 --- a/plugins/terminals/src/node/rpc/functions/list.ts +++ b/plugins/terminals/src/node/rpc/functions/list.ts @@ -7,7 +7,6 @@ export const list = defineRpcFunction({ name: 'devframes:plugin:terminals:list', type: 'query', jsonSerializable: true, - snapshot: true, args: [], returns: s.array(sessionInfoSchema), agent: { diff --git a/plugins/terminals/src/node/rpc/functions/presets.ts b/plugins/terminals/src/node/rpc/functions/presets.ts index f6c98cdea..82d4ca42c 100644 --- a/plugins/terminals/src/node/rpc/functions/presets.ts +++ b/plugins/terminals/src/node/rpc/functions/presets.ts @@ -7,7 +7,6 @@ export const presets = defineRpcFunction({ name: 'devframes:plugin:terminals:presets', type: 'query', jsonSerializable: true, - snapshot: true, args: [], returns: s.array(presetSchema), setup: ctx => ({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62f69105b..f4d96b05c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2150,9 +2150,6 @@ importers: react-dom: specifier: catalog:frontend version: 19.2.8(react@19.2.8) - shiki: - specifier: catalog:deps - version: 4.4.3 storybook: specifier: catalog:storybook version: 10.5.10(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) diff --git a/tests/__snapshots__/tsnapi/@devframes/plugin-assets/rpc.snapshot.d.ts b/tests/__snapshots__/tsnapi/@devframes/plugin-assets/rpc.snapshot.d.ts index 2cef3b00a..ea7fff0ad 100644 --- a/tests/__snapshots__/tsnapi/@devframes/plugin-assets/rpc.snapshot.d.ts +++ b/tests/__snapshots__/tsnapi/@devframes/plugin-assets/rpc.snapshot.d.ts @@ -42,7 +42,7 @@ export declare const capabilities: { }>; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable>>) | undefined; @@ -53,7 +53,7 @@ export declare const capabilities: { dump?: import("devframe/rpc").RpcDump<[], import("devframe/rpc").Thenable<{ write: boolean; uploadExtensions: string[] | "*"; - }>, DevframeNodeContext> | undefined; + }>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + }>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + }[]>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable>>) | undefined; handler?: ((args_0: { @@ -191,7 +191,7 @@ export declare const mkdir: { }) => import("devframe/rpc").Thenable) | undefined; dump?: import("devframe/rpc").RpcDump<[{ path: string; - }], import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + }], import("devframe/rpc").Thenable, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + } | null>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable>>) | undefined; + setup?: ((context: import("devframe").DevframeNodeContext) => import("devframe/rpc").Thenable>>) | undefined; handler?: ((args_0: string, args_1: number | undefined) => import("devframe/rpc").Thenable) | undefined; - dump?: import("devframe/rpc").RpcDump<[string, number | undefined], import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + dump?: import("devframe/rpc").RpcDump<[string, number | undefined], import("devframe/rpc").Thenable, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap>>> | undefined; __promise?: import("devframe/rpc").Thenable>> | undefined; @@ -441,7 +441,7 @@ export declare const rename: { }>; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + }>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap; jsonSerializable?: boolean; agent?: import("devframe").RpcFunctionAgentOptions; - setup?: ((context: DevframeNodeContext) => import("devframe/rpc").Thenable import("devframe/rpc").Thenable, DevframeNodeContext> | undefined; + }>, import("devframe").DevframeNodeContext> | undefined; snapshot?: boolean; __cache?: WeakMap