@openreef/cli 0.1.1 → 0.3.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/README.md +14 -7
- package/dist/commands/install.d.ts +14 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +612 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +81 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/logs.d.ts +8 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +118 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/repair.d.ts +10 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +328 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +181 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/uninstall.d.ts +9 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +166 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +12 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +518 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/core/agents-md-generator.d.ts +3 -0
- package/dist/core/agents-md-generator.d.ts.map +1 -0
- package/dist/core/agents-md-generator.js +24 -0
- package/dist/core/agents-md-generator.js.map +1 -0
- package/dist/core/config-patcher.d.ts +32 -0
- package/dist/core/config-patcher.d.ts.map +1 -0
- package/dist/core/config-patcher.js +156 -0
- package/dist/core/config-patcher.js.map +1 -0
- package/dist/core/device-identity.d.ts +37 -0
- package/dist/core/device-identity.d.ts.map +1 -0
- package/dist/core/device-identity.js +135 -0
- package/dist/core/device-identity.js.map +1 -0
- package/dist/core/gateway-client.d.ts +98 -0
- package/dist/core/gateway-client.d.ts.map +1 -0
- package/dist/core/gateway-client.js +238 -0
- package/dist/core/gateway-client.js.map +1 -0
- package/dist/core/log-reader.d.ts +28 -0
- package/dist/core/log-reader.d.ts.map +1 -0
- package/dist/core/log-reader.js +69 -0
- package/dist/core/log-reader.js.map +1 -0
- package/dist/core/migration-planner.d.ts +37 -0
- package/dist/core/migration-planner.d.ts.map +1 -0
- package/dist/core/migration-planner.js +160 -0
- package/dist/core/migration-planner.js.map +1 -0
- package/dist/core/openclaw-paths.d.ts +23 -0
- package/dist/core/openclaw-paths.d.ts.map +1 -0
- package/dist/core/openclaw-paths.js +189 -0
- package/dist/core/openclaw-paths.js.map +1 -0
- package/dist/core/state-differ.d.ts +15 -0
- package/dist/core/state-differ.d.ts.map +1 -0
- package/dist/core/state-differ.js +135 -0
- package/dist/core/state-differ.js.map +1 -0
- package/dist/core/state-manager.d.ts +7 -0
- package/dist/core/state-manager.d.ts.map +1 -0
- package/dist/core/state-manager.js +61 -0
- package/dist/core/state-manager.js.map +1 -0
- package/dist/core/variable-resolver.d.ts +1 -0
- package/dist/core/variable-resolver.d.ts.map +1 -1
- package/dist/core/variable-resolver.js +21 -10
- package/dist/core/variable-resolver.js.map +1 -1
- package/dist/index.js +133 -1
- package/dist/index.js.map +1 -1
- package/dist/types/state.d.ts +55 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +2 -0
- package/dist/types/state.js.map +1 -0
- package/dist/utils/identifiers.d.ts +18 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +50 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/package.json +6 -3
- package/template/reef.json +6 -6
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { networkInterfaces } from 'node:os';
|
|
5
|
+
const CONFIG_FILENAMES = [
|
|
6
|
+
'openclaw.json',
|
|
7
|
+
'clawdbot.json',
|
|
8
|
+
'moldbot.json',
|
|
9
|
+
'moltbot.json',
|
|
10
|
+
];
|
|
11
|
+
const LEGACY_DIRS = ['.clawdbot', '.moldbot', '.moltbot'];
|
|
12
|
+
export function resolveHomeDir(env) {
|
|
13
|
+
const e = env ?? process.env;
|
|
14
|
+
const raw = e.OPENCLAW_HOME ?? e.HOME ?? e.USERPROFILE;
|
|
15
|
+
if (raw) {
|
|
16
|
+
if (raw.startsWith('~')) {
|
|
17
|
+
return join(os.homedir(), raw.slice(1));
|
|
18
|
+
}
|
|
19
|
+
return raw;
|
|
20
|
+
}
|
|
21
|
+
return os.homedir();
|
|
22
|
+
}
|
|
23
|
+
export function resolveStateDir(env) {
|
|
24
|
+
const e = env ?? process.env;
|
|
25
|
+
const explicit = e.OPENCLAW_STATE_DIR ?? e.CLAWDBOT_STATE_DIR;
|
|
26
|
+
if (explicit)
|
|
27
|
+
return explicit;
|
|
28
|
+
const homeDir = resolveHomeDir(env);
|
|
29
|
+
const primary = join(homeDir, '.openclaw');
|
|
30
|
+
if (existsSync(primary))
|
|
31
|
+
return primary;
|
|
32
|
+
for (const legacy of LEGACY_DIRS) {
|
|
33
|
+
const candidate = join(homeDir, legacy);
|
|
34
|
+
if (existsSync(candidate))
|
|
35
|
+
return candidate;
|
|
36
|
+
}
|
|
37
|
+
return primary;
|
|
38
|
+
}
|
|
39
|
+
export function resolveConfigPath(env) {
|
|
40
|
+
const e = env ?? process.env;
|
|
41
|
+
// 1. Explicit config path env
|
|
42
|
+
const explicitPath = e.OPENCLAW_CONFIG_PATH ?? e.CLAWDBOT_CONFIG_PATH;
|
|
43
|
+
if (explicitPath)
|
|
44
|
+
return explicitPath;
|
|
45
|
+
const stateDir = resolveStateDir(env);
|
|
46
|
+
// 2. Search state dir for first existing config file
|
|
47
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
48
|
+
const candidate = join(stateDir, filename);
|
|
49
|
+
if (existsSync(candidate))
|
|
50
|
+
return candidate;
|
|
51
|
+
}
|
|
52
|
+
// 3. If OPENCLAW_STATE_DIR was explicitly set, return canonical path (skip home search)
|
|
53
|
+
const hasExplicitStateDir = !!(e.OPENCLAW_STATE_DIR ?? e.CLAWDBOT_STATE_DIR);
|
|
54
|
+
if (hasExplicitStateDir) {
|
|
55
|
+
return join(stateDir, 'openclaw.json');
|
|
56
|
+
}
|
|
57
|
+
// 4. Only for default state dir: search across all home directories
|
|
58
|
+
const homeDir = resolveHomeDir(env);
|
|
59
|
+
const homeDirs = [
|
|
60
|
+
join(homeDir, '.openclaw'),
|
|
61
|
+
join(homeDir, '.clawdbot'),
|
|
62
|
+
join(homeDir, '.moldbot'),
|
|
63
|
+
join(homeDir, '.moltbot'),
|
|
64
|
+
];
|
|
65
|
+
for (const dir of homeDirs) {
|
|
66
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
67
|
+
const candidate = join(dir, filename);
|
|
68
|
+
if (existsSync(candidate))
|
|
69
|
+
return candidate;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// 5. Ultimate fallback
|
|
73
|
+
return join(stateDir, 'openclaw.json');
|
|
74
|
+
}
|
|
75
|
+
export function resolveWorkspacePath(agentId, env) {
|
|
76
|
+
return join(resolveStateDir(env), `workspace-${agentId}`);
|
|
77
|
+
}
|
|
78
|
+
export function resolveReefStateDir(env) {
|
|
79
|
+
return join(resolveStateDir(env), '.reef');
|
|
80
|
+
}
|
|
81
|
+
export function resolveGatewayUrl(config, env) {
|
|
82
|
+
const e = env ?? process.env;
|
|
83
|
+
const gw = (config?.gateway ?? {});
|
|
84
|
+
const tls = (gw.tls ?? {});
|
|
85
|
+
const bind = gw.bind ?? 'loopback';
|
|
86
|
+
const envPort = e.OPENCLAW_GATEWAY_PORT
|
|
87
|
+
? parseInt(e.OPENCLAW_GATEWAY_PORT, 10)
|
|
88
|
+
: null;
|
|
89
|
+
const port = gw.port ??
|
|
90
|
+
(envPort !== null && !isNaN(envPort) ? envPort : null) ??
|
|
91
|
+
18789;
|
|
92
|
+
const scheme = tls.enabled ? 'wss' : 'ws';
|
|
93
|
+
if (bind === 'tailnet') {
|
|
94
|
+
const ip = findIPv4('tailscale');
|
|
95
|
+
// Tailnet uses scheme from TLS config, not hardcoded wss
|
|
96
|
+
if (ip)
|
|
97
|
+
return `${scheme}://${ip}:${port}`;
|
|
98
|
+
}
|
|
99
|
+
if (bind === 'lan') {
|
|
100
|
+
const ip = findLanIPv4();
|
|
101
|
+
if (ip)
|
|
102
|
+
return `${scheme}://${ip}:${port}`;
|
|
103
|
+
}
|
|
104
|
+
return `${scheme}://127.0.0.1:${port}`;
|
|
105
|
+
}
|
|
106
|
+
function findIPv4(interfacePrefix) {
|
|
107
|
+
const ifaces = networkInterfaces();
|
|
108
|
+
for (const [name, addrs] of Object.entries(ifaces)) {
|
|
109
|
+
if (!name.toLowerCase().startsWith(interfacePrefix))
|
|
110
|
+
continue;
|
|
111
|
+
for (const addr of addrs ?? []) {
|
|
112
|
+
if (addr.family === 'IPv4' && !addr.internal)
|
|
113
|
+
return addr.address;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function findLanIPv4() {
|
|
119
|
+
const ifaces = networkInterfaces();
|
|
120
|
+
for (const addrs of Object.values(ifaces)) {
|
|
121
|
+
for (const addr of addrs ?? []) {
|
|
122
|
+
if (addr.family === 'IPv4' && !addr.internal)
|
|
123
|
+
return addr.address;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const AGENT_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
129
|
+
export function validateAgentId(id) {
|
|
130
|
+
const normalized = id.toLowerCase();
|
|
131
|
+
if (normalized.includes('.')) {
|
|
132
|
+
return {
|
|
133
|
+
valid: false,
|
|
134
|
+
normalized,
|
|
135
|
+
error: `Agent ID "${id}" contains dots — OpenClaw collapses dots to dashes. Use dashes instead.`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (normalized.length > 64) {
|
|
139
|
+
return {
|
|
140
|
+
valid: false,
|
|
141
|
+
normalized,
|
|
142
|
+
error: `Agent ID "${id}" exceeds 64 characters (${normalized.length}).`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (!AGENT_ID_RE.test(normalized)) {
|
|
146
|
+
return {
|
|
147
|
+
valid: false,
|
|
148
|
+
normalized,
|
|
149
|
+
error: `Agent ID "${id}" does not match [a-z0-9][a-z0-9_-]{0,63}.`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return { valid: true, normalized };
|
|
153
|
+
}
|
|
154
|
+
export function validateAgentIds(slugs, namespace) {
|
|
155
|
+
const ids = new Map();
|
|
156
|
+
const errors = [];
|
|
157
|
+
const seen = new Map();
|
|
158
|
+
for (const slug of slugs) {
|
|
159
|
+
const id = `${namespace}-${slug}`;
|
|
160
|
+
const result = validateAgentId(id);
|
|
161
|
+
if (!result.valid) {
|
|
162
|
+
errors.push(result.error);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const existing = seen.get(result.normalized);
|
|
166
|
+
if (existing) {
|
|
167
|
+
errors.push(`Slugs "${existing}" and "${slug}" produce the same normalized ID "${result.normalized}".`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
seen.set(result.normalized, slug);
|
|
171
|
+
ids.set(slug, result.normalized);
|
|
172
|
+
}
|
|
173
|
+
return { valid: errors.length === 0, ids, errors };
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Return paths under $STATE_DIR/agents/{agentId}/ that should be cleaned up
|
|
177
|
+
* on uninstall: sessions, agent state, qmd memory, and the parent directory.
|
|
178
|
+
* Order: children first, so the parent can be rmdir'd if empty.
|
|
179
|
+
*/
|
|
180
|
+
export function resolveAgentStatePaths(agentId, env) {
|
|
181
|
+
const stateDir = resolveStateDir(env);
|
|
182
|
+
return [
|
|
183
|
+
join(stateDir, 'agents', agentId, 'sessions'),
|
|
184
|
+
join(stateDir, 'agents', agentId, 'agent'),
|
|
185
|
+
join(stateDir, 'agents', agentId, 'qmd'),
|
|
186
|
+
join(stateDir, 'agents', agentId),
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=openclaw-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-paths.js","sourceRoot":"","sources":["../../src/core/openclaw-paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FormationState } from '../types/state.js';
|
|
2
|
+
import type { CronJob } from './gateway-client.js';
|
|
3
|
+
export interface Discrepancy {
|
|
4
|
+
kind: 'agent' | 'binding' | 'cron' | 'file' | 'a2a';
|
|
5
|
+
type: 'missing' | 'orphaned' | 'changed';
|
|
6
|
+
description: string;
|
|
7
|
+
agentId?: string;
|
|
8
|
+
fixable: boolean;
|
|
9
|
+
needsSource: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function diffStateVsConfig(state: FormationState, config: Record<string, unknown>): Discrepancy[];
|
|
12
|
+
export declare function diffStateVsFilesystem(state: FormationState): Discrepancy[];
|
|
13
|
+
export declare function diffStateVsCron(state: FormationState, liveCronJobs: CronJob[] | null): Discrepancy[];
|
|
14
|
+
export declare function collectDiscrepancies(state: FormationState, config: Record<string, unknown>, liveCronJobs: CronJob[] | null): Discrepancy[];
|
|
15
|
+
//# sourceMappingURL=state-differ.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-differ.d.ts","sourceRoot":"","sources":["../../src/core/state-differ.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAiC,MAAM,mBAAmB,CAAC;AACvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACpD,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,WAAW,EAAE,CAsDf;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,cAAc,GACpB,WAAW,EAAE,CAwDf;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,OAAO,EAAE,GAAG,IAAI,GAC7B,WAAW,EAAE,CAoBf;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,YAAY,EAAE,OAAO,EAAE,GAAG,IAAI,GAC7B,WAAW,EAAE,CAMf"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { computeFileHash } from './state-manager.js';
|
|
4
|
+
import { bindingsEqual } from './config-patcher.js';
|
|
5
|
+
export function diffStateVsConfig(state, config) {
|
|
6
|
+
const discrepancies = [];
|
|
7
|
+
const agentsList = config.agents?.list ?? [];
|
|
8
|
+
// Check each agent in state exists in config
|
|
9
|
+
for (const agent of Object.values(state.agents)) {
|
|
10
|
+
const found = agentsList.some((a) => a.id === agent.id);
|
|
11
|
+
if (!found) {
|
|
12
|
+
discrepancies.push({
|
|
13
|
+
kind: 'agent',
|
|
14
|
+
type: 'missing',
|
|
15
|
+
description: `${agent.slug} (${agent.id}) not in config`,
|
|
16
|
+
agentId: agent.id,
|
|
17
|
+
fixable: true,
|
|
18
|
+
needsSource: false,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Check bindings
|
|
23
|
+
const configBindings = (config.bindings ?? []);
|
|
24
|
+
for (const binding of state.bindings) {
|
|
25
|
+
const found = configBindings.some((b) => bindingsEqual(b, binding));
|
|
26
|
+
if (!found) {
|
|
27
|
+
discrepancies.push({
|
|
28
|
+
kind: 'binding',
|
|
29
|
+
type: 'missing',
|
|
30
|
+
description: `${binding.match.channel} → ${binding.agentId} not in config`,
|
|
31
|
+
fixable: true,
|
|
32
|
+
needsSource: false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Check a2a
|
|
37
|
+
if (state.agentToAgent?.allowAdded) {
|
|
38
|
+
const tools = config.tools;
|
|
39
|
+
const a2a = tools?.agentToAgent;
|
|
40
|
+
const allow = a2a?.allow ?? [];
|
|
41
|
+
const pattern = `${state.namespace}-*`;
|
|
42
|
+
if (!allow.includes(pattern)) {
|
|
43
|
+
discrepancies.push({
|
|
44
|
+
kind: 'a2a',
|
|
45
|
+
type: 'missing',
|
|
46
|
+
description: `Agent-to-agent allow pattern "${pattern}" not in config`,
|
|
47
|
+
fixable: true,
|
|
48
|
+
needsSource: false,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return discrepancies;
|
|
53
|
+
}
|
|
54
|
+
export function diffStateVsFilesystem(state) {
|
|
55
|
+
const discrepancies = [];
|
|
56
|
+
for (const agent of Object.values(state.agents)) {
|
|
57
|
+
if (!existsSync(agent.workspace)) {
|
|
58
|
+
discrepancies.push({
|
|
59
|
+
kind: 'file',
|
|
60
|
+
type: 'missing',
|
|
61
|
+
description: `Workspace ${agent.workspace} missing`,
|
|
62
|
+
agentId: agent.id,
|
|
63
|
+
fixable: false,
|
|
64
|
+
needsSource: true,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Check individual file hashes
|
|
69
|
+
for (const [key, expectedHash] of Object.entries(state.fileHashes)) {
|
|
70
|
+
// key format: "agentId:relativePath"
|
|
71
|
+
const colonIdx = key.indexOf(':');
|
|
72
|
+
if (colonIdx === -1)
|
|
73
|
+
continue;
|
|
74
|
+
const agentId = key.slice(0, colonIdx);
|
|
75
|
+
const relativePath = key.slice(colonIdx + 1);
|
|
76
|
+
// Find the agent
|
|
77
|
+
const agent = Object.values(state.agents).find((a) => a.id === agentId);
|
|
78
|
+
if (!agent)
|
|
79
|
+
continue;
|
|
80
|
+
const filePath = join(agent.workspace, relativePath);
|
|
81
|
+
if (!existsSync(filePath)) {
|
|
82
|
+
discrepancies.push({
|
|
83
|
+
kind: 'file',
|
|
84
|
+
type: 'missing',
|
|
85
|
+
description: `File ${relativePath} missing from ${agent.slug} workspace`,
|
|
86
|
+
agentId: agent.id,
|
|
87
|
+
fixable: false,
|
|
88
|
+
needsSource: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// File exists — check hash
|
|
93
|
+
const actualContent = readFileSync(filePath);
|
|
94
|
+
const actualHash = computeFileHash(actualContent);
|
|
95
|
+
if (actualHash !== expectedHash) {
|
|
96
|
+
discrepancies.push({
|
|
97
|
+
kind: 'file',
|
|
98
|
+
type: 'changed',
|
|
99
|
+
description: `File ${relativePath} changed in ${agent.slug} workspace`,
|
|
100
|
+
agentId: agent.id,
|
|
101
|
+
fixable: false,
|
|
102
|
+
needsSource: true,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return discrepancies;
|
|
108
|
+
}
|
|
109
|
+
export function diffStateVsCron(state, liveCronJobs) {
|
|
110
|
+
if (liveCronJobs === null)
|
|
111
|
+
return [];
|
|
112
|
+
const discrepancies = [];
|
|
113
|
+
const liveIds = new Set(liveCronJobs.map((j) => j.id));
|
|
114
|
+
for (const job of state.cronJobs) {
|
|
115
|
+
if (!liveIds.has(job.id)) {
|
|
116
|
+
const hasScheduleData = !!(job.schedule && job.prompt);
|
|
117
|
+
discrepancies.push({
|
|
118
|
+
kind: 'cron',
|
|
119
|
+
type: 'missing',
|
|
120
|
+
description: `Cron job ${job.name} (${job.id}) not found on Gateway`,
|
|
121
|
+
fixable: hasScheduleData,
|
|
122
|
+
needsSource: !hasScheduleData,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return discrepancies;
|
|
127
|
+
}
|
|
128
|
+
export function collectDiscrepancies(state, config, liveCronJobs) {
|
|
129
|
+
return [
|
|
130
|
+
...diffStateVsConfig(state, config),
|
|
131
|
+
...diffStateVsFilesystem(state),
|
|
132
|
+
...diffStateVsCron(state, liveCronJobs),
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=state-differ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-differ.js","sourceRoot":"","sources":["../../src/core/state-differ.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormationState } from '../types/state.js';
|
|
2
|
+
export declare function loadState(namespace: string, name: string, env?: NodeJS.ProcessEnv): Promise<FormationState | null>;
|
|
3
|
+
export declare function saveState(state: FormationState, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
4
|
+
export declare function deleteState(namespace: string, name: string, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
5
|
+
export declare function listStates(env?: NodeJS.ProcessEnv): Promise<FormationState[]>;
|
|
6
|
+
export declare function computeFileHash(content: Buffer): string;
|
|
7
|
+
//# sourceMappingURL=state-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../../src/core/state-manager.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMxD,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GACtB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAShC;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GACtB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GACtB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,UAAU,CAC9B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GACtB,OAAO,CAAC,cAAc,EAAE,CAAC,CAqB3B;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readFile, writeFile, unlink, readdir, mkdir, } from 'node:fs/promises';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { resolveReefStateDir } from './openclaw-paths.js';
|
|
5
|
+
function stateFileName(namespace, name) {
|
|
6
|
+
return `${namespace}--${name}.state.json`;
|
|
7
|
+
}
|
|
8
|
+
export async function loadState(namespace, name, env) {
|
|
9
|
+
const dir = resolveReefStateDir(env);
|
|
10
|
+
const filePath = join(dir, stateFileName(namespace, name));
|
|
11
|
+
try {
|
|
12
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
13
|
+
return JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function saveState(state, env) {
|
|
20
|
+
const dir = resolveReefStateDir(env);
|
|
21
|
+
await mkdir(dir, { recursive: true });
|
|
22
|
+
const filePath = join(dir, stateFileName(state.namespace, state.name));
|
|
23
|
+
await writeFile(filePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
export async function deleteState(namespace, name, env) {
|
|
26
|
+
const dir = resolveReefStateDir(env);
|
|
27
|
+
const filePath = join(dir, stateFileName(namespace, name));
|
|
28
|
+
try {
|
|
29
|
+
await unlink(filePath);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Already gone
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function listStates(env) {
|
|
36
|
+
const dir = resolveReefStateDir(env);
|
|
37
|
+
let entries;
|
|
38
|
+
try {
|
|
39
|
+
entries = await readdir(dir);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const states = [];
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (!entry.endsWith('.state.json'))
|
|
47
|
+
continue;
|
|
48
|
+
try {
|
|
49
|
+
const raw = await readFile(join(dir, entry), 'utf-8');
|
|
50
|
+
states.push(JSON.parse(raw));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Skip corrupt state files
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return states;
|
|
57
|
+
}
|
|
58
|
+
export function computeFileHash(content) {
|
|
59
|
+
return createHash('sha256').update(content).digest('hex');
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=state-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-manager.js","sourceRoot":"","sources":["../../src/core/state-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variable-resolver.d.ts","sourceRoot":"","sources":["../../src/core/variable-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"variable-resolver.d.ts","sourceRoot":"","sources":["../../src/core/variable-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACnC,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAyCxB"}
|
|
@@ -4,15 +4,17 @@ import { parse as parseDotenv } from 'dotenv';
|
|
|
4
4
|
export async function resolveVariables(variables, formationDir, options = {}) {
|
|
5
5
|
const resolved = {};
|
|
6
6
|
const missing = [];
|
|
7
|
-
// Load .env file if present
|
|
7
|
+
// Load .env file if present (skip with --no-env)
|
|
8
8
|
let envFileVars = {};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
if (!options.noEnv) {
|
|
10
|
+
const envPath = options.envFilePath ?? join(formationDir, '.env');
|
|
11
|
+
try {
|
|
12
|
+
const envContent = await readFile(envPath, 'utf-8');
|
|
13
|
+
envFileVars = parseDotenv(Buffer.from(envContent));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// .env file not found — that's fine
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
for (const [name, config] of Object.entries(variables)) {
|
|
18
20
|
// Precedence: CLI > .env > env > defaults
|
|
@@ -29,8 +31,17 @@ export async function resolveVariables(variables, formationDir, options = {}) {
|
|
|
29
31
|
resolved[name] = String(config.default);
|
|
30
32
|
}
|
|
31
33
|
else if (config.required) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
if (options.interactive) {
|
|
35
|
+
const { input, password } = await import('@inquirer/prompts');
|
|
36
|
+
const promptFn = config.sensitive ? password : input;
|
|
37
|
+
const answer = await promptFn({
|
|
38
|
+
message: `${name}${config.description ? ` (${config.description})` : ''}:`,
|
|
39
|
+
});
|
|
40
|
+
resolved[name] = answer;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
missing.push(name);
|
|
44
|
+
}
|
|
34
45
|
}
|
|
35
46
|
}
|
|
36
47
|
return { resolved, missing };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variable-resolver.js","sourceRoot":"","sources":["../../src/core/variable-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"variable-resolver.js","sourceRoot":"","sources":["../../src/core/variable-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AAe9C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAmC,EACnC,YAAoB,EACpB,UAA0B,EAAE;IAE5B,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,iDAAiD;IACjD,IAAI,WAAW,GAA2B,EAAE,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACvD,0CAA0C;QAC1C,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QACtC,CAAC;aAAM,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACxC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;gBAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;gBACrD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;oBAC5B,OAAO,EAAE,GAAG,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG;iBAC3E,CAAC,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC"}
|