@karmaniverous/jeeves 0.3.0 → 0.4.0

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/index.d.ts CHANGED
@@ -87,6 +87,18 @@ interface WriteComponentVersionOptions {
87
87
  * @param options - Component version data to write.
88
88
  */
89
89
  declare function writeComponentVersion(coreConfigDir: string, options: WriteComponentVersionOptions): void;
90
+ /**
91
+ * Remove a component's version entry from the shared state file.
92
+ *
93
+ * @remarks
94
+ * Called during plugin uninstall to prevent the HEARTBEAT writer from
95
+ * probing a service that's intentionally gone. If the component isn't
96
+ * in the file, this is a no-op.
97
+ *
98
+ * @param coreConfigDir - Path to the core config directory.
99
+ * @param componentName - The component name to remove.
100
+ */
101
+ declare function removeComponentVersion(coreConfigDir: string, componentName: string): void;
90
102
 
91
103
  /**
92
104
  * Component interface types for the Jeeves platform.
@@ -119,6 +131,22 @@ interface PluginCommands {
119
131
  /** Uninstall the plugin. */
120
132
  uninstall(): Promise<void>;
121
133
  }
134
+ /** Component dependency declarations. */
135
+ interface ComponentDependencies {
136
+ /**
137
+ * Hard dependencies — the component cannot function without these.
138
+ * If a hard dep is not healthy, suppress all alerts for this component
139
+ * except a "waiting for dependency" message. If a hard dep is declined,
140
+ * auto-decline this component.
141
+ */
142
+ hard: string[];
143
+ /**
144
+ * Soft dependencies — the component works without these but with reduced
145
+ * functionality. When the component is healthy and a soft dep is missing,
146
+ * generate an informational alert. No alert when a soft dep is declined.
147
+ */
148
+ soft: string[];
149
+ }
122
150
  /**
123
151
  * Component descriptor — the contract that Jeeves component plugins
124
152
  * must implement to participate in the platform.
@@ -142,6 +170,12 @@ interface JeevesComponent {
142
170
  serviceCommands: ServiceCommands;
143
171
  /** Plugin lifecycle commands. */
144
172
  pluginCommands: PluginCommands;
173
+ /**
174
+ * Component dependencies. Optional — components with no dependencies
175
+ * omit this field (runner, watcher). Components with dependencies
176
+ * declare them here (meta: hard=['watcher'], server: soft=['watcher','runner','meta']).
177
+ */
178
+ dependencies?: ComponentDependencies;
145
179
  }
146
180
 
147
181
  /**
@@ -268,6 +302,92 @@ declare function createAsyncContentCache(options: AsyncContentCacheOptions): ()
268
302
  */
269
303
  declare function createComponentWriter(component: JeevesComponent): ComponentWriter;
270
304
 
