@h-rig/core 0.0.6-alpha.18 → 0.0.6-alpha.180

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 (105) hide show
  1. package/dist/src/agent-role-registry.d.ts +4 -0
  2. package/dist/src/agent-role-registry.js +27 -0
  3. package/dist/src/authority-paths.d.ts +15 -0
  4. package/dist/src/authority-paths.js +80 -0
  5. package/dist/src/baked-secrets.d.ts +3 -0
  6. package/dist/src/baked-secrets.js +63 -0
  7. package/dist/src/build-time-config.d.ts +12 -0
  8. package/dist/src/build-time-config.js +25 -0
  9. package/dist/src/build-time-config.macro.d.ts +1 -0
  10. package/dist/src/capability-loaders.d.ts +51 -0
  11. package/dist/src/capability-loaders.js +870 -0
  12. package/dist/src/capability.d.ts +79 -0
  13. package/dist/src/capability.js +63 -0
  14. package/dist/src/checkout-root.d.ts +1 -0
  15. package/dist/src/checkout-root.js +30 -0
  16. package/dist/src/config-env.d.ts +4 -0
  17. package/dist/src/config-env.js +23 -0
  18. package/dist/src/config.d.ts +3 -0
  19. package/dist/src/config.js +44 -0
  20. package/dist/src/declarative-config.d.ts +14 -0
  21. package/dist/src/declarative-config.js +85 -0
  22. package/dist/src/default-kernel.d.ts +1 -0
  23. package/dist/src/default-kernel.js +12 -0
  24. package/dist/src/define-config.d.ts +20 -0
  25. package/dist/src/define-config.js +28 -15
  26. package/dist/src/define-plugin.d.ts +13 -0
  27. package/dist/src/define-plugin.js +4 -43
  28. package/dist/src/embedded-plugins.d.ts +59 -0
  29. package/dist/src/embedded-plugins.js +22 -0
  30. package/dist/src/exec.d.ts +13 -0
  31. package/dist/src/exec.js +101 -0
  32. package/dist/src/harness-paths.d.ts +9 -0
  33. package/dist/src/harness-paths.js +126 -0
  34. package/dist/src/hook-materializer.d.ts +21 -0
  35. package/dist/src/hook-materializer.js +152 -0
  36. package/dist/src/hook-protocol.d.ts +2 -0
  37. package/dist/src/hook-protocol.js +432 -0
  38. package/dist/src/hook-runner.d.ts +48 -0
  39. package/dist/src/hook-runner.js +868 -0
  40. package/dist/src/hook-runtime.d.ts +52 -0
  41. package/dist/src/hook-runtime.js +432 -0
  42. package/dist/src/index.d.ts +8 -0
  43. package/dist/src/index.js +210 -2499
  44. package/dist/src/json-files.d.ts +9 -0
  45. package/dist/src/json-files.js +124 -0
  46. package/dist/src/kernel-boot.d.ts +2 -0
  47. package/dist/src/kernel-boot.js +10 -0
  48. package/dist/src/kernel-entrypoint.d.ts +22 -0
  49. package/dist/src/kernel-entrypoint.js +660 -0
  50. package/dist/src/kernel-plugin-abi.d.ts +1 -0
  51. package/dist/src/kernel-plugin-abi.js +1 -0
  52. package/dist/src/kernel-resolver.d.ts +2 -0
  53. package/dist/src/kernel-resolver.js +6 -0
  54. package/dist/src/layout.d.ts +10 -0
  55. package/dist/src/layout.js +138 -0
  56. package/dist/src/load-config.d.ts +2 -0
  57. package/dist/src/load-config.js +535 -30
  58. package/dist/src/placement.d.ts +58 -0
  59. package/dist/src/placement.js +53 -0
  60. package/dist/src/plugin-host-context.d.ts +65 -0
  61. package/dist/src/plugin-host-context.js +1171 -0
  62. package/dist/src/plugin-host-registries.d.ts +31 -0
  63. package/dist/src/plugin-host-registries.js +79 -0
  64. package/dist/src/plugin-host.d.ts +77 -0
  65. package/dist/src/plugin-host.js +127 -63
  66. package/dist/src/plugin-runtime.d.ts +173 -0
  67. package/dist/src/project-plugins.d.ts +63 -0
  68. package/dist/src/project-plugins.js +905 -0
  69. package/dist/src/remote-config.d.ts +125 -0
  70. package/dist/src/remote-config.js +85 -0
  71. package/dist/src/root-resolver.d.ts +5 -0
  72. package/dist/src/root-resolver.js +68 -0
  73. package/dist/src/run-provisioning.d.ts +37 -0
  74. package/dist/src/run-provisioning.js +35 -0
  75. package/dist/src/runtime-context.d.ts +20 -0
  76. package/dist/src/runtime-context.js +257 -0
  77. package/dist/src/runtime-events.d.ts +44 -0
  78. package/dist/src/runtime-events.js +208 -0
  79. package/dist/src/runtime-overlay.d.ts +11 -0
  80. package/dist/src/runtime-overlay.js +69 -0
  81. package/dist/src/runtime-paths.d.ts +21 -0
  82. package/dist/src/runtime-paths.js +181 -0
  83. package/dist/src/runtime-provisioning-env.d.ts +5 -0
  84. package/dist/src/runtime-provisioning-env.js +217 -0
  85. package/dist/src/runtime-runner-context.d.ts +12 -0
  86. package/dist/src/runtime-runner-context.js +1 -0
  87. package/dist/src/safe-identifiers.d.ts +44 -0
  88. package/dist/src/safe-identifiers.js +96 -0
  89. package/dist/src/scope-rules.d.ts +4 -0
  90. package/dist/src/scope-rules.js +21 -0
  91. package/dist/src/server-paths.d.ts +22 -0
  92. package/dist/src/server-paths.js +219 -0
  93. package/dist/src/setup-version.d.ts +3 -0
  94. package/dist/src/setup-version.js +14 -0
  95. package/dist/src/task-record-reader.d.ts +3 -0
  96. package/dist/src/task-record-reader.js +9 -0
  97. package/dist/src/validator-registry.d.ts +27 -0
  98. package/dist/src/validator-registry.js +64 -0
  99. package/package.json +162 -10
  100. package/dist/src/engineReadModelReducer.js +0 -1780
  101. package/dist/src/rig-init-builder.js +0 -57
  102. package/dist/src/rigSelectors.js +0 -293
  103. package/dist/src/taskGraph.js +0 -64
  104. package/dist/src/taskGraphCodes.js +0 -26
  105. 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 runtimeByName = new Map;
7
- const plugins = cfg.plugins ?? [];
8
- for (const plugin of plugins) {
9
- if (plugin?.__runtime) {
10
- runtimeByName.set(plugin.name, plugin.__runtime);
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: decodedPlugins };
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(meta, runtime) {
6
- const validated = Schema.decodeUnknownSync(RigPlugin)(meta);
7
- if (!runtime) {
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[];