@llm4ts/shell 2.44.1 → 2.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/Cli.d.ts +3 -7
  2. package/dist/Cli.d.ts.map +1 -1
  3. package/dist/Cli.js +20 -4
  4. package/dist/Cli.js.map +1 -1
  5. package/dist/FlowLaunch.d.ts +2 -16
  6. package/dist/FlowLaunch.d.ts.map +1 -1
  7. package/dist/FlowLaunch.js +20 -66
  8. package/dist/FlowLaunch.js.map +1 -1
  9. package/dist/FlowProcess.d.ts +67 -0
  10. package/dist/FlowProcess.d.ts.map +1 -0
  11. package/dist/FlowProcess.js +175 -0
  12. package/dist/FlowProcess.js.map +1 -0
  13. package/dist/Menu.d.ts +1 -1
  14. package/dist/Menu.d.ts.map +1 -1
  15. package/dist/OperatorActTools.d.ts +170 -0
  16. package/dist/OperatorActTools.d.ts.map +1 -0
  17. package/dist/OperatorActTools.js +332 -0
  18. package/dist/OperatorActTools.js.map +1 -0
  19. package/dist/OperatorConfig.d.ts +44 -0
  20. package/dist/OperatorConfig.d.ts.map +1 -0
  21. package/dist/OperatorConfig.js +88 -0
  22. package/dist/OperatorConfig.js.map +1 -0
  23. package/dist/OperatorNode.d.ts +45 -0
  24. package/dist/OperatorNode.d.ts.map +1 -0
  25. package/dist/OperatorNode.js +103 -0
  26. package/dist/OperatorNode.js.map +1 -0
  27. package/dist/OperatorRuns.d.ts +76 -0
  28. package/dist/OperatorRuns.d.ts.map +1 -0
  29. package/dist/OperatorRuns.js +146 -0
  30. package/dist/OperatorRuns.js.map +1 -0
  31. package/dist/OperatorServer.d.ts +160 -0
  32. package/dist/OperatorServer.d.ts.map +1 -0
  33. package/dist/OperatorServer.js +123 -0
  34. package/dist/OperatorServer.js.map +1 -0
  35. package/dist/OperatorTools.d.ts +558 -0
  36. package/dist/OperatorTools.d.ts.map +1 -0
  37. package/dist/OperatorTools.js +398 -0
  38. package/dist/OperatorTools.js.map +1 -0
  39. package/dist/Refine.d.ts +2 -2
  40. package/dist/Refine.d.ts.map +1 -1
  41. package/dist/Refine.js +3 -5
  42. package/dist/Refine.js.map +1 -1
  43. package/dist/RunSupervisor.d.ts +51 -0
  44. package/dist/RunSupervisor.d.ts.map +1 -0
  45. package/dist/RunSupervisor.js +282 -0
  46. package/dist/RunSupervisor.js.map +1 -0
  47. package/dist/ShellErrors.d.ts +9 -0
  48. package/dist/ShellErrors.d.ts.map +1 -0
  49. package/dist/ShellErrors.js +7 -0
  50. package/dist/ShellErrors.js.map +1 -0
  51. package/flows/lib/epic-stories.js +83 -30
  52. package/flows/port-guide.js +4 -1
  53. package/kits/j2ee-nextjs/packs/j2ee-nextjs-spa/pack.md +1 -0
  54. package/kits/j2ee-nextjs/packs/jsp-nextjs/pack.md +1 -0
  55. package/kits/port/packs/scala-ts/pack.md +1 -0
  56. package/kits/soap-ace/fixtures/demo-bank-soap/RUNBOOK.md +5 -2
  57. package/kits/soap-ace/flows/soap-epic.js +1 -2
  58. package/package.json +13 -4
  59. package/src/Cli.ts +64 -3
  60. package/src/FlowLaunch.ts +20 -66
  61. package/src/FlowProcess.ts +239 -0
  62. package/src/OperatorActTools.ts +407 -0
  63. package/src/OperatorConfig.ts +148 -0
  64. package/src/OperatorNode.ts +147 -0
  65. package/src/OperatorRuns.ts +270 -0
  66. package/src/OperatorServer.ts +192 -0
  67. package/src/OperatorTools.ts +610 -0
  68. package/src/Refine.ts +4 -7
  69. package/src/RunSupervisor.ts +403 -0
  70. package/src/ShellErrors.ts +6 -0
