relay-dsh-plugin-manager 0.1.0-rc.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/conversation.ts","../src/hot-runtime.ts","../src/source.ts","../src/search.ts","../src/profile.ts","../src/plans.ts","../src/operations.ts","../src/manager.ts","../src/providers.ts","../src/restart.ts","../src/runner.ts","../src/index.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport type { CommandInvocation } from '@deepseek-ai/dsh-commands'\nimport { createUserMessage } from '@deepseek-ai/dsh-llm'\nimport { defineTool, type ToolRunContext } from '@deepseek-ai/dsh-tools'\nimport type { PluginManager } from './manager.ts'\nimport type { MutationAction } from './plans.ts'\nimport { fail } from './errors.ts'\n\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\nfunction jsonValue(value: unknown): JsonValue {\n return JSON.parse(JSON.stringify(value)) as JsonValue\n}\n\nfunction renderJson(_args: unknown, value: JsonValue): Array<{ type: 'text'; text: string }> {\n return [{ type: 'text', text: JSON.stringify(value, null, 2) }]\n}\n\ninterface ConfirmationCursor {\n sessionId: string\n userMessageSeq: number\n expiresAt: number\n}\n\nfunction confirmationCursor(execution: ToolRunContext): Omit<ConfirmationCursor, 'expiresAt'> | null {\n const session = execution.agent?.session\n if (session === undefined) return null\n let userMessageSeq = -1\n for (const event of session.events) if (event.type === 'user/message') userMessageSeq = event.seq\n return { sessionId: String(session.id), userMessageSeq }\n}\n\nexport function registerConversationSurface(ctx: Context, manager: PluginManager): void {\n const confirmations = new Map<string, ConfirmationCursor>()\n ctx.tools.register(defineTool({\n name: 'plugin_discover',\n description: 'Read-only DSH plugin discovery. List installed plugins, search registered sources, inspect one npm/GitHub source, or query plugin/operation status. This tool never changes the profile.',\n parameters: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'inspect', 'status'],\n required: true,\n description: 'The read-only operation.',\n },\n query: { type: 'string', description: 'Natural-language search query.' },\n target: { type: 'string', description: 'npm package, GitHub source, or installed package name.' },\n operationId: { type: 'string', description: 'Operation id returned by plugin_manage.' },\n maxResults: { type: 'integer', description: 'Maximum merged search results.' },\n },\n output: { schema: { type: 'json' }, render: renderJson },\n timeoutMs: 35_000,\n isConcurrencySafe: () => true,\n execute: async (args, execution) => jsonValue(await manager.discover(args, execution.signal)),\n }))\n\n ctx.tools.register(defineTool({\n name: 'plugin_manage',\n description: 'Plan and run DSH plugin mutations. ALWAYS call action=plan first and show its impact. NEVER treat the request that produced a plan as confirmation. Only call action=execute with its confirmationToken after a later, explicit user confirmation. Install sources are npm or GitHub; search providers do not define installers.',\n parameters: {\n action: {\n type: 'string',\n enum: ['plan', 'execute', 'status', 'cancel'],\n required: true,\n description: 'Lifecycle stage. Mutations require plan followed by execute.',\n },\n operation: {\n type: 'string',\n enum: ['install', 'remove', 'update', 'enable', 'disable', 'restart'],\n description: 'Mutation to plan.',\n },\n target: { type: 'string', description: 'Installed package name, or install source when source is omitted.' },\n source: { type: 'string', description: 'npm package/version or canonical GitHub repository/ref.' },\n confirmationToken: { type: 'string', description: 'One-use token from a prior plan.' },\n operationId: { type: 'string', description: 'Tracked operation id.' },\n },\n output: { schema: { type: 'json' }, render: renderJson },\n execute: async (args, execution) => {\n if (args.action === 'plan') {\n if (args.operation === undefined) fail('INVALID_ACTION', 'Planning requires an operation.')\n const plan = await manager.plan({\n operation: args.operation as MutationAction,\n ...(args.target === undefined ? {} : { target: args.target }),\n ...(args.source === undefined ? {} : { source: args.source }),\n }, execution.signal)\n const cursor = confirmationCursor(execution)\n if (cursor === null) fail('CONFIRMATION_REQUIRED', 'Planning requires a DSH Agent session.')\n const now = Date.now()\n for (const [token, binding] of confirmations) if (binding.expiresAt <= now) confirmations.delete(token)\n confirmations.set(plan.confirmationToken, { ...cursor, expiresAt: Date.parse(plan.expiresAt) })\n return jsonValue(plan)\n }\n if (args.action === 'execute') {\n if (args.confirmationToken === undefined) fail('CONFIRMATION_REQUIRED', 'Execution requires a confirmation token.')\n const binding = confirmations.get(args.confirmationToken)\n const cursor = confirmationCursor(execution)\n if (binding === undefined || cursor === null || cursor.sessionId !== binding.sessionId) {\n fail('CONFIRMATION_REQUIRED', 'Confirmation token is not bound to this DSH conversation.')\n }\n if (cursor.userMessageSeq <= binding.userMessageSeq) {\n fail('CONFIRMATION_REQUIRED', 'Wait for a later explicit user confirmation before execution.')\n }\n confirmations.delete(args.confirmationToken)\n return jsonValue(manager.execute(args.confirmationToken))\n }\n if (args.operationId === undefined) fail('OPERATION_NOT_FOUND', `${args.action} requires an operation id.`)\n return jsonValue(args.action === 'cancel'\n ? manager.cancel(args.operationId)\n : manager.operation(args.operationId))\n },\n }))\n\n ctx.commands.register({\n name: 'plugins',\n description: 'manage DSH plugins through this conversation',\n input: { hint: '<request>' },\n handler: ({ agent, rawInput }: CommandInvocation) => {\n const request = rawInput.trim() === ''\n ? 'List the installed DSH plugins and summarize their status.'\n : rawInput.trim()\n agent.steer(createUserMessage({\n content: [{ type: 'text', text: request }],\n source: { kind: 'user' },\n }))\n return { kind: 'success', text: 'Plugin request submitted to this conversation.' }\n },\n })\n}\n","import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { parse } from 'yaml'\nimport type { PackageSurface } from './profile.ts'\n\nexport interface HotInsertRow {\n id: string\n name: string\n}\n\nexport interface HotActivationResult {\n active: boolean\n restartRequired: boolean\n reason: string | null\n}\n\ninterface PluginHandle {\n await(): Promise<unknown>\n dispose(): Promise<unknown> | void\n}\n\ninterface HotContext {\n plugin(plugin: unknown, config: unknown): PluginHandle\n logger?: { info?(message: string): void; warn?(message: string): void }\n}\n\nexport function parseSimpleHotPatch(text: string): HotInsertRow[] | null {\n let value: unknown\n try {\n value = parse(text)\n } catch {\n return null\n }\n if (!Array.isArray(value) || value.length === 0) return null\n const rows: HotInsertRow[] = []\n for (const patch of value) {\n if (typeof patch !== 'object' || patch === null || Array.isArray(patch)) return null\n if (Object.keys(patch).length !== 1 || !Array.isArray((patch as { insert?: unknown }).insert)) return null\n for (const raw of (patch as { insert: unknown[] }).insert) {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return null\n const entry = raw as { id?: unknown; name?: unknown }\n if (Object.keys(entry).some(key => key !== 'id' && key !== 'name')) return null\n if (typeof entry.id !== 'string' || entry.id === '' || typeof entry.name !== 'string' || entry.name === '') return null\n rows.push({ id: entry.id, name: entry.name })\n }\n }\n return rows.length === 0 ? null : rows\n}\n\nexport class HotRuntime {\n private readonly handles = new Map<string, PluginHandle>()\n private sequence = 0\n private includeClass: unknown | null | undefined\n private readonly ctx: HotContext\n private readonly profileDir: string\n private readonly timeoutMs: number\n private readonly loadInclude?: () => Promise<unknown | null>\n\n constructor(\n ctx: HotContext,\n profileDir: string,\n timeoutMs = 10_000,\n loadInclude?: () => Promise<unknown | null>,\n ) {\n this.ctx = ctx\n this.profileDir = profileDir\n this.timeoutMs = timeoutMs\n this.loadInclude = loadInclude\n this.clean()\n }\n\n private hotDir(): string {\n return join(this.profileDir, '.relay-plugin-manager')\n }\n\n clean(): void {\n let files: string[]\n try {\n files = readdirSync(this.hotDir())\n } catch {\n return\n }\n for (const file of files) if (/^hot-\\d+\\.yml$/u.test(file)) rmSync(join(this.hotDir(), file), { force: true })\n }\n\n private async include(): Promise<unknown | null> {\n if (this.includeClass !== undefined) return this.includeClass\n if (this.loadInclude !== undefined) {\n this.includeClass = await this.loadInclude()\n return this.includeClass\n }\n try {\n const module = await import('@deepseek-ai/cordis-plugin-include') as { Include?: new (...args: never[]) => object; default?: new (...args: never[]) => object }\n const Include = module.Include ?? module.default\n if (Include === undefined) throw new Error('missing Include export')\n this.includeClass = class RuntimeHotInclude extends Include {\n write(): void {}\n }\n } catch {\n this.includeClass = null\n }\n return this.includeClass\n }\n\n async activate(surface: PackageSurface): Promise<HotActivationResult> {\n if (this.handles.has(surface.packageName)) return { active: true, restartRequired: false, reason: null }\n const Include = await this.include()\n if (Include === null) return { active: false, restartRequired: true, reason: 'DSH Include runtime is unavailable.' }\n let rows: HotInsertRow[] | null = null\n if (surface.bundlePatch !== null) {\n try {\n rows = parseSimpleHotPatch(readFileSync(\n join(this.profileDir, 'node_modules', surface.packageName, surface.bundlePatch),\n 'utf8',\n ))\n } catch {\n rows = null\n }\n if (rows === null) {\n return { active: false, restartRequired: true, reason: 'Bundle patch is not a plain insert-only patch.' }\n }\n } else if (surface.client) {\n rows = [{ id: `client-${surface.packageName.replace(/[^A-Za-z0-9_.-]/gu, '-')}`, name: surface.packageName }]\n } else {\n return { active: false, restartRequired: true, reason: 'Package has no hot-activatable DSH surface.' }\n }\n mkdirSync(this.hotDir(), { recursive: true, mode: 0o700 })\n const file = join(this.hotDir(), `hot-${String(++this.sequence)}.yml`)\n writeFileSync(file, rows.map(row => [\n '- id: ' + JSON.stringify(`rpm-${row.id}`),\n ' name: ' + JSON.stringify(row.name),\n ].join('\\n')).join('\\n') + '\\n', { mode: 0o600 })\n let handle: PluginHandle | undefined\n let timeout: NodeJS.Timeout | undefined\n try {\n handle = this.ctx.plugin(Include, { path: pathToFileURL(file).href })\n await Promise.race([\n handle.await(),\n new Promise<never>((_resolve, reject) => {\n timeout = setTimeout(() => reject(new Error('hot activation timed out')), this.timeoutMs)\n }),\n ])\n this.handles.set(surface.packageName, handle)\n return { active: true, restartRequired: false, reason: null }\n } catch (error) {\n try { await handle?.dispose() } catch { /* best effort */ }\n return {\n active: false,\n restartRequired: true,\n reason: error instanceof Error ? error.message : String(error),\n }\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n }\n }\n\n async deactivate(packageName: string): Promise<boolean> {\n const handle = this.handles.get(packageName)\n if (handle === undefined) return false\n this.handles.delete(packageName)\n try {\n await handle.dispose()\n return true\n } catch {\n return false\n }\n }\n\n isActive(packageName: string): boolean {\n return this.handles.has(packageName)\n }\n}\n","import { fail } from './errors.ts'\n\nexport const EXACT_SEMVER = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/u\nexport const NPM_NAME = /^(?:@[a-z0-9][a-z0-9._-]*\\/)?[a-z0-9][a-z0-9._-]*$/u\nexport const FULL_COMMIT = /^[a-f0-9]{40}$/iu\nconst GITHUB_PART = /^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,98}[A-Za-z0-9])?$/u\nconst UNSAFE_TOKEN = /[\\u0000-\\u0020\\u007f;&|`$<>]/u\n\nexport interface NpmPluginSource {\n kind: 'npm'\n package: string\n version?: string\n}\n\nexport interface GithubPluginSource {\n kind: 'github'\n owner: string\n repo: string\n ref?: string\n}\n\nexport type PluginSource = NpmPluginSource | GithubPluginSource\n\nexport interface PluginInspection {\n source: PluginSource\n sourceType: PluginSource['kind']\n requestedSpec: string\n installSpec: string\n packageName: string\n version?: string\n commit?: string\n integrity?: string\n repository: string | null\n description: string | null\n bundlePatch: string | null\n client: boolean\n}\n\nexport interface FetchOptions {\n fetch?: typeof globalThis.fetch\n env?: NodeJS.ProcessEnv\n signal?: AbortSignal\n}\n\nfunction safeToken(value: unknown): string {\n const source = String(value ?? '').trim()\n if (source === '' || source.startsWith('-') || UNSAFE_TOKEN.test(source)) {\n fail('INVALID_SOURCE', 'Plugin source must be one safe npm or GitHub token.')\n }\n return source\n}\n\nexport function parseNpmSpec(value: unknown, requireExact = false): NpmPluginSource {\n const spec = safeToken(value)\n let packageName = spec\n let version: string | undefined\n const separator = spec.lastIndexOf('@')\n const scopedBoundary = spec.startsWith('@') ? spec.indexOf('/') : -1\n if (separator > Math.max(0, scopedBoundary)) {\n packageName = spec.slice(0, separator)\n version = spec.slice(separator + 1)\n }\n if (!NPM_NAME.test(packageName)) {\n fail('INVALID_NPM_SPEC', 'Plugin source is not a valid npm package name.')\n }\n if (version !== undefined && !EXACT_SEMVER.test(version)) {\n fail('INVALID_NPM_VERSION', 'npm plugin versions must be exact semantic versions.')\n }\n if (requireExact && version === undefined) {\n fail('IMMUTABLE_SOURCE_REQUIRED', 'Installation requires an exact npm version.')\n }\n return { kind: 'npm', package: packageName, ...(version === undefined ? {} : { version }) }\n}\n\nfunction validGithubPart(value: string): boolean {\n return GITHUB_PART.test(value) && value !== '.' && value !== '..' && !value.endsWith('.git')\n}\n\nexport function parseGithubSpec(value: unknown, requireCommit = false): GithubPluginSource | null {\n const spec = safeToken(value)\n let owner: string | undefined\n let repo: string | undefined\n let ref: string | undefined\n if (spec.startsWith('github:')) {\n const match = /^github:([^/]+)\\/([^#]+?)(?:#(.+))?$/u.exec(spec)\n if (match === null) fail('INVALID_GITHUB_SPEC', 'GitHub source must use github:owner/repo[#ref].')\n owner = match[1]\n repo = match[2]\n ref = match[3]\n } else if (spec.startsWith('https://github.com/')) {\n let url: URL\n try {\n url = new URL(spec)\n } catch {\n fail('INVALID_GITHUB_SPEC', 'GitHub URL is invalid.')\n }\n if (url.protocol !== 'https:' || url.hostname !== 'github.com' || url.search !== '') {\n fail('INVALID_GITHUB_SPEC', 'Only canonical HTTPS github.com repository URLs are supported.')\n }\n const parts = url.pathname.split('/').filter(Boolean)\n owner = parts[0]\n repo = parts[1]?.replace(/\\.git$/u, '')\n if (parts.length > 2) {\n if ((parts[2] !== 'tree' && parts[2] !== 'commit') || parts.length < 4) {\n fail('INVALID_GITHUB_SPEC', 'GitHub URL must identify a repository, tree, or commit.')\n }\n ref = decodeURIComponent(parts.slice(3).join('/'))\n } else if (url.hash !== '') {\n fail('INVALID_GITHUB_SPEC', 'Use a tree/commit URL or github:owner/repo#ref for GitHub refs.')\n }\n } else if (/^[A-Za-z][A-Za-z0-9+.-]*:\\/\\//u.test(spec)) {\n fail('INVALID_GITHUB_SPEC', 'Only canonical HTTPS github.com repository URLs are supported.')\n } else {\n return null\n }\n if (!validGithubPart(owner ?? '') || !validGithubPart(repo ?? '')) {\n fail('INVALID_GITHUB_SPEC', 'GitHub owner or repository name is invalid.')\n }\n if (ref !== undefined && (ref === '' || ref.length > 200 || UNSAFE_TOKEN.test(ref))) {\n fail('INVALID_GITHUB_REF', 'GitHub ref is invalid.')\n }\n if (requireCommit && !FULL_COMMIT.test(ref ?? '')) {\n fail('IMMUTABLE_SOURCE_REQUIRED', 'Installation requires a full GitHub commit.')\n }\n return { kind: 'github', owner: owner!, repo: repo!, ...(ref === undefined ? {} : { ref }) }\n}\n\nexport function parsePluginSource(value: string | PluginSource): PluginSource {\n if (typeof value === 'string') return parseGithubSpec(value) ?? parseNpmSpec(value)\n if (value.kind === 'npm') {\n return parseNpmSpec(`${value.package}${value.version === undefined ? '' : `@${value.version}`}`)\n }\n return parseGithubSpec(`github:${value.owner}/${value.repo}${value.ref === undefined ? '' : `#${value.ref}`}`)!\n}\n\nexport function renderSource(source: PluginSource): string {\n if (source.kind === 'npm') return `${source.package}${source.version === undefined ? '' : `@${source.version}`}`\n return `github:${source.owner}/${source.repo}${source.ref === undefined ? '' : `#${source.ref}`}`\n}\n\nfunction manifestDsh(value: unknown): { bundlePatch: string | null; client: boolean } {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return { bundlePatch: null, client: false }\n const dsh = (value as { dsh?: unknown }).dsh\n if (typeof dsh !== 'object' || dsh === null || Array.isArray(dsh)) return { bundlePatch: null, client: false }\n const bundle = (dsh as { bundle?: unknown }).bundle\n const patch = typeof bundle === 'object' && bundle !== null && !Array.isArray(bundle)\n ? (bundle as { patch?: unknown }).patch\n : undefined\n return {\n bundlePatch: typeof patch === 'string' && patch.trim() !== '' ? patch : null,\n client: (dsh as { client?: unknown }).client !== undefined,\n }\n}\n\nexport function validatePluginManifest(\n manifest: unknown,\n expectedName?: string,\n): { packageName: string; bundlePatch: string | null; client: boolean } {\n if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {\n fail('INVALID_PLUGIN_MANIFEST', 'Plugin package manifest must be an object.')\n }\n const packageName = String((manifest as { name?: unknown }).name ?? '')\n if (!NPM_NAME.test(packageName)) fail('INVALID_PLUGIN_MANIFEST', 'Plugin manifest has no valid package name.')\n if (expectedName !== undefined && packageName !== expectedName) {\n fail('PACKAGE_NAME_MISMATCH', 'Resolved package name does not match the requested npm package.')\n }\n const surface = manifestDsh(manifest)\n if (surface.bundlePatch === null && !surface.client) {\n fail('NOT_DSH_PLUGIN', `${packageName} declares neither dsh.bundle.patch nor dsh.client.`)\n }\n return { packageName, ...surface }\n}\n\nasync function fetchJson(url: string, options: FetchOptions, headers: Record<string, string> = {}): Promise<unknown> {\n const fetchImpl = options.fetch ?? globalThis.fetch\n let response: Response\n try {\n response = await fetchImpl(url, {\n headers: { accept: 'application/json', ...headers },\n redirect: 'follow',\n signal: options.signal,\n })\n } catch (error) {\n fail('NETWORK_ERROR', `Could not reach plugin source: ${error instanceof Error ? error.message : String(error)}`)\n }\n if (!response.ok) fail('SOURCE_HTTP_ERROR', `Plugin source returned HTTP ${response.status}.`, { url, status: response.status })\n try {\n return await response.json()\n } catch {\n fail('INVALID_SOURCE_METADATA', 'Plugin source returned invalid JSON metadata.', { url })\n }\n}\n\nfunction repositoryIdentity(value: unknown): string | null {\n const raw = typeof value === 'string'\n ? value\n : typeof value === 'object' && value !== null\n ? (value as { url?: unknown }).url\n : undefined\n if (typeof raw !== 'string' || raw.trim() === '') return null\n const normalized = raw.trim()\n .replace(/^git\\+/u, '')\n .replace(/^git@github\\.com:/u, 'https://github.com/')\n .replace(/^github:/u, 'https://github.com/')\n .replace(/\\.git(?:#.*)?$/u, '')\n .replace(/\\/$/u, '')\n const match = /^https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)$/iu.exec(normalized)\n return match === null\n ? normalized.toLowerCase()\n : `github.com/${match[1]!.toLowerCase()}/${match[2]!.toLowerCase()}`\n}\n\nfunction npmMetadataUrl(name: string, version?: string): string {\n return `https://registry.npmjs.org/${encodeURIComponent(name).replace(/^%40/u, '@')}/${encodeURIComponent(version ?? 'latest')}`\n}\n\nexport async function inspectNpm(source: NpmPluginSource, options: FetchOptions = {}): Promise<PluginInspection> {\n const manifest = await fetchJson(npmMetadataUrl(source.package, source.version), options)\n const plugin = validatePluginManifest(manifest, source.package)\n const version = String((manifest as { version?: unknown }).version ?? '')\n if (!EXACT_SEMVER.test(version)) fail('INVALID_NPM_VERSION', 'Registry metadata has no exact semantic version.')\n const integrity = (manifest as { dist?: { integrity?: unknown } }).dist?.integrity\n if (typeof integrity !== 'string' || !/^sha512-[A-Za-z0-9+/=]+$/u.test(integrity)) {\n fail('NPM_INTEGRITY_MISSING', 'Registry metadata has no SHA-512 package integrity.')\n }\n const exact: NpmPluginSource = { kind: 'npm', package: plugin.packageName, version }\n return {\n source: exact,\n sourceType: 'npm',\n requestedSpec: renderSource(source),\n installSpec: renderSource(exact),\n packageName: plugin.packageName,\n version,\n integrity,\n repository: repositoryIdentity((manifest as { repository?: unknown }).repository),\n description: typeof (manifest as { description?: unknown }).description === 'string'\n ? (manifest as { description: string }).description\n : null,\n bundlePatch: plugin.bundlePatch,\n client: plugin.client,\n }\n}\n\nfunction githubHeaders(env: NodeJS.ProcessEnv = process.env): Record<string, string> {\n const token = env.GITHUB_TOKEN ?? env.GH_TOKEN\n return {\n 'user-agent': 'relay-dsh-plugin-manager',\n 'x-github-api-version': '2022-11-28',\n ...(token === undefined || token === '' ? {} : { authorization: `Bearer ${token}` }),\n }\n}\n\nexport async function inspectGithub(source: GithubPluginSource, options: FetchOptions = {}): Promise<PluginInspection> {\n const headers = githubHeaders(options.env)\n let ref = source.ref\n if (ref === undefined) {\n const repository = await fetchJson(`https://api.github.com/repos/${source.owner}/${source.repo}`, options, headers)\n ref = typeof (repository as { default_branch?: unknown }).default_branch === 'string'\n ? (repository as { default_branch: string }).default_branch\n : undefined\n if (ref === undefined || ref === '') fail('INVALID_SOURCE_METADATA', 'GitHub repository has no default branch.')\n }\n const commit = await fetchJson(\n `https://api.github.com/repos/${source.owner}/${source.repo}/commits/${encodeURIComponent(ref)}`,\n options,\n headers,\n )\n const sha = String((commit as { sha?: unknown }).sha ?? '').toLowerCase()\n if (!FULL_COMMIT.test(sha)) fail('INVALID_SOURCE_METADATA', 'GitHub did not resolve the source to a full commit.')\n const manifest = await fetchJson(\n `https://raw.githubusercontent.com/${source.owner}/${source.repo}/${sha}/package.json`,\n options,\n )\n const plugin = validatePluginManifest(manifest)\n const exact: GithubPluginSource = { kind: 'github', owner: source.owner, repo: source.repo, ref: sha }\n return {\n source: exact,\n sourceType: 'github',\n requestedSpec: renderSource(source),\n installSpec: renderSource(exact),\n packageName: plugin.packageName,\n commit: sha,\n repository: `github.com/${source.owner.toLowerCase()}/${source.repo.toLowerCase()}`,\n description: typeof (manifest as { description?: unknown }).description === 'string'\n ? (manifest as { description: string }).description\n : null,\n bundlePatch: plugin.bundlePatch,\n client: plugin.client,\n }\n}\n\nexport async function inspectPluginSource(\n value: string | PluginSource,\n options: FetchOptions = {},\n): Promise<PluginInspection> {\n const source = parsePluginSource(value)\n return source.kind === 'npm' ? inspectNpm(source, options) : inspectGithub(source, options)\n}\n\nexport function inspectionIdentity(inspection: PluginInspection): string {\n return inspection.repository ?? `${inspection.sourceType}:${inspection.packageName.toLowerCase()}`\n}\n","import type {\n PluginSearchCandidate,\n PluginSearchProvider,\n PluginSearchRuntime,\n} from './search-runtime.ts'\nimport {\n inspectionIdentity,\n inspectPluginSource,\n parsePluginSource,\n type FetchOptions,\n type PluginInspection,\n type PluginSource,\n} from './source.ts'\nimport { fail } from './errors.ts'\n\nexport interface SearchResultSource {\n inspection: PluginInspection\n providers: string[]\n evidence: string[]\n}\n\nexport interface SearchResult {\n query: string\n candidates: Array<{\n identity: string\n packageName: string\n description: string | null\n repository: string | null\n sources: SearchResultSource[]\n recommendedSource: string\n }>\n providerErrors: Array<{ provider: string; error: string }>\n rejectedCandidates: number\n}\n\nexport interface SearchOptions extends FetchOptions {\n maxResults?: number\n providerTimeoutMs?: number\n inspect?: typeof inspectPluginSource\n}\n\nfunction searchQuery(value: string): string {\n const query = value.trim()\n if (query === '' || query.length > 120 || /[\\u0000-\\u001f\\u007f]/u.test(query)) {\n fail('INVALID_SEARCH_QUERY', 'Search query must contain 1 to 120 printable characters.')\n }\n return query\n}\n\nfunction abortReason(signal: AbortSignal): Error {\n return signal.reason instanceof Error ? signal.reason : new Error('search cancelled')\n}\n\nasync function searchProvider(\n provider: PluginSearchProvider,\n query: string,\n maxResults: number,\n parent: AbortSignal | undefined,\n timeoutMs: number,\n): Promise<readonly PluginSearchCandidate[]> {\n const controller = new AbortController()\n const onAbort = (): void => controller.abort(parent?.reason)\n if (parent?.aborted === true) throw abortReason(parent)\n parent?.addEventListener('abort', onAbort, { once: true })\n const timeout = setTimeout(() => controller.abort(new Error(`provider timed out after ${timeoutMs}ms`)), timeoutMs)\n try {\n const result = await provider.search({ query, maxResults, signal: controller.signal })\n if (!Array.isArray(result)) throw new TypeError('provider result must be an array')\n return result.slice(0, maxResults)\n } finally {\n clearTimeout(timeout)\n parent?.removeEventListener('abort', onAbort)\n }\n}\n\ninterface DiscoveredSource {\n source: PluginSource\n provider: string\n evidence: string[]\n rank: number\n}\n\nfunction candidateSources(provider: string, rows: readonly PluginSearchCandidate[]): DiscoveredSource[] {\n const output: DiscoveredSource[] = []\n const ranked = [...rows].sort((left, right) => (right.score ?? 0) - (left.score ?? 0) || left.id.localeCompare(right.id))\n for (const [rank, candidate] of ranked.entries()) {\n if (typeof candidate.id !== 'string' || candidate.id.trim() === '' || !Array.isArray(candidate.sources)) continue\n for (const raw of candidate.sources.slice(0, 3)) {\n try {\n output.push({\n source: parsePluginSource(raw),\n provider,\n evidence: [...(candidate.evidence ?? [])].filter(value => typeof value === 'string').slice(0, 5),\n rank,\n })\n } catch {\n // Provider data is untrusted. Invalid sources are rejected during normalization.\n }\n }\n }\n return output\n}\n\nexport async function searchPlugins(\n runtime: Pick<PluginSearchRuntime, 'entries'>,\n rawQuery: string,\n options: SearchOptions = {},\n): Promise<SearchResult> {\n const query = searchQuery(rawQuery)\n const maxResults = Math.max(1, Math.min(20, options.maxResults ?? 6))\n const timeoutMs = Math.max(100, options.providerTimeoutMs ?? 10_000)\n const providers = runtime.entries()\n const settled = await Promise.allSettled(providers.map(async provider => ({\n provider: provider.id,\n rows: await searchProvider(provider, query, maxResults, options.signal, timeoutMs),\n })))\n if (options.signal?.aborted === true) throw abortReason(options.signal)\n\n const providerErrors: SearchResult['providerErrors'] = []\n const discovered: DiscoveredSource[] = []\n for (let index = 0; index < settled.length; index += 1) {\n const result = settled[index]!\n const provider = providers[index]!.id\n if (result.status === 'rejected') {\n providerErrors.push({ provider, error: result.reason instanceof Error ? result.reason.message : String(result.reason) })\n continue\n }\n discovered.push(...candidateSources(result.value.provider, result.value.rows))\n }\n\n const inspect = options.inspect ?? inspectPluginSource\n const inspected = await Promise.all(discovered.map(async item => {\n try {\n const inspection = await inspect(item.source, options)\n return { ok: true as const, item, inspection }\n } catch {\n return { ok: false as const }\n }\n }))\n\n const projects = new Map<string, SearchResult['candidates'][number] & { rank: number }>()\n let rejectedCandidates = 0\n for (const result of inspected) {\n if (!result.ok) {\n rejectedCandidates += 1\n continue\n }\n const identity = inspectionIdentity(result.inspection)\n const existing = projects.get(identity) ?? {\n identity,\n packageName: result.inspection.packageName,\n description: result.inspection.description,\n repository: result.inspection.repository,\n sources: [],\n recommendedSource: result.inspection.installSpec,\n rank: result.item.rank,\n }\n const sameSource = existing.sources.find(source => source.inspection.installSpec === result.inspection.installSpec)\n if (sameSource === undefined) {\n existing.sources.push({\n inspection: result.inspection,\n providers: [result.item.provider],\n evidence: [...result.item.evidence],\n })\n } else {\n if (!sameSource.providers.includes(result.item.provider)) sameSource.providers.push(result.item.provider)\n for (const evidence of result.item.evidence) if (!sameSource.evidence.includes(evidence)) sameSource.evidence.push(evidence)\n }\n existing.rank = Math.min(existing.rank, result.item.rank)\n const npm = existing.sources.find(source => source.inspection.sourceType === 'npm')\n existing.recommendedSource = npm?.inspection.installSpec ?? existing.sources[0]!.inspection.installSpec\n projects.set(identity, existing)\n }\n\n const candidates = [...projects.values()]\n .sort((left, right) => left.rank - right.rank || left.packageName.localeCompare(right.packageName))\n .slice(0, maxResults)\n .map(({ rank: _rank, ...candidate }) => candidate)\n return { query, candidates, providerErrors, rejectedCandidates }\n}\n","import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { parseDocument, type Document } from 'yaml'\nimport { fail } from './errors.ts'\n\nexport const MANAGER_PACKAGE = 'relay-dsh-plugin-manager'\nconst STATE_VERSION = 1\nconst STATE_DIR = '.relay-plugin-manager'\n\nexport interface ProfileManifest {\n dependencies?: Record<string, string>\n dsh?: { profile?: { bundles?: string[] } }\n}\n\nexport interface ManagerState {\n version: 1\n disabled: Record<string, string[]>\n}\n\nexport interface PackageSurface {\n packageName: string\n source: string\n bundle: boolean\n bundlePatch: string | null\n client: boolean\n entryIds: string[] | null\n}\n\nexport interface LoaderEntrySnapshot {\n id: string\n name?: string\n disabled: boolean\n phase: string | null\n}\n\nexport interface PluginStatus {\n packageName: string\n source: string\n bundle: boolean\n enablement: 'enabled' | 'disabled' | 'mixed' | 'unknown'\n runtime: 'active' | 'inactive' | 'failed' | 'loading' | 'unknown'\n restartRequired: boolean\n entryIds: string[] | null\n}\n\nfunction readJsonObject<T extends object>(file: string, missing: T): T {\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return missing\n return parsed as T\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return missing\n fail('PROFILE_READ_FAILED', `Could not read ${file}: ${error instanceof Error ? error.message : String(error)}`)\n }\n}\n\nfunction atomicWrite(file: string, text: string): void {\n try {\n mkdirSync(dirname(file), { recursive: true, mode: 0o700 })\n const temporary = `${file}.tmp-${process.pid}-${Date.now()}`\n writeFileSync(temporary, text, { mode: 0o600 })\n renameSync(temporary, file)\n } catch (error) {\n fail('PROFILE_WRITE_FAILED', `Could not write ${file}: ${error instanceof Error ? error.message : String(error)}`)\n }\n}\n\nexport function writeProfileManifest(dir: string, manifest: ProfileManifest): void {\n atomicWrite(join(dir, 'package.json'), `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\nexport function reconcileRemovedPackage(dir: string, packageName: string): void {\n const manifest = readProfileManifest(dir)\n if (manifest.dependencies !== undefined) delete manifest.dependencies[packageName]\n const bundles = manifest.dsh?.profile?.bundles\n if (bundles !== undefined) manifest.dsh!.profile!.bundles = bundles.filter(name => name !== packageName)\n writeProfileManifest(dir, manifest)\n}\n\nexport function dshHome(env: NodeJS.ProcessEnv = process.env): string {\n const configured = env.DSH_HOME?.trim()\n return resolve(configured === undefined || configured === '' ? join(homedir(), '.dsh') : configured)\n}\n\nexport function profileDirectory(profile = 'web', env: NodeJS.ProcessEnv = process.env): string {\n return join(dshHome(env), 'profiles', profile)\n}\n\nexport function readProfileManifest(dir: string): ProfileManifest {\n return readJsonObject<ProfileManifest>(join(dir, 'package.json'), {})\n}\n\nexport function profileManifestText(dir: string): string | null {\n try {\n return readFileSync(join(dir, 'package.json'), 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null\n fail('PROFILE_READ_FAILED', `Could not read profile manifest: ${error instanceof Error ? error.message : String(error)}`)\n }\n}\n\nexport function restoreProfileManifest(dir: string, text: string | null): void {\n if (text === null) return\n atomicWrite(join(dir, 'package.json'), text)\n}\n\nfunction packageManifest(dir: string, packageName: string): Record<string, unknown> | null {\n const file = join(dir, 'node_modules', packageName, 'package.json')\n if (!existsSync(file)) return null\n return readJsonObject<Record<string, unknown>>(file, {})\n}\n\nexport function bundleEntryIds(dir: string, packageName: string, patch: string): string[] | null {\n try {\n const document = parseDocument(readFileSync(join(dir, 'node_modules', packageName, patch), 'utf8'))\n if (document.errors.length > 0 || !Array.isArray(document.toJS())) return null\n const ids: string[] = []\n for (const row of document.toJS() as unknown[]) {\n if (typeof row !== 'object' || row === null || Array.isArray(row)) continue\n const inserted = (row as { insert?: unknown }).insert\n if (!Array.isArray(inserted)) continue\n for (const entry of inserted) {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return null\n const id = (entry as { id?: unknown }).id\n if (typeof id !== 'string' || id.trim() === '') return null\n if (!ids.includes(id)) ids.push(id)\n }\n }\n return ids.length === 0 ? null : ids\n } catch {\n return null\n }\n}\n\nexport function packageSurface(dir: string, packageName: string, source: string): PackageSurface {\n const manifest = packageManifest(dir, packageName)\n const dsh = typeof manifest?.dsh === 'object' && manifest.dsh !== null && !Array.isArray(manifest.dsh)\n ? manifest.dsh as { bundle?: unknown; client?: unknown }\n : {}\n const bundle = typeof dsh.bundle === 'object' && dsh.bundle !== null && !Array.isArray(dsh.bundle)\n ? dsh.bundle as { patch?: unknown }\n : {}\n const patch = typeof bundle.patch === 'string' && bundle.patch.trim() !== '' ? bundle.patch : null\n return {\n packageName,\n source,\n bundle: patch !== null,\n bundlePatch: patch,\n client: dsh.client !== undefined,\n entryIds: patch === null ? null : bundleEntryIds(dir, packageName, patch),\n }\n}\n\nfunction statePath(dir: string): string {\n return join(dir, STATE_DIR, 'state.json')\n}\n\nexport function readManagerState(dir: string): ManagerState {\n const state = readJsonObject<Partial<ManagerState>>(statePath(dir), {})\n const disabled: Record<string, string[]> = {}\n if (state.version === STATE_VERSION && typeof state.disabled === 'object' && state.disabled !== null) {\n for (const [name, ids] of Object.entries(state.disabled)) {\n if (Array.isArray(ids) && ids.every(id => typeof id === 'string')) disabled[name] = [...new Set(ids)]\n }\n }\n return { version: STATE_VERSION, disabled }\n}\n\nfunction writeManagerState(dir: string, state: ManagerState): void {\n atomicWrite(statePath(dir), `${JSON.stringify(state, null, 2)}\\n`)\n}\n\nfunction patchDocument(file: string): Document.Parsed {\n let source = '[]\\n'\n try {\n source = readFileSync(file, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n fail('PROFILE_READ_FAILED', `Could not read profile patch: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n const document = parseDocument(source)\n if (document.errors.length > 0) fail('ENABLEMENT_CONFLICT', 'Profile cordis.patch.yml is not valid YAML.')\n const value = document.toJS()\n if (value === null) document.contents = document.createNode([]) as never\n else if (!Array.isArray(value)) fail('ENABLEMENT_CONFLICT', 'Profile cordis.patch.yml must contain a patch list.')\n return document\n}\n\nfunction exactDisabledRow(value: unknown, id: string): boolean {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const keys = Object.keys(value)\n return keys.length === 2 && (value as { id?: unknown }).id === id && (value as { disabled?: unknown }).disabled === true\n}\n\nexport function disablePackage(dir: string, surface: PackageSurface): string[] {\n if (surface.packageName === MANAGER_PACKAGE) fail('PROTECTED_PLUGIN', 'The plugin manager cannot disable itself.')\n if (surface.entryIds === null || surface.entryIds.length === 0) {\n fail('ENABLEMENT_UNSUPPORTED', `${surface.packageName} has no safely attributable Loader entry ids.`)\n }\n const file = join(dir, 'cordis.patch.yml')\n const state = readManagerState(dir)\n const document = patchDocument(file)\n const rows = document.toJS() as unknown[]\n const alreadyOwned = new Set(state.disabled[surface.packageName] ?? [])\n for (const id of surface.entryIds) {\n const existing = rows.find(row => typeof row === 'object' && row !== null && !Array.isArray(row)\n && (row as { id?: unknown }).id === id)\n if (existing !== undefined && !(alreadyOwned.has(id) && exactDisabledRow(existing, id))) {\n fail('ENABLEMENT_CONFLICT', `Profile patch already owns Loader entry \"${id}\"; it will not be overwritten.`)\n }\n if (existing === undefined) document.add({ id, disabled: true })\n }\n state.disabled[surface.packageName] = [...surface.entryIds]\n atomicWrite(file, document.toString())\n writeManagerState(dir, state)\n return [...surface.entryIds]\n}\n\nexport function enablePackage(dir: string, surface: PackageSurface): string[] {\n if (surface.packageName === MANAGER_PACKAGE) fail('PROTECTED_PLUGIN', 'The plugin manager cannot change its own enablement.')\n const state = readManagerState(dir)\n const owned = state.disabled[surface.packageName]\n if (owned === undefined || owned.length === 0) return []\n const file = join(dir, 'cordis.patch.yml')\n const document = patchDocument(file)\n const rows = document.toJS() as unknown[]\n for (const id of owned) {\n const matching = rows.filter(row => typeof row === 'object' && row !== null && !Array.isArray(row)\n && (row as { id?: unknown }).id === id)\n if (matching.some(row => !exactDisabledRow(row, id))) {\n fail('ENABLEMENT_CONFLICT', `Manager-owned Loader entry \"${id}\" was modified and will not be removed.`)\n }\n }\n const keep = rows.filter(row => !owned.some(id => exactDisabledRow(row, id)))\n document.contents = document.createNode(keep) as never\n delete state.disabled[surface.packageName]\n atomicWrite(file, document.toString())\n writeManagerState(dir, state)\n return [...owned]\n}\n\nfunction runtimeState(entries: LoaderEntrySnapshot[]): PluginStatus['runtime'] {\n const phases = entries.map(entry => entry.phase)\n if (phases.includes('failed')) return 'failed'\n if (phases.includes('active')) return 'active'\n if (phases.some(phase => phase === 'loading' || phase === 'pending')) return 'loading'\n if (entries.length > 0) return 'inactive'\n return 'unknown'\n}\n\nexport function listPluginStatuses(dir: string, loaderEntries: readonly LoaderEntrySnapshot[] = []): PluginStatus[] {\n const manifest = readProfileManifest(dir)\n const bundles = new Set(manifest.dsh?.profile?.bundles ?? [])\n const state = readManagerState(dir)\n return Object.entries(manifest.dependencies ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(([packageName, source]) => {\n const surface = packageSurface(dir, packageName, source)\n const ids = surface.entryIds\n const entries = ids === null ? [] : loaderEntries.filter(entry => ids.includes(entry.id))\n let enablement: PluginStatus['enablement'] = 'unknown'\n if (ids !== null) {\n const disabledIds = new Set(state.disabled[packageName] ?? [])\n const disabled = ids.filter(id => disabledIds.has(id) || entries.some(entry => entry.id === id && entry.disabled)).length\n enablement = disabled === 0 ? 'enabled' : disabled === ids.length ? 'disabled' : 'mixed'\n }\n const runtime = runtimeState(entries)\n return {\n packageName,\n source,\n bundle: bundles.has(packageName) || surface.bundle,\n enablement,\n runtime,\n restartRequired: surface.bundle && runtime === 'unknown' && !state.disabled[packageName],\n entryIds: ids,\n }\n })\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { fail } from './errors.ts'\n\nexport type MutationAction = 'install' | 'remove' | 'update' | 'enable' | 'disable' | 'restart'\n\nexport interface PlanInput {\n action: MutationAction\n profile: 'web'\n packageName?: string\n installSpec?: string\n currentSource?: string\n impact: string\n restartExpected: boolean\n}\n\nexport interface ConfirmationPlan extends PlanInput {\n id: string\n digest: string\n confirmationToken: string\n createdAt: string\n expiresAt: string\n}\n\nexport interface PlanStoreOptions {\n now?: () => number\n random?: () => string\n ttlMs?: number\n}\n\nexport class PlanStore {\n private readonly plans = new Map<string, ConfirmationPlan>()\n private readonly used = new Set<string>()\n private readonly now: () => number\n private readonly random: () => string\n private readonly ttlMs: number\n\n constructor(options: PlanStoreOptions = {}) {\n this.now = options.now ?? Date.now\n this.random = options.random ?? randomUUID\n this.ttlMs = options.ttlMs ?? 10 * 60_000\n }\n\n create(input: PlanInput): ConfirmationPlan {\n const created = this.now()\n const id = this.random()\n const confirmationToken = this.random()\n const digest = createHash('sha256').update(JSON.stringify({ id, ...input })).digest('hex')\n const plan = Object.freeze({\n ...input,\n id,\n digest,\n confirmationToken,\n createdAt: new Date(created).toISOString(),\n expiresAt: new Date(created + this.ttlMs).toISOString(),\n })\n this.plans.set(confirmationToken, plan)\n return plan\n }\n\n consume(token: string): ConfirmationPlan {\n if (this.used.has(token)) fail('CONFIRMATION_REPLAYED', 'Confirmation token has already been used.')\n const plan = this.plans.get(token)\n if (plan === undefined) fail('CONFIRMATION_REQUIRED', 'A valid confirmation token is required.')\n this.plans.delete(token)\n this.used.add(token)\n if (this.now() >= Date.parse(plan.expiresAt)) fail('CONFIRMATION_EXPIRED', 'Confirmation token has expired.')\n return plan\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { fail } from './errors.ts'\nimport type { MutationAction } from './plans.ts'\n\nexport type OperationStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled'\n\nexport interface OperationSnapshot<T = unknown> {\n id: string\n action: MutationAction\n target: string\n status: OperationStatus\n progress: string\n startedAt: string\n finishedAt?: string\n result?: T\n error?: { code?: string; message: string }\n}\n\ninterface OperationRecord<T> {\n snapshot: OperationSnapshot<T>\n controller: AbortController\n done: Promise<void>\n}\n\nexport interface OperationContext {\n signal: AbortSignal\n progress(message: string): void\n}\n\nexport class OperationTracker {\n private readonly records = new Map<string, OperationRecord<unknown>>()\n private active: string | null = null\n private readonly random: () => string\n private readonly now: () => number\n\n constructor(options: { random?: () => string; now?: () => number } = {}) {\n this.random = options.random ?? randomUUID\n this.now = options.now ?? Date.now\n }\n\n start<T>(\n action: MutationAction,\n target: string,\n execute: (context: OperationContext) => Promise<T>,\n ): OperationSnapshot<T> {\n if (this.active !== null) fail('OPERATION_BUSY', `Plugin operation ${this.active} is still running.`)\n const id = this.random()\n const controller = new AbortController()\n const snapshot: OperationSnapshot<T> = {\n id,\n action,\n target,\n status: 'queued',\n progress: 'queued',\n startedAt: new Date(this.now()).toISOString(),\n }\n const record: OperationRecord<T> = { snapshot, controller, done: Promise.resolve() }\n this.records.set(id, record as OperationRecord<unknown>)\n this.active = id\n record.done = Promise.resolve().then(async () => {\n snapshot.status = 'running'\n snapshot.progress = 'running'\n try {\n const result = await execute({\n signal: controller.signal,\n progress: message => { snapshot.progress = message.slice(0, 500) },\n })\n if (controller.signal.aborted) {\n snapshot.status = 'cancelled'\n snapshot.progress = 'cancelled'\n } else {\n snapshot.status = 'succeeded'\n snapshot.progress = 'completed'\n snapshot.result = result\n }\n } catch (error) {\n if (controller.signal.aborted) {\n snapshot.status = 'cancelled'\n snapshot.progress = 'cancelled'\n } else {\n snapshot.status = 'failed'\n snapshot.progress = 'failed'\n snapshot.error = {\n ...typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string'\n ? { code: error.code }\n : {},\n message: error instanceof Error ? error.message : String(error),\n }\n }\n } finally {\n snapshot.finishedAt = new Date(this.now()).toISOString()\n if (this.active === id) this.active = null\n }\n })\n return structuredClone(snapshot)\n }\n\n get(id: string): OperationSnapshot {\n const record = this.records.get(id)\n if (record === undefined) fail('OPERATION_NOT_FOUND', `Plugin operation ${id} was not found.`)\n return structuredClone(record.snapshot)\n }\n\n cancel(id: string): OperationSnapshot {\n const record = this.records.get(id)\n if (record === undefined) fail('OPERATION_NOT_FOUND', `Plugin operation ${id} was not found.`)\n if (record.snapshot.status === 'queued' || record.snapshot.status === 'running') {\n record.snapshot.progress = 'cancelling'\n record.controller.abort(new Error('Plugin operation cancelled by user.'))\n }\n return structuredClone(record.snapshot)\n }\n\n async wait(id: string): Promise<OperationSnapshot> {\n const record = this.records.get(id)\n if (record === undefined) fail('OPERATION_NOT_FOUND', `Plugin operation ${id} was not found.`)\n await record.done\n return this.get(id)\n }\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { PluginSearchRuntime } from './search-runtime.ts'\nimport { searchPlugins, type SearchOptions, type SearchResult } from './search.ts'\nimport {\n inspectPluginSource,\n NPM_NAME,\n parseGithubSpec,\n parseNpmSpec,\n renderSource,\n type FetchOptions,\n type PluginInspection,\n} from './source.ts'\nimport {\n disablePackage,\n enablePackage,\n listPluginStatuses,\n packageSurface,\n profileManifestText,\n readProfileManifest,\n reconcileRemovedPackage,\n restoreProfileManifest,\n type LoaderEntrySnapshot,\n type PackageSurface,\n type PluginStatus,\n} from './profile.ts'\nimport { PlanStore, type ConfirmationPlan, type MutationAction } from './plans.ts'\nimport { OperationTracker, type OperationSnapshot } from './operations.ts'\nimport type { DshCliRunner, RunnerResult } from './runner.ts'\nimport type { HotRuntime, HotActivationResult } from './hot-runtime.ts'\nimport type { DshRestarter } from './restart.ts'\nimport { fail } from './errors.ts'\n\ninterface LoaderEntryLike {\n id?: string\n disabled?: boolean\n options?: { id?: string; name?: string }\n fiber?: { state?: number | string }\n}\n\ninterface LoaderLike {\n entries(): Iterable<LoaderEntryLike>\n}\n\nexport interface PluginManagerDependencies {\n profileDir: string\n searchRuntime: Pick<PluginSearchRuntime, 'entries'>\n runner: Pick<DshCliRunner, 'runPlugin'>\n hot: Pick<HotRuntime, 'activate' | 'deactivate' | 'isActive'>\n restarter: Pick<DshRestarter, 'available' | 'schedule'>\n loader?: LoaderLike\n inspect?: typeof inspectPluginSource\n plans?: PlanStore\n operations?: OperationTracker\n fetchOptions?: Omit<FetchOptions, 'signal'>\n hmrTimeoutMs?: number\n}\n\nexport interface DiscoverRequest {\n action: 'list' | 'search' | 'inspect' | 'status'\n query?: string\n target?: string\n operationId?: string\n maxResults?: number\n}\n\nexport interface PlanRequest {\n operation: MutationAction\n target?: string\n source?: string\n}\n\nexport interface MutationResult {\n action: MutationAction\n packageName?: string\n installSpec?: string\n changed: boolean\n activated?: boolean\n restartRequired: boolean\n reason?: string\n command?: { exitCode: number; stdout: string; stderr: string }\n restart?: { helperPid: number | undefined; logFile: string }\n}\n\nconst FIBER_PHASE: Record<number, string | null> = {\n 0: 'pending',\n 1: 'loading',\n 2: 'active',\n 3: 'failed',\n 4: null,\n 5: 'unloading',\n}\n\nconst PROTECTED_ENTRY_IDS = new Set([\n 'relay-plugin-search-runtime',\n 'relay-plugin-manager-host',\n 'commands',\n 'tools',\n 'webserver',\n 'web-runtime',\n])\n\nfunction safePackageName(value: string | undefined): string {\n const name = value?.trim() ?? ''\n if (!NPM_NAME.test(name)) fail('INVALID_NPM_SPEC', 'A valid installed package name is required.')\n return name\n}\n\nfunction commandResult(result: RunnerResult): MutationResult['command'] {\n return { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr }\n}\n\nfunction installedPackageManifest(profileDir: string, packageName: string): { name?: unknown; version?: unknown } | null {\n try {\n return JSON.parse(readFileSync(join(profileDir, 'node_modules', packageName, 'package.json'), 'utf8')) as {\n name?: unknown\n version?: unknown\n }\n } catch {\n return null\n }\n}\n\nfunction installedSourceMatches(packageName: string, dependency: string, installSpec: string): boolean {\n const github = parseGithubSpec(installSpec, true)\n if (github !== null) return dependency === installSpec\n const npm = parseNpmSpec(installSpec, true)\n return npm.package === packageName && dependency === npm.version\n}\n\nexport class PluginManager {\n private readonly profileDir: string\n private readonly searchRuntime: PluginManagerDependencies['searchRuntime']\n private readonly runner: PluginManagerDependencies['runner']\n private readonly hot: PluginManagerDependencies['hot']\n private readonly restarter: PluginManagerDependencies['restarter']\n private readonly loader?: LoaderLike\n private readonly inspect: typeof inspectPluginSource\n private readonly plans: PlanStore\n private readonly operations: OperationTracker\n private readonly fetchOptions: Omit<FetchOptions, 'signal'>\n private readonly hmrTimeoutMs: number\n\n constructor(dependencies: PluginManagerDependencies) {\n this.profileDir = dependencies.profileDir\n this.searchRuntime = dependencies.searchRuntime\n this.runner = dependencies.runner\n this.hot = dependencies.hot\n this.restarter = dependencies.restarter\n this.loader = dependencies.loader\n this.inspect = dependencies.inspect ?? inspectPluginSource\n this.plans = dependencies.plans ?? new PlanStore()\n this.operations = dependencies.operations ?? new OperationTracker()\n this.fetchOptions = dependencies.fetchOptions ?? {}\n this.hmrTimeoutMs = dependencies.hmrTimeoutMs ?? 5_000\n }\n\n private loaderEntries(): LoaderEntrySnapshot[] {\n if (this.loader === undefined) return []\n return [...this.loader.entries()].flatMap((entry) => {\n const id = entry.options?.id ?? entry.id\n if (id === undefined || id === '') return []\n const rawPhase = entry.fiber?.state\n const phase = typeof rawPhase === 'number' ? (FIBER_PHASE[rawPhase] ?? 'unknown') : rawPhase ?? null\n return [{\n id,\n ...(entry.options?.name === undefined ? {} : { name: entry.options.name }),\n disabled: entry.disabled === true,\n phase,\n }]\n })\n }\n\n list(): PluginStatus[] {\n return listPluginStatuses(this.profileDir, this.loaderEntries())\n }\n\n async discover(request: DiscoverRequest, signal?: AbortSignal): Promise<unknown> {\n if (request.action === 'list') return { profile: 'web', plugins: this.list() }\n if (request.action === 'search') {\n const options: SearchOptions = {\n ...this.fetchOptions,\n signal,\n maxResults: request.maxResults,\n inspect: this.inspect,\n }\n return await searchPlugins(this.searchRuntime, request.query ?? '', options)\n }\n if (request.action === 'inspect') {\n if (request.target === undefined) fail('INVALID_SOURCE', 'A plugin source is required for inspection.')\n return await this.inspect(request.target, { ...this.fetchOptions, signal })\n }\n if (request.operationId !== undefined) return this.operations.get(request.operationId)\n if (request.target === undefined) return { profile: 'web', plugins: this.list() }\n const name = safePackageName(request.target)\n const status = this.list().find(plugin => plugin.packageName === name)\n if (status === undefined) fail('PLUGIN_NOT_INSTALLED', `${name} is not installed in the web profile.`)\n return status\n }\n\n private installed(name: string): { source: string; surface: PackageSurface } {\n const source = readProfileManifest(this.profileDir).dependencies?.[name]\n if (source === undefined) fail('PLUGIN_NOT_INSTALLED', `${name} is not installed in the web profile.`)\n return { source, surface: packageSurface(this.profileDir, name, source) }\n }\n\n private assertEnablementAllowed(surface: PackageSurface): void {\n if (surface.entryIds?.some(id => PROTECTED_ENTRY_IDS.has(id)) === true) {\n fail('PROTECTED_PLUGIN', `${surface.packageName} owns protected DSH infrastructure and cannot be toggled.`)\n }\n }\n\n private async updateInspection(name: string, sourceOverride: string | undefined, signal?: AbortSignal): Promise<PluginInspection> {\n if (sourceOverride !== undefined) {\n const inspection = await this.inspect(sourceOverride, { ...this.fetchOptions, signal })\n if (inspection.packageName !== name) fail('PACKAGE_NAME_MISMATCH', 'Update source resolves to a different package name.')\n return inspection\n }\n const current = this.installed(name).source\n const github = parseGithubSpec(current)\n const source = github === null\n ? name\n : renderSource({ kind: 'github', owner: github.owner, repo: github.repo })\n return await this.inspect(source, { ...this.fetchOptions, signal })\n }\n\n async plan(request: PlanRequest, signal?: AbortSignal): Promise<ConfirmationPlan> {\n if (request.operation === 'restart') {\n if (!this.restarter.available()) fail('RESTART_UNAVAILABLE', 'Automatic restart is unavailable in this deployment.')\n return this.plans.create({\n action: 'restart', profile: 'web', impact: 'Restart the running DSH process.', restartExpected: true,\n })\n }\n if (request.operation === 'install') {\n const source = request.source ?? request.target\n if (source === undefined) fail('INVALID_SOURCE', 'Install requires an npm or GitHub source.')\n const inspection = await this.inspect(source, { ...this.fetchOptions, signal })\n if (readProfileManifest(this.profileDir).dependencies?.[inspection.packageName] !== undefined) {\n fail('PLUGIN_ALREADY_INSTALLED', `${inspection.packageName} is already installed; use update.`)\n }\n return this.plans.create({\n action: 'install', profile: 'web', packageName: inspection.packageName,\n installSpec: inspection.installSpec,\n impact: `Install ${inspection.packageName} from ${inspection.installSpec}.`,\n restartExpected: inspection.bundlePatch !== null,\n })\n }\n const name = safePackageName(request.target)\n const installed = this.installed(name)\n if (request.operation === 'update') {\n const inspection = await this.updateInspection(name, request.source, signal)\n return this.plans.create({\n action: 'update', profile: 'web', packageName: name, currentSource: installed.source,\n installSpec: inspection.installSpec,\n impact: `Update ${name} from ${installed.source} to ${inspection.installSpec}.`,\n restartExpected: true,\n })\n }\n if (request.operation === 'enable' || request.operation === 'disable') {\n this.assertEnablementAllowed(installed.surface)\n if (installed.surface.entryIds === null) {\n fail('ENABLEMENT_UNSUPPORTED', `${name} has no safely attributable Loader entries.`)\n }\n }\n return this.plans.create({\n action: request.operation,\n profile: 'web',\n packageName: name,\n currentSource: installed.source,\n impact: request.operation === 'disable'\n ? `Disable ${name}. Conversations currently using capabilities from this plugin may be interrupted; confirm from another backend or session when continuity matters.`\n : `${request.operation[0]!.toUpperCase()}${request.operation.slice(1)} ${name}.`,\n restartExpected: request.operation === 'remove',\n })\n }\n\n execute(confirmationToken: string): OperationSnapshot {\n const plan = this.plans.consume(confirmationToken)\n const dependencies = readProfileManifest(this.profileDir).dependencies ?? {}\n if (plan.action === 'install' && plan.packageName !== undefined && dependencies[plan.packageName] !== undefined) {\n fail('PLAN_STALE', `${plan.packageName} was installed after this plan was created; create a new plan.`)\n }\n if (plan.action !== 'install' && plan.action !== 'restart' && plan.packageName !== undefined\n && dependencies[plan.packageName] !== plan.currentSource) {\n fail('PLAN_STALE', `${plan.packageName} changed after this plan was created; create a new plan.`)\n }\n const target = plan.packageName ?? 'dsh'\n return this.operations.start(plan.action, target, async context => {\n if (plan.action === 'restart') {\n context.progress('scheduling restart')\n const restart = this.restarter.schedule()\n return { action: 'restart', changed: true, restartRequired: false, restart } satisfies MutationResult\n }\n if (plan.packageName === undefined) fail('POSTCONDITION_FAILED', 'Mutation plan has no package name.')\n if (plan.action === 'install' || plan.action === 'update') {\n if (plan.installSpec === undefined) fail('POSTCONDITION_FAILED', 'Install/update plan has no immutable source.')\n return await this.installOrUpdate(plan.action, plan.packageName, plan.installSpec, context)\n }\n if (plan.action === 'remove') return await this.remove(plan.packageName, context)\n return await this.toggle(plan.action, plan.packageName, context)\n })\n }\n\n operation(id: string): OperationSnapshot {\n return this.operations.get(id)\n }\n\n cancel(id: string): OperationSnapshot {\n return this.operations.cancel(id)\n }\n\n wait(id: string): Promise<OperationSnapshot> {\n return this.operations.wait(id)\n }\n\n private async installOrUpdate(\n action: 'install' | 'update',\n packageName: string,\n installSpec: string,\n context: { signal: AbortSignal; progress(message: string): void },\n ): Promise<MutationResult> {\n const before = profileManifestText(this.profileDir)\n context.progress(`${action}: running official DSH plugin command`)\n const result = await this.runner.runPlugin('web', ['add', '--save-exact', installSpec], context.signal, context.progress)\n if (result.exitCode !== 0 || result.timedOut || result.cancelled) {\n restoreProfileManifest(this.profileDir, before)\n fail('DSH_COMMAND_FAILED', `Official DSH plugin command failed with exit code ${result.exitCode}.`, commandResult(result))\n }\n const manifest = readProfileManifest(this.profileDir)\n const dependency = manifest.dependencies?.[packageName]\n const surface = dependency === undefined ? null : packageSurface(this.profileDir, packageName, dependency)\n const installedManifest = installedPackageManifest(this.profileDir, packageName)\n const bundleCount = manifest.dsh?.profile?.bundles?.filter(name => name === packageName).length ?? 0\n const validSurface = surface !== null && (surface.bundle || surface.client)\n const validBundleMembership = surface !== null && (surface.bundle ? bundleCount === 1 : bundleCount === 0)\n const validIdentity = installedManifest?.name === packageName\n const validSource = dependency !== undefined && installedSourceMatches(packageName, dependency, installSpec)\n const npmSource = parseGithubSpec(installSpec, true) === null ? parseNpmSpec(installSpec, true) : null\n const validVersion = npmSource === null || installedManifest?.version === npmSource.version\n if (!validSource || !validSurface || !validBundleMembership || !validIdentity || !validVersion) {\n restoreProfileManifest(this.profileDir, before)\n fail('POSTCONDITION_FAILED', `Official command completed but ${packageName} did not satisfy profile postconditions.`)\n }\n let activation: HotActivationResult\n if (action === 'update') {\n activation = { active: false, restartRequired: true, reason: 'Updated bundles activate after DSH restart.' }\n } else {\n context.progress('install: attempting restart-free activation')\n activation = await this.hot.activate(surface)\n }\n return {\n action,\n packageName,\n installSpec,\n changed: true,\n activated: activation.active,\n restartRequired: activation.restartRequired,\n ...(activation.reason === null ? {} : { reason: activation.reason }),\n command: commandResult(result),\n }\n }\n\n private async remove(\n packageName: string,\n context: { signal: AbortSignal; progress(message: string): void },\n ): Promise<MutationResult> {\n this.installed(packageName)\n const before = profileManifestText(this.profileDir)\n const wasHot = this.hot.isActive(packageName)\n context.progress('remove: running official DSH plugin command')\n const result = await this.runner.runPlugin('web', ['remove', packageName], context.signal, context.progress)\n const packageExists = existsSync(join(this.profileDir, 'node_modules', packageName, 'package.json'))\n if (result.exitCode !== 0 || result.timedOut || result.cancelled) {\n if (!result.cancelled && !packageExists) reconcileRemovedPackage(this.profileDir, packageName)\n else restoreProfileManifest(this.profileDir, before)\n if (packageExists || result.cancelled) {\n fail('DSH_COMMAND_FAILED', `Official DSH plugin remove failed with exit code ${result.exitCode}.`, commandResult(result))\n }\n }\n const manifest = readProfileManifest(this.profileDir)\n const remains = manifest.dependencies?.[packageName] !== undefined\n || manifest.dsh?.profile?.bundles?.includes(packageName) === true\n if (remains) fail('POSTCONDITION_FAILED', `${packageName} remains in the profile after removal.`)\n const deactivated = wasHot ? await this.hot.deactivate(packageName) : false\n return {\n action: 'remove',\n packageName,\n changed: true,\n activated: false,\n restartRequired: !deactivated,\n ...deactivated ? {} : { reason: 'A boot-loaded plugin remains in the current process until DSH restarts.' },\n command: commandResult(result),\n }\n }\n\n private async toggle(\n action: 'enable' | 'disable',\n packageName: string,\n context: { signal: AbortSignal; progress(message: string): void },\n ): Promise<MutationResult> {\n const { surface } = this.installed(packageName)\n this.assertEnablementAllowed(surface)\n context.progress(`${action}: updating profile patch`)\n const ids = action === 'disable' ? disablePackage(this.profileDir, surface) : enablePackage(this.profileDir, surface)\n if (action === 'disable' && this.hot.isActive(packageName)) await this.hot.deactivate(packageName)\n if (action === 'enable' && !this.loaderEntries().some(entry => surface.entryIds?.includes(entry.id))) {\n const activation = await this.hot.activate(surface)\n return {\n action, packageName, changed: ids.length > 0, activated: activation.active,\n restartRequired: activation.restartRequired,\n ...(activation.reason === null ? {} : { reason: activation.reason }),\n }\n }\n const expectedDisabled = action === 'disable'\n const deadline = Date.now() + this.hmrTimeoutMs\n let verified = false\n while (Date.now() < deadline && !context.signal.aborted) {\n const relevant = this.loaderEntries().filter(entry => surface.entryIds?.includes(entry.id))\n if (relevant.length > 0 && relevant.every(entry => entry.disabled === expectedDisabled)) {\n verified = true\n break\n }\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n return {\n action,\n packageName,\n changed: ids.length > 0,\n activated: action === 'enable' && verified,\n restartRequired: !verified,\n ...verified ? {} : { reason: 'Loader HMR state could not be verified; restart is required.' },\n }\n }\n}\n\nexport type { SearchResult }\n","import type { PluginSearchProvider } from './search-runtime.ts'\nimport { NPM_NAME } from './source.ts'\n\nconst MAX_PROVIDER_RESULTS = 12\n\nfunction query(value: string): string {\n const normalized = value.trim()\n if (normalized === '' || normalized.length > 120 || /[\\u0000-\\u001f\\u007f]/u.test(normalized)) {\n throw new Error('Search query must contain 1 to 120 printable characters.')\n }\n return normalized\n}\n\nexport function npmSearchProvider(fetchImpl: typeof globalThis.fetch = globalThis.fetch): PluginSearchProvider {\n return {\n id: 'npm',\n async search(request) {\n const text = query(request.query)\n const response = await fetchImpl(\n `https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(`${text} keywords:dsh-plugin`)}&size=${Math.min(request.maxResults, MAX_PROVIDER_RESULTS)}`,\n { signal: request.signal, headers: { accept: 'application/json' } },\n )\n if (!response.ok) throw new Error(`npm search returned HTTP ${response.status}`)\n const data = await response.json() as { objects?: Array<{ package?: { name?: unknown; description?: unknown; links?: { homepage?: unknown; repository?: unknown } }; score?: { final?: unknown } }> }\n const searched = (data.objects ?? []).flatMap((entry) => {\n const name = entry.package?.name\n if (typeof name !== 'string' || !NPM_NAME.test(name)) return []\n return [{\n id: `npm:${name}`,\n title: name,\n ...(typeof entry.package?.description === 'string' ? { description: entry.package.description } : {}),\n ...(typeof entry.package?.links?.homepage === 'string' ? { homepage: entry.package.links.homepage } : {}),\n ...(typeof entry.package?.links?.repository === 'string' ? { repository: entry.package.links.repository } : {}),\n sources: [{ kind: 'npm' as const, package: name }],\n ...(typeof entry.score?.final === 'number' ? { score: entry.score.final } : {}),\n }]\n })\n if (!NPM_NAME.test(text) || searched.some(candidate => candidate.sources.some(source => source.kind === 'npm' && source.package === text))) {\n return searched\n }\n return [{\n id: `npm:${text}`,\n title: text,\n sources: [{ kind: 'npm' as const, package: text }],\n score: Number.MAX_SAFE_INTEGER,\n evidence: ['Exact npm package-name query'],\n }, ...searched]\n },\n }\n}\n\nexport function githubSearchProvider(\n fetchImpl: typeof globalThis.fetch = globalThis.fetch,\n env: NodeJS.ProcessEnv = process.env,\n): PluginSearchProvider {\n return {\n id: 'github',\n async search(request) {\n const text = query(request.query)\n const token = env.GITHUB_TOKEN ?? env.GH_TOKEN\n const response = await fetchImpl(\n `https://api.github.com/search/repositories?q=${encodeURIComponent(`${text} topic:dsh-plugin`)}&per_page=${Math.min(request.maxResults, MAX_PROVIDER_RESULTS)}`,\n {\n signal: request.signal,\n headers: {\n accept: 'application/vnd.github+json',\n 'user-agent': 'relay-dsh-plugin-manager',\n 'x-github-api-version': '2022-11-28',\n ...(token === undefined || token === '' ? {} : { authorization: `Bearer ${token}` }),\n },\n },\n )\n if (!response.ok) throw new Error(`GitHub search returned HTTP ${response.status}`)\n const data = await response.json() as { items?: Array<{ id?: unknown; full_name?: unknown; description?: unknown; html_url?: unknown; stargazers_count?: unknown }> }\n return (data.items ?? []).flatMap((entry) => {\n if (typeof entry.full_name !== 'string') return []\n const [owner, repo, ...extra] = entry.full_name.split('/')\n if (owner === undefined || repo === undefined || extra.length > 0) return []\n return [{\n id: `github:${entry.id ?? entry.full_name}`,\n title: entry.full_name,\n ...(typeof entry.description === 'string' ? { description: entry.description } : {}),\n ...(typeof entry.html_url === 'string' ? { homepage: entry.html_url, repository: entry.html_url } : {}),\n sources: [{ kind: 'github' as const, owner, repo }],\n ...(typeof entry.stargazers_count === 'number' ? { score: entry.stargazers_count } : {}),\n evidence: [`GitHub stars: ${String(entry.stargazers_count ?? 0)}`],\n }]\n })\n },\n }\n}\n","import { spawn } from 'node:child_process'\nimport { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { writeFileSync } from 'node:fs'\nimport { fail } from './errors.ts'\n\nexport function detectedSupervisor(env: NodeJS.ProcessEnv = process.env, ppid = process.ppid): string | null {\n const systemd = (env.INVOCATION_ID ?? '') !== '' || (env.JOURNAL_STREAM ?? '') !== ''\n return systemd && ppid === 1 ? 'systemd' : null\n}\n\nexport function restartAllowed(\n allowRestart: boolean | undefined,\n env: NodeJS.ProcessEnv = process.env,\n ppid = process.ppid,\n): boolean {\n if (allowRestart !== undefined) return allowRestart\n return detectedSupervisor(env, ppid) === null\n}\n\nexport interface RestarterOptions {\n allowRestart?: boolean\n env?: NodeJS.ProcessEnv\n argv?: string[]\n execPath?: string\n cwd?: string\n ppid?: number\n spawn?: typeof spawn\n terminate?: () => void\n}\n\nexport class DshRestarter {\n private readonly options: RestarterOptions\n\n constructor(options: RestarterOptions = {}) {\n this.options = options\n }\n\n available(): boolean {\n return restartAllowed(this.options.allowRestart, this.options.env, this.options.ppid)\n }\n\n schedule(): { helperPid: number | undefined; logFile: string } {\n if (!this.available()) fail('RESTART_UNAVAILABLE', 'Automatic restart is disabled or owned by the process supervisor.')\n const argv = this.options.argv ?? process.argv\n if (argv[1] === undefined) fail('RESTART_UNAVAILABLE', 'The current DSH entry point cannot be identified.')\n const execPath = this.options.execPath ?? process.execPath\n const cwd = this.options.cwd ?? process.cwd()\n const env = this.options.env ?? process.env\n const logFile = join(tmpdir(), `relay-dsh-plugin-manager-restart-${Date.now()}.log`)\n const source = [\n \"const { spawn } = require('node:child_process')\",\n \"const fs = require('node:fs')\",\n 'setTimeout(() => {',\n ` const out = fs.openSync(${JSON.stringify(logFile)}, 'a')`,\n ` const child = spawn(${JSON.stringify(execPath)}, ${JSON.stringify(argv.slice(1))}, {`,\n ` cwd: ${JSON.stringify(cwd)}, env: process.env, detached: true, stdio: ['ignore', out, out]`,\n ' })',\n \" child.on('error', error => fs.appendFileSync(\" + JSON.stringify(logFile) + \", String(error) + '\\\\n'))\",\n ' child.unref()',\n '}, 1200)',\n ].join('\\n')\n writeFileSync(logFile, '', { flag: 'a', mode: 0o600 })\n const helper = (this.options.spawn ?? spawn)(execPath, ['-e', source], {\n detached: true,\n stdio: 'ignore',\n env,\n })\n helper.unref()\n setTimeout(this.options.terminate ?? (() => process.kill(process.pid, 'SIGTERM')), 500).unref()\n return { helperPid: helper.pid, logFile }\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { existsSync, realpathSync } from 'node:fs'\n\nexport interface DshLaunch {\n file: string\n prefix: string[]\n cwd: string\n shell: boolean\n}\n\nexport interface RunnerResult {\n exitCode: number\n signal: NodeJS.Signals | null\n stdout: string\n stderr: string\n cancelled: boolean\n timedOut: boolean\n}\n\nexport interface RunnerOptions {\n env?: NodeJS.ProcessEnv\n argv?: string[]\n execPath?: string\n cwd?: string\n platform?: NodeJS.Platform\n spawn?: typeof spawn\n timeoutMs?: number\n maxOutputBytes?: number\n}\n\nexport function resolveDshLaunch(options: RunnerOptions = {}): DshLaunch {\n const env = options.env ?? process.env\n const argv = options.argv ?? process.argv\n const execPath = options.execPath ?? process.execPath\n const cwd = options.cwd ?? process.cwd()\n const platform = options.platform ?? process.platform\n const configured = env.DSH_EXECUTABLE?.trim()\n let file: string\n let prefix: string[]\n if (configured !== undefined && configured !== '') {\n file = configured\n prefix = []\n } else if (argv[1] !== undefined && existsSync(argv[1])) {\n file = execPath\n prefix = [realpathSync(argv[1])]\n } else {\n file = 'dsh'\n prefix = []\n }\n return {\n file,\n prefix,\n cwd,\n shell: platform === 'win32' && /\\.(?:cmd|bat)$/iu.test(file),\n }\n}\n\nfunction boundedAppend(current: string, chunk: Buffer | string, maxBytes: number): string {\n const combined = current + chunk.toString()\n return Buffer.byteLength(combined) <= maxBytes ? combined : combined.slice(-maxBytes)\n}\n\nexport class DshCliRunner {\n private readonly options: RunnerOptions\n\n constructor(options: RunnerOptions = {}) {\n this.options = options\n }\n\n runPlugin(\n profile: string,\n args: readonly string[],\n signal: AbortSignal,\n progress: (message: string) => void = () => undefined,\n ): Promise<RunnerResult> {\n const launch = resolveDshLaunch(this.options)\n const spawnImpl = this.options.spawn ?? spawn\n const timeoutMs = this.options.timeoutMs ?? 5 * 60_000\n const maxOutput = this.options.maxOutputBytes ?? 64 * 1024\n return new Promise((resolve, reject) => {\n let child: ChildProcess\n try {\n child = spawnImpl(\n launch.file,\n [...launch.prefix, 'plugin', '--profile', profile, ...args],\n {\n cwd: launch.cwd,\n env: this.options.env ?? process.env,\n shell: launch.shell,\n stdio: ['ignore', 'pipe', 'pipe'],\n },\n )\n } catch (error) {\n reject(error)\n return\n }\n let stdout = ''\n let stderr = ''\n let timedOut = false\n let cancelled = false\n let settled = false\n const terminate = (reason: 'timeout' | 'cancel'): void => {\n if (reason === 'timeout') timedOut = true\n else cancelled = true\n child.kill('SIGTERM')\n setTimeout(() => { if (!settled) child.kill('SIGKILL') }, 2_000).unref()\n }\n const timer = setTimeout(() => terminate('timeout'), timeoutMs)\n const onAbort = (): void => terminate('cancel')\n if (signal.aborted) onAbort()\n else signal.addEventListener('abort', onAbort, { once: true })\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout = boundedAppend(stdout, chunk, maxOutput)\n progress(chunk.toString().trim().slice(-500))\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr = boundedAppend(stderr, chunk, maxOutput)\n progress(chunk.toString().trim().slice(-500))\n })\n child.once('error', (error) => {\n clearTimeout(timer)\n signal.removeEventListener('abort', onAbort)\n settled = true\n reject(error)\n })\n child.once('close', (code, closeSignal) => {\n clearTimeout(timer)\n signal.removeEventListener('abort', onAbort)\n settled = true\n resolve({\n exitCode: code ?? 1,\n signal: closeSignal,\n stdout,\n stderr,\n cancelled,\n timedOut,\n })\n })\n })\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport '@deepseek-ai/cordis-plugin-loader'\nimport { registerConversationSurface } from './conversation.ts'\nimport { HotRuntime } from './hot-runtime.ts'\nimport { PluginManager } from './manager.ts'\nimport { profileDirectory } from './profile.ts'\nimport { githubSearchProvider, npmSearchProvider } from './providers.ts'\nimport { DshRestarter } from './restart.ts'\nimport { DshCliRunner } from './runner.ts'\n\nexport const name = 'relay-dsh-plugin-manager'\nexport const inject = ['pluginSearch', 'tools', 'commands', 'loader']\n\nexport interface Config {\n allowRestart?: boolean\n}\n\nexport function apply(ctx: Context, config: Config = {}): void {\n const profileDir = profileDirectory('web')\n ctx.pluginSearch.register(npmSearchProvider())\n ctx.pluginSearch.register(githubSearchProvider())\n\n const manager = new PluginManager({\n profileDir,\n searchRuntime: ctx.pluginSearch,\n runner: new DshCliRunner(),\n hot: new HotRuntime(ctx, profileDir),\n restarter: new DshRestarter({ allowRestart: config.allowRestart }),\n loader: ctx.loader,\n })\n registerConversationSurface(ctx, manager)\n}\n\nexport { PluginManager } from './manager.ts'\nexport type { DiscoverRequest, MutationResult, PlanRequest } from './manager.ts'\nexport type { PluginSearchCandidate, PluginSearchProvider, PluginSearchRequest } from './search-runtime.ts'\nexport type { PluginInspection, PluginSource } from './source.ts'\n"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { Context, Service } from "@deepseek-ai/cordis";
2
+
3
+ //#region src/source.d.ts
4
+ interface NpmPluginSource {
5
+ kind: 'npm';
6
+ package: string;
7
+ version?: string;
8
+ }
9
+ interface GithubPluginSource {
10
+ kind: 'github';
11
+ owner: string;
12
+ repo: string;
13
+ ref?: string;
14
+ }
15
+ type PluginSource = NpmPluginSource | GithubPluginSource;
16
+ interface PluginInspection {
17
+ source: PluginSource;
18
+ sourceType: PluginSource['kind'];
19
+ requestedSpec: string;
20
+ installSpec: string;
21
+ packageName: string;
22
+ version?: string;
23
+ commit?: string;
24
+ integrity?: string;
25
+ repository: string | null;
26
+ description: string | null;
27
+ bundlePatch: string | null;
28
+ client: boolean;
29
+ }
30
+ interface FetchOptions {
31
+ fetch?: typeof globalThis.fetch;
32
+ env?: NodeJS.ProcessEnv;
33
+ signal?: AbortSignal;
34
+ }
35
+ declare function inspectPluginSource(value: string | PluginSource, options?: FetchOptions): Promise<PluginInspection>;
36
+ //#endregion
37
+ //#region src/search-runtime.d.ts
38
+ interface PluginSearchRequest {
39
+ query: string;
40
+ maxResults: number;
41
+ signal: AbortSignal;
42
+ }
43
+ interface PluginSearchCandidate {
44
+ id: string;
45
+ title: string;
46
+ description?: string;
47
+ homepage?: string;
48
+ repository?: string;
49
+ sources: PluginSource[];
50
+ score?: number;
51
+ evidence?: string[];
52
+ }
53
+ interface PluginSearchProvider {
54
+ id: string;
55
+ search(request: PluginSearchRequest): Promise<readonly PluginSearchCandidate[]>;
56
+ }
57
+ declare module '@deepseek-ai/cordis' {
58
+ interface Context {
59
+ pluginSearch: PluginSearchRuntime;
60
+ }
61
+ }
62
+ declare class PluginSearchRuntime extends Service {
63
+ readonly apiVersion: 1;
64
+ private readonly providers;
65
+ constructor(ctx: Context);
66
+ register(provider: PluginSearchProvider): () => void;
67
+ list(): readonly string[];
68
+ entries(): readonly PluginSearchProvider[];
69
+ }
70
+ //#endregion
71
+ export { FetchOptions as a, inspectPluginSource as c, PluginSearchRuntime as i, PluginSearchProvider as n, PluginInspection as o, PluginSearchRequest as r, PluginSource as s, PluginSearchCandidate as t };
72
+ //# sourceMappingURL=search-runtime-Be3SS1k2.d.ts.map
@@ -0,0 +1,2 @@
1
+ import { i as PluginSearchRuntime, n as PluginSearchProvider, r as PluginSearchRequest, t as PluginSearchCandidate } from "./search-runtime-Be3SS1k2.js";
2
+ export { PluginSearchCandidate, PluginSearchProvider, PluginSearchRequest, PluginSearchRuntime, PluginSearchRuntime as default };
@@ -0,0 +1,30 @@
1
+ import { t as fail } from "./errors-BGx4K2uq.js";
2
+ import { Service } from "@deepseek-ai/cordis";
3
+ //#region src/search-runtime.ts
4
+ const PROVIDER_ID = /^[a-z][a-z0-9._-]{0,63}$/u;
5
+ var PluginSearchRuntime = class extends Service {
6
+ apiVersion = 1;
7
+ providers = /* @__PURE__ */ new Map();
8
+ constructor(ctx) {
9
+ super(ctx, "pluginSearch");
10
+ }
11
+ register(provider) {
12
+ if (!PROVIDER_ID.test(provider.id) || typeof provider.search !== "function") throw new TypeError("plugin search provider requires a lowercase stable id and search function");
13
+ if (this.providers.has(provider.id)) fail("DUPLICATE_SEARCH_PROVIDER", `A plugin search provider named "${provider.id}" is already registered.`);
14
+ const dispose = this.ctx.effect(function* () {
15
+ this.providers.set(provider.id, provider);
16
+ yield () => this.providers.delete(provider.id);
17
+ }.bind(this), "pluginSearch.register()");
18
+ return () => void dispose();
19
+ }
20
+ list() {
21
+ return Object.freeze([...this.providers.keys()].sort());
22
+ }
23
+ entries() {
24
+ return Object.freeze([...this.providers.values()]);
25
+ }
26
+ };
27
+ //#endregion
28
+ export { PluginSearchRuntime, PluginSearchRuntime as default };
29
+
30
+ //# sourceMappingURL=search-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-runtime.js","names":[],"sources":["../src/search-runtime.ts"],"sourcesContent":["import { Context, Service } from '@deepseek-ai/cordis'\nimport { fail } from './errors.ts'\nimport type { PluginSource } from './source.ts'\n\nexport interface PluginSearchRequest {\n query: string\n maxResults: number\n signal: AbortSignal\n}\n\nexport interface PluginSearchCandidate {\n id: string\n title: string\n description?: string\n homepage?: string\n repository?: string\n sources: PluginSource[]\n score?: number\n evidence?: string[]\n}\n\nexport interface PluginSearchProvider {\n id: string\n search(request: PluginSearchRequest): Promise<readonly PluginSearchCandidate[]>\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n pluginSearch: PluginSearchRuntime\n }\n}\n\nconst PROVIDER_ID = /^[a-z][a-z0-9._-]{0,63}$/u\n\nexport class PluginSearchRuntime extends Service {\n readonly apiVersion = 1 as const\n private readonly providers = new Map<string, PluginSearchProvider>()\n\n constructor(ctx: Context) {\n super(ctx, 'pluginSearch')\n }\n\n register(provider: PluginSearchProvider): () => void {\n if (!PROVIDER_ID.test(provider.id) || typeof provider.search !== 'function') {\n throw new TypeError('plugin search provider requires a lowercase stable id and search function')\n }\n if (this.providers.has(provider.id)) {\n fail('DUPLICATE_SEARCH_PROVIDER', `A plugin search provider named \"${provider.id}\" is already registered.`)\n }\n const dispose = this.ctx.effect(function* (this: PluginSearchRuntime) {\n this.providers.set(provider.id, provider)\n yield () => this.providers.delete(provider.id)\n }.bind(this), 'pluginSearch.register()')\n return () => void dispose()\n }\n\n list(): readonly string[] {\n return Object.freeze([...this.providers.keys()].sort())\n }\n\n entries(): readonly PluginSearchProvider[] {\n return Object.freeze([...this.providers.values()])\n }\n}\n\nexport default PluginSearchRuntime\n"],"mappings":";;;AAgCA,MAAM,cAAc;AAEpB,IAAa,sBAAb,cAAyC,QAAQ;CAC/C,aAAsB;CACtB,4BAA6B,IAAI,IAAkC;CAEnE,YAAY,KAAc;EACxB,MAAM,KAAK,cAAc;CAC3B;CAEA,SAAS,UAA4C;EACnD,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,KAAK,OAAO,SAAS,WAAW,YAC/D,MAAM,IAAI,UAAU,2EAA2E;EAEjG,IAAI,KAAK,UAAU,IAAI,SAAS,EAAE,GAChC,KAAK,6BAA6B,mCAAmC,SAAS,GAAG,yBAAyB;EAE5G,MAAM,UAAU,KAAK,IAAI,OAAO,aAAsC;GACpE,KAAK,UAAU,IAAI,SAAS,IAAI,QAAQ;GACxC,YAAY,KAAK,UAAU,OAAO,SAAS,EAAE;EAC/C,EAAE,KAAK,IAAI,GAAG,yBAAyB;EACvC,aAAa,KAAK,QAAQ;CAC5B;CAEA,OAA0B;EACxB,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;CACxD;CAEA,UAA2C;EACzC,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC;CACnD;AACF"}
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "relay-dsh-plugin-manager",
3
+ "version": "0.1.0-rc.1",
4
+ "description": "Conversation-first plugin discovery and lifecycle management for DeepSeek Harness.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/yangbobo2021/relay-dsh-plugin-manager.git"
9
+ },
10
+ "homepage": "https://github.com/yangbobo2021/relay-dsh-plugin-manager#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/yangbobo2021/relay-dsh-plugin-manager/issues"
13
+ },
14
+ "type": "module",
15
+ "main": "lib/index.js",
16
+ "types": "lib/index.d.ts",
17
+ "engines": {
18
+ "node": ">=22.13"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "clean": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\"",
25
+ "build": "npm run clean && tsdown --config tsdown.config.ts",
26
+ "typecheck": "tsc -p tsconfig.json --noEmit",
27
+ "test": "vitest run && node --test test/*.test.mjs",
28
+ "test:unit": "vitest run test/unit",
29
+ "test:integration": "vitest run test/integration",
30
+ "acceptance:live:codex": "RELAY_LIVE_PLUGIN_ACCEPTANCE=1 vitest run test/live/codex.live.test.ts --reporter=verbose",
31
+ "acceptance": "node scripts/accept-local-package.mjs",
32
+ "release:dry-run": "npm publish --dry-run --tag next",
33
+ "verify": "npm run typecheck && npm test && npm run build && npm run acceptance",
34
+ "prepack": "npm run build"
35
+ },
36
+ "exports": {
37
+ ".": {
38
+ "types": "./lib/index.d.ts",
39
+ "default": "./lib/index.js"
40
+ },
41
+ "./search": {
42
+ "types": "./lib/search-runtime.d.ts",
43
+ "default": "./lib/search-runtime.js"
44
+ },
45
+ "./package.json": "./package.json"
46
+ },
47
+ "files": [
48
+ "README.md",
49
+ "SPEC.md",
50
+ "CHANGELOG.md",
51
+ "LICENSE",
52
+ "docs",
53
+ "cordis.patch.yml",
54
+ "lib"
55
+ ],
56
+ "dsh": {
57
+ "bundle": {
58
+ "patch": "./cordis.patch.yml"
59
+ }
60
+ },
61
+ "dependencies": {
62
+ "yaml": "2.9.0"
63
+ },
64
+ "peerDependencies": {
65
+ "@deepseek-ai/cordis": ">=4.0.1 <5",
66
+ "@deepseek-ai/cordis-plugin-include": ">=1.0.6 <2",
67
+ "@deepseek-ai/cordis-plugin-loader": ">=1.0.2 <2",
68
+ "@deepseek-ai/dsh-agent": ">=0.1.0-rc.6 <0.2.0",
69
+ "@deepseek-ai/dsh-commands": ">=0.1.0-rc.6 <0.2.0",
70
+ "@deepseek-ai/dsh-llm": ">=0.1.0-rc.6 <0.2.0",
71
+ "@deepseek-ai/dsh-tools": ">=0.1.0-rc.6 <0.2.0"
72
+ },
73
+ "peerDependenciesMeta": {
74
+ "@deepseek-ai/cordis": {
75
+ "optional": true
76
+ },
77
+ "@deepseek-ai/cordis-plugin-include": {
78
+ "optional": true
79
+ },
80
+ "@deepseek-ai/cordis-plugin-loader": {
81
+ "optional": true
82
+ },
83
+ "@deepseek-ai/dsh-agent": {
84
+ "optional": true
85
+ },
86
+ "@deepseek-ai/dsh-commands": {
87
+ "optional": true
88
+ },
89
+ "@deepseek-ai/dsh-llm": {
90
+ "optional": true
91
+ },
92
+ "@deepseek-ai/dsh-tools": {
93
+ "optional": true
94
+ }
95
+ },
96
+ "devDependencies": {
97
+ "@deepseek-ai/cordis": "4.0.1",
98
+ "@deepseek-ai/cordis-plugin-include": "1.0.6",
99
+ "@deepseek-ai/cordis-plugin-loader": "1.0.2",
100
+ "@deepseek-ai/dsh-agent": "0.1.1-rc.2",
101
+ "@deepseek-ai/dsh-commands": "0.1.1-rc.2",
102
+ "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
103
+ "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
104
+ "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
105
+ "@types/node": "^24.0.0",
106
+ "tsdown": "0.22.2",
107
+ "typescript": "6.0.3",
108
+ "vitest": "^4.0.0"
109
+ }
110
+ }