0d6bfd8856
New process/ capability family: @deepseek-ai/dsh-process owns ctx.processes — abstract ProcessManager.spawn(spec) over a fully-explicit ProcessSpawnSpec — plus the shared DSH_* managed-environment and CollectedOutput vocabulary; @deepseek-ai/dsh-process-local carries the former bash-local run.ts plumbing (detached groups, tail-keep spill-backed output, credential scrub, kill escalation, kill-and-join disposal) with no config of its own. dsh-bash-local becomes a consumer: it keeps command defaulting, the fused deadline timedOut/aborted classification, the model-friendly terminal env (now merged through the ordinary env channel), and the [stderr]-marked background read merge, and spawns through ctx.processes. Background-process lifetime moves to the manager, so an executor reload no longer kills live background work; a background spawn failure is injected once into the read path instead of being buffered as fake stderr. dsh-bash re-exports the moved vocabulary so bash consumers keep one import root; dsh-bash-sandbox only redeclares the inherited inject. Every composition loading a bash executor now loads dsh-process-local (CLI, examples, python bundled runtime, create-sdk bash feature, inline test configs).
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
/**
|
|
* The child-process manager seam (`ctx.processes`): spawn fully-specified
|
|
* commands into managed process groups with bounded, spill-backed output and
|
|
* escalated kills. Command defaulting, shell semantics, deadlines, and
|
|
* presentation belong to consumers — the bash executor seam is the owning
|
|
* template. The local implementation lives in
|
|
* `@deepseek-ai/dsh-process-local`.
|
|
* @module @deepseek-ai/dsh-process
|
|
*/
|
|
|
|
import { Context, Service } from 'cordis'
|
|
import type { ProcessHandle, ProcessSpawnSpec } from './types.ts'
|
|
|
|
export { DSH_ENV_PREFIX } from './types.ts'
|
|
export type {
|
|
CollectedOutput,
|
|
DshEnvironment,
|
|
DshEnvironmentKey,
|
|
ProcessHandle,
|
|
ProcessOutcome,
|
|
ProcessOutputRead,
|
|
ProcessOutputReader,
|
|
ProcessSpawnSpec,
|
|
} from './types.ts'
|
|
|
|
declare module 'cordis' {
|
|
interface Context {
|
|
processes: ProcessManager
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Abstract process manager. Subclass, implement {@link spawn}, and load the
|
|
* subclass as a plugin — it registers as `ctx.processes` (one implementation
|
|
* per context; loading a second throws, which is cordis' standard
|
|
* duplicate-service behavior).
|
|
*
|
|
* Implementations must honor these semantics:
|
|
* - {@link spawn} returns immediately with a live handle; `done` resolves at
|
|
* process close and rejects only for spawn-level failures.
|
|
* - Output readers are offset-based and non-consuming, so independent readers
|
|
* never consume one another's output; lossy reads report truncation and the
|
|
* spill file holding the complete stream when one exists.
|
|
* - {@link ProcessHandle.kill} and the spec's abort signal escalate
|
|
* SIGTERM→grace→SIGKILL across the whole process group.
|
|
* - Disposal kills all still-running managed processes and awaits their exit.
|
|
*/
|
|
export abstract class ProcessManager extends Service {
|
|
constructor(ctx: Context) {
|
|
super(ctx, 'processes')
|
|
}
|
|
|
|
/**
|
|
* Start one managed child process from a fully-specified spec; this seam
|
|
* applies no defaults.
|
|
* @param spec - argv, directory, limits, grace, cancellation, and environment.
|
|
* @returns the live process handle (readers, kill, outcome promise).
|
|
*/
|
|
abstract spawn(spec: ProcessSpawnSpec): ProcessHandle
|
|
}
|
|
|
|
export default ProcessManager
|