305
+ /**
306
+ * Heading-based HEARTBEAT section writer.
307
+ *
308
+ * @remarks
309
+ * Manages the `# Jeeves Platform Status` section in HEARTBEAT.md.
310
+ * Unlike TOOLS/SOUL/AGENTS (which use HTML comment markers), HEARTBEAT
311
+ * uses markdown headings as markers — this ensures the file passes
312
+ * OpenClaw's heartbeat emptiness check when only headings remain.
313
+ *
314
+ * The section is always at the bottom of the file (H1 to EOF).
315
+ * User heartbeat items above the section are preserved.
316
+ */
317
+ /** The H1 heading that anchors the platform status section. */
318
+ declare const HEARTBEAT_HEADING = "# Jeeves Platform Status";
319
+ /** A single component entry in the HEARTBEAT section. */
320
+ interface HeartbeatEntry {
321
+ /** Component name (e.g., 'runner', 'watcher'). */
322
+ name: string;
323
+ /** Whether the component is declined. */
324
+ declined: boolean;
325
+ /** Alert content (list items). Empty string if healthy or declined. */
326
+ content: string;
327
+ }
328
+ /** Result of parsing the HEARTBEAT section. */
329
+ interface ParsedHeartbeat {
330
+ /** Content above the `# Jeeves Platform Status` heading (user zone). */
331
+ userContent: string;
332
+ /** Whether the heading was found. */
333
+ found: boolean;
334
+ /** Parsed component entries. */
335
+ entries: HeartbeatEntry[];
336
+ }
337
+ /**
338
+ * Parse the HEARTBEAT.md file content.
339
+ *
340
+ * @param fileContent - Full file content.
341
+ * @returns Parsed result with user zone and component entries.
342
+ */
343
+ declare function parseHeartbeat(fileContent: string): ParsedHeartbeat;
344
+ /**
345
+ * Build the HEARTBEAT section content from entries.
346
+ *
347
+ * @param entries - Component entries to write.
348
+ * @returns The full section string (H1 + H2s).
349
+ */
350
+ declare function buildHeartbeatSection(entries: HeartbeatEntry[]): string;
351
+ /**
352
+ * Write the HEARTBEAT section to a file.
353
+ *
354
+ * @remarks
355
+ * Replaces everything from `# Jeeves Platform Status` to EOF.
356
+ * Preserves user content above the heading. Uses file-level locking.
357
+ *
358
+ * @param filePath - Absolute path to HEARTBEAT.md.
359
+ * @param entries - Component entries to write.
360
+ */
361
+ declare function writeHeartbeatSection(filePath: string, entries: HeartbeatEntry[]): Promise<void>;
362
+
363
+ /**
364
+ * HEARTBEAT health orchestration.
365
+ *
366
+ * @remarks
367
+ * Determines the state of each platform component and generates
368
+ * HEARTBEAT entries with actionable alert text. Applies the dependency
369
+ * graph for alert suppression and auto-decline.
370
+ */
371
+
372
+ /** Component state as determined by the orchestrator. */
373
+ type ComponentState = 'not_installed' | 'deps_missing' | 'config_missing' | 'service_not_installed' | 'service_stopped' | 'healthy' | 'update_available';
374
+ /** Options for the orchestrator. */
375
+ interface OrchestrateHeartbeatOptions {
376
+ /** Path to the core config directory. */
377
+ coreConfigDir: string;
378
+ /** Path to the config root. */
379
+ configRoot: string;
380
+ /** Existing declined component names (from parsing current HEARTBEAT). */
381
+ declinedNames: Set<string>;
382
+ }
383
+ /**
384
+ * Orchestrate HEARTBEAT entries for all platform components.
385
+ *
386
+ * @param options - Orchestration configuration.
387
+ * @returns Array of HeartbeatEntry for writeHeartbeatSection.
388
+ */
389
+ declare function orchestrateHeartbeat(options: OrchestrateHeartbeatOptions): Promise<HeartbeatEntry[]>;
390
+
271
391
  /**
272
392
  * Comment markers for managed content blocks.
273
393
  *
@@ -285,6 +405,14 @@ interface ManagedMarkers {
285
405
  end: string;
286
406
  /** Optional H1 title prepended inside the managed block. */
287
407
  title?: string;
408
+ /**
409
+ * Position of the managed block within the file.
410
+ * - `'top'`: managed block first, user content below (current default).
411
+ * - `'bottom'`: user content first, managed block at end.
412
+ *
413
+ * @defaultValue `'top'`
414
+ */
415
+ position?: 'top' | 'bottom';
288
416
  }
289
417
  /** Default markers for TOOLS.md managed block. */
290
418
  declare const TOOLS_MARKERS: ManagedMarkers;
@@ -320,6 +448,8 @@ declare const WORKSPACE_FILES: {
320
448
  readonly soul: "SOUL.md";
321
449
  /** AGENTS.md — operational protocols and memory architecture. */
322
450
  readonly agents: "AGENTS.md";
451
+ /** HEARTBEAT.md — platform status and health alerts. */
452
+ readonly heartbeat: "HEARTBEAT.md";
323
453
  };
324
454
  /** Templates directory name within core config. */
325
455
  declare const TEMPLATES_DIR = "templates";
@@ -352,7 +482,7 @@ declare const META_PORT = 1938;
352
482
  declare const DEFAULT_PORTS: Record<string, number>;
353
483
 
354
484
  /**
355
- * Managed section IDs and their stable ordering for TOOLS.md.
485
+ * Managed section IDs, stable ordering, and platform component registry.
356
486
  *
357
487
  * @remarks
358
488
  * Section ordering is fixed to prevent diff churn regardless of which
@@ -378,6 +508,19 @@ type SectionId = (typeof SECTION_IDS)[keyof typeof SECTION_IDS];
378
508
  * Sections always appear in this order regardless of write order.
379
509
  */
380
510
  declare const SECTION_ORDER: readonly string[];
511
+ /**
512
+ * The four essential platform components.
513
+ *
514
+ * @remarks
515
+ * These components constitute the Jeeves platform. `jeeves install` writes
516
+ * initial HEARTBEAT "Not installed" alerts for all of them. The HEARTBEAT
517
+ * writer generates "Not installed" alerts only for platform components not
518
+ * in `component-versions.json`. Optional future components (not in this list)
519
+ * appear in HEARTBEAT only after explicit install.
520
+ */
521
+ declare const PLATFORM_COMPONENTS: readonly ["runner", "watcher", "server", "meta"];
522
+ /** A platform component name. */
523
+ type PlatformComponent = (typeof PLATFORM_COMPONENTS)[number];
381
524
 
382
525
  /**
383
526
  * Core library version, inlined at build time.
@@ -403,12 +546,19 @@ declare const CORE_VERSION: string;
403
546
  * 3. Hardcoded library defaults
404
547
  */
