@h-rig/core 0.0.6-alpha.9 → 0.0.6-alpha.91

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.
@@ -1,17 +1,269 @@
1
1
  // @bun
2
2
  // packages/core/src/load-config.ts
3
- import { existsSync, readFileSync } from "fs";
4
- import { join } from "path";
5
- import { pathToFileURL } from "url";
3
+ import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "fs";
4
+ import { tmpdir } from "os";
5
+ import { dirname, join } from "path";
6
+ import { fileURLToPath, pathToFileURL } from "url";
7
+ import { Schema as Schema2 } from "effect";
8
+ import { RigConfig as RigConfig2 } from "@rig/contracts";
9
+
10
+ // packages/core/src/define-config.ts
6
11
  import { Schema } from "effect";
7
12
  import { RigConfig } from "@rig/contracts";
13
+ function normalizeWorkspaceConfig(raw) {
14
+ const workspace = raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : { mainRepo: "." };
15
+ workspace.checkout = workspace.checkout ?? workspace.isolation ?? "worktree";
16
+ workspace.isolation = workspace.isolation ?? workspace.checkout;
17
+ workspace.sandbox = workspace.sandbox ?? "enforce";
18
+ return workspace;
19
+ }
20
+ function applyConfigDefaults(raw) {
21
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
22
+ return raw;
23
+ const record = raw;
24
+ return {
25
+ ...record,
26
+ plugins: Array.isArray(record.plugins) ? record.plugins : [],
27
+ workspace: normalizeWorkspaceConfig(record.workspace)
28
+ };
29
+ }
30
+
31
+ // packages/core/src/load-config.ts
8
32
  var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
9
33
  var JSON_NAMES = ["rig.config.json"];
