@h-rig/core 0.0.6-alpha.18 → 0.0.6-alpha.181
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.
- package/dist/src/agent-role-registry.d.ts +4 -0
- package/dist/src/agent-role-registry.js +27 -0
- package/dist/src/authority-paths.d.ts +15 -0
- package/dist/src/authority-paths.js +80 -0
- package/dist/src/baked-secrets.d.ts +3 -0
- package/dist/src/baked-secrets.js +63 -0
- package/dist/src/build-time-config.d.ts +12 -0
- package/dist/src/build-time-config.js +25 -0
- package/dist/src/build-time-config.macro.d.ts +1 -0
- package/dist/src/capability-loaders.d.ts +51 -0
- package/dist/src/capability-loaders.js +870 -0
- package/dist/src/capability.d.ts +79 -0
- package/dist/src/capability.js +63 -0
- package/dist/src/checkout-root.d.ts +1 -0
- package/dist/src/checkout-root.js +30 -0
- package/dist/src/config-env.d.ts +4 -0
- package/dist/src/config-env.js +23 -0
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.js +44 -0
- package/dist/src/declarative-config.d.ts +14 -0
- package/dist/src/declarative-config.js +85 -0
- package/dist/src/default-kernel.d.ts +1 -0
- package/dist/src/default-kernel.js +12 -0
- package/dist/src/define-config.d.ts +20 -0
- package/dist/src/define-config.js +28 -15
- package/dist/src/define-plugin.d.ts +13 -0
- package/dist/src/define-plugin.js +4 -43
- package/dist/src/embedded-plugins.d.ts +59 -0
- package/dist/src/embedded-plugins.js +22 -0
- package/dist/src/exec.d.ts +13 -0
- package/dist/src/exec.js +101 -0
- package/dist/src/harness-paths.d.ts +9 -0
- package/dist/src/harness-paths.js +126 -0
- package/dist/src/hook-materializer.d.ts +21 -0
- package/dist/src/hook-materializer.js +152 -0
- package/dist/src/hook-protocol.d.ts +2 -0
- package/dist/src/hook-protocol.js +432 -0
- package/dist/src/hook-runner.d.ts +48 -0
- package/dist/src/hook-runner.js +868 -0
- package/dist/src/hook-runtime.d.ts +52 -0
- package/dist/src/hook-runtime.js +432 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +210 -2499
- package/dist/src/json-files.d.ts +9 -0
- package/dist/src/json-files.js +124 -0
- package/dist/src/kernel-boot.d.ts +2 -0
- package/dist/src/kernel-boot.js +10 -0
- package/dist/src/kernel-entrypoint.d.ts +22 -0
- package/dist/src/kernel-entrypoint.js +660 -0
- package/dist/src/kernel-plugin-abi.d.ts +1 -0
- package/dist/src/kernel-plugin-abi.js +1 -0
- package/dist/src/kernel-resolver.d.ts +2 -0
- package/dist/src/kernel-resolver.js +6 -0
- package/dist/src/layout.d.ts +10 -0
- package/dist/src/layout.js +138 -0
- package/dist/src/load-config.d.ts +2 -0
- package/dist/src/load-config.js +535 -30
- package/dist/src/placement.d.ts +58 -0
- package/dist/src/placement.js +53 -0
- package/dist/src/plugin-host-context.d.ts +65 -0
- package/dist/src/plugin-host-context.js +1171 -0
- package/dist/src/plugin-host-registries.d.ts +31 -0
- package/dist/src/plugin-host-registries.js +79 -0
- package/dist/src/plugin-host.d.ts +77 -0
- package/dist/src/plugin-host.js +127 -63
- package/dist/src/plugin-runtime.d.ts +173 -0
- package/dist/src/project-plugins.d.ts +63 -0
- package/dist/src/project-plugins.js +905 -0
- package/dist/src/remote-config.d.ts +125 -0
- package/dist/src/remote-config.js +85 -0
- package/dist/src/root-resolver.d.ts +5 -0
- package/dist/src/root-resolver.js +68 -0
- package/dist/src/run-provisioning.d.ts +37 -0
- package/dist/src/run-provisioning.js +35 -0
- package/dist/src/runtime-context.d.ts +20 -0
- package/dist/src/runtime-context.js +257 -0
- package/dist/src/runtime-events.d.ts +44 -0
- package/dist/src/runtime-events.js +208 -0
- package/dist/src/runtime-overlay.d.ts +11 -0
- package/dist/src/runtime-overlay.js +69 -0
- package/dist/src/runtime-paths.d.ts +21 -0
- package/dist/src/runtime-paths.js +181 -0
- package/dist/src/runtime-provisioning-env.d.ts +5 -0
- package/dist/src/runtime-provisioning-env.js +217 -0
- package/dist/src/runtime-runner-context.d.ts +12 -0
- package/dist/src/runtime-runner-context.js +1 -0
- package/dist/src/safe-identifiers.d.ts +44 -0
- package/dist/src/safe-identifiers.js +96 -0
- package/dist/src/scope-rules.d.ts +4 -0
- package/dist/src/scope-rules.js +21 -0
- package/dist/src/server-paths.d.ts +22 -0
- package/dist/src/server-paths.js +219 -0
- package/dist/src/setup-version.d.ts +3 -0
- package/dist/src/setup-version.js +14 -0
- package/dist/src/task-record-reader.d.ts +3 -0
- package/dist/src/task-record-reader.js +9 -0
- package/dist/src/validator-registry.d.ts +27 -0
- package/dist/src/validator-registry.js +64 -0
- package/package.json +162 -10
- package/dist/src/engineReadModelReducer.js +0 -1780
- package/dist/src/rig-init-builder.js +0 -57
- package/dist/src/rigSelectors.js +0 -293
- package/dist/src/taskGraph.js +0 -64
- package/dist/src/taskGraphCodes.js +0 -26
- package/dist/src/taskGraphLayout.js +0 -374
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The capability SEAM helper.
|
|
3
|
+
*
|
|
4
|
+
* `defineCapability<T>(id)` turns a phantom-typed `CapabilityId<T>` (from
|
|
5
|
+
* `@rig/contracts`) into a tiny typed wrapper a provider plugin and its
|
|
6
|
+
* consumers share:
|
|
7
|
+
*
|
|
8
|
+
* - `provide(impl, opts)` builds the single-channel `FeatureCapability`
|
|
9
|
+
* contribution entry (`{ id, title, run }`) the plugin host indexes. `impl`
|
|
10
|
+
* is either the service value `T` or a (lazy) factory `() => T | Promise<T>`
|
|
11
|
+
* — the factory form keeps a provider CONFIG-LIGHT (it can `await import()`
|
|
12
|
+
* its heavy impl inside `run()` instead of at module top level).
|
|
13
|
+
* - `resolve(host)` looks the capability up by id on the host
|
|
14
|
+
* (`host.listExecutableCapabilities().find(c => c.id === id)`) and awaits its
|
|
15
|
+
* `run()`, typed as `T`. There is exactly ONE `unknown → T` cast in this
|
|
16
|
+
* file (inside `resolve`), justified because the seam — not the caller —
|
|
17
|
+
* owns the `CapabilityId<T>` ⇄ impl correspondence.
|
|
18
|
+
* - `require(host)` is `resolve` that throws a typed
|
|
19
|
+
* `CapabilityProviderMissingError` instead of returning `null`.
|
|
20
|
+
*
|
|
21
|
+
* This is the seam the locked architecture's `defineCapability` describes,
|
|
22
|
+
* resolving over the EXISTING `FeatureCapability`/`listExecutableCapabilities`
|
|
23
|
+
* single channel (no change to `RigPlugin` in this step).
|
|
24
|
+
*/
|
|
25
|
+
import type { CapabilityId } from "@rig/contracts";
|
|
26
|
+
import type { PluginHost } from "./plugin-host";
|
|
27
|
+
import type { FeatureCapability } from "./plugin-runtime";
|
|
28
|
+
/** A value `T`, or a (possibly async, possibly lazy) factory that yields one. */
|
|
29
|
+
export type CapabilityImpl<T> = T | (() => T | Promise<T>);
|
|
30
|
+
/** Metadata for the contributed capability entry (the serializable manifest). */
|
|
31
|
+
export interface CapabilityProvideOptions {
|
|
32
|
+
/** Human title shown in capability listings. Defaults to the capability id. */
|
|
33
|
+
readonly title?: string;
|
|
34
|
+
/** Optional human description. */
|
|
35
|
+
readonly description?: string;
|
|
36
|
+
}
|
|
37
|
+
/** Thrown by `require` when no plugin provides the capability on the host. */
|
|
38
|
+
export declare class CapabilityProviderMissingError extends Error {
|
|
39
|
+
readonly capabilityId: string;
|
|
40
|
+
readonly name = "CapabilityProviderMissingError";
|
|
41
|
+
constructor(capabilityId: string);
|
|
42
|
+
}
|
|
43
|
+
/** The typed wrapper `defineCapability<T>` returns. */
|
|
44
|
+
export interface Capability<T> {
|
|
45
|
+
readonly id: CapabilityId<T>;
|
|
46
|
+
/** Build the single-channel capability contribution entry for a plugin. */
|
|
47
|
+
provide(impl: CapabilityImpl<T>, opts?: CapabilityProvideOptions): FeatureCapability;
|
|
48
|
+
/** Resolve the impl off a built plugin host, or `null` when absent. */
|
|
49
|
+
resolve(host: PluginHost): Promise<T | null>;
|
|
50
|
+
/** Resolve the impl or throw `CapabilityProviderMissingError`. */
|
|
51
|
+
require(host: PluginHost): Promise<T>;
|
|
52
|
+
}
|
|
53
|
+
/** A service object `TService`, or a factory that yields one. */
|
|
54
|
+
export type ServiceCapabilityImpl<TService extends object> = CapabilityImpl<TService>;
|
|
55
|
+
/** The service-object wrapper `defineServiceCapability<TService>` returns. */
|
|
56
|
+
export interface ServiceCapability<TService extends object> extends Capability<TService> {
|
|
57
|
+
/** Build the single-channel capability contribution entry for a service provider plugin. */
|
|
58
|
+
provideService(impl: ServiceCapabilityImpl<TService>, opts?: CapabilityProvideOptions): FeatureCapability;
|
|
59
|
+
/** Resolve the service object off a built plugin host, or `null` when absent. */
|
|
60
|
+
resolveService(host: PluginHost): Promise<TService | null>;
|
|
61
|
+
/** Resolve the service object or throw `CapabilityProviderMissingError`. */
|
|
62
|
+
requireService(host: PluginHost): Promise<TService>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Define a typed capability seam for `id`. Pure and id-keyed: it holds no
|
|
66
|
+
* mutable state, so independent `defineCapability(SAME_ID)` calls (the provider
|
|
67
|
+
* plugin and a substrate consumer, which must not import each other) behave
|
|
68
|
+
* identically — the shared source of truth is the `CapabilityId<T>` in
|
|
69
|
+
* `@rig/contracts`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function defineCapability<T>(id: CapabilityId<T>): Capability<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Define a typed multi-method service-object capability seam for `id`.
|
|
74
|
+
*
|
|
75
|
+
* This is an explicit naming layer over `defineCapability`: providers call
|
|
76
|
+
* `provideService`, consumers call `resolveService`/`requireService`, and all
|
|
77
|
+
* three aliases delegate to the same single resolver path as `defineCapability`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function defineServiceCapability<TService extends object>(id: CapabilityId<TService>): ServiceCapability<TService>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/capability.ts
|
|
3
|
+
import { resolveCapability } from "@rig/kernel-seed";
|
|
4
|
+
|
|
5
|
+
class CapabilityProviderMissingError extends Error {
|
|
6
|
+
capabilityId;
|
|
7
|
+
name = "CapabilityProviderMissingError";
|
|
8
|
+
constructor(capabilityId) {
|
|
9
|
+
super(`No provider resolved for capability "${capabilityId}"`);
|
|
10
|
+
this.capabilityId = capabilityId;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function isFactory(impl) {
|
|
14
|
+
return typeof impl === "function";
|
|
15
|
+
}
|
|
16
|
+
function defineCapability(id) {
|
|
17
|
+
const idString = String(id);
|
|
18
|
+
const tag = idString;
|
|
19
|
+
async function resolve(host) {
|
|
20
|
+
const providers = host.listExecutableCapabilities().filter((c) => c.id === idString && typeof c.run === "function").map((c) => ({
|
|
21
|
+
name: c.id,
|
|
22
|
+
provides: [c.id],
|
|
23
|
+
capabilityProviders: { [c.id]: c.run }
|
|
24
|
+
}));
|
|
25
|
+
const resolution = resolveCapability(providers, tag);
|
|
26
|
+
const run = resolution?.value;
|
|
27
|
+
if (!run)
|
|
28
|
+
return null;
|
|
29
|
+
return await run(undefined);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
id,
|
|
33
|
+
provide(impl, opts) {
|
|
34
|
+
return {
|
|
35
|
+
id: idString,
|
|
36
|
+
title: opts?.title ?? idString,
|
|
37
|
+
...opts?.description !== undefined ? { description: opts.description } : {},
|
|
38
|
+
run: isFactory(impl) ? () => impl() : () => impl
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
resolve,
|
|
42
|
+
async require(host) {
|
|
43
|
+
const value = await resolve(host);
|
|
44
|
+
if (value === null)
|
|
45
|
+
throw new CapabilityProviderMissingError(idString);
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function defineServiceCapability(id) {
|
|
51
|
+
const capability = defineCapability(id);
|
|
52
|
+
return {
|
|
53
|
+
...capability,
|
|
54
|
+
provideService: capability.provide,
|
|
55
|
+
resolveService: capability.resolve,
|
|
56
|
+
requireService: capability.require
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
defineServiceCapability,
|
|
61
|
+
defineCapability,
|
|
62
|
+
CapabilityProviderMissingError
|
|
63
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveCheckoutRoot(projectRoot: string): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/checkout-root.ts
|
|
3
|
+
import { dirname, resolve } from "path";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
function findNearestGitCheckoutRoot(startDir) {
|
|
6
|
+
let current = resolve(startDir);
|
|
7
|
+
for (;; ) {
|
|
8
|
+
if (existsSync(resolve(current, ".git")))
|
|
9
|
+
return current;
|
|
10
|
+
const parent = dirname(current);
|
|
11
|
+
if (parent === current)
|
|
12
|
+
return null;
|
|
13
|
+
current = parent;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function resolveCheckoutRoot(projectRoot) {
|
|
17
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
18
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
19
|
+
if (explicit) {
|
|
20
|
+
const explicitRoot = resolve(explicit);
|
|
21
|
+
const gitRoot = findNearestGitCheckoutRoot(explicitRoot);
|
|
22
|
+
if (gitRoot)
|
|
23
|
+
return gitRoot;
|
|
24
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there or above it.`);
|
|
25
|
+
}
|
|
26
|
+
return findNearestGitCheckoutRoot(normalizedProjectRoot) ?? normalizedProjectRoot;
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
resolveCheckoutRoot
|
|
30
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RigConfig } from "@rig/contracts";
|
|
2
|
+
/** Apply rig.config.ts environment defaults without overriding ambient env. */
|
|
3
|
+
export declare function applyConfigEnv(config: Pick<RigConfig, "env" | "runtime">, env?: NodeJS.ProcessEnv): void;
|
|
4
|
+
export declare const applyRigConfigEnv: typeof applyConfigEnv;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/config-env.ts
|
|
3
|
+
function applyConfigEnv(config, env = process.env) {
|
|
4
|
+
const fill = (key, value) => {
|
|
5
|
+
if (value && !env[key])
|
|
6
|
+
env[key] = value;
|
|
7
|
+
};
|
|
8
|
+
const server = config.runtime?.server;
|
|
9
|
+
if (server) {
|
|
10
|
+
const host = server.host?.trim();
|
|
11
|
+
fill("RIG_COLLAB_RELAY", server.relayUrl ?? (host ? `wss://${host}` : undefined));
|
|
12
|
+
fill("RIG_REGISTRY_URL", server.registryUrl ?? (host ? `https://${host}/registry` : undefined));
|
|
13
|
+
fill("RIG_SSH_TARGET", server.sshTarget);
|
|
14
|
+
fill("RIG_REMOTE_CHECKOUT", server.checkout);
|
|
15
|
+
}
|
|
16
|
+
for (const [key, value] of Object.entries(config.env ?? {}))
|
|
17
|
+
fill(key, value);
|
|
18
|
+
}
|
|
19
|
+
var applyRigConfigEnv = applyConfigEnv;
|
|
20
|
+
export {
|
|
21
|
+
applyRigConfigEnv,
|
|
22
|
+
applyConfigEnv
|
|
23
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { defineConfig, type RigConfigInput } from "./define-config";
|
|
2
|
+
export { definePlugin } from "./define-plugin";
|
|
3
|
+
export type { RigPlugin, PluginContributes, PluginConfigContribution, ConfigDefaultsContext, Validator, TaskSource, FeatureCapability, Panel, BlockerClassifierEntry, CliCommand, Hook, StageEntry, SessionExtensionEntry, SessionExtensionInstall, SeedEntrypoint, SeedEntrypointContext, SeedEntrypointRunResult, RuntimeCliContext, TaskSourceFactoryContext, ValidatorContext, ValidatorResult, } from "./plugin-runtime";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/define-config.ts
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
import { RigConfig } from "@rig/contracts";
|
|
5
|
+
function normalizeWorkspaceConfig(raw) {
|
|
6
|
+
const workspace = raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
|
|
7
|
+
if (workspace.mainRepo === undefined)
|
|
8
|
+
workspace.mainRepo = ".";
|
|
9
|
+
if (workspace.checkout === undefined && workspace.isolation !== undefined)
|
|
10
|
+
workspace.checkout = workspace.isolation;
|
|
11
|
+
if (workspace.isolation === undefined && workspace.checkout !== undefined)
|
|
12
|
+
workspace.isolation = workspace.checkout;
|
|
13
|
+
return workspace;
|
|
14
|
+
}
|
|
15
|
+
function applyConfigDefaults(raw) {
|
|
16
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
17
|
+
return raw;
|
|
18
|
+
const record = raw;
|
|
19
|
+
return {
|
|
20
|
+
...record,
|
|
21
|
+
plugins: Array.isArray(record.plugins) ? record.plugins.flat() : [],
|
|
22
|
+
workspace: normalizeWorkspaceConfig(record.workspace)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function defineConfig(cfg) {
|
|
26
|
+
const withDefaults = applyConfigDefaults(cfg);
|
|
27
|
+
const explicitPlugins = Array.isArray(withDefaults.plugins) ? [...withDefaults.plugins] : [];
|
|
28
|
+
const decoded = Schema.decodeUnknownSync(RigConfig)({
|
|
29
|
+
...withDefaults,
|
|
30
|
+
plugins: explicitPlugins
|
|
31
|
+
});
|
|
32
|
+
return { ...decoded, plugins: explicitPlugins };
|
|
33
|
+
}
|
|
34
|
+
// packages/core/src/define-plugin.ts
|
|
35
|
+
import { Schema as Schema2 } from "effect";
|
|
36
|
+
import { RigPlugin as RigPluginManifest } from "@rig/contracts";
|
|
37
|
+
function definePlugin(plugin) {
|
|
38
|
+
Schema2.decodeUnknownSync(RigPluginManifest)(plugin);
|
|
39
|
+
return plugin;
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
definePlugin,
|
|
43
|
+
defineConfig
|
|
44
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RigConfig } from "@rig/contracts";
|
|
2
|
+
/**
|
|
3
|
+
* Locate a declarative `.rig/rigfig.{toml,json}`, or null if the project has none.
|
|
4
|
+
*
|
|
5
|
+
* All declarative configuration lives inside the project's `.rig/` directory
|
|
6
|
+
* (autocreated) — there is no top-level config file. `.rig/` keeps the data
|
|
7
|
+
* config alongside the rest of rig's per-project state.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findDeclarativeConfigPath(cwd: string): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Load a declarative `.rig/` config into a fully-formed RigConfig, resolving
|
|
12
|
+
* `plugins` from the embedded standard collection.
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadDeclarativeConfig(path: string): RigConfig;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/declarative-config.ts
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { parse as parseToml } from "smol-toml";
|
|
6
|
+
import { Schema as Schema2 } from "effect";
|
|
7
|
+
import { RigConfig as RigConfig2 } from "@rig/contracts";
|
|
8
|
+
|
|
9
|
+
// packages/core/src/define-config.ts
|
|
10
|
+
import { Schema } from "effect";
|
|
11
|
+
import { RigConfig } from "@rig/contracts";
|
|
12
|
+
function normalizeWorkspaceConfig(raw) {
|
|
13
|
+
const workspace = raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
|
|
14
|
+
if (workspace.mainRepo === undefined)
|
|
15
|
+
workspace.mainRepo = ".";
|
|
16
|
+
if (workspace.checkout === undefined && workspace.isolation !== undefined)
|
|
17
|
+
workspace.checkout = workspace.isolation;
|
|
18
|
+
if (workspace.isolation === undefined && workspace.checkout !== undefined)
|
|
19
|
+
workspace.isolation = workspace.checkout;
|
|
20
|
+
return workspace;
|
|
21
|
+
}
|
|
22
|
+
function applyConfigDefaults(raw) {
|
|
23
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
24
|
+
return raw;
|
|
25
|
+
const record = raw;
|
|
26
|
+
return {
|
|
27
|
+
...record,
|
|
28
|
+
plugins: Array.isArray(record.plugins) ? record.plugins.flat() : [],
|
|
29
|
+
workspace: normalizeWorkspaceConfig(record.workspace)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// packages/core/src/embedded-plugins.ts
|
|
34
|
+
var registered = null;
|
|
35
|
+
function getStandardPluginsResolver() {
|
|
36
|
+
return registered;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// packages/core/src/declarative-config.ts
|
|
40
|
+
var DECLARATIVE_CONFIG_NAMES = ["rigfig.toml", "rigfig.json"];
|
|
41
|
+
function findDeclarativeConfigPath(cwd) {
|
|
42
|
+
const dir = join(cwd, ".rig");
|
|
43
|
+
for (const name of DECLARATIVE_CONFIG_NAMES) {
|
|
44
|
+
const candidate = join(dir, name);
|
|
45
|
+
if (existsSync(candidate))
|
|
46
|
+
return candidate;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
function parseDeclarativeFile(path) {
|
|
51
|
+
const raw = readFileSync(path, "utf8");
|
|
52
|
+
const parsed = path.endsWith(".json") ? JSON.parse(raw) : parseToml(raw);
|
|
53
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
54
|
+
throw new Error(`Declarative config ${path} must parse to an object.`);
|
|
55
|
+
}
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
function loadDeclarativeConfig(path) {
|
|
59
|
+
const data = parseDeclarativeFile(path);
|
|
60
|
+
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : null;
|
|
61
|
+
if (standardSection?.enabled !== true && standardSection?.enabled !== false) {
|
|
62
|
+
throw new Error(`Declarative config ${path} must explicitly set [standard] enabled = true or false.`);
|
|
63
|
+
}
|
|
64
|
+
const useStandard = standardSection.enabled === true;
|
|
65
|
+
let plugins = [];
|
|
66
|
+
if (useStandard) {
|
|
67
|
+
const resolver = getStandardPluginsResolver();
|
|
68
|
+
if (!resolver) {
|
|
69
|
+
throw new Error(`Declarative config ${path} needs the embedded standard plugins, but none were registered. ` + `This is a seed/boot wiring error (the binary entrypoint must import the standard-plugin registration).`);
|
|
70
|
+
}
|
|
71
|
+
plugins = resolver(data);
|
|
72
|
+
}
|
|
73
|
+
const { standard: _standardDirective, ...configFields } = data;
|
|
74
|
+
const withDefaults = applyConfigDefaults({ ...configFields, plugins });
|
|
75
|
+
const explicitPlugins = Array.isArray(withDefaults.plugins) ? [...withDefaults.plugins] : [];
|
|
76
|
+
const decoded = Schema2.decodeUnknownSync(RigConfig2)({
|
|
77
|
+
...withDefaults,
|
|
78
|
+
plugins: explicitPlugins
|
|
79
|
+
});
|
|
80
|
+
return { ...decoded, plugins: explicitPlugins };
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
loadDeclarativeConfig,
|
|
84
|
+
findDeclarativeConfigPath
|
|
85
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDefaultKernel, createDefaultKernelPlugin, createPlacementTransportPlugin, } from "@rig/kernel-seed/default-kernel";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/default-kernel.ts
|
|
3
|
+
import {
|
|
4
|
+
createDefaultKernel,
|
|
5
|
+
createDefaultKernelPlugin,
|
|
6
|
+
createPlacementTransportPlugin
|
|
7
|
+
} from "@rig/kernel-seed/default-kernel";
|
|
8
|
+
export {
|
|
9
|
+
createPlacementTransportPlugin,
|
|
10
|
+
createDefaultKernelPlugin,
|
|
11
|
+
createDefaultKernel
|
|
12
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RigConfig } from "@rig/contracts";
|
|
2
|
+
import type { RigPlugin } from "./plugin-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Author-facing config input: `plugins` and `workspace` are optional and
|
|
5
|
+
* default to a plugin-less worktree setup, so the minimal documented config
|
|
6
|
+
* (project + taskSource) works out of the box.
|
|
7
|
+
*/
|
|
8
|
+
export type RigConfigInput = Omit<RigConfig, "plugins" | "workspace"> & {
|
|
9
|
+
plugins?: ReadonlyArray<RigPlugin | readonly RigPlugin[]> | RigConfig["plugins"];
|
|
10
|
+
workspace?: RigConfig["workspace"];
|
|
11
|
+
};
|
|
12
|
+
/** Fill optional top-level sections before Schema decode (which requires them). */
|
|
13
|
+
export declare function applyConfigDefaults(raw: unknown): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Validate a Rig config while preserving the explicit plugin object identities
|
|
16
|
+
* supplied by the config author. Schema validates the serializable metadata
|
|
17
|
+
* shape, but the returned config keeps the original executable plugin objects;
|
|
18
|
+
* there is no name-based runtime hydration or reattachment step.
|
|
19
|
+
*/
|
|
20
|
+
export declare function defineConfig(cfg: RigConfigInput): RigConfig;
|
|
@@ -2,23 +2,36 @@
|
|
|
2
2
|
// packages/core/src/define-config.ts
|
|
3
3
|
import { Schema } from "effect";
|
|
4
4
|
import { RigConfig } from "@rig/contracts";
|
|
5
|
+
function normalizeWorkspaceConfig(raw) {
|
|
6
|
+
const workspace = raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
|
|
7
|
+
if (workspace.mainRepo === undefined)
|
|
8
|
+
workspace.mainRepo = ".";
|
|
9
|
+
if (workspace.checkout === undefined && workspace.isolation !== undefined)
|
|
10
|
+
workspace.checkout = workspace.isolation;
|
|
11
|
+
if (workspace.isolation === undefined && workspace.checkout !== undefined)
|
|
12
|
+
workspace.isolation = workspace.checkout;
|
|
13
|
+
return workspace;
|
|
14
|
+
}
|
|
15
|
+
function applyConfigDefaults(raw) {
|
|
16
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
17
|
+
return raw;
|
|
18
|
+
const record = raw;
|
|
19
|
+
return {
|
|
20
|
+
...record,
|
|
21
|
+
plugins: Array.isArray(record.plugins) ? record.plugins.flat() : [],
|
|
22
|
+
workspace: normalizeWorkspaceConfig(record.workspace)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
5
25
|
function defineConfig(cfg) {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const decoded = Schema.decodeUnknownSync(RigConfig)(cfg);
|
|
14
|
-
const decodedPlugins = decoded.plugins.map((p) => {
|
|
15
|
-
const runtime = runtimeByName.get(p.name);
|
|
16
|
-
if (!runtime)
|
|
17
|
-
return p;
|
|
18
|
-
return { ...p, __runtime: runtime };
|
|
26
|
+
const withDefaults = applyConfigDefaults(cfg);
|
|
27
|
+
const explicitPlugins = Array.isArray(withDefaults.plugins) ? [...withDefaults.plugins] : [];
|
|
28
|
+
const decoded = Schema.decodeUnknownSync(RigConfig)({
|
|
29
|
+
...withDefaults,
|
|
30
|
+
plugins: explicitPlugins
|
|
19
31
|
});
|
|
20
|
-
return { ...decoded, plugins:
|
|
32
|
+
return { ...decoded, plugins: explicitPlugins };
|
|
21
33
|
}
|
|
22
34
|
export {
|
|
23
|
-
defineConfig
|
|
35
|
+
defineConfig,
|
|
36
|
+
applyConfigDefaults
|
|
24
37
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RigPlugin } from "./plugin-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Define a Rig plugin. Single-channel: the plugin is ONE object whose
|
|
4
|
+
* `contributes` entries each carry their schema-validated metadata AND their
|
|
5
|
+
* executable fn together (no second argument, no separate runtime channel).
|
|
6
|
+
*
|
|
7
|
+
* Validation decodes the plugin against the `RigPlugin` metadata manifest in
|
|
8
|
+
* @rig/contracts — this throws on malformed metadata (bad name/version,
|
|
9
|
+
* invalid registration). The executable fns and `capabilityProviders` ride on
|
|
10
|
+
* the same object and are ignored by Schema decode (effect strips excess), so
|
|
11
|
+
* the original object is returned unchanged with its fns intact.
|
|
12
|
+
*/
|
|
13
|
+
export declare function definePlugin(plugin: RigPlugin): RigPlugin;
|
|
@@ -1,49 +1,10 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/core/src/define-plugin.ts
|
|
3
3
|
import { Schema } from "effect";
|
|
4
|
-
import { RigPlugin } from "@rig/contracts";
|
|
5
|
-
function definePlugin(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return validated;
|
|
9
|
-
}
|
|
10
|
-
const declaredValidators = new Map((validated.contributes?.validators ?? []).map((v) => [v.id, v]));
|
|
11
|
-
const runtimeValidators = new Map((runtime.validators ?? []).map((v) => [v.id, v]));
|
|
12
|
-
for (const v of runtimeValidators.values()) {
|
|
13
|
-
const metadata = declaredValidators.get(v.id);
|
|
14
|
-
if (!metadata) {
|
|
15
|
-
throw new Error(`definePlugin(${validated.name}): executable validator "${v.id}" has no matching metadata entry in contributes.validators`);
|
|
16
|
-
}
|
|
17
|
-
if (metadata.category !== v.category) {
|
|
18
|
-
throw new Error(`definePlugin(${validated.name}): executable validator "${v.id}" category "${v.category}" does not match metadata category "${metadata.category}"`);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (runtime.validators) {
|
|
22
|
-
for (const v of declaredValidators.values()) {
|
|
23
|
-
if (!runtimeValidators.has(v.id)) {
|
|
24
|
-
throw new Error(`definePlugin(${validated.name}): validator metadata "${v.id}" has no runtime implementation`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const declaredSources = new Map((validated.contributes?.taskSources ?? []).map((s) => [s.id, s]));
|
|
29
|
-
const runtimeSources = new Map((runtime.taskSources ?? []).map((s) => [s.id, s]));
|
|
30
|
-
for (const s of runtimeSources.values()) {
|
|
31
|
-
const metadata = declaredSources.get(s.id);
|
|
32
|
-
if (!metadata) {
|
|
33
|
-
throw new Error(`definePlugin(${validated.name}): executable task source "${s.id}" has no matching metadata entry in contributes.taskSources`);
|
|
34
|
-
}
|
|
35
|
-
if (metadata.kind !== s.kind) {
|
|
36
|
-
throw new Error(`definePlugin(${validated.name}): executable task source "${s.id}" kind "${s.kind}" does not match metadata kind "${metadata.kind}"`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (runtime.taskSources) {
|
|
40
|
-
for (const s of declaredSources.values()) {
|
|
41
|
-
if (!runtimeSources.has(s.id)) {
|
|
42
|
-
throw new Error(`definePlugin(${validated.name}): task source metadata "${s.id}" has no runtime implementation`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return { ...validated, __runtime: runtime };
|
|
4
|
+
import { RigPlugin as RigPluginManifest } from "@rig/contracts";
|
|
5
|
+
function definePlugin(plugin) {
|
|
6
|
+
Schema.decodeUnknownSync(RigPluginManifest)(plugin);
|
|
7
|
+
return plugin;
|
|
47
8
|
}
|
|
48
9
|
export {
|
|
49
10
|
definePlugin
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* embedded-plugins.ts — the seam that lets the seed hand its OWN compiled-in
|
|
3
|
+
* standard plugin collection to the config loader, without @rig/core (substrate)
|
|
4
|
+
* importing any plugin package.
|
|
5
|
+
*
|
|
6
|
+
* The two-category model: the bootstrap seed (cli/bin/rig.ts) is the only place
|
|
7
|
+
* that may import @rig/standard-plugin, so it is the only place the standard
|
|
8
|
+
* collection is compiled INTO the binary. A declarative `.rig/` config names the
|
|
9
|
+
* standard collection rather than `import`-ing it, so the loader needs a way to
|
|
10
|
+
* obtain those embedded plugin objects. The seed registers them here at boot;
|
|
11
|
+
* the loader (loadDeclarativeConfig) reads them back. One process, one binary —
|
|
12
|
+
* a module-level holder is the whole mechanism. No node_modules, no Bun.build,
|
|
13
|
+
* no runtime resolution of a parallel dependency tree.
|
|
14
|
+
*/
|
|
15
|
+
import type { RigPlugin } from "./plugin-runtime";
|
|
16
|
+
/**
|
|
17
|
+
* The resolver receives the parsed declarative-config DATA as an OPAQUE blob.
|
|
18
|
+
* The floor never reaches into product-specific config keys (no github field
|
|
19
|
+
* names): each plugin owns its own config section shape, so the standard
|
|
20
|
+
* collection's seed-registered resolver is the one place that interprets the
|
|
21
|
+
* `[standard]`/`[taskSource]` sections. The floor only hands it the raw data.
|
|
22
|
+
*/
|
|
23
|
+
export type StandardPluginsResolver = (configData?: Record<string, unknown>) => readonly RigPlugin[];
|
|
24
|
+
/**
|
|
25
|
+
* Called once at seed boot with the binary's embedded standardPlugins(). Idempotent
|
|
26
|
+
* (last registration wins) so re-imports across entrypoints are harmless.
|
|
27
|
+
*/
|
|
28
|
+
export declare function registerStandardPluginsResolver(resolver: StandardPluginsResolver): void;
|
|
29
|
+
/** The embedded standard collection resolver, or null if the seed never registered one. */
|
|
30
|
+
export declare function getStandardPluginsResolver(): StandardPluginsResolver | null;
|
|
31
|
+
/**
|
|
32
|
+
* The CODE-config power-path twin of the standard-plugins seam above.
|
|
33
|
+
*
|
|
34
|
+
* The happy path (declarative `.rig/rigfig.toml`) resolves plugins from the
|
|
35
|
+
* embedded standard collection. The power path is for projects that ship a
|
|
36
|
+
* top-level `rig.config.ts`: the seed builds a project-specific `.rig/rig`
|
|
37
|
+
* binary with that config compiled IN (its generated entrypoint imports the
|
|
38
|
+
* config at BUILD time and calls `registerEmbeddedProjectConfig` at boot). With
|
|
39
|
+
* the config already baked into the process, `loadConfig` returns it directly —
|
|
40
|
+
* no per-invocation runtime `Bun.build` of `rig.config.ts`.
|
|
41
|
+
*
|
|
42
|
+
* The held value is the RAW config module export (the result of `defineConfig`),
|
|
43
|
+
* NOT a decoded `RigConfig`: `loadConfig` runs it through the same
|
|
44
|
+
* `decodeExplicitPluginConfig` path the on-disk loaders use, so the explicit
|
|
45
|
+
* plugin objects survive identically.
|
|
46
|
+
*/
|
|
47
|
+
export type EmbeddedProjectConfig = {
|
|
48
|
+
/** The raw `rig.config.ts` default export (pre-decode). */
|
|
49
|
+
readonly raw: unknown;
|
|
50
|
+
/** Absolute project root this baked config belongs to. */
|
|
51
|
+
readonly projectRoot: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Called once at boot by a project-binary's generated entrypoint with the
|
|
55
|
+
* compiled-in `rig.config.ts` export. Idempotent (last registration wins).
|
|
56
|
+
*/
|
|
57
|
+
export declare function registerEmbeddedProjectConfig(raw: unknown, projectRoot: string): void;
|
|
58
|
+
/** The baked code-config for this project binary, or null in the global binary. */
|
|
59
|
+
export declare function getEmbeddedProjectConfig(): EmbeddedProjectConfig | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/embedded-plugins.ts
|
|
3
|
+
var registered = null;
|
|
4
|
+
function registerStandardPluginsResolver(resolver) {
|
|
5
|
+
registered = resolver;
|
|
6
|
+
}
|
|
7
|
+
function getStandardPluginsResolver() {
|
|
8
|
+
return registered;
|
|
9
|
+
}
|
|
10
|
+
var bakedProjectConfig = null;
|
|
11
|
+
function registerEmbeddedProjectConfig(raw, projectRoot) {
|
|
12
|
+
bakedProjectConfig = { raw, projectRoot };
|
|
13
|
+
}
|
|
14
|
+
function getEmbeddedProjectConfig() {
|
|
15
|
+
return bakedProjectConfig;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
registerStandardPluginsResolver,
|
|
19
|
+
registerEmbeddedProjectConfig,
|
|
20
|
+
getStandardPluginsResolver,
|
|
21
|
+
getEmbeddedProjectConfig
|
|
22
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type CaptureResult = {
|
|
2
|
+
exitCode: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function runCapture(command: string[], cwd: string, env?: Record<string, string>): CaptureResult;
|
|
7
|
+
export declare function getValidationTimeoutMs(): number;
|
|
8
|
+
export declare function runCaptureAsync(command: string[], cwd: string, env?: Record<string, string>, timeoutMs?: number): Promise<CaptureResult>;
|
|
9
|
+
export declare function runInherit(command: string[], cwd: string, env?: Record<string, string>): number;
|
|
10
|
+
export declare function readJsonFile<T>(path: string, fallback: T): T;
|
|
11
|
+
export declare function nowIso(): string;
|
|
12
|
+
export declare function unique<T>(values: T[]): T[];
|
|
13
|
+
export declare function fileLines(path: string): string[];
|