@shardworks/nexus-core 0.1.270 → 0.1.271

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/README.md CHANGED
@@ -101,11 +101,12 @@ writeGuildConfig(home, config);
101
101
  | `name` | `string` | Guild name |
102
102
  | `nexus` | `string` | Framework version at last init/upgrade |
103
103
  | `plugins` | `string[]` | Installed plugin ids |
104
- | `clockworks?` | `ClockworksConfig` | Events and standing orders |
105
- | `writTypes?` | `Record<string, WritTypeDeclaration>` | Guild-declared writ types |
106
104
  | `settings?` | `GuildSettings` | Operational flags including default `model` |
107
105
 
108
- All other top-level keys are plugin configuration sections, keyed by derived plugin id.
106
+ All other top-level keys are plugin configuration sections, keyed by derived
107
+ plugin id. Plugin-owned sections (e.g. `clockworks?`, `lattice?`) are
108
+ contributed via `declare module '@shardworks/nexus-core'` from the owning
109
+ apparatus package; the shape of those sections lives with the plugin, not here.
109
110
 
110
111
  ### Other Exports
111
112
 
@@ -113,10 +114,6 @@ All other top-level keys are plugin configuration sections, keyed by derived plu
113
114
  |---|---|
114
115
  | `createInitialGuildConfig(name, version, model)` | Default config for `nsg init` |
115
116
  | `guildConfigPath(home)` | Resolve path to `guild.json` |
116
- | `EventDeclaration` | Custom event: `description`, optional `schema` |
117
- | `StandingOrder` | Event → action mapping (run / summon / brief) |
118
- | `ClockworksConfig` | Container for events and standing orders |
119
- | `WritTypeDeclaration` | Writ type: `description` |
120
117
  | `GuildSettings` | Settings: `model`, `autoMigrate` |
121
118
 
122
119
  ---
@@ -1,29 +1,3 @@
1
- /** A custom event declaration in guild.json clockworks.events. */
2
- export interface EventDeclaration {
3
- /** Human-readable description of what this event means. */
4
- description?: string;
5
- /** Optional payload schema hint (not enforced in Phase 1). */
6
- schema?: Record<string, string>;
7
- }
8
- /** A standing order — a registered response to an event. */
9
- export type StandingOrder = {
10
- on: string;
11
- run: string;
12
- } | {
13
- on: string;
14
- summon: string;
15
- prompt?: string;
16
- } | {
17
- on: string;
18
- brief: string;
19
- };
20
- /** The clockworks configuration block in guild.json. */
21
- export interface ClockworksConfig {
22
- /** Custom event declarations. */
23
- events?: Record<string, EventDeclaration>;
24
- /** Standing orders — event → action mappings. */
25
- standingOrders?: StandingOrder[];
26
- }
27
1
  /** Guild-level settings — operational flags and preferences. */