@@ -0,0 +1,103 @@
1
+ import { readFileSync, readdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
4
+ import * as Clock from "effect/Clock";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Fiber from "effect/Fiber";
7
+ import { nodeListTraces } from "@llm4ts/runner/Costs";
8
+ import { collectDoctorReport } from "@llm4ts/runner/Doctor";
9
+ import { httpProbe, rosterReport } from "@llm4ts/runner/ExecutorRoster";
10
+ import { interruptOnSignal } from "@llm4ts/runner/FlowRunner";
11
+ import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore";
12
+ import { nodeTranscriptFiles } from "@llm4ts/runner/Transcripts";
13
+ import { nodeListEpics } from "@llm4ts/runner/Watch";
14
+ import { discoverFlows } from "./FlowCatalog.js";
15
+ import { nodeFlowProcess } from "./FlowProcess.js";
16
+ import { runOperatorServer } from "./OperatorServer.js";
17
+ import { makeRunSupervisor } from "./RunSupervisor.js";
18
+ /**
19
+ * Serves the operator until the server ends or a signal arrives. The first
20
+ * SIGINT or SIGTERM interrupts the server; closing the scope then runs the
21
+ * supervisor's finalizer, which stops every flow it started. A second signal
22
+ * exits at once (130 or 143). The handlers are removed on the way out.
23
+ */
24
+ export const runMcp = (config, runtime, signals) => {
25
+ const disposers = [];
26
+ return Effect.scoped(Effect.gen(function* () {
27
+ const supervisor = yield* makeRunSupervisor({
28
+ repos: config.repos,
29
+ environment: runtime.operator.environment,
30
+ files: runtime.operator.files,
31
+ process: runtime.flowProcess,
32
+ parallelRuns: config.parallelRuns,
33
+ ...(runtime.graceMs === undefined ? {} : { graceMs: runtime.graceMs })
34
+ });
35
+ const fiber = yield* Effect.forkScoped(runtime.serve(config, { ...runtime.operator, supervisor }));
36
+ disposers.push(interruptOnSignal(fiber, signals, "SIGINT"));
37
+ disposers.push(interruptOnSignal(fiber, signals, "SIGTERM"));
38
+ return yield* Fiber.join(fiber);
39
+ })).pipe(Effect.ensuring(Effect.sync(() => {
40
+ for (const dispose of disposers)
41
+ dispose();
42
+ })));
43
+ };
44
+ /** A file's text, or `undefined` when it cannot be read (the `mcp` config and token file). */
45
+ export const nodeRead = (path) => Effect.sync(() => {
46
+ try {
47
+ return readFileSync(path, "utf8");
48
+ }
49
+ catch {
50
+ return undefined;
51
+ }
52
+ });
53
+ /**
54
+ * Relative paths of every regular file under a directory, recursively; never
55
+ * directory names, and none when the directory is absent or unreadable.
56
+ */
57
+ export const nodeListFiles = (directory) => {
58
+ const found = [];
59
+ const walk = (relative) => {
60
+ let names;
61
+ try {
62
+ names = readdirSync(join(directory, relative), { withFileTypes: true });
63
+ }
64
+ catch {
65
+ return;
66
+ }
67
+ for (const entry of names) {
68
+ const path = relative.length === 0 ? entry.name : join(relative, entry.name);
69
+ if (entry.isDirectory()) {
70
+ walk(path);
71
+ }
72
+ else if (entry.isFile()) {
73
+ found.push(path);
74
+ }
75
+ }
76
+ };
77
+ walk("");
78
+ return found.sort();
79
+ };
80
+ /**
81
+ * The operator's dependencies on Node. `tierPaths` gives the flow tiers for a
82
+ * repository (the CLI's `shellTierPaths`, passed in to keep this module free
83
+ * of the CLI).
84
+ */
85
+ export const nodeOperatorRuntime = (config, tierPaths, environment = process.env) => ({
86
+ operator: {
87
+ config,
88
+ files: nodePlainFileStore,
89
+ listTraces: nodeListTraces,
90
+ listEpics: nodeListEpics,
91
+ listFiles: nodeListFiles,
92
+ transcripts: nodeTranscriptFiles,
93
+ doctor: collectDoctorReport(),
94
+ roster: (repoPath) => rosterReport({ files: nodePlainFileStore, environment, workDir: repoPath }),
95
+ probe: httpProbe,
96
+ flows: (repoPath) => discoverFlows(tierPaths(repoPath)).pipe(Effect.provide(NodeFileSystem.layer)),
97
+ now: Clock.currentTimeMillis,
98
+ environment
99
+ },
100
+ flowProcess: nodeFlowProcess,
101
+ serve: runOperatorServer
102
+ });
103
+ //# sourceMappingURL=OperatorNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperatorNode.js","sourceRoot":"","sources":["../src/OperatorNode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { EpicRun } from "@llm4ts/flow/EpicRuns";
3
+ import { TraceLine } from "@llm4ts/flow/FlowRecorder";
4
+ import { OperatorRun, ReadFailed, UnknownEpic, UnknownRun, type OperatorRunState } from "@llm4ts/flow/OperatorSchemas";
5
+ import type { PlainFileStoreShape } from "@llm4ts/flow/Persistence";
6
+ import { TraceUnreadable } from "@llm4ts/runner/RunReaders";
7
+ import type { OperatorConfig } from "./OperatorConfig.ts";
8
+ import type { RunSupervisorShape } from "./RunSupervisor.ts";
9
+ /**
10
+ * Where the operator finds a run: the supervisor's registry first, then each
11
+ * served repository's epic `runs.jsonl` files and `.llm4ts/trace-*.jsonl`
12
+ * traces. A client never names a path; epics and runs are ids found on disk.
13
+ */
14
+ /** What run lookup reads; the operator's full dependency record extends it. */
15
+ export interface RunLookupDeps {
16
+ readonly config: OperatorConfig;
17
+ readonly files: PlainFileStoreShape;
18
+ /** Absolute trace paths under one `.llm4ts/` directory. */
19
+ readonly listTraces: (directory: string) => ReadonlyArray<string>;
20
+ /** Folder names under `.llm4ts/epics/`. */
21
+ readonly listEpics: (directory: string) => ReadonlyArray<string>;
22
+ readonly supervisor: RunSupervisorShape;
23
+ }
24
+ export interface Repo {
25
+ readonly id: string;
26
+ readonly path: string;
27
+ }
28
+ export declare const stateRoot: (repo: Repo) => string;
29
+ export declare const epicsDir: (repo: Repo) => string;
30
+ export declare const transcriptsDir: (repo: Repo, runId: string) => string;
31
+ export declare const readFailed: (error: unknown) => ReadFailed;
32
+ /** The epic's state folder, only for an id found on disk, so no client text becomes a path. */
33
+ export declare const epicDirOf: (deps: RunLookupDeps, repo: Repo, epic: string) => Effect.Effect<string, UnknownEpic>;
34
+ /**
35
+ * An epic's runs, oldest first. A missing file is no runs and a torn last line
36
+ * (a write in progress) is skipped, but any other line that does not decode
37
+ * fails `ReadFailed` naming the file.
38
+ */
39
+ export declare const readEpicRunsStrict: (files: PlainFileStoreShape, stateDir: string) => Effect.Effect<ReadonlyArray<EpicRun>, ReadFailed>;
40
+ export interface EpicRunEntry {
41
+ readonly epic: string;
42
+ readonly dir: string;
43
+ readonly run: EpicRun;
44
+ }
45
+ export declare const epicRunsOf: (deps: RunLookupDeps, repo: Repo) => Effect.Effect<ReadonlyArray<EpicRunEntry>, ReadFailed>;
46
+ export interface TraceHead {
47
+ readonly runId: string;
48
+ readonly startedAt: number;
49
+ readonly ended: boolean;
50
+ }
51
+ /** The run a trace belongs to and whether it ended, from its first and last lines. */
52
+ export declare const traceHead: (files: PlainFileStoreShape, path: string) => Effect.Effect<TraceHead | undefined>;
53
+ export declare const traceState: (head: TraceHead | undefined) => OperatorRunState;
54
+ export interface ResolvedRun {
55
+ readonly runId: string;
56
+ readonly repo: Repo;
57
+ readonly flow: string;
58
+ readonly state: OperatorRunState;
59
+ readonly tracePath: string;
60
+ readonly supervised?: OperatorRun;
61
+ }
62
+ /** A run id through the supervisor first, then each repository's epic runs and traces. */
63
+ export declare const resolveRun: (deps: RunLookupDeps, runId: string) => Effect.Effect<ResolvedRun, UnknownRun | ReadFailed>;
64
+ /** The epic a run worked on: the epic whose `runs.jsonl` lists it. */
65
+ export declare const epicOfRun: (deps: RunLookupDeps, run: ResolvedRun) => Effect.Effect<EpicRunEntry | undefined, ReadFailed>;
66
+ /** Runs found on disk (epic run lists and traces) that the supervisor does not hold. */
67
+ export declare const discoveredRuns: (deps: RunLookupDeps, repo: Repo, known: ReadonlySet<string>) => Effect.Effect<ReadonlyArray<OperatorRun>, ReadFailed>;
68
+ /**
69
+ * A run's trace lines. A supervised run whose trace file does not exist yet
70
+ * (the flow has not written its first line) reads as an empty trace; any other
71
+ * missing or unreadable trace fails `TraceUnreadable`.
72
+ */
73
+ export declare const runTraceLines: (files: PlainFileStoreShape, run: ResolvedRun) => Effect.Effect<ReadonlyArray<TraceLine>, TraceUnreadable>;
74
+ /** Whether the run is supervised and its flow has not written a trace yet. */
75
+ export declare const tracePending: (files: PlainFileStoreShape, run: ResolvedRun) => Effect.Effect<boolean, TraceUnreadable>;
76
+ //# sourceMappingURL=OperatorRuns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperatorRuns.d.ts","sourceRoot":"","sources":["../src/OperatorRuns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { join } from "node:path";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Option from "effect/Option";
4
+ import * as Schema from "effect/Schema";
5
+ import { EpicRun, epicRunsPath } from "@llm4ts/flow/EpicRuns";
6
+ import { describeFlowError } from "@llm4ts/flow/FlowError";
7
+ import { TraceLine } from "@llm4ts/flow/FlowRecorder";
8
+ import { OperatorRun, ReadFailed, UnknownEpic, UnknownRun } from "@llm4ts/flow/OperatorSchemas";
9
+ import { readTrace } from "@llm4ts/flow/Replay";
10
+ import { TraceUnreadable } from "@llm4ts/runner/RunReaders";
11
+ export const stateRoot = (repo) => join(repo.path, ".llm4ts");
12
+ export const epicsDir = (repo) => join(stateRoot(repo), "epics");
13
+ export const transcriptsDir = (repo, runId) => join(stateRoot(repo), "transcripts", runId);
14
+ export const readFailed = (error) => ReadFailed.make({ message: describeFlowError(error) });
15
+ /** The epic's state folder, only for an id found on disk, so no client text becomes a path. */
16
+ export const epicDirOf = (deps, repo, epic) => deps.listEpics(epicsDir(repo)).includes(epic)
17
+ ? Effect.succeed(join(epicsDir(repo), epic))
18
+ : Effect.fail(UnknownEpic.make({ message: `unknown epic '${epic}' in ${repo.id}` }));
19
+ const decodeEpicRun = Schema.decodeUnknownOption(Schema.fromJsonString(EpicRun));
20
+ /**
21
+ * An epic's runs, oldest first. A missing file is no runs and a torn last line
22
+ * (a write in progress) is skipped, but any other line that does not decode
23
+ * fails `ReadFailed` naming the file.
24
+ */
25
+ export const readEpicRunsStrict = (files, stateDir) => {
26
+ const path = epicRunsPath(stateDir);
27
+ return files.read(path).pipe(Effect.mapError(readFailed), Effect.flatMap((contents) => {
28
+ const rows = (contents ?? "").split("\n").filter((row) => row.trim().length > 0);
29
+ const runs = [];
30
+ for (const [index, row] of rows.entries()) {
31
+ const decoded = Option.getOrUndefined(decodeEpicRun(row));
32
+ if (decoded !== undefined) {
33
+ runs.push(decoded);
34
+ }
35
+ else if (index < rows.length - 1) {
36
+ return Effect.fail(ReadFailed.make({ message: `malformed ${path}:${index + 1}: not an epic run record` }));
37
+ }
38
+ }
39
+ return Effect.succeed(runs);
40
+ }));
41
+ };
42
+ export const epicRunsOf = (deps, repo) => Effect.forEach(deps.listEpics(epicsDir(repo)), (epic) => {
43
+ const dir = join(epicsDir(repo), epic);
44
+ return readEpicRunsStrict(deps.files, dir).pipe(Effect.map((runs) => runs.map((run) => ({ epic, dir, run }))));
45
+ }).pipe(Effect.map((all) => all.flat()));
46
+ const decodeTraceLine = Schema.decodeUnknownOption(Schema.fromJsonString(TraceLine));
47
+ /** The run a trace belongs to and whether it ended, from its first and last lines. */
48
+ export const traceHead = (files, path) => files.read(path).pipe(Effect.catch(() => Effect.succeed(undefined)), Effect.map((contents) => {
49
+ const rows = (contents ?? "").split(/\r?\n/u).filter((row) => row.trim().length > 0);
50
+ const first = Option.getOrUndefined(decodeTraceLine(rows[0] ?? ""));
51
+ if (first === undefined)
52
+ return undefined;
53
+ const last = Option.getOrUndefined(decodeTraceLine(rows[rows.length - 1] ?? ""));
54
+ return { runId: first.runId, startedAt: first.timestamp, ended: last?.kind === "RunEnded" };
55
+ }));
56
+ export const traceState = (head) => head === undefined ? "lost" : head.ended ? "exited" : "running";
57
+ /** A run id through the supervisor first, then each repository's epic runs and traces. */
58
+ export const resolveRun = (deps, runId) => Effect.gen(function* () {
59
+ const supervised = yield* deps.supervisor.get(runId);
60
+ if (supervised !== undefined) {
61
+ const repo = deps.config.repos.find((candidate) => candidate.id === supervised.repo);
62
+ if (repo === undefined) {
63
+ return yield* UnknownRun.make({
64
+ message: `run ${runId} belongs to repo '${supervised.repo}', which this server does not serve`
65
+ });
66
+ }
67
+ if (supervised.tracePath === undefined) {
68
+ return yield* UnknownRun.make({ message: `run ${runId} has no trace yet` });
69
+ }
70
+ return {
71
+ runId,
72
+ repo,
73
+ flow: supervised.flow,
74
+ state: supervised.state,
75
+ tracePath: supervised.tracePath,
76
+ supervised
77
+ };
78
+ }
79
+ for (const repo of deps.config.repos) {
80
+ for (const entry of yield* epicRunsOf(deps, repo)) {
81
+ if (entry.run.runId === runId) {
82
+ const head = yield* traceHead(deps.files, entry.run.tracePath);
83
+ return {
84
+ runId,
85
+ repo,
86
+ flow: "?",
87
+ state: traceState(head),
88
+ tracePath: entry.run.tracePath
89
+ };
90
+ }
91
+ }
92
+ for (const path of deps.listTraces(stateRoot(repo))) {
93
+ const head = yield* traceHead(deps.files, path);
94
+ if (head?.runId === runId) {
95
+ return { runId, repo, flow: "?", state: traceState(head), tracePath: path };
96
+ }
97
+ }
98
+ }
99
+ return yield* UnknownRun.make({ message: `unknown run '${runId}'` });
100
+ });
101
+ /** The epic a run worked on: the epic whose `runs.jsonl` lists it. */
102
+ export const epicOfRun = (deps, run) => Effect.map(epicRunsOf(deps, run.repo), (entries) => entries.find((entry) => entry.run.runId === run.runId || entry.run.tracePath === run.tracePath));
103
+ /** Runs found on disk (epic run lists and traces) that the supervisor does not hold. */
104
+ export const discoveredRuns = (deps, repo, known) => Effect.gen(function* () {
105
+ const found = new Map();
106
+ const add = (runId, tracePath, startedAt, state) => {
107
+ if (known.has(runId) || found.has(runId))
108
+ return;
109
+ found.set(runId, new OperatorRun({
110
+ runId,
111
+ repo: repo.id,
112
+ flow: "?",
113
+ args: [],
114
+ knobs: {},
115
+ startedAt,
116
+ tracePath,
117
+ logDir: "",
118
+ state
119
+ }));
120
+ };
121
+ for (const entry of yield* epicRunsOf(deps, repo)) {
122
+ const head = yield* traceHead(deps.files, entry.run.tracePath);
123
+ add(entry.run.runId, entry.run.tracePath, entry.run.startedAt, traceState(head));
124
+ }
125
+ for (const path of deps.listTraces(stateRoot(repo))) {
126
+ const head = yield* traceHead(deps.files, path);
127
+ if (head !== undefined)
128
+ add(head.runId, path, head.startedAt, traceState(head));
129
+ }
130
+ return [...found.values()];
131
+ });
132
+ /**
133
+ * A run's trace lines. A supervised run whose trace file does not exist yet
134
+ * (the flow has not written its first line) reads as an empty trace; any other
135
+ * missing or unreadable trace fails `TraceUnreadable`.
136
+ */
137
+ export const runTraceLines = (files, run) => Effect.gen(function* () {
138
+ if (yield* tracePending(files, run))
139
+ return [];
140
+ return yield* readTrace(files, run.tracePath).pipe(Effect.mapError((error) => TraceUnreadable.make({ path: run.tracePath, message: describeFlowError(error) })));
141
+ });
142
+ /** Whether the run is supervised and its flow has not written a trace yet. */
143
+ export const tracePending = (files, run) => run.supervised === undefined
144
+ ? Effect.succeed(false)
145
+ : files.read(run.tracePath).pipe(Effect.map((contents) => contents === undefined), Effect.mapError((error) => TraceUnreadable.make({ path: run.tracePath, message: describeFlowError(error) })));
146
+ //# sourceMappingURL=OperatorRuns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperatorRuns.js","sourceRoot":"","sources":["../src/OperatorRuns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ import type * as Cause from "effect/Cause";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as Schema from "effect/Schema";
5
+ import * as McpServer from "effect/ai/McpServer";
6
+ import * as Toolkit from "effect/ai/Toolkit";
7
+ import * as HttpRouter from "effect/http/HttpRouter";
8
+ import type { ServeError } from "effect/http/HttpServerError";
9
+ import type { OperatorConfig } from "./OperatorConfig.ts";
10
+ import { type OperatorDeps } from "./OperatorTools.ts";
11
+ /**
12
+ * The operator MCP server (`llm4ts mcp`, ADR 0041): the read, wait and allowed
13
+ * act tools served over stdio, or over HTTP at `/mcp` behind a bearer token.
14
+ * A tool that the configuration does not allow is never registered, so it is
15
+ * absent from `tools/list` rather than refused when called.
16
+ */
17
+ export declare const serverName = "llm4ts";
18
+ export declare const serverPath = "/mcp";
19
+ type HttpTransport = Extract<OperatorConfig["transport"], {
20
+ readonly _tag: "http";
21
+ }>;
22
+ export type HttpOperatorConfig = OperatorConfig & {
23
+ readonly transport: HttpTransport;
24
+ };
25
+ /** The act tools a configuration allows: `--allow-run` and `--allow-approve` each add their own. */
26
+ export declare const actToolkitFor: (config: OperatorConfig) => Toolkit.Toolkit<{
27
+ readonly start_run: import("effect/ai/Tool").Tool<"start_run", {
28
+ readonly parameters: Schema.Struct<{
29
+ readonly repo: Schema.optional<Schema.String>;
30
+ readonly flow: Schema.String;
31
+ readonly task: Schema.optional<Schema.String>;
32
+ readonly epic: Schema.optional<Schema.String>;
33
+ readonly pack: Schema.optional<Schema.String>;
34
+ readonly executors: Schema.optional<Schema.$Array<Schema.String>>;
35
+ readonly coder: Schema.optional<Schema.String>;
36
+ readonly judgeRounds: Schema.optional<Schema.Int>;
37
+ readonly mergeRevisions: Schema.optional<Schema.Int>;
38
+ readonly land: Schema.optional<Schema.String>;
39
+ readonly flags: Schema.optional<Schema.$Array<Schema.String>>;
40
+ readonly requestId: Schema.optional<Schema.String>;
41
+ }>;
42
+ readonly success: Schema.Struct<{
43
+ readonly runId: Schema.String;
44
+ readonly tracePath: Schema.optionalKey<Schema.String>;
45
+ readonly pid: Schema.optionalKey<Schema.Int>;
46
+ }>;
47
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").InvalidKnob, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownFlow, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("./FlowProcess.ts").FlowLaunchError, typeof import("@llm4ts/flow/OperatorSchemas.ts").RunInProgress, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
48
+ readonly failureMode: "error";
49
+ }, never>;
50
+ readonly stop_run: import("effect/ai/Tool").Tool<"stop_run", {
51
+ readonly parameters: Schema.Struct<{
52
+ readonly runId: Schema.String;
53
+ }>;
54
+ readonly success: typeof import("@llm4ts/flow/OperatorSchemas.ts").OperatorRun;
55
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun]>;
56
+ readonly failureMode: "error";
57
+ }, never>;
58
+ readonly retro_start: import("effect/ai/Tool").Tool<"retro_start", {
59
+ readonly parameters: Schema.Struct<{
60
+ readonly repo: Schema.optional<Schema.String>;
61
+ readonly epic: Schema.String;
62
+ readonly run: Schema.optional<Schema.String>;
63
+ }>;
64
+ readonly success: Schema.Struct<{
65
+ readonly runId: Schema.String;
66
+ readonly tracePath: Schema.optionalKey<Schema.String>;
67
+ readonly pid: Schema.optionalKey<Schema.Int>;
68
+ }>;
69
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").InvalidKnob, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownFlow, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("./FlowProcess.ts").FlowLaunchError, typeof import("@llm4ts/flow/OperatorSchemas.ts").RunInProgress, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
70
+ readonly failureMode: "error";
71
+ }, never>;
72
+ readonly approve: import("effect/ai/Tool").Tool<"approve", {
73
+ readonly parameters: Schema.Struct<{
74
+ readonly repo: Schema.optional<Schema.String>;
75
+ readonly kind: Schema.Literals<readonly ["retro"]>;
76
+ readonly epic: Schema.String;
77
+ readonly id: Schema.String;
78
+ }>;
79
+ readonly success: Schema.Struct<{
80
+ readonly path: Schema.String;
81
+ readonly approved: Schema.Boolean;
82
+ }>;
83
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
84
+ readonly failureMode: "error";
85
+ }, never>;
86
+ }> | Toolkit.Toolkit<{
87
+ readonly start_run: import("effect/ai/Tool").Tool<"start_run", {
88
+ readonly parameters: Schema.Struct<{
89
+ readonly repo: Schema.optional<Schema.String>;
90
+ readonly flow: Schema.String;
91
+ readonly task: Schema.optional<Schema.String>;
92
+ readonly epic: Schema.optional<Schema.String>;
93
+ readonly pack: Schema.optional<Schema.String>;
94
+ readonly executors: Schema.optional<Schema.$Array<Schema.String>>;
95
+ readonly coder: Schema.optional<Schema.String>;
96
+ readonly judgeRounds: Schema.optional<Schema.Int>;
97
+ readonly mergeRevisions: Schema.optional<Schema.Int>;
98
+ readonly land: Schema.optional<Schema.String>;
99
+ readonly flags: Schema.optional<Schema.$Array<Schema.String>>;
100
+ readonly requestId: Schema.optional<Schema.String>;
101
+ }>;
102
+ readonly success: Schema.Struct<{
103
+ readonly runId: Schema.String;
104
+ readonly tracePath: Schema.optionalKey<Schema.String>;
105
+ readonly pid: Schema.optionalKey<Schema.Int>;
106
+ }>;
107
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").InvalidKnob, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownFlow, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("./FlowProcess.ts").FlowLaunchError, typeof import("@llm4ts/flow/OperatorSchemas.ts").RunInProgress, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
108
+ readonly failureMode: "error";
109
+ }, never>;
110
+ readonly stop_run: import("effect/ai/Tool").Tool<"stop_run", {
111
+ readonly parameters: Schema.Struct<{
112
+ readonly runId: Schema.String;
113
+ }>;
114
+ readonly success: typeof import("@llm4ts/flow/OperatorSchemas.ts").OperatorRun;
115
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun]>;
116
+ readonly failureMode: "error";
117
+ }, never>;
118
+ readonly retro_start: import("effect/ai/Tool").Tool<"retro_start", {
119
+ readonly parameters: Schema.Struct<{
120
+ readonly repo: Schema.optional<Schema.String>;
121
+ readonly epic: Schema.String;
122
+ readonly run: Schema.optional<Schema.String>;
123
+ }>;
124
+ readonly success: Schema.Struct<{
125
+ readonly runId: Schema.String;
126
+ readonly tracePath: Schema.optionalKey<Schema.String>;
127
+ readonly pid: Schema.optionalKey<Schema.Int>;
128
+ }>;
129
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").InvalidKnob, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownFlow, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("./FlowProcess.ts").FlowLaunchError, typeof import("@llm4ts/flow/OperatorSchemas.ts").RunInProgress, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
130
+ readonly failureMode: "error";
131
+ }, never>;
132
+ }> | Toolkit.Toolkit<{
133
+ readonly approve: import("effect/ai/Tool").Tool<"approve", {
134
+ readonly parameters: Schema.Struct<{
135
+ readonly repo: Schema.optional<Schema.String>;
136
+ readonly kind: Schema.Literals<readonly ["retro"]>;
137
+ readonly epic: Schema.String;
138
+ readonly id: Schema.String;
139
+ }>;
140
+ readonly success: Schema.Struct<{
141
+ readonly path: Schema.String;
142
+ readonly approved: Schema.Boolean;
143
+ }>;
144
+ readonly failure: Schema.Union<readonly [typeof import("@llm4ts/flow/OperatorSchemas.ts").NotAllowed, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRepo, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownEpic, typeof import("@llm4ts/flow/OperatorSchemas.ts").UnknownRun, typeof import("@llm4ts/flow/OperatorSchemas.ts").ReadFailed, typeof import("@llm4ts/flow/FlowError.ts").PersistenceError]>;
145
+ readonly failureMode: "error";
146
+ }, never>;
147
+ }> | Toolkit.Toolkit<{}>;
148
+ /** Every tool this configuration serves, registered on the server it is provided. */
149
+ export declare const toolLayer: (config: OperatorConfig, deps: OperatorDeps) => Layer.Layer<never, never, McpServer.McpServer>;
150
+ /**
151
+ * Lets a request through only with `Authorization: Bearer <token>`, compared in
152
+ * constant time; anything else is a bare 401. The token is never logged.
153
+ */
154
+ export declare const bearerMiddleware: (token: string) => Layer.Layer<never>;
155
+ /** The HTTP application: the tools on an MCP endpoint at `/mcp`, behind the bearer token. */
156
+ export declare const httpAppLayer: (config: HttpOperatorConfig, deps: OperatorDeps) => Layer.Layer<never, Cause.IllegalArgumentError, HttpRouter.HttpRouter>;
157
+ /** Serves the operator tools on the configured transport until interrupted. */
158
+ export declare const runOperatorServer: (config: OperatorConfig, deps: OperatorDeps) => Effect.Effect<never, ServeError | Cause.IllegalArgumentError>;
159
+ export {};
160
+ //# sourceMappingURL=OperatorServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperatorServer.d.ts","sourceRoot":"","sources":["../src/OperatorServer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAGrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAA;AAC5C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAa7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGjF;;;;;GAKG;AAEH,eAAO,MAAM,UAAU,WAAW,CAAA;AAClC,eAAO,MAAM,UAAU,SAAS,CAAA;AAEhC,KAAK,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AACpF,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;CAAE,CAAA;AAWvF,oGAAoG;AACpG,eAAO,MAAM,aAAa,GAAI,QAAQ,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAO/B,CAAA;AAsBrB,qFAAqF;AACrF,eAAO,MAAM,SAAS,GACpB,QAAQ,cAAc,EACtB,MAAM,YAAY,KACjB,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,SAAS,CAK7C,CAAA;AAIH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAajE,CAAA;AAED,6FAA6F;AAC7F,eAAO,MAAM,YAAY,GACvB,QAAQ,kBAAkB,EAC1B,MAAM,YAAY,KACjB,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,EAAE,UAAU,CAAC,UAAU,CAIpE,CAAA;AA2CH,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,cAAc,EACtB,MAAM,YAAY,KACjB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,CAAC,oBAAoB,CAoB9D,CAAA"}