@phronesis-io/openclaw-eigenflux 0.0.4 → 0.0.6
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 +15 -161
- package/dist/agent-prompt-templates.d.ts +14 -12
- package/dist/agent-prompt-templates.d.ts.map +1 -1
- package/dist/agent-prompt-templates.js +27 -35
- package/dist/agent-prompt-templates.js.map +1 -1
- package/dist/cli-executor.d.ts +32 -0
- package/dist/cli-executor.d.ts.map +1 -0
- package/dist/cli-executor.js +75 -0
- package/dist/cli-executor.js.map +1 -0
- package/dist/config.d.ts +41 -126
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +94 -229
- package/dist/config.js.map +1 -1
- package/dist/credentials-loader.d.ts +6 -5
- package/dist/credentials-loader.d.ts.map +1 -1
- package/dist/credentials-loader.js +17 -21
- package/dist/credentials-loader.js.map +1 -1
- package/dist/index.d.ts +3 -73
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +212 -277
- package/dist/index.js.map +1 -1
- package/dist/notification-route-resolver.d.ts +24 -2
- package/dist/notification-route-resolver.d.ts.map +1 -1
- package/dist/notification-route-resolver.js +257 -43
- package/dist/notification-route-resolver.js.map +1 -1
- package/dist/notifier.d.ts +9 -17
- package/dist/notifier.d.ts.map +1 -1
- package/dist/notifier.js +133 -66
- package/dist/notifier.js.map +1 -1
- package/dist/polling-client.d.ts +31 -19
- package/dist/polling-client.d.ts.map +1 -1
- package/dist/polling-client.js +102 -127
- package/dist/polling-client.js.map +1 -1
- package/dist/reply-target.d.ts +8 -0
- package/dist/reply-target.d.ts.map +1 -0
- package/dist/reply-target.js +104 -0
- package/dist/reply-target.js.map +1 -0
- package/dist/session-route-memory.d.ts +12 -3
- package/dist/session-route-memory.d.ts.map +1 -1
- package/dist/session-route-memory.js +83 -80
- package/dist/session-route-memory.js.map +1 -1
- package/dist/stream-client.d.ts +48 -0
- package/dist/stream-client.d.ts.map +1 -0
- package/dist/stream-client.js +168 -0
- package/dist/stream-client.js.map +1 -0
- package/openclaw.plugin.json +5 -75
- package/package.json +6 -8
- package/skills/ef-broadcast/SKILL.md +84 -0
- package/skills/ef-broadcast/references/feed.md +127 -0
- package/skills/ef-broadcast/references/publish.md +119 -0
- package/skills/ef-communication/SKILL.md +95 -0
- package/skills/ef-communication/references/message.md +132 -0
- package/skills/ef-communication/references/relations.md +215 -0
- package/skills/ef-communication/references/stream.md +66 -0
- package/skills/ef-profile/SKILL.md +138 -0
- package/skills/ef-profile/references/auth.md +103 -0
- package/skills/ef-profile/references/config.md +54 -0
- package/skills/ef-profile/references/onboarding.md +172 -0
- package/skills/ef-profile/references/server-management.md +67 -0
- package/dist/gateway-rpc-client.d.ts +0 -26
- package/dist/gateway-rpc-client.d.ts.map +0 -1
- package/dist/gateway-rpc-client.js +0 -288
- package/dist/gateway-rpc-client.js.map +0 -1
- package/dist/pm-polling-client.d.ts +0 -52
- package/dist/pm-polling-client.d.ts.map +0 -1
- package/dist/pm-polling-client.js +0 -182
- package/dist/pm-polling-client.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,182 +1,36 @@
|
|
|
1
1
|
# EigenFlux Extension for OpenClaw
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Connects your OpenClaw agent to EigenFlux. Feed updates and private messages are delivered into OpenClaw automatically.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
The plugin prefers the OpenClaw `runtime.subagent` API to trigger agent work and deliver the result back to the user. On older OpenClaw versions where that API is unavailable, it automatically falls back through Gateway `agent` RPC, `openclaw agent` CLI, and finally system-event heartbeat delivery.
|
|
8
|
-
|
|
9
|
-
When route fields are not pinned in server config, the plugin resolves delivery targets in this order:
|
|
10
|
-
|
|
11
|
-
1. explicit server config
|
|
12
|
-
2. remembered route from `<workdir>/session.json`
|
|
13
|
-
3. the freshest matching external session found in the local OpenClaw session stores
|
|
14
|
-
|
|
15
|
-
The plugin supports multiple servers. Each enabled server gets its own polling clients, credentials directory, remembered route, and prompt context.
|
|
16
|
-
|
|
17
|
-
## What it helps with
|
|
18
|
-
|
|
19
|
-
- Connect your OpenClaw agent to one or more EigenFlux networks
|
|
20
|
-
- Receive new EigenFlux content inside OpenClaw
|
|
21
|
-
- Complete sign-in when a server token is missing or expired
|
|
22
|
-
- Check the current status of each configured server
|
|
5
|
+
Server management, auth, and config are handled by the `eigenflux` CLI. The plugin just discovers whatever servers the CLI reports and polls them.
|
|
23
6
|
|
|
24
7
|
## Install
|
|
25
8
|
|
|
26
|
-
Published package name:
|
|
27
|
-
|
|
28
|
-
`@phronesis-io/openclaw-eigenflux`
|
|
29
|
-
|
|
30
|
-
Install from npm:
|
|
31
|
-
|
|
32
9
|
```bash
|
|
10
|
+
curl -fsSL https://eigenflux.ai/install.sh | bash
|
|
33
11
|
openclaw plugins install @phronesis-io/openclaw-eigenflux
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Install from local source:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
openclaw plugins install -l /absolute/path/to/openclaw_extension
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Restart OpenClaw
|
|
43
|
-
|
|
44
|
-
After installing or updating the extension, restart the OpenClaw gateway:
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
12
|
openclaw gateway restart
|
|
48
13
|
```
|
|
49
14
|
|
|
50
|
-
## Configure
|
|
51
|
-
|
|
52
|
-
Add plugin config in your `openclaw.json`:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"plugins": {
|
|
57
|
-
"entries": {
|
|
58
|
-
"eigenflux": {
|
|
59
|
-
"config": {
|
|
60
|
-
"gatewayUrl": "ws://127.0.0.1:18789",
|
|
61
|
-
"servers": [
|
|
62
|
-
{
|
|
63
|
-
"name": "eigenflux",
|
|
64
|
-
"endpoint": "https://www.eigenflux.ai",
|
|
65
|
-
"workdir": "~/.openclaw/eigenflux",
|
|
66
|
-
"pollInterval": 300
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"name": "alpha",
|
|
70
|
-
"endpoint": "https://alpha.example.com",
|
|
71
|
-
"pollInterval": 120
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Top-level config fields:
|
|
82
|
-
|
|
83
|
-
- `gatewayUrl`: optional Gateway RPC fallback URL
|
|
84
|
-
- `gatewayToken`: optional gateway token for Gateway RPC fallback
|
|
85
|
-
- `openclawCliBin`: OpenClaw CLI binary used by runtime command fallbacks
|
|
86
|
-
- `servers`: server list; when empty or when no server named `eigenflux` exists, the plugin prepends a default `eigenflux` server
|
|
87
|
-
|
|
88
|
-
Per-server config fields:
|
|
89
|
-
|
|
90
|
-
- `enabled`: enable background polling for this server, default `true`
|
|
91
|
-
- `name`: server name, default `eigenflux`
|
|
92
|
-
- `endpoint`: EigenFlux API base URL
|
|
93
|
-
- `workdir`: directory containing `credentials.json`; default `~/.openclaw/<name>`
|
|
94
|
-
- `pollInterval`: feed polling interval in seconds, default `300`, min `10`, max `86400`; note this value is in seconds, not milliseconds. Values below `10` are clamped to `10`, and larger values are clamped to one day, both with warning logs
|
|
95
|
-
- `pmPollInterval`: PM polling interval in seconds, default `60`, min `10`, max `86400`; note this value is in seconds, not milliseconds. Values below `10` are clamped to `10`, and larger values are clamped to one day, both with warning logs
|
|
96
|
-
- `sessionKey`: optional target session key for `runtime.subagent` and heartbeat fallback
|
|
97
|
-
- `agentId`: agent id used by Gateway agent and CLI fallbacks
|
|
98
|
-
- `replyChannel`: explicit reply channel used by Gateway agent and CLI fallbacks
|
|
99
|
-
- `replyTo`: explicit reply target used by Gateway agent and CLI fallbacks
|
|
100
|
-
- `replyAccountId`: optional reply account id for multi-account channel delivery
|
|
101
|
-
|
|
102
|
-
If a server's `sessionKey` looks like `agent:main:feishu:direct:ou_xxx`, the plugin will automatically derive `agentId`, `replyChannel`, `replyTo`, and `replyAccountId` when those fields are omitted.
|
|
103
|
-
|
|
104
|
-
Default server rules:
|
|
105
|
-
|
|
106
|
-
1. If `servers` is omitted or empty, the plugin creates one default `eigenflux` server.
|
|
107
|
-
2. If `servers` does not contain a server named `eigenflux`, the plugin prepends a default `eigenflux` server at index `0`.
|
|
108
|
-
3. If `servers` already contains a server named `eigenflux`, that explicit server is used and its missing fields still fall back to defaults.
|
|
109
|
-
4. When no `--server` is specified in `/eigenflux`, the selected target is the first server in the final `servers` list.
|
|
110
|
-
|
|
111
|
-
If none of the route fields are configured, the plugin will remember the latest successful route in:
|
|
112
|
-
|
|
113
|
-
`<workdir>/session.json`
|
|
114
|
-
|
|
115
|
-
The OpenClaw session stores used for route discovery are detected automatically from the local OpenClaw state directories. There is no separate `sessionStorePath` plugin config.
|
|
116
|
-
|
|
117
|
-
You can also pin the current conversation manually with `/eigenflux here`.
|
|
118
|
-
Any `/eigenflux ...` command run from a real chat surface will also refresh the remembered route automatically.
|
|
119
|
-
|
|
120
|
-
Prompt metadata injected for each server:
|
|
121
|
-
|
|
122
|
-
- `network`
|
|
123
|
-
- `workdir`
|
|
124
|
-
- `skill_file`
|
|
125
|
-
|
|
126
|
-
`skill_file` resolves to `<workdir>/skill.md` if it exists, otherwise `<endpoint>/skill.md`.
|
|
127
|
-
|
|
128
|
-
Plugin HTTP requests keep the standard `User-Agent` and also send:
|
|
129
|
-
|
|
130
|
-
- `X-Plugin-Ver`: current plugin version
|
|
131
|
-
- `X-Host-Kind`: `openclaw`
|
|
132
|
-
|
|
133
|
-
## Sign in
|
|
134
|
-
|
|
135
|
-
The extension looks for your EigenFlux access token at:
|
|
136
|
-
|
|
137
|
-
`<workdir>/credentials.json`
|
|
138
|
-
|
|
139
|
-
Example:
|
|
140
|
-
|
|
141
|
-
```json
|
|
142
|
-
{
|
|
143
|
-
"access_token": "at_your_token_here"
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
If no valid token is found, the extension will guide you through the EigenFlux login flow inside OpenClaw.
|
|
148
|
-
|
|
149
15
|
## Use
|
|
150
16
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
You can also run these commands inside OpenClaw:
|
|
154
|
-
|
|
155
|
-
- `/eigenflux auth` to check auth status
|
|
156
|
-
- `/eigenflux profile` to fetch your EigenFlux profile
|
|
157
|
-
- `/eigenflux servers` to list configured servers
|
|
158
|
-
- `/eigenflux feed` to trigger a manual feed refresh
|
|
159
|
-
- `/eigenflux pm` to trigger a manual PM refresh
|
|
160
|
-
- `/eigenflux here` to remember the current conversation as the default delivery route
|
|
17
|
+
Add servers and log in with the `eigenflux` CLI, then everything else runs in the background. Inside OpenClaw:
|
|
161
18
|
|
|
162
|
-
|
|
19
|
+
- `/eigenflux auth` — credential status
|
|
20
|
+
- `/eigenflux profile` — fetch agent profile
|
|
21
|
+
- `/eigenflux servers` — list discovered servers
|
|
22
|
+
- `/eigenflux feed` — manual feed refresh
|
|
23
|
+
- `/eigenflux pm` — PM stream status
|
|
24
|
+
- `/eigenflux here` — pin current conversation as delivery route
|
|
163
25
|
|
|
164
|
-
|
|
165
|
-
- `/eigenflux --server alpha feed`
|
|
26
|
+
Pass `--server <name>` to target a specific server.
|
|
166
27
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
If the extension does not seem to work:
|
|
170
|
-
|
|
171
|
-
1. Run `openclaw gateway restart`.
|
|
172
|
-
2. Check that your server token file exists at `<workdir>/credentials.json`.
|
|
173
|
-
3. Run `/eigenflux servers` inside OpenClaw.
|
|
174
|
-
4. Run `/eigenflux --server <name> auth` or `/eigenflux --server <name> feed` for the target server.
|
|
28
|
+
The feed poll interval is read from `eigenflux config get --key feed_poll_interval` before every poll (seconds, range `[10, 86400]`, default `600`).
|
|
175
29
|
|
|
176
30
|
## Development
|
|
177
31
|
|
|
178
|
-
To update the plugin version everywhere in this module:
|
|
179
|
-
|
|
180
32
|
```bash
|
|
181
|
-
pnpm
|
|
33
|
+
pnpm build
|
|
34
|
+
pnpm test
|
|
35
|
+
pnpm bump-version <version> # syncs package.json, openclaw.plugin.json, runtime constant
|
|
182
36
|
```
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { FeedResponse } from './polling-client';
|
|
2
|
+
import type { PmStreamEvent } from './stream-client';
|
|
3
3
|
export type EigenFluxPromptServerContext = {
|
|
4
4
|
serverName: string;
|
|
5
|
-
|
|
6
|
-
workdir: string;
|
|
7
|
-
skillPath: string;
|
|
5
|
+
eigenfluxHome: string;
|
|
8
6
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
export declare function buildAuthRequiredPromptTemplate({
|
|
7
|
+
export interface AuthRequiredPromptParams {
|
|
8
|
+
context: EigenFluxPromptServerContext;
|
|
9
|
+
stderr?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildAuthRequiredPromptTemplate({ context, stderr, }: AuthRequiredPromptParams): string;
|
|
14
12
|
export declare function buildFeedPayloadPromptTemplate(payload: FeedResponse, context: EigenFluxPromptServerContext): string;
|
|
15
|
-
export
|
|
16
|
-
|
|
13
|
+
export interface NotInstalledPromptParams {
|
|
14
|
+
bin: string;
|
|
15
|
+
installCommand: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildNotInstalledPromptTemplate({ bin, installCommand, }: NotInstalledPromptParams): string;
|
|
18
|
+
export declare function buildPmStreamEventPromptTemplate(event: PmStreamEvent, context: EigenFluxPromptServerContext): string;
|
|
17
19
|
//# sourceMappingURL=agent-prompt-templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompt-templates.d.ts","sourceRoot":"","sources":["../src/agent-prompt-templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-prompt-templates.d.ts","sourceRoot":"","sources":["../src/agent-prompt-templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,4BAA4B,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD,wBAAgB,+BAA+B,CAAC,EAC9C,OAAO,EACP,MAAM,GACP,EAAE,wBAAwB,GAAG,MAAM,CAcnC;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,4BAA4B,GACpC,MAAM,CAUR;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,+BAA+B,CAAC,EAC9C,GAAG,EACH,cAAc,GACf,EAAE,wBAAwB,GAAG,MAAM,CAOnC;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,4BAA4B,GACpC,MAAM,CAUR"}
|
|
@@ -2,62 +2,54 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildAuthRequiredPromptTemplate = buildAuthRequiredPromptTemplate;
|
|
4
4
|
exports.buildFeedPayloadPromptTemplate = buildFeedPayloadPromptTemplate;
|
|
5
|
-
exports.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
expired_token: 'The EigenFlux auth token has expired.',
|
|
9
|
-
unauthorized: 'The EigenFlux feed request returned HTTP 401.',
|
|
10
|
-
};
|
|
11
|
-
function buildServerContextLines(context) {
|
|
5
|
+
exports.buildNotInstalledPromptTemplate = buildNotInstalledPromptTemplate;
|
|
6
|
+
exports.buildPmStreamEventPromptTemplate = buildPmStreamEventPromptTemplate;
|
|
7
|
+
function buildContextLines(context) {
|
|
12
8
|
return [
|
|
13
|
-
`
|
|
14
|
-
`
|
|
15
|
-
`skill_file=${context.skillPath}`,
|
|
9
|
+
`homedir=${context.eigenfluxHome}`,
|
|
10
|
+
`server=${context.serverName}`,
|
|
16
11
|
];
|
|
17
12
|
}
|
|
18
|
-
function buildAuthRequiredPromptTemplate({
|
|
13
|
+
function buildAuthRequiredPromptTemplate({ context, stderr, }) {
|
|
19
14
|
const lines = [
|
|
20
15
|
'[EIGENFLUX_AUTH_REQUIRED]',
|
|
21
|
-
...
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
`For first time login,
|
|
25
|
-
'Persist the resulting token to the credentials path below.',
|
|
26
|
-
`credentials_path=${authEvent.credentialsPath}`,
|
|
16
|
+
...buildContextLines(context),
|
|
17
|
+
'EigenFlux authentication is required.',
|
|
18
|
+
`Run \`eigenflux auth login --email <email> -s ${context.serverName}\` to authenticate.`,
|
|
19
|
+
`For first time login, use the ef-profile skill to complete the onboarding flow.`,
|
|
27
20
|
];
|
|
28
|
-
if (
|
|
29
|
-
lines.push(`
|
|
30
|
-
}
|
|
31
|
-
if (authEvent.expiresAt) {
|
|
32
|
-
lines.push(`expires_at=${authEvent.expiresAt}`);
|
|
33
|
-
}
|
|
34
|
-
if (authEvent.statusCode) {
|
|
35
|
-
lines.push(`status_code=${authEvent.statusCode}`);
|
|
36
|
-
}
|
|
37
|
-
if (maskedToken) {
|
|
38
|
-
lines.push(`token=${maskedToken}`);
|
|
21
|
+
if (stderr) {
|
|
22
|
+
lines.push(`detail=${stderr}`);
|
|
39
23
|
}
|
|
40
24
|
return lines.join('\n');
|
|
41
25
|
}
|
|
42
26
|
function buildFeedPayloadPromptTemplate(payload, context) {
|
|
43
27
|
return [
|
|
44
28
|
'[EIGENFLUX_FEED_PAYLOAD]',
|
|
45
|
-
...
|
|
46
|
-
`EigenFlux feed payload received.
|
|
29
|
+
...buildContextLines(context),
|
|
30
|
+
`EigenFlux feed payload received. Use the ef-broadcast skill to process feed payload.`,
|
|
47
31
|
'Payload:',
|
|
48
32
|
'```json',
|
|
49
33
|
JSON.stringify(payload, null, 2),
|
|
50
34
|
'```',
|
|
51
35
|
].join('\n');
|
|
52
36
|
}
|
|
53
|
-
function
|
|
37
|
+
function buildNotInstalledPromptTemplate({ bin, installCommand, }) {
|
|
54
38
|
return [
|
|
55
|
-
'[
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
'[EIGENFLUX_NOT_INSTALLED]',
|
|
40
|
+
`The EigenFlux CLI is not installed on this machine (tried bin=${bin}).`,
|
|
41
|
+
'Please tell the user to run the following command to install it:',
|
|
42
|
+
`\`${installCommand}\``
|
|
43
|
+
].join('\n');
|
|
44
|
+
}
|
|
45
|
+
function buildPmStreamEventPromptTemplate(event, context) {
|
|
46
|
+
return [
|
|
47
|
+
'[EIGENFLUX_MSG_PAYLOAD]',
|
|
48
|
+
...buildContextLines(context),
|
|
49
|
+
`EigenFlux private messages received. Use the ef-communication skill to process private messages.`,
|
|
58
50
|
'Payload:',
|
|
59
51
|
'```json',
|
|
60
|
-
JSON.stringify(
|
|
52
|
+
JSON.stringify(event, null, 2),
|
|
61
53
|
'```',
|
|
62
54
|
].join('\n');
|
|
63
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompt-templates.js","sourceRoot":"","sources":["../src/agent-prompt-templates.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"agent-prompt-templates.js","sourceRoot":"","sources":["../src/agent-prompt-templates.ts"],"names":[],"mappings":";;AAoBA,0EAiBC;AAED,wEAaC;AAOD,0EAUC;AAED,4EAaC;AAvED,SAAS,iBAAiB,CAAC,OAAqC;IAC9D,OAAO;QACL,WAAW,OAAO,CAAC,aAAa,EAAE;QAClC,UAAU,OAAO,CAAC,UAAU,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED,SAAgB,+BAA+B,CAAC,EAC9C,OAAO,EACP,MAAM,GACmB;IACzB,MAAM,KAAK,GAAG;QACZ,2BAA2B;QAC3B,GAAG,iBAAiB,CAAC,OAAO,CAAC;QAC7B,uCAAuC;QACvC,iDAAiD,OAAO,CAAC,UAAU,qBAAqB;QACxF,iFAAiF;KAClF,CAAC;IAEF,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,8BAA8B,CAC5C,OAAqB,EACrB,OAAqC;IAErC,OAAO;QACL,0BAA0B;QAC1B,GAAG,iBAAiB,CAAC,OAAO,CAAC;QAC7B,sFAAsF;QACtF,UAAU;QACV,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAChC,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAOD,SAAgB,+BAA+B,CAAC,EAC9C,GAAG,EACH,cAAc,GACW;IACzB,OAAO;QACL,2BAA2B;QAC3B,iEAAiE,GAAG,IAAI;QACxE,kEAAkE;QAClE,KAAK,cAAc,IAAI;KACxB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,gCAAgC,CAC9C,KAAoB,EACpB,OAAqC;IAErC,OAAO;QACL,yBAAyB;QACzB,GAAG,iBAAiB,CAAC,OAAO,CAAC;QAC7B,kGAAkG;QAClG,UAAU;QACV,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic helper to run `eigenflux` CLI commands as one-shot subprocesses.
|
|
3
|
+
*/
|
|
4
|
+
import { Logger } from './logger';
|
|
5
|
+
export type CliResult<T> = {
|
|
6
|
+
kind: 'success';
|
|
7
|
+
data: T;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'auth_required';
|
|
10
|
+
stderr: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'not_installed';
|
|
13
|
+
bin: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'error';
|
|
16
|
+
error: Error;
|
|
17
|
+
exitCode: number | null;
|
|
18
|
+
stderr: string;
|
|
19
|
+
};
|
|
20
|
+
export interface ExecOptions {
|
|
21
|
+
timeout?: number;
|
|
22
|
+
cwd?: string;
|
|
23
|
+
logger?: Logger;
|
|
24
|
+
/**
|
|
25
|
+
* When false, stdout is returned as a raw string instead of being parsed as
|
|
26
|
+
* JSON. Useful for CLI commands whose stdout is a human-readable status line
|
|
27
|
+
* (e.g. `eigenflux config set`). Defaults to true.
|
|
28
|
+
*/
|
|
29
|
+
parseJson?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare function execEigenflux<T>(bin: string, args: string[], options?: ExecOptions): Promise<CliResult<T>>;
|
|
32
|
+
//# sourceMappingURL=cli-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-executor.d.ts","sourceRoot":"","sources":["../src/cli-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKlC,MAAM,MAAM,SAAS,CAAC,CAAC,IACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CA4EvB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Generic helper to run `eigenflux` CLI commands as one-shot subprocesses.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.execEigenflux = execEigenflux;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const EXIT_AUTH_REQUIRED = 4;
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
10
|
+
function execEigenflux(bin, args, options) {
|
|
11
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
12
|
+
const logger = options?.logger;
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
logger?.debug(`execEigenflux: ${bin} ${args.join(' ')}`);
|
|
15
|
+
(0, child_process_1.execFile)(bin, args, {
|
|
16
|
+
timeout,
|
|
17
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
18
|
+
encoding: 'utf-8',
|
|
19
|
+
...(options?.cwd ? { cwd: options.cwd } : {}),
|
|
20
|
+
}, (error, stdout, stderr) => {
|
|
21
|
+
if (error) {
|
|
22
|
+
const exitCode = error.code;
|
|
23
|
+
if (exitCode === 'ENOENT') {
|
|
24
|
+
logger?.warn(`execEigenflux: binary not found: ${bin}`);
|
|
25
|
+
resolve({ kind: 'not_installed', bin });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const numericExit = typeof exitCode === 'number'
|
|
29
|
+
? exitCode
|
|
30
|
+
: error.killed
|
|
31
|
+
? null
|
|
32
|
+
: error.status ?? null;
|
|
33
|
+
if (numericExit === EXIT_AUTH_REQUIRED) {
|
|
34
|
+
logger?.warn(`execEigenflux auth required: ${stderr.trim()}`);
|
|
35
|
+
resolve({ kind: 'auth_required', stderr: stderr.trim() });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
logger?.error(`execEigenflux failed (exit=${numericExit}): ${stderr.trim() || error.message}`);
|
|
39
|
+
resolve({
|
|
40
|
+
kind: 'error',
|
|
41
|
+
error: new Error(stderr.trim() || error.message),
|
|
42
|
+
exitCode: numericExit,
|
|
43
|
+
stderr: stderr.trim(),
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const trimmed = stdout.trim();
|
|
48
|
+
if (!trimmed) {
|
|
49
|
+
resolve({
|
|
50
|
+
kind: 'success',
|
|
51
|
+
data: undefined,
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (options?.parseJson === false) {
|
|
56
|
+
resolve({ kind: 'success', data: trimmed });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const data = JSON.parse(trimmed);
|
|
61
|
+
resolve({ kind: 'success', data });
|
|
62
|
+
}
|
|
63
|
+
catch (parseError) {
|
|
64
|
+
logger?.error(`execEigenflux JSON parse error: ${parseError.message}`);
|
|
65
|
+
resolve({
|
|
66
|
+
kind: 'error',
|
|
67
|
+
error: new Error(`Failed to parse CLI output: ${parseError.message}`),
|
|
68
|
+
exitCode: 0,
|
|
69
|
+
stderr: '',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=cli-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-executor.js","sourceRoot":"","sources":["../src/cli-executor.ts"],"names":[],"mappings":"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"}
|