mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
* feat(plugins): build-less TypeScript workers A worker's main may be .ts/.mts. The plugin host installs module.registerHooks scoped to the plugin folder: .ts files are transpiled with the frames' sucrase options (lines kept, inline source map, source maps on), relative imports fall back to the frames' candidate files, and a value import of the type-only 'orca/worker' fails with a clear error. Needs engines.orca >=1.4.246. * feat(plugins): components panels hot reload with their state - In dev folders a save swaps only the hidden guest: keyed memory atoms are handed to the new guest (ui.retain → ui.hydrate memory), dropped when an atom's version changes. - A save that fails to load keeps the last good render and shows an inline file:line:col error banner; the next good save clears it. A subtle Reloaded mark follows a reload. - Transpile and import errors carry line and column; dev worker restarts keep storage. * feat(plugins): orca plugin dev watch One command for the inner loop: refreshes .orca/types, dev-loads the folder, follows its frame and worker logs (plugins.getLogs gains an optional cursor), prints reloads (optional devChangeCount on list entries) and status changes, and unloads on Ctrl-C. --json streams NDJSON events for agents. * feat(skills): orca-plugin-authoring bundled skill guide A guide for agents to build Orca plugins end to end (decision table, build-less rules, the dev watch loop, test/check, validate, release-entry, approvals, gotchas) with references generated from the component catalog, host API table, event schemas, manifest schema and CLI specs, checked for drift. Fixes the components template's Reset to set(count, 0). * feat(plugins): orca plugin dev watch --check; test kit details in the authoring skill - --check runs orca plugin check after the load and after each reload (one at a time; saves made meanwhile fold into one rerun) and prints each panel's render or errors inline, as a `check` event with --json. Local folders only, since it runs the plugin's code here. - The orca-plugin-authoring guide's Test and check section now documents orca plugin test and check from #36969 exactly (JSON results, exit codes, test placement, the orca/testing kit and its common mistakes), and the loop uses dev watch --check. * refactor(plugins): move the components renderer's timing and helper constants to their own module
71 lines
2.4 KiB
TypeScript
71 lines
2.4 KiB
TypeScript
import { z } from 'zod'
|
|
import { isQualifiedPluginKey } from '../plugins/manifest/plugin-manifest'
|
|
|
|
// Why optional: only `approval_required` hands it out; older hosts strip it and older callers omit it.
|
|
const approvalFingerprintParam = z.string().min(1).max(128).optional()
|
|
|
|
export const PluginSetEnabledParams = z.object({
|
|
pluginKey: z.string().refine(isQualifiedPluginKey, 'invalid qualified plugin key'),
|
|
enabled: z.boolean(),
|
|
approvalFingerprint: approvalFingerprintParam
|
|
})
|
|
|
|
export const PluginSetSystemEnabledParams = z.object({ enabled: z.boolean() })
|
|
|
|
/** Over RPC, approval needs the explicit CLI fingerprint; the desktop review dialog uses IPC. */
|
|
export const PluginRpcConsentParams = z
|
|
.object({
|
|
pluginKey: z.string().min(1),
|
|
reviewedFingerprint: z.string().min(1).max(256).optional(),
|
|
decision: z.enum(['approve', 'keep-disabled']),
|
|
approvalFingerprint: approvalFingerprintParam
|
|
})
|
|
.strip()
|
|
|
|
export const PluginReadPanelEntryParams = z.object({
|
|
pluginKey: z.string().min(1),
|
|
panelId: z.string().min(1)
|
|
})
|
|
|
|
export const PluginInvokeCommandParams = z.object({
|
|
pluginKey: z.string().min(1),
|
|
commandId: z.string().min(1),
|
|
args: z.unknown().optional()
|
|
})
|
|
|
|
export const PluginsPanelActionParams = z.unknown()
|
|
|
|
// Why 32 KiB: the same bound settings keep for each development folder entry.
|
|
const devFolderPathParam = z
|
|
.string()
|
|
.min(1)
|
|
.max(32 * 1024)
|
|
|
|
export const PluginDevLoadParams = z.object({
|
|
path: devFolderPathParam,
|
|
approvalFingerprint: approvalFingerprintParam
|
|
})
|
|
|
|
export const PluginDevUnloadParams = z
|
|
.object({
|
|
path: devFolderPathParam.optional(),
|
|
pluginKey: z.string().refine(isQualifiedPluginKey, 'invalid qualified plugin key').optional()
|
|
})
|
|
.refine((params) => (params.path === undefined) !== (params.pluginKey === undefined), {
|
|
message: 'pass exactly one of path or pluginKey'
|
|
})
|
|
|
|
export const PluginGetLogsParams = z.object({
|
|
pluginKey: z.string().refine(isQualifiedPluginKey, 'invalid qualified plugin key'),
|
|
/** `cursor` from an earlier reply; only later lines come back. Older hosts ignore it. */
|
|
after: z.string().max(64).optional()
|
|
})
|
|
|
|
export const PluginDevInspectParams = z.object({
|
|
pluginKey: z.string().refine(isQualifiedPluginKey, 'invalid qualified plugin key')
|
|
})
|
|
|
|
export const PluginRestartParams = z.object({
|
|
pluginKey: z.string().refine(isQualifiedPluginKey, 'invalid qualified plugin key')
|
|
})
|