@jamaynor/hal-config 1.0.1

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/CLAUDE.md ADDED
@@ -0,0 +1,84 @@
1
+ # CLAUDE.md — @jamaynor/hal-config
2
+
3
+ ## Overview
4
+
5
+ Shared configuration loader for HAL OpenClaw skills. Reads `hal-system-config.json` once, caches for the process lifetime, and provides accessors for shared data and skill discovery.
6
+
7
+ Zero runtime dependencies. ESM (ES modules). Node >= 22.
8
+
9
+ ## API
10
+
11
+ ```js
12
+ import halConfig from '@jamaynor/hal-config';
13
+
14
+ // Loading
15
+ halConfig.load(configDir?) // Read hal-system-config.json (defaults to HAL_SYSTEM_CONFIG env)
16
+ halConfig.reload() // Bust cache and re-read
17
+ halConfig.raw() // Full config object
18
+ halConfig.configDir() // Resolved config directory path
19
+
20
+ // Shared data
21
+ halConfig.vaults() // hal-obsidian-vaults array (raw)
22
+ halConfig.accounts(provider?) // hal-communication-accounts, optionally filtered
23
+ halConfig.timezone() // string or null
24
+ halConfig.workHours() // { start, end } or null
25
+
26
+ // Skill discovery
27
+ halConfig.skill(name) // Full skill config block or null
28
+ halConfig.isEnabled(name) // boolean — exists and enabled !== false
29
+ halConfig.isInstalled(name) // boolean — enabled + binary on PATH (sync)
30
+ halConfig.isInstalledAsync(name) // Promise<boolean> — async version
31
+ halConfig.skillWorkspace(name) // runtime.workspace or null
32
+ halConfig.skillBinaries(name) // string[] of binary names from install metadata
33
+ halConfig.homeAgent(name) // homeAgent string or null (null = primary agent)
34
+
35
+ // Deterministic locations (no searching)
36
+ halConfig.openclawSharedWorkspaceRoot() // /data/openclaw/workspace
37
+ halConfig.openclawConfigFilePath() // /data/openclaw/openclaw.json
38
+ halConfig.halSystemConfigDir() // /data/openclaw/hal (or HAL_SYSTEM_CONFIG)
39
+ halConfig.halSystemConfigFilePath() // {halSystemConfigDir}/hal-system-config.json
40
+ halConfig.halSkillAdminRoot(skillName) // /data/openclaw/hal/{skillName} (or HAL_SKILL_ADMIN_ROOT)
41
+ halConfig.halSkillConfigDir(skillName) // /data/openclaw/hal/{skillName}/config
42
+ halConfig.skillConfigPath(skillName) // /data/openclaw/hal/{skillName}/config/{skillName}.json
43
+ halConfig.skillConfigDir(skillName) // /data/openclaw/hal/{skillName}/config
44
+ halConfig.halSkillLogDir(skillName) // /data/openclaw/hal/{skillName}/log
45
+
46
+ // Per-skill config files (read/write)
47
+ halConfig.halSkillConfig.read(skillNameOrScope) // {} if missing; throws on invalid JSON
48
+ halConfig.halSkillConfig.getSetting(skillNameOrScope, key) // returns value or undefined
49
+ halConfig.halSkillConfig.write(skillNameOrScope, obj) // overwrites entire {skill}.json (atomic)
50
+ halConfig.halSkillConfig.merge(skillNameOrScope, patchObj) // deep merge (objects merge, arrays replace) + write (atomic)
51
+ halConfig.halSkillConfig.setSetting(skillNameOrScope, key, value) // merge single key + write (atomic)
52
+
53
+ // Registration (for init wizards to write back)
54
+ halConfig.register(name, data) // Merge into skills[name].runtime
55
+ halConfig.writeAccounts(accounts) // Merge-by-label upsert into hal-communication-accounts
56
+ halConfig.writeSkillConfig(name, data) // Merge into skills[name]
57
+ halConfig.writeSharedSettings(settings) // Write top-level keys (hal-timezone, etc.)
58
+ ```
59
+
60
+ ## Config Location
61
+
62
+ Resolved in order: `configDir` argument > `HAL_SYSTEM_CONFIG` env > `/data/openclaw/hal`
63
+
64
+ File: `hal-system-config.json` (v2.0)
65
+
66
+ ## Error Handling
67
+
68
+ - Missing file → returns `{}` (graceful). Skills that require the file (email-triage) enforce this at their wrapper level.
69
+ - Corrupt JSON → throws `SyntaxError`
70
+ - Auto-loads on first accessor call if `load()` not called explicitly
71
+
72
+ ## Testing
73
+
74
+ ```bash
75
+ npm test
76
+ ```
77
+
78
+ 147 tests using `node:test`. Tests use temp directories with synthetic configs — no real system-config needed.
79
+
80
+ ## How Skills Use It
81
+
82
+ Each skill adds `"hal-config": "file:../hal-config"` to its `package.json` dependencies. When `npm install -g` runs inside the container, npm resolves the `file:` path relative to the skill's source directory (`/repos/jamaynor/<skill>/`).
83
+
84
+ Skills keep thin wrappers in `lib/config/system-config.js` that delegate to this package while preserving their existing function signatures.
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import * as config from './lib/config.js';
2
+ export default config;
3
+ export * from './lib/config.js';