@shardworks/nexus-arbor 0.1.101

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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Sean Boots
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # `@shardworks/nexus-arbor`
2
+
3
+ The guild runtime host for Nexus Mk 2.1. The arbor reads `guild.json`, loads all declared plugins, validates the dependency graph, starts each apparatus in dependency order, and wires the `guild()` singleton. It is the bootstrap layer — every entry point (the CLI, the MCP server, the Clockworks daemon) calls `createGuild()` once at startup.
4
+
5
+ ```
6
+ @shardworks/nexus-core — public SDK, types, guild() singleton
7
+ @shardworks/nexus-arbor — guild host, createGuild(), Guild object
8
+ @shardworks/nexus (cli) — nsg binary, framework commands + Instrumentarium tools
9
+ plugins — import from nexus-core only
10
+ ```
11
+
12
+ Plugin authors import from `@shardworks/nexus-core`. The arbor is an internal concern of the CLI and session provider — plugins never depend on it directly.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ ```json
19
+ {
20
+ "dependencies": {
21
+ "@shardworks/nexus-arbor": "workspace:*"
22
+ }
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## API
29
+
30
+ ### `createGuild(root?)`
31
+
32
+ The single entry point. Creates and starts a guild, returning the `Guild` object.
33
+
34
+ ```typescript
35
+ import { createGuild } from '@shardworks/nexus-arbor';
36
+
37
+ const guild = await createGuild('/path/to/guild');
38
+ ```
39
+
40
+ If `root` is omitted, auto-detects by walking up from cwd until `guild.json` is found.
41
+
42
+ `createGuild()` also sets the `guild()` singleton from `@shardworks/nexus-core`, so apparatus code can call `guild()` immediately after startup.
43
+
44
+ ### `Guild`
45
+
46
+ The object returned by `createGuild()` — also accessible via `guild()` from `@shardworks/nexus-core`.
47
+
48
+ | Method | Returns | Description |
49
+ |---|---|---|
50
+ | `home` | `string` | Absolute path to the guild root |
51
+ | `apparatus<T>(name)` | `T` | Retrieve a started apparatus's `provides` API by plugin id. Throws if the apparatus has no `provides` |
52
+ | `config<T>(pluginId)` | `T` | Read the plugin-specific configuration section from `guild.json` |
53
+ | `guildConfig()` | `GuildConfig` | The full parsed `guild.json` |
54
+ | `kits()` | `LoadedKit[]` | All loaded kits (snapshot copy) |
55
+ | `apparatuses()` | `LoadedApparatus[]` | All loaded apparatus in start order (snapshot copy) |
56
+
57
+ ### `LoadedKit` and `LoadedApparatus`
58
+
59
+ Installed plugin packages as seen by the runtime:
60
+
61
+ ```typescript
62
+ interface LoadedKit {
63
+ packageName: string; // full npm name, e.g. '@shardworks/nexus-stdlib'
64
+ id: string; // derived plugin id, e.g. 'nexus-stdlib'
65
+ version: string;
66
+ kit: Kit; // the package's Kit object
67
+ }
68
+
69
+ interface LoadedApparatus {
70
+ packageName: string;
71
+ id: string;
72
+ version: string;
73
+ apparatus: Apparatus; // the package's Apparatus object
74
+ }
75
+
76
+ type LoadedPlugin = LoadedKit | LoadedApparatus;
77
+ ```
78
+
79
+ Type guards: `isLoadedKit(p)` and `isLoadedApparatus(p)` from `@shardworks/nexus-core`.
80
+
81
+ ---
82
+
83
+ ## Plugin Lifecycle
84
+
85
+ `createGuild()` runs the full plugin lifecycle on each call:
86
+
87
+ 1. **Load** — imports all declared plugin packages from `node_modules`, discriminates kit vs. apparatus.
88
+ 2. **Validate** — checks `requires` declarations (apparatus and kit), detects circular apparatus dependencies. Fails loudly before any apparatus starts.
89
+ 3. **Warn** — advisory warnings for kit contributions that no apparatus `consumes`, and for missing `recommends`.
90
+ 4. **Wire** — sets the `guild()` singleton. The `provides` map is populated progressively as each apparatus starts; dependency ordering guarantees declared deps are available.
91
+ 5. **Start** — fires `plugin:initialized` for all kits, then calls `start(ctx)` on each apparatus in dependency-resolved order, firing `plugin:initialized` after each.
92
+
93
+ Apparatus start order is determined by topological sort on `apparatus.requires`. Circular dependencies throw with a descriptive error. Kit `requires` validate that the named apparatus is installed but do not affect start order (kits have no lifecycle).
94
+
95
+ ---
96
+
97
+ ## Guild Lifecycle Internals
98
+
99
+ Pure validation and ordering logic lives in `guild-lifecycle.ts`, separated from I/O:
100
+
101
+ | Function | Description |
102
+ |---|---|
103
+ | `validateRequires(kits, apparatuses)` | Validates all `requires` declarations and detects circular dependencies |
104
+ | `topoSort(apparatuses)` | Topological sort by `requires` — determines apparatus start order |
105
+ | `collectStartupWarnings(kits, apparatuses)` | Advisory warnings for unconsumed contributions and missing recommends |
106
+ | `buildStartupContext(eventHandlers)` | Creates the `StartupContext` passed to `apparatus.start()` |
107
+ | `fireEvent(eventHandlers, event, ...args)` | Fires lifecycle events to registered handlers |
108
+
109
+ These are exported for testing but are not part of the consumer-facing API.
110
+
111
+ ---
112
+
113
+ ## Lazy Startup
114
+
115
+ The arbor does no work at import time. `createGuild()` is async and performs all plugin loading, validation, and startup in a single call. There is no background process or persistent state — the `Guild` object is alive for the lifetime of the process that created it.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Arbor — the guild runtime.
3
+ *
4
+ * `createGuild()` is the single entry point. It reads guild.json, loads all
5
+ * declared plugins, validates dependencies, starts apparatus in order, wires
6
+ * the guild() singleton, and returns the Guild object.
7
+ *
8
+ * The full plugin lifecycle:
9
+ * 1. Load — imports all declared plugin packages, discriminates kit vs apparatus
10
+ * 2. Validate — checks `requires` declarations, detects circular dependencies
11
+ * 3. Start — calls start(ctx) on each apparatus in dependency-resolved order
12
+ * 4. Events — fires `plugin:initialized` after each plugin loads
13
+ * 5. Warn — advisory warnings for mismatched kit contributions / recommends
14
+ *
15
+ * Pure logic (validation, ordering, events) lives in guild-lifecycle.ts.
16
+ * This file handles I/O and orchestration.
17
+ */
18
+ import type { Guild } from '@shardworks/nexus-core';
19
+ /**
20
+ * Create and start a guild.
21
+ *
22
+ * Reads guild.json, loads all declared plugins, validates dependencies,
23
+ * starts apparatus in dependency order, and returns the Guild object.
24
+ * Also sets the guild() singleton so apparatus code can access it.
25
+ *
26
+ * @param root - Absolute path to the guild root. Defaults to auto-detection
27
+ * by walking up from cwd until guild.json is found.
28
+ * @returns The initialized Guild — the same object guild() returns.
29
+ */
30
+ export declare function createGuild(root?: string): Promise<Guild>;
31
+ //# sourceMappingURL=arbor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arbor.d.ts","sourceRoot":"","sources":["../src/arbor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAaH,OAAO,KAAK,EACV,KAAK,EAGN,MAAM,wBAAwB,CAAC;AAahC;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAgI/D"}
package/dist/arbor.js ADDED
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Arbor — the guild runtime.
3
+ *
4
+ * `createGuild()` is the single entry point. It reads guild.json, loads all
5
+ * declared plugins, validates dependencies, starts apparatus in order, wires
6
+ * the guild() singleton, and returns the Guild object.
7
+ *
8
+ * The full plugin lifecycle:
9
+ * 1. Load — imports all declared plugin packages, discriminates kit vs apparatus
10
+ * 2. Validate — checks `requires` declarations, detects circular dependencies
11
+ * 3. Start — calls start(ctx) on each apparatus in dependency-resolved order
12
+ * 4. Events — fires `plugin:initialized` after each plugin loads
13
+ * 5. Warn — advisory warnings for mismatched kit contributions / recommends
14
+ *
15
+ * Pure logic (validation, ordering, events) lives in guild-lifecycle.ts.
16
+ * This file handles I/O and orchestration.
17
+ */
18
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
19
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
20
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
21
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
22
+ });
23
+ }
24
+ return path;
25
+ };
26
+ import { readGuildConfig, writeGuildConfig, findGuildRoot, isKit, isApparatus, setGuild, resolveGuildPackageEntry, resolvePackageNameForPluginId, readGuildPackageJson, } from '@shardworks/nexus-core';
27
+ import { validateRequires, topoSort, collectStartupWarnings, buildStartupContext, fireEvent, } from "./guild-lifecycle.js";
28
+ // ── Public API ────────────────────────────────────────────────────────
29
+ /**
30
+ * Create and start a guild.
31
+ *
32
+ * Reads guild.json, loads all declared plugins, validates dependencies,
33
+ * starts apparatus in dependency order, and returns the Guild object.
34
+ * Also sets the guild() singleton so apparatus code can access it.
35
+ *
36
+ * @param root - Absolute path to the guild root. Defaults to auto-detection
37
+ * by walking up from cwd until guild.json is found.
38
+ * @returns The initialized Guild — the same object guild() returns.
39
+ */
40
+ export async function createGuild(root) {
41
+ const guildRoot = root ?? findGuildRoot();
42
+ const config = readGuildConfig(guildRoot);
43
+ const kits = [];
44
+ const apparatuses = [];
45
+ const eventHandlers = new Map();
46
+ // ── Load phase ─────────────────────────────────────────────────────
47
+ for (const pluginId of config.plugins) {
48
+ const packageName = resolvePackageNameForPluginId(guildRoot, pluginId);
49
+ if (!packageName) {
50
+ console.warn(`[arbor] No package found in package.json for plugin "${pluginId}" — skipping`);
51
+ continue;
52
+ }
53
+ const { version } = readGuildPackageJson(guildRoot, packageName);
54
+ try {
55
+ const entryPath = resolveGuildPackageEntry(guildRoot, packageName);
56
+ const mod = await import(__rewriteRelativeImportExtension(entryPath));
57
+ const raw = mod.default;
58
+ if (isApparatus(raw)) {
59
+ apparatuses.push({ packageName, id: pluginId, version, apparatus: raw.apparatus });
60
+ }
61
+ else if (isKit(raw)) {
62
+ kits.push({ packageName, id: pluginId, version, kit: raw.kit });
63
+ }
64
+ else {
65
+ console.warn(`[arbor] Plugin "${packageName}" does not export a kit or apparatus — skipping. ` +
66
+ `Plugins must export { kit: ... } or { apparatus: ... }.`);
67
+ }
68
+ }
69
+ catch (err) {
70
+ const message = err instanceof Error ? err.message : String(err);
71
+ console.warn(`[arbor] Failed to load plugin "${packageName}": ${message}`);
72
+ }
73
+ }
74
+ // ── Validation phase ───────────────────────────────────────────────
75
+ validateRequires(kits, apparatuses);
76
+ // ── Startup warnings ───────────────────────────────────────────────
77
+ for (const warning of collectStartupWarnings(kits, apparatuses)) {
78
+ console.warn(warning);
79
+ }
80
+ // ── Start phase ────────────────────────────────────────────────────
81
+ const orderedApparatuses = topoSort(apparatuses);
82
+ const provides = new Map();
83
+ // Wire guild singleton before any apparatus starts so start() methods
84
+ // can call guild(). The provides Map is populated progressively as each
85
+ // apparatus starts; dependency ordering guarantees declared deps are
86
+ // available.
87
+ const guildInstance = {
88
+ home: guildRoot,
89
+ apparatus(name) {
90
+ const p = provides.get(name);
91
+ if (p === undefined) {
92
+ throw new Error(`[guild] apparatus("${name}") is not available. ` +
93
+ `No loaded apparatus provides this id. Check guild.json plugins list.`);
94
+ }
95
+ return p;
96
+ },
97
+ config(pluginId) {
98
+ // GuildConfig types only the framework-level keys (name, nexus, plugins, etc.).
99
+ // Plugin-specific config sections (e.g. "animator", "stacks") are additional
100
+ // top-level keys in guild.json that GuildConfig doesn't model. The cast is safe
101
+ // because guild.json is a plain JSON object — all keys are accessible at runtime.
102
+ // Plugins can use module augmentation on GuildConfig to get typed access; this
103
+ // generic path remains the untyped fallback.
104
+ const cfg = config;
105
+ return (cfg[pluginId] ?? {});
106
+ },
107
+ writeConfig(pluginId, value) {
108
+ // Update the in-memory config so subsequent reads reflect the change,
109
+ // then persist to disk. The cast is the same pattern as config() above.
110
+ const cfg = config;
111
+ cfg[pluginId] = value;
112
+ writeGuildConfig(guildRoot, config);
113
+ },
114
+ guildConfig() {
115
+ return config;
116
+ },
117
+ kits() { return [...kits]; },
118
+ apparatuses() { return [...orderedApparatuses]; },
119
+ };
120
+ setGuild(guildInstance);
121
+ // Fire plugin:initialized for all kits before starting any apparatus
122
+ for (const kit of kits) {
123
+ await fireEvent(eventHandlers, 'plugin:initialized', kit);
124
+ }
125
+ // Start each apparatus in dependency order
126
+ const startupCtx = buildStartupContext(eventHandlers);
127
+ for (const app of orderedApparatuses) {
128
+ // Register provides before start() so apparatuses with eager provides are
129
+ // visible to later startups that run during this loop.
130
+ if (app.apparatus.provides !== undefined) {
131
+ provides.set(app.id, app.apparatus.provides);
132
+ }
133
+ await app.apparatus.start(startupCtx);
134
+ // Re-check after start() for deferred provides (e.g. Stacks uses a getter
135
+ // that returns undefined until start() populates the backing variable).
136
+ if (!provides.has(app.id) && app.apparatus.provides !== undefined) {
137
+ provides.set(app.id, app.apparatus.provides);
138
+ }
139
+ await fireEvent(eventHandlers, 'plugin:initialized', app);
140
+ }
141
+ return guildInstance;
142
+ }
143
+ //# sourceMappingURL=arbor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arbor.js","sourceRoot":"","sources":["../src/arbor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Guild lifecycle — pure logic for plugin validation, ordering, and events.
3
+ *
4
+ * All functions here operate on in-memory data structures (LoadedKit[],
5
+ * LoadedApparatus[], Maps) with no I/O. This makes them independently
6
+ * testable with synthetic fixtures.
7
+ *
8
+ * `createGuild()` in arbor.ts is the orchestrator that performs I/O
9
+ * (config reading, dynamic imports) then delegates to these functions.
10
+ */
11
+ import type { StartupContext, LoadedKit, LoadedApparatus } from '@shardworks/nexus-core';
12
+ export type EventHandlerMap = Map<string, Array<(...args: unknown[]) => void | Promise<void>>>;
13
+ /**
14
+ * Validate all `requires` declarations and detect circular dependencies.
15
+ * Throws with a descriptive error on the first problem found.
16
+ *
17
+ * Checks:
18
+ * - Apparatus requires: every named dependency must exist (kit or apparatus).
19
+ * - Kit requires: every named dependency must be an apparatus (kits can't
20
+ * depend on kits).
21
+ * - Cycle detection: no circular dependency chains among apparatuses.
22
+ */
23
+ export declare function validateRequires(kits: LoadedKit[], apparatuses: LoadedApparatus[]): void;
24
+ /**
25
+ * Sort apparatuses in dependency-resolved order using topological sort.
26
+ * validateRequires() must be called first to ensure the graph is acyclic.
27
+ */
28
+ export declare function topoSort(apparatuses: LoadedApparatus[]): LoadedApparatus[];
29
+ /**
30
+ * Collect advisory warnings for kit contributions that no apparatus
31
+ * consumes, and for missing recommended apparatuses.
32
+ *
33
+ * Returns an array of warning strings. The caller decides how to emit
34
+ * them (console.warn, logger, etc.).
35
+ */
36
+ export declare function collectStartupWarnings(kits: LoadedKit[], apparatuses: LoadedApparatus[]): string[];
37
+ /**
38
+ * Build a StartupContext for an apparatus's start() call.
39
+ * The context provides event subscription; handlers are stored in the
40
+ * shared eventHandlers map so fireEvent can invoke them later.
41
+ */
42
+ export declare function buildStartupContext(eventHandlers: EventHandlerMap): StartupContext;
43
+ /**
44
+ * Fire a lifecycle event, awaiting each handler sequentially.
45
+ */
46
+ export declare function fireEvent(eventHandlers: EventHandlerMap, event: string, ...args: unknown[]): Promise<void>;
47
+ //# sourceMappingURL=guild-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guild-lifecycle.d.ts","sourceRoot":"","sources":["../src/guild-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,eAAe,EAChB,MAAM,wBAAwB,CAAC;AAIhC,MAAM,MAAM,eAAe,GAAG,GAAG,CAC/B,MAAM,EACN,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CACpD,CAAC;AAIF;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EAAE,EACjB,WAAW,EAAE,eAAe,EAAE,GAC7B,IAAI,CA2DN;AAID;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAoB1E;AAID;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAS,SAAS,EAAE,EACxB,WAAW,EAAE,eAAe,EAAE,GAC7B,MAAM,EAAE,CA4CV;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,eAAe,GAC7B,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,aAAa,EAAE,eAAe,EAC9B,KAAK,EAAU,MAAM,EACrB,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Guild lifecycle — pure logic for plugin validation, ordering, and events.
3
+ *
4
+ * All functions here operate on in-memory data structures (LoadedKit[],
5
+ * LoadedApparatus[], Maps) with no I/O. This makes them independently
6
+ * testable with synthetic fixtures.
7
+ *
8
+ * `createGuild()` in arbor.ts is the orchestrator that performs I/O
9
+ * (config reading, dynamic imports) then delegates to these functions.
10
+ */
11
+ // ── Validation ───────────────────────────────────────────────────────
12
+ /**
13
+ * Validate all `requires` declarations and detect circular dependencies.
14
+ * Throws with a descriptive error on the first problem found.
15
+ *
16
+ * Checks:
17
+ * - Apparatus requires: every named dependency must exist (kit or apparatus).
18
+ * - Kit requires: every named dependency must be an apparatus (kits can't
19
+ * depend on kits).
20
+ * - Cycle detection: no circular dependency chains among apparatuses.
21
+ */
22
+ export function validateRequires(kits, apparatuses) {
23
+ const apparatusIds = new Set(apparatuses.map((a) => a.id));
24
+ const allIds = new Set([
25
+ ...kits.map((k) => k.id),
26
+ ...apparatuses.map((a) => a.id),
27
+ ]);
28
+ // Check apparatus requires
29
+ for (const app of apparatuses) {
30
+ for (const dep of app.apparatus.requires ?? []) {
31
+ if (!allIds.has(dep)) {
32
+ throw new Error(`[arbor] "${app.id}" requires "${dep}", which is not installed.`);
33
+ }
34
+ }
35
+ }
36
+ // Check kit requires (must be apparatus names — kits can't depend on kits)
37
+ for (const kit of kits) {
38
+ for (const dep of kit.kit.requires ?? []) {
39
+ if (!apparatusIds.has(dep)) {
40
+ if (!allIds.has(dep)) {
41
+ throw new Error(`[arbor] kit "${kit.id}" requires "${dep}", which is not installed.`);
42
+ }
43
+ throw new Error(`[arbor] kit "${kit.id}" requires "${dep}", but that plugin is a kit, not an apparatus. ` +
44
+ `Kit requires must name apparatus plugins.`);
45
+ }
46
+ }
47
+ }
48
+ // Detect circular dependencies among apparatuses
49
+ const visiting = new Set();
50
+ const visited = new Set();
51
+ function visit(id, chain) {
52
+ if (visited.has(id))
53
+ return;
54
+ if (visiting.has(id)) {
55
+ const cycle = [...chain, id].join(' → ');
56
+ throw new Error(`[arbor] Circular dependency detected: ${cycle}`);
57
+ }
58
+ visiting.add(id);
59
+ const app = apparatuses.find((a) => a.id === id);
60
+ if (app) {
61
+ for (const dep of app.apparatus.requires ?? []) {
62
+ visit(dep, [...chain, id]);
63
+ }
64
+ }
65
+ visiting.delete(id);
66
+ visited.add(id);
67
+ }
68
+ for (const app of apparatuses) {
69
+ visit(app.id, []);
70
+ }
71
+ }
72
+ // ── Dependency ordering ──────────────────────────────────────────────
73
+ /**
74
+ * Sort apparatuses in dependency-resolved order using topological sort.
75
+ * validateRequires() must be called first to ensure the graph is acyclic.
76
+ */
77
+ export function topoSort(apparatuses) {
78
+ const sorted = [];
79
+ const visited = new Set();
80
+ function visit(id) {
81
+ if (visited.has(id))
82
+ return;
83
+ const app = apparatuses.find((a) => a.id === id);
84
+ if (!app)
85
+ return;
86
+ for (const dep of app.apparatus.requires ?? []) {
87
+ visit(dep);
88
+ }
89
+ visited.add(id);
90
+ sorted.push(app);
91
+ }
92
+ for (const app of apparatuses) {
93
+ visit(app.id);
94
+ }
95
+ return sorted;
96
+ }
97
+ // ── Startup warnings ─────────────────────────────────────────────────
98
+ /**
99
+ * Collect advisory warnings for kit contributions that no apparatus
100
+ * consumes, and for missing recommended apparatuses.
101
+ *
102
+ * Returns an array of warning strings. The caller decides how to emit
103
+ * them (console.warn, logger, etc.).
104
+ */
105
+ export function collectStartupWarnings(kits, apparatuses) {
106
+ const warnings = [];
107
+ const consumedTypes = new Set();
108
+ const installedIds = new Set(apparatuses.map((a) => a.id));
109
+ for (const app of apparatuses) {
110
+ for (const token of app.apparatus.consumes ?? []) {
111
+ consumedTypes.add(token);
112
+ }
113
+ }
114
+ // Check apparatus recommends
115
+ for (const app of apparatuses) {
116
+ for (const rec of app.apparatus.recommends ?? []) {
117
+ if (!installedIds.has(rec)) {
118
+ warnings.push(`[arbor] warn: "${app.id}" recommends "${rec}" but it is not installed.`);
119
+ }
120
+ }
121
+ }
122
+ for (const kit of kits) {
123
+ // Check kit recommends
124
+ for (const rec of kit.kit.recommends ?? []) {
125
+ if (!installedIds.has(rec)) {
126
+ warnings.push(`[arbor] warn: "${kit.id}" recommends "${rec}" but it is not installed.`);
127
+ }
128
+ }
129
+ // Check contribution types against consumes
130
+ for (const key of Object.keys(kit.kit)) {
131
+ if (key === 'requires' || key === 'recommends')
132
+ continue;
133
+ if (!consumedTypes.has(key)) {
134
+ warnings.push(`[arbor] warn: "${kit.id}" contributes "${key}" but no installed apparatus declares consumes: ["${key}"]`);
135
+ }
136
+ }
137
+ }
138
+ return warnings;
139
+ }
140
+ // ── Event system ─────────────────────────────────────────────────────
141
+ /**
142
+ * Build a StartupContext for an apparatus's start() call.
143
+ * The context provides event subscription; handlers are stored in the
144
+ * shared eventHandlers map so fireEvent can invoke them later.
145
+ */
146
+ export function buildStartupContext(eventHandlers) {
147
+ return {
148
+ on(event, handler) {
149
+ const list = eventHandlers.get(event) ?? [];
150
+ list.push(handler);
151
+ eventHandlers.set(event, list);
152
+ },
153
+ };
154
+ }
155
+ /**
156
+ * Fire a lifecycle event, awaiting each handler sequentially.
157
+ */
158
+ export async function fireEvent(eventHandlers, event, ...args) {
159
+ const handlers = eventHandlers.get(event) ?? [];
160
+ for (const h of handlers) {
161
+ await h(...args);
162
+ }
163
+ }
164
+ //# sourceMappingURL=guild-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guild-lifecycle.js","sourceRoot":"","sources":["../src/guild-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @shardworks/nexus-arbor — guild runtime
3
+ *
4
+ * The arbor is the guild host: plugin loading, dependency validation,
5
+ * apparatus lifecycle management. It does NOT own tool discovery — that
6
+ * belongs to The Instrumentarium (tools-apparatus).
7
+ *
8
+ * Plugin authors never import from arbor — they import from @shardworks/nexus-core.
9
+ * The CLI imports from arbor to create the guild runtime and trigger startup.
10
+ *
11
+ * Package dependency graph:
12
+ * core — public SDK, types, tool() factory
13
+ * arbor — guild host, createGuild()
14
+ * cli — nsg binary, Commander.js, framework commands + Instrumentarium tools
15
+ * plugins — import from core only
16
+ */
17
+ export { createGuild } from './arbor.ts';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @shardworks/nexus-arbor — guild runtime
3
+ *
4
+ * The arbor is the guild host: plugin loading, dependency validation,
5
+ * apparatus lifecycle management. It does NOT own tool discovery — that
6
+ * belongs to The Instrumentarium (tools-apparatus).
7
+ *
8
+ * Plugin authors never import from arbor — they import from @shardworks/nexus-core.
9
+ * The CLI imports from arbor to create the guild runtime and trigger startup.
10
+ *
11
+ * Package dependency graph:
12
+ * core — public SDK, types, tool() factory
13
+ * arbor — guild host, createGuild()
14
+ * cli — nsg binary, Commander.js, framework commands + Instrumentarium tools
15
+ * plugins — import from core only
16
+ */
17
+ export { createGuild } from "./arbor.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@shardworks/nexus-arbor",
3
+ "version": "0.1.101",
4
+ "license": "ISC",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/shardworks/nexus",
8
+ "directory": "packages/framework/arbor"
9
+ },
10
+ "description": "The Arbor — guild runtime host: loads plugins, validates dependencies, starts apparatus in order, wires the guild() singleton",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "dependencies": {
19
+ "@shardworks/nexus-core": "0.1.101"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "25.5.0"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts'",
30
+ "typecheck": "tsc --noEmit"
31
+ }
32
+ }