28
2
  export interface GuildSettings {
29
3
  /**
@@ -45,6 +19,11 @@ export interface GuildSettings {
45
19
  * training content) are declared by plugins and discovered dynamically at runtime.
46
20
  * Framework-level keys (`name`, `nexus`, `plugins`, `settings`) are defined here;
47
21
  * all other top-level keys are plugin configuration sections, keyed by plugin id.
22
+ *
23
+ * Plugin-owned config sections (e.g. `clockworks?`, `lattice?`) are contributed
24
+ * via `declare module '@shardworks/nexus-core'` from the owning apparatus
25
+ * package. GuildConfig is an open interface — anything a plugin augments onto
26
+ * it is visible at every call site that imports this type.
48
27
  */
49
28
  export interface GuildConfig {
50
29
  /** Guild name — used as the guildhall npm package name. */
@@ -53,8 +32,6 @@ export interface GuildConfig {
53
32
  nexus: string;
54
33
  /** Installed plugin ids (derived from npm package names). Always present; starts empty. */
55
34
  plugins: string[];
56
- /** Clockworks configuration — events, standing orders. */
57
- clockworks?: ClockworksConfig;
58
35
  /** Guild-level settings — operational flags and preferences. Includes default model. */
59
36
  settings?: GuildSettings;
60
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"guild-config.d.ts","sourceRoot":"","sources":["../src/guild-config.ts"],"names":[],"mappings":"AAGA,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAGD,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,iDAAiD;IACjD,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAOvG;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAGzD;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAGxE;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"guild-config.d.ts","sourceRoot":"","sources":["../src/guild-config.ts"],"names":[],"mappings":"AAGA,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAOvG;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAGzD;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAGxE;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"guild-config.js","sourceRoot":"","sources":["../src/guild-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AA6D7B;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY,EAAE,YAAoB,EAAE,KAAa;IACxF,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE,KAAK,EAAE;KACpB,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAgB,CAAC;AACzE,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAmB;IAChE,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACvE,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"guild-config.js","sourceRoot":"","sources":["../src/guild-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAyC7B;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY,EAAE,YAAoB,EAAE,KAAa;IACxF,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE,KAAK,EAAE;KACpB,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAgB,CAAC;AACzE,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAmB;IAChE,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACvE,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACvC,CAAC"}
package/dist/guild.d.ts CHANGED
@@ -9,6 +9,13 @@
9
9
  * it via `setGuild()`. The instance is backed by live data structures
10
10
  * (e.g. the provides Map) that are populated progressively as apparatus start.
11
11
  *
12
+ * The `Guild` interface is the contract plugin code sees — it deliberately
13
+ * does not expose `shutdown()`. Lifecycle teardown is the responsibility
14
+ * of the bootstrapping process (the CLI, a daemon entry point, a one-shot
15
+ * helper) that called `createGuild()`. That caller receives a
16
+ * `StartedGuild` (a `Guild` plus a `shutdown()` method) and is expected
17
+ * to invoke it before exit. See `StartedGuild` and `clearGuild()` below.
18
+ *
12
19
  * See: docs/architecture/plugins.md
13
20
  */
14
21
  import type { GuildConfig } from './guild-config.ts';
@@ -17,7 +24,10 @@ import type { LoadedKit, LoadedApparatus, FailedPlugin } from './plugin.ts';
17
24
  * Runtime access to guild infrastructure.
18
25
  *
19
26
  * Available after Arbor creates the instance (before apparatus start).
20
- * One instance per process.
27
+ * One instance per process. Plugin code only ever sees this narrow
28
+ * interface — `shutdown()` is intentionally not part of it. The
29
+ * bootstrap caller of `createGuild()` receives the richer
30
+ * `StartedGuild` and owns the shutdown lifecycle.
21
31
  */
22
32
  export interface Guild {
23
33
  /** Absolute path to the guild root (contains guild.json). */
@@ -65,6 +75,43 @@ export interface Guild {
65
75
  /** Advisory warnings collected during guild startup (missing recommends, unconsumed contributions). */
66
76
  startupWarnings(): string[];
67
77
  }
78
+ /**
79
+ * Extension of {@link Guild} returned by `createGuild()` — adds the
80
+ * `shutdown()` method that drives reverse-topo apparatus teardown.
81
+ *
82
+ * The `Guild` interface is what plugin code sees through the
83
+ * process-level singleton; `shutdown()` is deliberately not exposed
84
+ * there because plugin code has no legitimate reason to tear down the
85
+ * guild it is running inside. The bootstrap caller of `createGuild()`
86
+ * — a CLI command, a daemon entry point, or a one-shot helper —
87
+ * receives this richer type and is responsible for invoking
88
+ * `shutdown()` on the way out.
89
+ *
90
+ * `shutdown()` invokes every started apparatus's optional `stop()` in
91
+ * reverse topological order, fires the `guild:shutdown` lifecycle
92
+ * event before any `stop()` runs, collects per-apparatus errors and
93
+ * surfaces them as a single aggregate (continuing iteration even when
94
+ * one throws), is idempotent under repeated calls, and clears the
95
+ * `guild()` singleton as its last act so subsequent `guild()` calls
96
+ * fail loudly with the existing "Guild not initialized" error rather
97
+ * than handing out stale references to apparatus whose handles are
98
+ * already gone.
99
+ */
100
+ export interface StartedGuild extends Guild {
101
+ /**
102
+ * Tear the guild down: fire `guild:shutdown`, call `stop()` on every
103
+ * started apparatus in reverse topological order, then clear the
104
+ * `guild()` singleton.
105
+ *
106
+ * Idempotent — second and subsequent calls return immediately.
107
+ *
108
+ * If one or more `stop()` invocations throw, every remaining
109
+ * apparatus is still attempted; once iteration completes, an
110
+ * aggregate `Error` is thrown summarising each failure. The
111
+ * singleton is cleared regardless of whether any `stop()` threw.
112
+ */
113
+ shutdown(): Promise<void>;
114
+ }
68
115
  /**
69
116
  * Get the active guild instance.
70
117
  *
@@ -79,9 +126,16 @@ export declare function guild(): Guild;
79
126
  */
80
127
  export declare function setGuild(g: Guild): void;
81
128
  /**
82
- * Clear the guild instance. Called by Arbor at shutdown or in tests.
129
+ * Clear the guild instance.
83
130
  *
84
- * Not for plugin use this is framework infrastructure.
131
+ * Called as the last act of `StartedGuild.shutdown()` after every
132
+ * apparatus's optional `stop()` has run, so subsequent `guild()` calls
133
+ * fail loudly with the "Guild not initialized" error rather than
134
+ * handing out stale references to apparatus whose handles are gone.
135
+ * Tests call it directly to reset between cases.
136
+ *
137
+ * Not for plugin use — this is framework infrastructure. Plugin code
138
+ * should never need to tear the guild down.
85
139
  */
86
140
  export declare function clearGuild(): void;
87
141
  //# sourceMappingURL=guild.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guild.d.ts","sourceRoot":"","sources":["../src/guild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI5E;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;;;;OAMG;IACH,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAAA;IAE7B;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAA;IAExD;;;;;;;;;OASG;IACH,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;IAE1E;;;;;OAKG;IACH,WAAW,IAAI,WAAW,CAAA;IAE1B,6FAA6F;IAC7F,IAAI,IAAI,SAAS,EAAE,CAAA;IAEnB,2CAA2C;IAC3C,WAAW,IAAI,eAAe,EAAE,CAAA;IAEhC,mEAAmE;IACnE,aAAa,IAAI,YAAY,EAAE,CAAA;IAE/B,uGAAuG;IACvG,eAAe,IAAI,MAAM,EAAE,CAAA;CAC5B;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,IAAI,KAAK,CAQ7B;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
1
+ {"version":3,"file":"guild.d.ts","sourceRoot":"","sources":["../src/guild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI5E;;;;;;;;GAQG;AACH,MAAM,WAAW,KAAK;IACpB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;;;;OAMG;IACH,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAAA;IAE7B;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAA;IAExD;;;;;;;;;OASG;IACH,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;IAE1E;;;;;OAKG;IACH,WAAW,IAAI,WAAW,CAAA;IAE1B,6FAA6F;IAC7F,IAAI,IAAI,SAAS,EAAE,CAAA;IAEnB,2CAA2C;IAC3C,WAAW,IAAI,eAAe,EAAE,CAAA;IAEhC,mEAAmE;IACnE,aAAa,IAAI,YAAY,EAAE,CAAA;IAE/B,uGAAuG;IACvG,eAAe,IAAI,MAAM,EAAE,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC;;;;;;;;;;;OAWG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,IAAI,KAAK,CAQ7B;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAEvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
package/dist/guild.js CHANGED
@@ -9,6 +9,13 @@
9
9
  * it via `setGuild()`. The instance is backed by live data structures
10
10
  * (e.g. the provides Map) that are populated progressively as apparatus start.
11
11
  *
12
+ * The `Guild` interface is the contract plugin code sees — it deliberately
13
+ * does not expose `shutdown()`. Lifecycle teardown is the responsibility
14
+ * of the bootstrapping process (the CLI, a daemon entry point, a one-shot
15
+ * helper) that called `createGuild()`. That caller receives a
16
+ * `StartedGuild` (a `Guild` plus a `shutdown()` method) and is expected
17
+ * to invoke it before exit. See `StartedGuild` and `clearGuild()` below.
18
+ *
12
19
  * See: docs/architecture/plugins.md
13
20
  */
14
21
  // ── Singleton ──────────────────────────────────────────────────────────
@@ -35,9 +42,16 @@ export function setGuild(g) {
35
42
  _guild = g;
36
43
  }
37
44
  /**
38
- * Clear the guild instance. Called by Arbor at shutdown or in tests.
45
+ * Clear the guild instance.
39
46
  *
40
- * Not for plugin use this is framework infrastructure.
47
+ * Called as the last act of `StartedGuild.shutdown()` after every
48
+ * apparatus's optional `stop()` has run, so subsequent `guild()` calls
49
+ * fail loudly with the "Guild not initialized" error rather than
50
+ * handing out stale references to apparatus whose handles are gone.
51
+ * Tests call it directly to reset between cases.
52
+ *
53
+ * Not for plugin use — this is framework infrastructure. Plugin code
54
+ * should never need to tear the guild down.
41
55
  */
42
56
  export function clearGuild() {
43
57
  _guild = null;
package/dist/guild.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"guild.js","sourceRoot":"","sources":["../src/guild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoEH,0EAA0E;AAE1E,IAAI,MAAM,GAAiB,IAAI,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,UAAU,KAAK;IACnB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,+DAA+D;YAC/D,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAQ;IAC/B,MAAM,GAAG,CAAC,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"guild.js","sourceRoot":"","sources":["../src/guild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA6GH,0EAA0E;AAE1E,IAAI,MAAM,GAAiB,IAAI,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,UAAU,KAAK;IACnB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,+DAA+D;YAC/D,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAQ;IAC/B,MAAM,GAAG,CAAC,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export declare const VERSION: string;
2
2
  export { type Kit, type Apparatus, type Plugin, type LoadedKit, type LoadedApparatus, type LoadedPlugin, type FailedPlugin, type StartupContext, type KitEntry, isKit, isApparatus, isLoadedKit, isLoadedApparatus, } from './plugin.ts';
3
- export { type Guild, guild, setGuild, clearGuild, } from './guild.ts';
3
+ export { type Guild, type StartedGuild, guild, setGuild, clearGuild, } from './guild.ts';
4
4
  export { findGuildRoot, nexusDir, worktreesPath, clockPidPath, clockLogPath, } from './nexus-home.ts';
5
+ export { isProcessAlive, readPidFile, tryUnlink, waitForExit, } from './pid-helpers.ts';
5
6
  export { derivePluginId, readGuildPackageJson, resolvePackageNameForPluginId, resolveGuildPackageEntry, } from './resolve-package.ts';
6
- export { type GuildConfig, createInitialGuildConfig, readGuildConfig, writeGuildConfig, type EventDeclaration, type StandingOrder, type ClockworksConfig, type GuildSettings, guildConfigPath, } from './guild-config.ts';
7
+ export { type GuildConfig, createInitialGuildConfig, readGuildConfig, writeGuildConfig, type GuildSettings, guildConfigPath, } from './guild-config.ts';
7
8
  export { generateId, shortId } from './id.ts';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,EAAE,MAAqB,CAAC;AAI5C,OAAO,EAEL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,KAAK,EACV,KAAK,EACL,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,WAAW,EAChB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,EAAE,MAAqB,CAAC;AAI5C,OAAO,EAEL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,EACL,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,WAAW,EAChB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,KAAK,aAAa,EAClB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ export { isKit, isApparatus, isLoadedKit, isLoadedApparatus, } from "./plugin.js
8
8
  // Guild — the process-level singleton for accessing guild infrastructure.
9
9
  export { guild, setGuild, clearGuild, } from "./guild.js";
10
10
  export { findGuildRoot, nexusDir, worktreesPath, clockPidPath, clockLogPath, } from "./nexus-home.js";
11
+ export { isProcessAlive, readPidFile, tryUnlink, waitForExit, } from "./pid-helpers.js";
11
12
  export { derivePluginId, readGuildPackageJson, resolvePackageNameForPluginId, resolveGuildPackageEntry, } from "./resolve-package.js";
12
13
  export { createInitialGuildConfig, readGuildConfig, writeGuildConfig, guildConfigPath, } from "./guild-config.js";
13
14
  export { generateId, shortId } from "./id.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,OAAO,GAAW,IAAI,CAAC,OAAO,CAAC;AAE5C,0EAA0E;AAE1E,OAAO,EAWL,KAAK,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,0EAA0E;AAC1E,OAAO,EAEL,KAAK,EACL,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAKhB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,OAAO,GAAW,IAAI,CAAC,OAAO,CAAC;AAE5C,0EAA0E;AAE1E,OAAO,EAWL,KAAK,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,0EAA0E;AAC1E,OAAO,EAGL,KAAK,EACL,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAEhB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Shared PID-file and process-liveness helpers for daemon-style commands.
3
+ *
4
+ * Two daemons live in the framework today: `nsg start` (the guild daemon)
5
+ * and `nsg clock start` (the Clockworks daemon). Both share the same
6
+ * lifecycle primitives — read a pidfile, decide whether the pid behind
7
+ * it is still alive, unlink the pidfile when the daemon is gone, and
8
+ * poll until a pid actually exits after a SIGTERM.
9
+ *
10
+ * Centralising these helpers in `@shardworks/nexus-core` lets the CLI
11
+ * (`packages/framework/cli`) and the Clockworks apparatus
12
+ * (`packages/plugins/clockworks`) consume them without either depending
13
+ * on the other.
14
+ */
15
+ /**
16
+ * Returns true when a process with the given pid is alive on this host.
17
+ *
18
+ * Uses signal 0 (the existence probe). The corner case worth knowing:
19
+ * `EPERM` means the process exists but we lack permission to signal it —
20
+ * we still treat it as alive.
21
+ */
22
+ export declare function isProcessAlive(pid: number): boolean;
23
+ /**
24
+ * Read a pidfile and parse it into a positive integer pid. Returns null
25
+ * when the file is missing, unreadable, empty, or contains a value that
26
+ * doesn't parse as a positive number.
27
+ */
28
+ export declare function readPidFile(pidFile: string): number | null;
29
+ /**
30
+ * Delete a file, swallowing any error. Used for pidfile cleanup where
31
+ * a stale or already-deleted file should not be a fatal condition.
32
+ */
33
+ export declare function tryUnlink(file: string): void;
34
+ /**
35
+ * Poll `isProcessAlive(pid)` every 200ms until the pid exits or the
36
+ * timeout elapses. Returns true if the process exited within the
37
+ * window, false otherwise.
38
+ */
39
+ export declare function waitForExit(pid: number, timeoutMs: number): Promise<boolean>;
40
+ //# sourceMappingURL=pid-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid-helpers.d.ts","sourceRoot":"","sources":["../src/pid-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ1D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM5C;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOlF"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared PID-file and process-liveness helpers for daemon-style commands.
3
+ *
4
+ * Two daemons live in the framework today: `nsg start` (the guild daemon)
5
+ * and `nsg clock start` (the Clockworks daemon). Both share the same
6
+ * lifecycle primitives — read a pidfile, decide whether the pid behind
7
+ * it is still alive, unlink the pidfile when the daemon is gone, and
8
+ * poll until a pid actually exits after a SIGTERM.
9
+ *
10
+ * Centralising these helpers in `@shardworks/nexus-core` lets the CLI
11
+ * (`packages/framework/cli`) and the Clockworks apparatus
12
+ * (`packages/plugins/clockworks`) consume them without either depending
13
+ * on the other.
14
+ */
15
+ import fs from 'node:fs';
16
+ /**
17
+ * Returns true when a process with the given pid is alive on this host.
18
+ *
19
+ * Uses signal 0 (the existence probe). The corner case worth knowing:
20
+ * `EPERM` means the process exists but we lack permission to signal it —
21
+ * we still treat it as alive.
22
+ */
23
+ export function isProcessAlive(pid) {
24
+ try {
25
+ process.kill(pid, 0);
26
+ return true;
27
+ }
28
+ catch (err) {
29
+ const code = err.code;
30
+ if (code === 'ESRCH')
31
+ return false;
32
+ // EPERM → exists but we can't signal it. Treat as alive.
33
+ return true;
34
+ }
35
+ }
36
+ /**
37
+ * Read a pidfile and parse it into a positive integer pid. Returns null
38
+ * when the file is missing, unreadable, empty, or contains a value that
39
+ * doesn't parse as a positive number.
40
+ */
41
+ export function readPidFile(pidFile) {
42
+ try {
43
+ const raw = fs.readFileSync(pidFile, 'utf-8').trim();
44
+ const pid = Number(raw);
45
+ return Number.isFinite(pid) && pid > 0 ? pid : null;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ /**
52
+ * Delete a file, swallowing any error. Used for pidfile cleanup where
53
+ * a stale or already-deleted file should not be a fatal condition.
54
+ */
55
+ export function tryUnlink(file) {
56
+ try {
57
+ fs.unlinkSync(file);
58
+ }
59
+ catch {
60
+ // ignore
61
+ }
62
+ }
63
+ /**
64
+ * Poll `isProcessAlive(pid)` every 200ms until the pid exits or the
65
+ * timeout elapses. Returns true if the process exited within the
66
+ * window, false otherwise.
67
+ */
68
+ export async function waitForExit(pid, timeoutMs) {
69
+ const deadline = Date.now() + timeoutMs;
70
+ while (Date.now() < deadline) {
71
+ if (!isProcessAlive(pid))
72
+ return true;
73
+ await new Promise((r) => setTimeout(r, 200));
74
+ }
75
+ return false;
76
+ }
77
+ //# sourceMappingURL=pid-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid-helpers.js","sourceRoot":"","sources":["../src/pid-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;QACnC,yDAAyD;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,SAAiB;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardworks/nexus-core",
3
- "version": "0.1.270",
3
+ "version": "0.1.271",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",