34
+ function isModuleResolutionError(error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ return message.includes("Cannot find module") || message.includes("Could not resolve");
37
+ }
38
+ function runningFromCompiledBinary() {
39
+ return import.meta.url.includes("$bunfs");
40
+ }
41
+ function packageNameAndSubpath(specifier) {
42
+ if (specifier.startsWith(".") || specifier.startsWith("/") || /^[a-zA-Z]+:/.test(specifier))
43
+ return null;
44
+ const parts = specifier.split("/");
45
+ const packageName = specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
46
+ if (!packageName)
47
+ return null;
48
+ const rest = parts.slice(specifier.startsWith("@") ? 2 : 1).join("/");
49
+ return { packageName, subpath: rest ? `./${rest}` : "." };
50
+ }
51
+ function exportTargetFromEntry(entry) {
52
+ if (typeof entry === "string")
53
+ return entry;
54
+ if (entry && typeof entry === "object" && !Array.isArray(entry)) {
55
+ const conditions = entry;
56
+ for (const key of ["bun", "import", "default", "require"]) {
57
+ if (typeof conditions[key] === "string")
58
+ return conditions[key];
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ function patternExportTarget(record, subpath) {
64
+ for (const [pattern, entry] of Object.entries(record)) {
65
+ if (!pattern.includes("*"))
66
+ continue;
67
+ const [prefix = "", suffix = ""] = pattern.split("*");
68
+ if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
69
+ continue;
70
+ const replacement = subpath.slice(prefix.length, subpath.length - suffix.length);
71
+ const target = exportTargetFromEntry(entry);
72
+ if (target)
73
+ return target.replace("*", replacement);
74
+ }
75
+ return null;
76
+ }
77
+ function exportTargetFromPackageJson(pkg, subpath) {
78
+ const exportsField = pkg.exports;
79
+ const target = (() => {
80
+ if (typeof exportsField === "string" && subpath === ".")
81
+ return exportsField;
82
+ if (!exportsField || typeof exportsField !== "object" || Array.isArray(exportsField))
83
+ return null;
84
+ const record = exportsField;
85
+ return exportTargetFromEntry(record[subpath] ?? (subpath === "." ? record["."] : undefined)) ?? patternExportTarget(record, subpath);
86
+ })();
87
+ if (target)
88
+ return target;
89
+ return subpath === "." && typeof pkg.module === "string" ? pkg.module : subpath === "." && typeof pkg.main === "string" ? pkg.main : null;
90
+ }
91
+ function resolvePackageDirFromBunStore(packageName, nodeModulesDir) {
92
+ const storeDir = join(nodeModulesDir, ".bun");
93
+ if (!existsSync(storeDir))
94
+ return null;
95
+ const encoded = packageName.replace("/", "+");
96
+ try {
97
+ for (const entry of readdirSync(storeDir).sort()) {
98
+ if (!entry.startsWith(`${encoded}@`))
99
+ continue;
100
+ const candidate = join(storeDir, entry, "node_modules", packageName);
101
+ if (existsSync(join(candidate, "package.json")))
102
+ return candidate;
103
+ }
104
+ } catch {
105
+ return null;
106
+ }
107
+ return null;
108
+ }
109
+ function resolvePackageExportFromDir(packageDir, subpath) {
110
+ const packageJsonPath = join(packageDir, "package.json");
111
+ if (!existsSync(packageJsonPath))
112
+ return null;
113
+ try {
114
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
115
+ const target = exportTargetFromPackageJson(pkg, subpath);
116
+ if (target) {
117
+ const resolved = join(packageDir, target);
118
+ if (existsSync(resolved))
119
+ return resolved;
120
+ }
121
+ } catch {
122
+ return null;
123
+ }
124
+ return null;
125
+ }
126
+ function resolveBarePackageExport(specifier, parentDir) {
127
+ const parsed = packageNameAndSubpath(specifier);
128
+ if (!parsed)
129
+ return null;
130
+ const packageNames = parsed.packageName.startsWith("@rig/") ? [parsed.packageName, parsed.packageName.replace(/^@rig\//, "@h-rig/")] : [parsed.packageName];
131
+ let current = parentDir;
132
+ while (true) {
133
+ const nodeModulesDir = join(current, "node_modules");
134
+ for (const packageName of packageNames) {
135
+ const directPackageDir = join(nodeModulesDir, packageName);
136
+ const resolvedDirect = resolvePackageExportFromDir(directPackageDir, parsed.subpath);
137
+ if (resolvedDirect)
138
+ return resolvedDirect;
139
+ const bunStorePackageDir = resolvePackageDirFromBunStore(packageName, nodeModulesDir);
140
+ if (bunStorePackageDir) {
141
+ const resolvedFromStore = resolvePackageExportFromDir(bunStorePackageDir, parsed.subpath);
142
+ if (resolvedFromStore)
143
+ return resolvedFromStore;
144
+ }
145
+ }
146
+ const next = dirname(current);
147
+ if (next === current)
148
+ break;
149
+ current = next;
150
+ }
151
+ return null;
152
+ }
153
+ var runtimeBundleQueue = Promise.resolve();
154
+ function enqueueRuntimeBundle(operation) {
155
+ const next = runtimeBundleQueue.then(operation, operation);
156
+ runtimeBundleQueue = next.then(() => {
157
+ return;
158
+ }, () => {
159
+ return;
160
+ });
161
+ return next;
162
+ }
163
+ async function importConfigViaRuntimeBundleUnserialized(configPath) {
164
+ const bun = globalThis.Bun;
165
+ if (!bun?.build) {
166
+ throw new Error(`Failed to import ${configPath}: bare imports could not be resolved and no Bun.build runtime bundler is available.`);
167
+ }
168
+ const hostDir = (() => {
169
+ try {
170
+ return dirname(fileURLToPath(import.meta.url));
171
+ } catch {
172
+ return process.cwd();
173
+ }
174
+ })();
175
+ const configDir = dirname(configPath);
176
+ const UNRESOLVED_NAMESPACE = "rig-config-unresolved";
177
+ const hostResolverPlugin = {
178
+ name: "rig-host-package-resolver",
179
+ setup(build) {
180
+ build.onResolve({ filter: /^@rig\// }, (args) => {
181
+ const candidates = [
182
+ [args.path, hostDir],
183
+ [args.path.replace(/^@rig\//, "@h-rig/"), hostDir],
184
+ [args.path, configDir]
185
+ ];
186
+ for (const [specifier, parent] of candidates) {
187
+ try {
188
+ const resolved = bun.resolveSync?.(specifier, parent) ?? resolveBarePackageExport(specifier, parent);
189
+ if (resolved)
190
+ return { path: resolved };
191
+ } catch {
192
+ const resolved = resolveBarePackageExport(specifier, parent);
193
+ if (resolved)
194
+ return { path: resolved };
195
+ }
196
+ }
197
+ return;
198
+ });
199
+ build.onResolve({ filter: /.*/ }, (args) => {
200
+ if (/^(?:node|bun):/.test(args.path))
201
+ return;
202
+ const parent = args.importer ? dirname(args.importer) : configDir;
203
+ try {
204
+ const resolved = bun.resolveSync?.(args.path, parent) ?? resolveBarePackageExport(args.path, parent);
205
+ if (resolved)
206
+ return { path: resolved };
207
+ } catch {
208
+ const resolved = resolveBarePackageExport(args.path, parent);
209
+ if (resolved)
210
+ return { path: resolved };
211
+ return { path: args.path, namespace: UNRESOLVED_NAMESPACE };
212
+ }
213
+ return;
214
+ });
215
+ build.onLoad({ filter: /.*/, namespace: UNRESOLVED_NAMESPACE }, (args) => ({
216
+ loader: "js",
217
+ contents: `module.exports = {};
218
+ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not resolve: "${args.path}". Maybe you need to "bun install"?`)});
219
+ `
220
+ }));
221
+ }
222
+ };
223
+ const result = await bun.build({
224
+ entrypoints: [configPath],
225
+ target: "bun",
226
+ format: "esm",
227
+ throw: false,
228
+ plugins: [hostResolverPlugin]
229
+ });
230
+ if (!result.success || !result.outputs[0]) {
231
+ const detail = result.logs.map((log) => String(log)).join(`
232
+ `);
233
+ throw new Error(`Failed to bundle ${configPath}: ${detail || "unknown bundler error"}`);
234
+ }
235
+ const dir = mkdtempSync(join(tmpdir(), "rig-config-bundle-"));
236
+ try {
237
+ const bundledPath = join(dir, "rig.config.bundled.js");
238
+ await bun.write(bundledPath, await result.outputs[0].text());
239
+ return await import(pathToFileURL(bundledPath).href);
240
+ } finally {
241
+ try {
242
+ rmSync(dir, { recursive: true, force: true });
243
+ } catch {}
244
+ }
245
+ }
10
246
  async function loadConfig(cwd) {
11
247
  for (const name of TS_NAMES) {
12
248
  const p = join(cwd, name);
13
249
  if (existsSync(p)) {
14
- const mod = await import(pathToFileURL(p).href);
250
+ const mod = await enqueueRuntimeBundle(async () => {
251
+ if (runningFromCompiledBinary()) {
252
+ return importConfigViaRuntimeBundleUnserialized(p);
253
+ }
254
+ const source = readFileSync(p, "utf8");
255
+ const importsRigHostPackages = /(?:import\s+[^;]*?from\s*|import\s*\()\s*["']@rig\//.test(source);
256
+ if (importsRigHostPackages) {
257
+ return importConfigViaRuntimeBundleUnserialized(p);
258
+ }
259
+ try {
260
+ return await import(pathToFileURL(p).href);
261
+ } catch (error) {
262
+ if (!isModuleResolutionError(error))
263
+ throw error;
264
+ return importConfigViaRuntimeBundleUnserialized(p);
265
+ }
266
+ });
15
267
  const raw = mod.default ?? mod.config;
16
268
  return decodePreservingRuntime(raw);
17
269
  }
@@ -35,7 +287,7 @@ function decodePreservingRuntime(raw) {
35
287
  }
36
288
  }
37
289
  }
38
- const decoded = Schema.decodeUnknownSync(RigConfig)(raw);
290
+ const decoded = Schema2.decodeUnknownSync(RigConfig2)(applyConfigDefaults(raw));
39
291
  const plugins = decoded.plugins.map((p) => {
40
292
  const runtime = runtimeByName.get(p.name);
41
293
  if (!runtime)
@@ -0,0 +1,40 @@
1
+ import type { ValidatorRegistration, HookRegistration, SkillRegistration, RepoSourceRegistration, AgentRoleRegistration, TaskFieldExtension, TaskSourceRegistration, CliCommandRegistration } from "@rig/contracts";
2
+ import type { RegisteredValidator, RigPluginWithRuntime, TaskSourceFactoryEntry } from "./plugin-runtime";
3
+ export interface PluginHost {
4
+ getValidator(id: string): ValidatorRegistration | undefined;
5
+ getHook(id: string): HookRegistration | undefined;
6
+ getSkill(id: string): SkillRegistration | undefined;
7
+ getRepoSource(id: string): RepoSourceRegistration | undefined;
8
+ getAgentRole(id: string): AgentRoleRegistration | undefined;
9
+ getTaskFieldExtension(id: string): TaskFieldExtension | undefined;
10
+ getTaskSource(id: string): TaskSourceRegistration | undefined;
11
+ getCliCommand(id: string): CliCommandRegistration | undefined;
12
+ listValidators(): readonly ValidatorRegistration[];
13
+ listHooks(): readonly HookRegistration[];
14
+ listSkills(): readonly SkillRegistration[];
15
+ listRepoSources(): readonly RepoSourceRegistration[];
16
+ listAgentRoles(): readonly AgentRoleRegistration[];
17
+ listTaskFieldExtensions(): readonly TaskFieldExtension[];
18
+ listTaskSources(): readonly TaskSourceRegistration[];
19
+ listCliCommands(): readonly CliCommandRegistration[];
20
+ /**
21
+ * Executable validators contributed by plugins. Only validators whose
22
+ * metadata appears in `listValidators()` and whose plugin shipped a runtime
23
+ * implementation via `definePlugin(meta, { validators: [...] })` appear here.
24
+ * Validators registered metadata-only (no run() implementation) are absent.
25
+ */
26
+ listExecutableValidators(): readonly RegisteredValidator[];
27
+ /**
28
+ * Executable task source factories contributed by plugins. Used by the
29
+ * runtime's `buildTaskSourceRegistry` to instantiate non-standard task
30
+ * source kinds (Linear, Jira, custom) declared by plugins.
31
+ */
32
+ listExecutableTaskSources(): readonly TaskSourceFactoryEntry[];
33
+ /**
34
+ * Look up an executable task source factory by its `kind` (the value in
35
+ * `config.taskSource.kind`). Returns undefined when no plugin provides
36
+ * a factory for that kind.
37
+ */
38
+ resolveTaskSourceFactoryByKind(kind: string): TaskSourceFactoryEntry | undefined;
39
+ }
40
+ export declare function createPluginHost(plugins: readonly RigPluginWithRuntime[]): PluginHost;
@@ -58,6 +58,24 @@ function assertRuntimeMatchesMetadata(plugin) {
58
58
  }
59
59
  }
60
60
  }
61
+ const declaredHooks = new Map((plugin.contributes?.hooks ?? []).map((hook) => [hook.id, hook]));
62
+ const runtimeHooks = plugin.__runtime?.hooks;
63
+ for (const hookId of Object.keys(runtimeHooks ?? {})) {
64
+ const metadata = declaredHooks.get(hookId);
65
+ if (!metadata) {
66
+ throw new Error(`plugin "${plugin.name}" typed hook "${hookId}" has no matching metadata entry in contributes.hooks`);
67
+ }
68
+ if (metadata.command) {
69
+ throw new Error(`plugin "${plugin.name}" hook "${hookId}" has both a typed implementation and a command string \u2014 pick one`);
70
+ }
71
+ }
72
+ if (runtimeHooks) {
73
+ for (const hook of declaredHooks.values()) {
74
+ if (!runtimeHooks[hook.id] && !hook.command) {
75
+ throw new Error(`plugin "${plugin.name}" hook metadata "${hook.id}" has no implementation (typed function or command)`);
76
+ }
77
+ }
78
+ }
61
79
  }
62
80
  function createPluginHost(plugins) {
63
81
  assertUniquePluginNames(plugins);
@@ -0,0 +1,64 @@
1
+ import type { HookImplementation, RegisteredTaskSource, RigConfig, RigPlugin, TaskSourceConfig, TaskSourceRegistration, ValidatorRegistration } from "@rig/contracts";
2
+ export interface ValidatorResult {
3
+ id: string;
4
+ passed: boolean;
5
+ summary: string;
6
+ details?: string;
7
+ }
8
+ export interface ValidatorContext {
9
+ taskId: string;
10
+ workspaceRoot: string;
11
+ scope: readonly string[];
12
+ monorepoRoot?: string;
13
+ artifactsDir?: string;
14
+ taskConfig?: unknown;
15
+ }
16
+ export interface RegisteredValidator extends ValidatorRegistration {
17
+ run(ctx: ValidatorContext): Promise<ValidatorResult>;
18
+ }
19
+ /**
20
+ * Project context handed to task-source factories at instantiation. The
21
+ * server process's cwd is NOT necessarily the project root (workspace-spawned
22
+ * servers run from the engine checkout), so factories that touch the
23
+ * filesystem must resolve relative config paths against `projectRoot`,
24
+ * never cwd.
25
+ */
26
+ export interface TaskSourceFactoryContext {
27
+ projectRoot: string;
28
+ /**
29
+ * Full project config for adapters that need source-adjacent top-level
30
+ * settings (for example github.projects). Factories should still treat
31
+ * TaskSourceConfig as the primary adapter config.
32
+ */
33
+ rigConfig?: RigConfig;
34
+ }
35
+ /**
36
+ * Executable task-source factory contributed by a plugin. A plugin
37
+ * registers a TaskSourceRegistration metadata entry (with `id` and `kind`)
38
+ * AND a factory here that turns a TaskSourceConfig into a RegisteredTaskSource.
39
+ *
40
+ * `kind` is matched against `config.taskSource.kind` at boot. The first
41
+ * matching plugin factory wins; if multiple plugins claim the same kind,
42
+ * `createPluginHost` throws a duplicate-kind error.
43
+ */
44
+ export interface TaskSourceFactoryEntry extends TaskSourceRegistration {
45
+ factory(config: TaskSourceConfig, context?: TaskSourceFactoryContext): RegisteredTaskSource;
46
+ }
47
+ export interface RigPluginRuntime {
48
+ validators?: readonly RegisteredValidator[];
49
+ taskSources?: readonly TaskSourceFactoryEntry[];
50
+ /**
51
+ * Typed hook implementations keyed by hook id. Each key must match a
52
+ * declared `contributes.hooks` entry on the same plugin. A typed hook and
53
+ * a metadata `command` string are mutually exclusive per hook — and when
54
+ * this channel is present, every declared hook must be implemented one way
55
+ * or the other (same all-or-none rule as validators). The runtime's
56
+ * hook-materializer generates the shim command that routes Claude Code's
57
+ * hook invocation to the typed function (see
58
+ * `@rig/runtime/control-plane/hook-runner`).
59
+ */
60
+ hooks?: Record<string, HookImplementation>;
61
+ }
62
+ export type RigPluginWithRuntime = RigPlugin & {
63
+ __runtime?: RigPluginRuntime;
64
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Pure builder that turns a small input shape into the source text of a
3
+ * `rig.config.ts` file. Shared between the CLI `rig init` wizard and the
4
+ * desktop app's in-app setup wizard so both surfaces produce identical
5
+ * output.
6
+ *
7
+ * Pure — no fs, no node, no imports outside this file. Safe to bundle into
8
+ * a renderer (Vite, esbuild, webpack).
9
+ */
10
+ export type RigInitConfigInput = {
11
+ projectName: string;
12
+ projectRepo?: string;
13
+ taskSource: {
14
+ kind: "github-issues";
15
+ owner: string;
16
+ repo: string;
17
+ assignee?: string;
18
+ } | {
19
+ kind: "files";
20
+ path: string;
21
+ };
22
+ useStandardPlugin: boolean;
23
+ };
24
+ export declare function buildRigInitConfigSource(input: RigInitConfigInput): string;
@@ -43,7 +43,7 @@ function buildRigInitConfigSource(input) {
43
43
  lines.push(` issueUpdates: "lifecycle",`);
44
44
  lines.push(` projects: { enabled: false },`);
45
45
  lines.push(` },`);
46
- lines.push(` automation: { maxValidationAttempts: 30, maxPrFixIterations: 30 },`);
46
+ lines.push(` automation: { maxValidationAttempts: 30, maxPrFixIterations: 100500 },`);
47
47
  lines.push(` pr: { mode: "auto", watchChecks: true, autoFixChecks: true, autoFixReview: true },`);
48
48
  lines.push(` merge: { mode: "auto", method: "repo-default", deleteBranch: "repo-default", bypass: false },`);
49
49
  lines.push(` issueAnalysis: { enabled: true, harness: "pi", mode: "continuous" },`);
@@ -0,0 +1,220 @@
1
+ import type { ArtifactSummary, ApprovalSummary, EngineReadModel, GraphSummary, QueueEntry, RemoteConnectionSummary, RemoteEndpoint, RunId, RunJournalProjection, RunStatus, RunSummary, TaskId, TaskStatus, TaskSummary, UserInputRequestSummary, WorkspaceId, WorkspaceSummary } from "@rig/contracts";
2
+ import type { TaskDependencyProjection } from "./taskGraph";
3
+ export declare function selectWorkspaces(snapshot: EngineReadModel | null): readonly WorkspaceSummary[];
4
+ export declare function selectPrimaryWorkspace(snapshot: EngineReadModel | null): WorkspaceSummary | null;
5
+ export declare function pickDefaultWorkspaceId(snapshot: EngineReadModel | null): WorkspaceId | null;
6
+ export declare function selectWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): WorkspaceSummary | null;
7
+ export declare function selectTask(snapshot: EngineReadModel | null, taskId: TaskId | null): TaskSummary | null;
8
+ export declare function selectTasksByWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): TaskSummary[];
9
+ export declare const selectTasksForWorkspace: typeof selectTasksByWorkspace;
10
+ export declare function selectTasksByStatus(snapshot: EngineReadModel | null, status: TaskStatus): TaskSummary[];
11
+ export type RigTaskSessionProjection = Pick<RunJournalProjection, "record" | "status" | "lastEventAt"> & {
12
+ readonly taskId?: string | null;
13
+ };
14
+ export interface RigTaskStatusGroupingInput<T extends TaskDependencyProjection = TaskDependencyProjection> {
15
+ readonly tasks: readonly T[];
16
+ readonly sessions?: readonly RigTaskSessionProjection[];
17
+ readonly workspaceId?: string | null;
18
+ }
19
+ export interface RigTaskStatusGroup<T extends TaskDependencyProjection = TaskDependencyProjection> {
20
+ readonly status: string;
21
+ readonly tasks: readonly T[];
22
+ }
23
+ export declare function projectTaskStatusForGrouping(status: string | null | undefined): string;
24
+ export declare function projectRunStatusForTaskGrouping(status: RunStatus | null | undefined): string | null;
25
+ export declare function projectTaskStatusWithSessions(task: TaskDependencyProjection, sessionsByTask?: ReadonlyMap<string, RigTaskSessionProjection>): string;
26
+ export declare function selectTasksGroupedByStatus(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): Array<{
27
+ status: string;
28
+ tasks: readonly TaskSummary[];
29
+ }>;
30
+ export declare function selectTasksGroupedByStatus<T extends TaskDependencyProjection>(input: RigTaskStatusGroupingInput<T>): Array<RigTaskStatusGroup<T>>;
31
+ export declare function normalizeTaskAssigneeFilter(assignee: string | null | undefined, currentUserLogin?: string | null): string | null;
32
+ export declare function readTaskAssigneeLogins(task: TaskDependencyProjection): readonly string[];
33
+ export declare function taskMatchesAssigneeFilter(task: TaskDependencyProjection, assignee: string | null | undefined, options?: {
34
+ readonly currentUserLogin?: string | null;
35
+ }): boolean;
36
+ export declare function selectTasksAssignedTo<T extends TaskDependencyProjection>(tasks: readonly T[], assignee: string | null | undefined, options?: {
37
+ readonly currentUserLogin?: string | null;
38
+ }): T[];
39
+ export declare function selectTasksAssignedToMe<T extends TaskDependencyProjection>(tasks: readonly T[], currentUserLogin: string | null | undefined): T[];
40
+ export declare function selectRun(snapshot: EngineReadModel | null, runId: RunId | null): RunSummary | null;
41
+ export declare function selectRunsByTask(snapshot: EngineReadModel | null, taskId: TaskId | null): RunSummary[];
42
+ export declare const selectRunsForTask: typeof selectRunsByTask;
43
+ export declare function selectRunsForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): RunSummary[];
44
+ export declare function selectAdhocRuns(snapshot: EngineReadModel | null): RunSummary[];
45
+ export declare function selectAdhocRunsForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): RunSummary[];
46
+ export declare function selectGraphsForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): GraphSummary[];
47
+ export declare function selectQueueForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): QueueEntry[];
48
+ export declare function selectPendingApprovals(snapshot: EngineReadModel | null): ApprovalSummary[];
49
+ export declare function selectApprovalsForRun(snapshot: EngineReadModel | null, runId: RunId | null): ApprovalSummary[];
50
+ export declare function selectPendingApprovalsForRun(snapshot: EngineReadModel | null, runId: RunId | null): ApprovalSummary[];
51
+ export declare function selectApprovalsForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): ApprovalSummary[];
52
+ export declare function selectUserInputsForRun(snapshot: EngineReadModel | null, runId: RunId | null): UserInputRequestSummary[];
53
+ export declare function selectPendingUserInputs(snapshot: EngineReadModel | null): UserInputRequestSummary[];
54
+ export declare function selectPendingUserInputsForRun(snapshot: EngineReadModel | null, runId: RunId | null): UserInputRequestSummary[];
55
+ export declare function selectUserInputsForWorkspace(snapshot: EngineReadModel | null, workspaceId: WorkspaceId | null): UserInputRequestSummary[];
56
+ export declare function selectRuntimeForRun(snapshot: EngineReadModel | null, runId: RunId | null): {
57
+ readonly id: string & import("effect/Brand").Brand<"EngineRuntimeId">;
58
+ readonly updatedAt: string;
59
+ readonly status: "starting" | "running" | "interrupted" | "failed" | "prepared" | "exited" | "destroyed";
60
+ readonly startedAt: string | null;
61
+ readonly pid: number | null;
62
+ readonly stateDir: string | null;
63
+ readonly workspaceId: string & import("effect/Brand").Brand<"WorkspaceId">;
64
+ readonly workspaceDir: string | null;
65
+ readonly homeDir: string | null;
66
+ readonly tmpDir: string | null;
67
+ readonly cacheDir: string | null;
68
+ readonly logsDir: string | null;
69
+ readonly sessionDir: string | null;
70
+ readonly sessionLogPath: string | null;
71
+ readonly exitedAt: string | null;
72
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
73
+ readonly adapterKind: string;
74
+ readonly sandboxMode: "read-only" | "workspace-write" | "danger-full-access";
75
+ readonly isolationMode: "none" | "env" | "worktree";
76
+ readonly executionTarget?: "remote" | "local" | undefined;
77
+ readonly remoteHostId?: string | null | undefined;
78
+ } | null;
79
+ export declare function selectLatestRuntimeForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
80
+ readonly id: string & import("effect/Brand").Brand<"EngineRuntimeId">;
81
+ readonly updatedAt: string;
82
+ readonly status: "starting" | "running" | "interrupted" | "failed" | "prepared" | "exited" | "destroyed";
83
+ readonly startedAt: string | null;
84
+ readonly pid: number | null;
85
+ readonly stateDir: string | null;
86
+ readonly workspaceId: string & import("effect/Brand").Brand<"WorkspaceId">;
87
+ readonly workspaceDir: string | null;
88
+ readonly homeDir: string | null;
89
+ readonly tmpDir: string | null;
90
+ readonly cacheDir: string | null;
91
+ readonly logsDir: string | null;
92
+ readonly sessionDir: string | null;
93
+ readonly sessionLogPath: string | null;
94
+ readonly exitedAt: string | null;
95
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
96
+ readonly adapterKind: string;
97
+ readonly sandboxMode: "read-only" | "workspace-write" | "danger-full-access";
98
+ readonly isolationMode: "none" | "env" | "worktree";
99
+ readonly executionTarget?: "remote" | "local" | undefined;
100
+ readonly remoteHostId?: string | null | undefined;
101
+ } | null;
102
+ export declare function selectActionsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
103
+ readonly id: string & import("effect/Brand").Brand<"ActionId">;
104
+ readonly title: string;
105
+ readonly completedAt: string | null;
106
+ readonly payload: unknown;
107
+ readonly startedAt: string;
108
+ readonly state: string;
109
+ readonly messageId: (string & import("effect/Brand").Brand<"MessageId">) | null;
110
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
111
+ readonly detail: string | null;
112
+ readonly actionType: string;
113
+ }[];
114
+ export declare function selectApprovalsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
115
+ readonly id: string;
116
+ readonly createdAt: string;
117
+ readonly status: "pending" | "resolved";
118
+ readonly payload: unknown;
119
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
120
+ readonly actionId: string | null;
121
+ readonly resolvedAt: string | null;
122
+ readonly requestKind: string;
123
+ }[];
124
+ export declare function selectUserInputsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
125
+ readonly id: string;
126
+ readonly createdAt: string;
127
+ readonly status: "pending" | "resolved";
128
+ readonly payload: unknown;
129
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
130
+ readonly resolvedAt: string | null;
131
+ }[];
132
+ export declare function selectValidationsForRun(snapshot: EngineReadModel | null, runId: RunId | null): {
133
+ readonly id: string & import("effect/Brand").Brand<"ValidationResultId">;
134
+ readonly status: "running" | "pending" | "failed" | "passed" | "skipped";
135
+ readonly completedAt: string | null;
136
+ readonly startedAt: string;
137
+ readonly taskId: (string & import("effect/Brand").Brand<"TaskId">) | null;
138
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
139
+ readonly validatorKey: string;
140
+ readonly output: unknown;
141
+ }[];
142
+ export declare function selectValidationsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
143
+ readonly id: string & import("effect/Brand").Brand<"ValidationResultId">;
144
+ readonly status: "running" | "pending" | "failed" | "passed" | "skipped";
145
+ readonly completedAt: string | null;
146
+ readonly startedAt: string;
147
+ readonly taskId: (string & import("effect/Brand").Brand<"TaskId">) | null;
148
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
149
+ readonly validatorKey: string;
150
+ readonly output: unknown;
151
+ }[];
152
+ export declare function selectFailedValidations(snapshot: EngineReadModel | null, runId: RunId | null): {
153
+ readonly id: string & import("effect/Brand").Brand<"ValidationResultId">;
154
+ readonly status: "running" | "pending" | "failed" | "passed" | "skipped";
155
+ readonly completedAt: string | null;
156
+ readonly startedAt: string;
157
+ readonly taskId: (string & import("effect/Brand").Brand<"TaskId">) | null;
158
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
159
+ readonly validatorKey: string;
160
+ readonly output: unknown;
161
+ }[];
162
+ export declare function selectReviewsForRun(snapshot: EngineReadModel | null, runId: RunId | null): {
163
+ readonly id: string & import("effect/Brand").Brand<"ReviewResultId">;
164
+ readonly createdAt: string;
165
+ readonly status: "running" | "error" | "rejected" | "pending" | "approved";
166
+ readonly completedAt: string | null;
167
+ readonly summary: string | null;
168
+ readonly provider: string;
169
+ readonly mode: "required" | "off" | "advisory";
170
+ readonly taskId: (string & import("effect/Brand").Brand<"TaskId">) | null;
171
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
172
+ readonly output: unknown;
173
+ }[];
174
+ export declare function selectReviewsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
175
+ readonly id: string & import("effect/Brand").Brand<"ReviewResultId">;
176
+ readonly createdAt: string;
177
+ readonly status: "running" | "error" | "rejected" | "pending" | "approved";
178
+ readonly completedAt: string | null;
179
+ readonly summary: string | null;
180
+ readonly provider: string;
181
+ readonly mode: "required" | "off" | "advisory";
182
+ readonly taskId: (string & import("effect/Brand").Brand<"TaskId">) | null;
183
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
184
+ readonly output: unknown;
185
+ }[];
186
+ export declare function selectArtifactsForRun(snapshot: EngineReadModel | null, runId: RunId | null): ArtifactSummary[];
187
+ export declare function selectArtifactsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): ArtifactSummary[];
188
+ export declare function selectPolicyDecisionsForTask(snapshot: EngineReadModel | null, taskId: TaskId | null): {
189
+ readonly id: string;
190
+ readonly createdAt: string;
191
+ readonly decision: "allow" | "block" | "warn";
192
+ readonly mode: "off" | "enforce" | "observe";
193
+ readonly runId: string & import("effect/Brand").Brand<"RunId">;
194
+ readonly actionId: (string & import("effect/Brand").Brand<"ActionId">) | null;
195
+ readonly reason: string;
196
+ readonly matchedRules: readonly string[];
197
+ }[];
198
+ export declare function selectRemoteEndpoints(snapshot: EngineReadModel | null): readonly RemoteEndpoint[];
199
+ export declare function selectRemoteConnections(snapshot: EngineReadModel | null): readonly RemoteConnectionSummary[];
200
+ export declare function selectRemoteEndpoint(snapshot: EngineReadModel | null, endpointId: string | null): {
201
+ readonly id: string & import("effect/Brand").Brand<"RemoteEndpointId">;
202
+ readonly port: number;
203
+ readonly lastConnectedAt: string | null;
204
+ readonly alias: string;
205
+ readonly host: string;
206
+ readonly token: string;
207
+ readonly addedAt: string;
208
+ readonly tokenConfigured?: boolean | undefined;
209
+ readonly autoConnect?: boolean | undefined;
210
+ } | null;
211
+ export declare function selectRemoteConnection(snapshot: EngineReadModel | null, endpointId: string | null): {
212
+ readonly error: string | null;
213
+ readonly status: "error" | "disconnected" | "connecting" | "authenticating" | "connected" | "reconnecting";
214
+ readonly endpointId: string & import("effect/Brand").Brand<"RemoteEndpointId">;
215
+ readonly connectedAt: string | null;
216
+ readonly tokenExpiresAt: string | null;
217
+ readonly latencyMs: number | null;
218
+ readonly subscribedEvents: readonly string[];
219
+ } | null;
220
+ export declare function selectConnectedRemoteCount(snapshot: EngineReadModel | null): number;