flow-agent-bridge 0.6.0 → 0.7.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 +26 -8
- package/dist/index.js +56 -17
- package/dist/index.js.map +1 -1
- package/dist/setup.d.ts +12 -1
- package/dist/setup.js +68 -48
- package/dist/setup.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,16 +14,34 @@ Flow WS ──> flow-agent-bridge daemon ──spawn──> claude -p --resume <
|
|
|
14
14
|
## Install & run
|
|
15
15
|
|
|
16
16
|
```sh
|
|
17
|
-
|
|
18
|
-
flow-agent-bridge # interactive setup on first run, daemon after
|
|
17
|
+
npx flow-agent-bridge # no install; setup on first run, daemon after
|
|
19
18
|
```
|
|
20
19
|
|
|
21
|
-
The first run
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
The first run asks only four things — **agent name, handle, sponsor email,
|
|
21
|
+
harness** (claude / codex / demo) — then registers and prints a pairing code.
|
|
22
|
+
Your sponsor (whoever owns the email you gave) approves it inside Flow via the
|
|
23
|
+
**Invite your Agent** prompt that pops up there, the code is exchanged for a
|
|
24
|
+
permanent agent token, the config is saved to `agent.json` (chmod 600) next to
|
|
25
|
+
where you ran it, and the daemon starts. Subsequent runs just start the daemon.
|
|
26
|
+
|
|
27
|
+
Every prompt can be pre-answered with a flag, so the whole thing runs
|
|
28
|
+
unattended:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npx flow-agent-bridge --name RepoBot --handle repobot \
|
|
32
|
+
--sponsor you@example.com --harness claude
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Flag | Default | Meaning |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `--name` / `--handle` / `--sponsor` / `--harness` | prompted | the four required answers |
|
|
38
|
+
| `--server` (or `--host`) | `https://app.flowtoo.org` | Flow server URL |
|
|
39
|
+
| `--token` | — | reuse an existing `flow-agent-token-…` (skips registration) |
|
|
40
|
+
| `--description` | none | one-line agent description |
|
|
41
|
+
| `--cwd` | current directory | working directory the agent runs in (its identity) |
|
|
42
|
+
|
|
43
|
+
Already have an agent? `--token flow-agent-token-…` reconnects as it and skips
|
|
44
|
+
registration.
|
|
27
45
|
|
|
28
46
|
## What you get
|
|
29
47
|
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
// flow-agent-bridge CLI:
|
|
3
3
|
// flow-agent-bridge [config.json] the one command: if the config
|
|
4
4
|
// exists, run the daemon; if not,
|
|
5
|
-
//
|
|
5
|
+
// streamlined setup (asks name, handle,
|
|
6
|
+
// sponsor email, harness → registers →
|
|
6
7
|
// sponsor approval → save) then run.
|
|
7
8
|
// Default config path: ./agent.json
|
|
9
|
+
// Skip any prompt with a flag:
|
|
10
|
+
// --name --handle --sponsor --harness
|
|
11
|
+
// --server --token --description --cwd
|
|
8
12
|
// flow-agent-bridge run <config.json> start the daemon (no setup)
|
|
9
13
|
// flow-agent-bridge register --server <url> --sponsor <email> --username <handle>
|
|
10
14
|
// --name <name> [--key <secret>] [--description <text>] [--avatar <url>]
|
|
@@ -25,6 +29,8 @@ import { runSetup } from './setup.js';
|
|
|
25
29
|
function usage() {
|
|
26
30
|
console.error('usage:\n' +
|
|
27
31
|
' flow-agent-bridge [config.json] setup (if missing) + run — default ./agent.json\n' +
|
|
32
|
+
' setup flags (skip a prompt): --name --handle --sponsor --harness\n' +
|
|
33
|
+
' --server --token --description --cwd\n' +
|
|
28
34
|
' flow-agent-bridge run <config.json>\n' +
|
|
29
35
|
' flow-agent-bridge register --server <url> --sponsor <email> --username <handle> --name <name>\n' +
|
|
30
36
|
' [--key <secret>] [--description <text>] [--avatar <url>]\n' +
|
|
@@ -36,6 +42,40 @@ function flag(args, name) {
|
|
|
36
42
|
const i = args.indexOf(`--${name}`);
|
|
37
43
|
return i >= 0 ? args[i + 1] : undefined;
|
|
38
44
|
}
|
|
45
|
+
/** First non-flag token (flags all take a value, so skip `--x val` pairs). */
|
|
46
|
+
function firstPositional(args) {
|
|
47
|
+
for (let i = 0; i < args.length; i++) {
|
|
48
|
+
const a = args[i];
|
|
49
|
+
if (a.startsWith('--'))
|
|
50
|
+
i++; // skip the flag's value too
|
|
51
|
+
else
|
|
52
|
+
return a;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
function parseSetupOptions(args) {
|
|
57
|
+
return {
|
|
58
|
+
serverUrl: flag(args, 'server') ?? flag(args, 'host'),
|
|
59
|
+
token: flag(args, 'token'),
|
|
60
|
+
name: flag(args, 'name'),
|
|
61
|
+
username: flag(args, 'username') ?? flag(args, 'handle'),
|
|
62
|
+
sponsor: flag(args, 'sponsor'),
|
|
63
|
+
harness: flag(args, 'harness') ?? flag(args, 'runtime'),
|
|
64
|
+
description: flag(args, 'description'),
|
|
65
|
+
cwd: flag(args, 'cwd'),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function startDaemon(configPath) {
|
|
69
|
+
const cfg = loadConfig(configPath);
|
|
70
|
+
const bridge = new AgentBridge(cfg);
|
|
71
|
+
await bridge.start();
|
|
72
|
+
const shutdown = () => {
|
|
73
|
+
bridge.stop();
|
|
74
|
+
setTimeout(() => process.exit(0), 200);
|
|
75
|
+
};
|
|
76
|
+
process.on('SIGINT', shutdown);
|
|
77
|
+
process.on('SIGTERM', shutdown);
|
|
78
|
+
}
|
|
39
79
|
async function main() {
|
|
40
80
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
41
81
|
if (cmd === 'mcp')
|
|
@@ -91,22 +131,21 @@ async function main() {
|
|
|
91
131
|
}
|
|
92
132
|
if (cmd === 'help' || cmd === '--help' || cmd === '-h')
|
|
93
133
|
usage();
|
|
94
|
-
// `run <config>`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
process.on('SIGTERM', shutdown);
|
|
134
|
+
// `run <config>` starts the daemon on an existing config — no setup.
|
|
135
|
+
if (cmd === 'run') {
|
|
136
|
+
const configPath = rest[0];
|
|
137
|
+
if (!configPath)
|
|
138
|
+
usage();
|
|
139
|
+
return startDaemon(configPath);
|
|
140
|
+
}
|
|
141
|
+
// Default path: setup (if the config is missing) + run. The config path is the
|
|
142
|
+
// first positional (default ./agent.json); everything else is a setup flag, so
|
|
143
|
+
// `npx flow-agent-bridge --sponsor me@x.com --harness claude` works bare.
|
|
144
|
+
const args = cmd === undefined ? [] : [cmd, ...rest];
|
|
145
|
+
const configPath = firstPositional(args) ?? 'agent.json';
|
|
146
|
+
if (!fs.existsSync(configPath))
|
|
147
|
+
await runSetup(configPath, parseSetupOptions(args));
|
|
148
|
+
return startDaemon(configPath);
|
|
110
149
|
}
|
|
111
150
|
main().catch((err) => {
|
|
112
151
|
console.error(`fatal: ${err.message}`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,yBAAyB;AACzB,2EAA2E;AAC3E,4EAA4E;AAC5E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/setup.d.ts
CHANGED
|
@@ -1 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/** Optional values that skip their prompt when supplied as CLI flags. */
|
|
2
|
+
export interface SetupOptions {
|
|
3
|
+
serverUrl?: string | undefined;
|
|
4
|
+
token?: string | undefined;
|
|
5
|
+
name?: string | undefined;
|
|
6
|
+
username?: string | undefined;
|
|
7
|
+
sponsor?: string | undefined;
|
|
8
|
+
harness?: string | undefined;
|
|
9
|
+
description?: string | undefined;
|
|
10
|
+
cwd?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function runSetup(configPath: string, opts?: SetupOptions): Promise<string>;
|
package/dist/setup.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
// Interactive first-run setup (AGENT_MEMBERS.md): register the agent like a
|
|
2
|
-
// person
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
2
|
+
// person and hand back a ready-to-run agent.json. The streamlined flow (phase
|
|
3
|
+
// 15) asks only the four things a person must decide — agent name, handle,
|
|
4
|
+
// sponsor email, harness — UP FRONT, then registers and waits for the sponsor
|
|
5
|
+
// to approve the pairing code inside Flow. Everything else (server URL, an
|
|
6
|
+
// existing token to reuse, a description, the working directory) has a sensible
|
|
7
|
+
// default and is overridable with a CLI flag, so the happy path is four
|
|
8
|
+
// answers. Advanced knobs (permissionMode, allowedTools, eventScope, …) are
|
|
9
|
+
// edited in the saved file.
|
|
7
10
|
import fs from 'node:fs';
|
|
8
11
|
import path from 'node:path';
|
|
9
12
|
import readline from 'node:readline/promises';
|
|
10
13
|
import { FlowApi, newAgentKey, startAgentRegistration, waitForApproval } from './api.js';
|
|
11
14
|
import { expandHome } from './config.js';
|
|
15
|
+
const HARNESSES = ['claude', 'codex', 'demo'];
|
|
12
16
|
async function ask(rl, q, def) {
|
|
13
17
|
const suffix = def ? ` [${def}]` : '';
|
|
14
18
|
const answer = (await rl.question(`${q}${suffix}: `)).trim();
|
|
@@ -22,38 +26,62 @@ function slugify(name) {
|
|
|
22
26
|
.replace(/^[-._]+|[-._]+$/g, '')
|
|
23
27
|
.slice(0, 32);
|
|
24
28
|
}
|
|
25
|
-
export async function runSetup(configPath) {
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
export async function runSetup(configPath, opts = {}) {
|
|
30
|
+
const serverUrl = (opts.serverUrl ?? process.env.FLOW_SERVER_URL ?? 'https://app.flowtoo.org').replace(/\/+$/, '');
|
|
31
|
+
const rl = process.stdin.isTTY ? readline.createInterface({ input: process.stdin, output: process.stdout }) : null;
|
|
32
|
+
// A required value: take the flag if given (validated), otherwise prompt.
|
|
33
|
+
// Without a TTY and without the flag there is no way to obtain it.
|
|
34
|
+
async function required(provided, label, opt = {}) {
|
|
35
|
+
const norm = opt.normalize ?? ((s) => s);
|
|
36
|
+
if (provided !== undefined) {
|
|
37
|
+
const v = norm(provided);
|
|
38
|
+
if (opt.validate && !opt.validate(v))
|
|
39
|
+
throw new Error(`invalid value for ${label}: "${provided}"`);
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
if (!rl)
|
|
43
|
+
throw new Error(`no config at ${configPath} and stdin is not a TTY — pass the setup flags or run interactively`);
|
|
44
|
+
let v = '';
|
|
45
|
+
do {
|
|
46
|
+
v = norm(await ask(rl, label, opt.def));
|
|
47
|
+
} while (!v || (opt.validate ? !opt.validate(v) : false));
|
|
48
|
+
return v;
|
|
28
49
|
}
|
|
29
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
30
50
|
try {
|
|
31
|
-
console.log('
|
|
32
|
-
const serverUrl = (await ask(rl, 'Flow server URL', process.env.FLOW_SERVER_URL ?? 'https://app.flowtoo.org')).replace(/\/+$/, '');
|
|
33
|
-
const existing = await ask(rl, 'Existing agent token (flow-agent-token-…) to reuse — or press enter to register');
|
|
51
|
+
console.log('Setting up your Flow agent.\n');
|
|
34
52
|
let agentToken;
|
|
35
53
|
let agentUsername;
|
|
36
54
|
let agentKey;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
let kind;
|
|
56
|
+
if (opts.token) {
|
|
57
|
+
// Reuse an existing agent: validate the token and skip registration.
|
|
58
|
+
console.log('Verifying the agent token…');
|
|
59
|
+
const me = await new FlowApi(serverUrl, opts.token).me();
|
|
60
|
+
console.log(`Reconnecting as existing agent ${me.displayName} <@${me.id}>.\n`);
|
|
61
|
+
agentToken = opts.token;
|
|
62
|
+
kind = await required(opts.harness, 'Agent harness — claude, codex, or demo', {
|
|
63
|
+
def: 'claude',
|
|
64
|
+
normalize: (s) => s.toLowerCase(),
|
|
65
|
+
validate: (s) => HARNESSES.includes(s),
|
|
66
|
+
});
|
|
43
67
|
}
|
|
44
68
|
else {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
// Ask the four required items UP FRONT, then register (phase 15).
|
|
70
|
+
const name = await required(opts.name, 'Agent name (shown in Flow, e.g. RepoBot)');
|
|
71
|
+
const username = await required(opts.username, 'Handle (the agent’s @username — its durable login)', {
|
|
72
|
+
def: slugify(name),
|
|
73
|
+
normalize: (s) => s.toLowerCase(),
|
|
74
|
+
validate: (s) => /^[a-z0-9][a-z0-9._-]{2,31}$/.test(s),
|
|
75
|
+
});
|
|
76
|
+
const sponsorEmail = await required(opts.sponsor, 'Sponsor email (YOUR Flow login — you approve and own this agent)', {
|
|
77
|
+
validate: (s) => s.includes('@'),
|
|
78
|
+
});
|
|
79
|
+
kind = await required(opts.harness, 'Agent harness — claude, codex, or demo', {
|
|
80
|
+
def: 'claude',
|
|
81
|
+
normalize: (s) => s.toLowerCase(),
|
|
82
|
+
validate: (s) => HARNESSES.includes(s),
|
|
83
|
+
});
|
|
84
|
+
const description = opts.description ?? '';
|
|
57
85
|
const key = newAgentKey();
|
|
58
86
|
console.log('\nRegistering…');
|
|
59
87
|
const start = await startAgentRegistration(serverUrl, {
|
|
@@ -77,10 +105,6 @@ export async function runSetup(configPath) {
|
|
|
77
105
|
agentUsername = username;
|
|
78
106
|
agentKey = key;
|
|
79
107
|
}
|
|
80
|
-
let kind = '';
|
|
81
|
-
while (!['claude', 'codex', 'demo'].includes(kind)) {
|
|
82
|
-
kind = (await ask(rl, 'Runtime — claude, codex, or demo', 'claude')).toLowerCase();
|
|
83
|
-
}
|
|
84
108
|
const config = {
|
|
85
109
|
serverUrl,
|
|
86
110
|
agentToken,
|
|
@@ -91,28 +115,24 @@ export async function runSetup(configPath) {
|
|
|
91
115
|
runtime: { kind },
|
|
92
116
|
};
|
|
93
117
|
if (kind !== 'demo') {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
cwd = resolved;
|
|
100
|
-
else
|
|
101
|
-
console.log(` ${resolved} does not exist — try again`);
|
|
102
|
-
}
|
|
118
|
+
// Optional; defaults to where `npx flow-agent-bridge` was run (usually the
|
|
119
|
+
// repo checkout that IS the agent's identity). --cwd overrides.
|
|
120
|
+
const cwd = path.resolve(expandHome(opts.cwd ?? '.'));
|
|
121
|
+
if (!fs.existsSync(cwd))
|
|
122
|
+
throw new Error(`working directory does not exist: ${cwd} (pass --cwd)`);
|
|
103
123
|
config.runtime.cwd = cwd;
|
|
104
124
|
// No allowedTools written: the default is full permissions in the cwd
|
|
105
|
-
// (operator ruling) — add allowedTools/permissionMode to the saved
|
|
106
|
-
//
|
|
125
|
+
// (operator ruling) — add allowedTools/permissionMode to the saved config
|
|
126
|
+
// to scope the agent down.
|
|
107
127
|
}
|
|
108
128
|
const abs = path.resolve(configPath);
|
|
109
129
|
fs.writeFileSync(abs, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
|
|
110
|
-
console.log(
|
|
111
|
-
console.log('
|
|
130
|
+
console.log(`Saved ${abs} (contains the agent token and key — keep it private).`);
|
|
131
|
+
console.log('Starting the agent — edit the config any time for permissions, scope, etc. (see AGENT_MEMBERS.md).\n');
|
|
112
132
|
return abs;
|
|
113
133
|
}
|
|
114
134
|
finally {
|
|
115
|
-
rl
|
|
135
|
+
rl?.close();
|
|
116
136
|
}
|
|
117
137
|
}
|
|
118
138
|
//# sourceMappingURL=setup.js.map
|
package/dist/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flow-agent-bridge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Flow agent bridge: joins a Flow workspace as a first-class AI agent and execs a coding-agent CLI (Claude Code, Codex) headlessly per conversation",
|
|
6
6
|
"license": "MIT",
|