405
548
 
549
+ /** Default bind address for all Jeeves services. */
550
+ declare const DEFAULT_BIND_ADDRESS = "0.0.0.0";
406
551
  /** Zod schema for the core config file. */
407
552
  declare const coreConfigSchema: z.ZodObject<{
408
553
  /** JSON Schema pointer for IDE autocomplete. */
409
554
  $schema: z.ZodOptional<z.ZodString>;
410
555
  /** Owner identity keys (canonical identityLinks references). */
411
556
  owners: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
557
+ /**
558
+ * Bind address for all Jeeves services. Default: `0.0.0.0` (all interfaces).
559
+ * Individual components can override in their own config.
560
+ */
561
+ bindAddress: z.ZodDefault<z.ZodString>;
412
562
  /** Service URL overrides keyed by service name. */
413
563
  services: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
414
564
  /** Service URL (must be a valid URL). */
@@ -429,6 +579,7 @@ declare const coreConfigSchema: z.ZodObject<{
429
579
  }>>;
430
580
  }, "strip", z.ZodTypeAny, {
431
581
  owners: string[];
582
+ bindAddress: string;
432
583
  services: Record<string, {
433
584
  url: string;
434
585
  }>;
@@ -439,6 +590,7 @@ declare const coreConfigSchema: z.ZodObject<{
439
590
  }, {
440
591
  $schema?: string | undefined;
441
592
  owners?: string[] | undefined;
593
+ bindAddress?: string | undefined;
442
594
  services?: Record<string, {
443
595
  url: string;
444
596
  }> | undefined;
@@ -455,6 +607,41 @@ type CoreConfig = z.infer<typeof coreConfigSchema>;
455
607
  */
456
608
  declare function generateJsonSchema(): Record<string, unknown>;
457
609
 
610
+ /**
611
+ * Resolve the bind address for a Jeeves service.
612
+ *
613
+ * @remarks
614
+ * Resolution order (four-tier):
615
+ * 1. Component config `bindAddress` field (if componentName provided)
616
+ * 2. Core config `bindAddress` field
617
+ * 3. `JEEVES_BIND_ADDRESS` environment variable
618
+ * 4. Default: `0.0.0.0`
619
+ */
620
+ /**
621
+ * Resolve the bind address for a Jeeves service.
622
+ *
623
+ * @param componentName - Optional component name for component-specific override.
624
+ * @returns The resolved bind address.
625
+ */
626
+ declare function getBindAddress(componentName?: string): string;
627
+
628
+ /**
629
+ * Platform-aware service state detection.
630
+ *
631
+ * @remarks
632
+ * Detects whether a system service is installed and running.
633
+ * Delegates to NSSM (Windows), systemd (Linux), or launchd (macOS).
634
+ */
635
+ /** Service states returned by getServiceState. */
636
+ type ServiceState = 'not_installed' | 'stopped' | 'running';
637
+ /**
638
+ * Detect the state of a system service by name.
639
+ *
640
+ * @param serviceName - The service name (e.g., 'jeeves-runner').
641
+ * @returns The detected service state.
642
+ */
643
+ declare function getServiceState(serviceName: string): ServiceState;
644
+
458
645
  /**
459
646
  * Service URL resolution.
460
647
  *
@@ -813,6 +1000,7 @@ interface SeedContentOptions {
813
1000
  * @remarks
814
1001
  * Uses the same `updateManagedSection()` code path as writer cycles.
815
1002
  * Creates core config with defaults if missing. Copies templates.
1003
+ * Writes initial HEARTBEAT with "Not installed" alerts for all platform components.
816
1004
  * Jaccard cleanup detection runs automatically via `updateManagedSection`.
817
1005
  *
818
1006
  * @param options - Seeding configuration.
@@ -910,7 +1098,9 @@ declare function patchConfig(config: Record<string, unknown>, pluginId: string,
910
1098
  interface ToolResult {
911
1099
  /** Content blocks — typically a single text block. */
912
1100
  content: Array<{
1101
+ /** MIME type identifier (e.g. `"text"`). */
913
1102
  type: string;
1103
+ /** Text content of the block. */
914
1104
  text: string;
915
1105
  }>;
916
1106
  /** Whether this result represents an error. */
@@ -955,6 +1145,7 @@ interface PluginApi {
955
1145
  plugins?: {
956
1146
  /** Plugin entries keyed by plugin ID. */
957
1147
  entries?: Record<string, {
1148
+ /** Plugin-specific configuration key-value pairs. */
958
1149
  config?: Record<string, unknown>;
959
1150
  }>;
960
1151
  };
@@ -1060,5 +1251,5 @@ declare function fail(error: unknown): ToolResult;
1060
1251
  */
1061
1252
  declare function connectionFail(error: unknown, baseUrl: string, pluginId: string): ToolResult;
1062
1253
 
1063
- export { AGENTS_MARKERS, CLEANUP_FLAG, COMPONENT_CONFIG_PREFIX, COMPONENT_VERSIONS_FILE, CONFIG_FILE, CORE_CONFIG_DIR, CORE_VERSION, ComponentWriter, DEFAULT_CORE_VERSION, DEFAULT_PORTS, META_PORT, REGISTRY_CACHE_FILE, RUNNER_PORT, SECTION_IDS, SECTION_ORDER, SERVER_PORT, SOUL_MARKERS, STALENESS_THRESHOLD_MS, STALE_LOCK_MS, TEMPLATES_DIR, TOOLS_MARKERS, VERSION_STAMP_PATTERN, WATCHER_PORT, WORKSPACE_FILES, atomicWrite, checkRegistryVersion, connectionFail, coreConfigSchema, createAsyncContentCache, createComponentWriter, createConfigQueryHandler, fail, fetchJson, fetchWithTimeout, formatBeginMarker, formatEndMarker, generateJsonSchema, getComponentConfigDir, getConfigRoot, getCoreConfigDir, getCoreConfigFile, getServiceUrl, getWorkspacePath, init, jaccard, needsCleanup, ok, parseManaged, patchConfig, postJson, readComponentVersions, refreshPlatformContent, removeManagedSection, resetInit, resolveConfigPath, resolveOpenClawHome, resolveOptionalPluginSetting, resolvePluginSetting, resolveWorkspacePath, seedContent, shingles, shouldWrite, updateManagedSection, withFileLock, writeComponentVersion };
1064
- export type { AsyncContentCacheOptions, ComponentVersionEntry, ComponentVersionsState, ConfigQueryHandler, ConfigQueryResponse, CoreConfig, InitOptions, JeevesComponent, ManagedMarkers, ManagedSection, ParseManagedResult, PluginApi, PluginCommands, RefreshPlatformContentOptions, RemoveManagedSectionOptions, SectionId, SeedContentOptions, ServiceCommands, ServiceStatus, ToolDescriptor, ToolRegistrationOptions, ToolResult, UpdateManagedSectionOptions, VersionStamp, WriteComponentVersionOptions };
1254
+ export { AGENTS_MARKERS, CLEANUP_FLAG, COMPONENT_CONFIG_PREFIX, COMPONENT_VERSIONS_FILE, CONFIG_FILE, CORE_CONFIG_DIR, CORE_VERSION, ComponentWriter, DEFAULT_BIND_ADDRESS, DEFAULT_CORE_VERSION, DEFAULT_PORTS, HEARTBEAT_HEADING, META_PORT, PLATFORM_COMPONENTS, REGISTRY_CACHE_FILE, RUNNER_PORT, SECTION_IDS, SECTION_ORDER, SERVER_PORT, SOUL_MARKERS, STALENESS_THRESHOLD_MS, STALE_LOCK_MS, TEMPLATES_DIR, TOOLS_MARKERS, VERSION_STAMP_PATTERN, WATCHER_PORT, WORKSPACE_FILES, atomicWrite, buildHeartbeatSection, checkRegistryVersion, connectionFail, coreConfigSchema, createAsyncContentCache, createComponentWriter, createConfigQueryHandler, fail, fetchJson, fetchWithTimeout, formatBeginMarker, formatEndMarker, generateJsonSchema, getBindAddress, getComponentConfigDir, getConfigRoot, getCoreConfigDir, getCoreConfigFile, getServiceState, getServiceUrl, getWorkspacePath, init, jaccard, needsCleanup, ok, orchestrateHeartbeat, parseHeartbeat, parseManaged, patchConfig, postJson, readComponentVersions, refreshPlatformContent, removeComponentVersion, removeManagedSection, resetInit, resolveConfigPath, resolveOpenClawHome, resolveOptionalPluginSetting, resolvePluginSetting, resolveWorkspacePath, seedContent, shingles, shouldWrite, updateManagedSection, withFileLock, writeComponentVersion, writeHeartbeatSection };
1255
+ export type { AsyncContentCacheOptions, ComponentDependencies, ComponentState, ComponentVersionEntry, ComponentVersionsState, ConfigQueryHandler, ConfigQueryResponse, CoreConfig, HeartbeatEntry, InitOptions, JeevesComponent, ManagedMarkers, ManagedSection, OrchestrateHeartbeatOptions, ParseManagedResult, ParsedHeartbeat, PlatformComponent, PluginApi, PluginCommands, RefreshPlatformContentOptions, RemoveManagedSectionOptions, SectionId, SeedContentOptions, ServiceCommands, ServiceState, ServiceStatus, ToolDescriptor, ToolRegistrationOptions, ToolResult, UpdateManagedSectionOptions, VersionStamp, WriteComponentVersionOptions };