openvisio-agent 0.3.0 → 0.3.2
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/bin/cli.mjs +57 -17
- package/package.json +1 -1
- package/src/watch.mjs +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -13,8 +13,8 @@ import { spawnSync } from 'node:child_process'
|
|
|
13
13
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
14
14
|
import { fileURLToPath } from 'node:url'
|
|
15
15
|
import { dirname, join } from 'node:path'
|
|
16
|
-
import { parseFlags, slugify, stripSlash, exchangeToken, ensureClaude, writeJson, mcpConfigPath, configPath, chmodSafe, OV_DIR, fail, ok, info } from '../src/lib.mjs'
|
|
17
|
-
import { runWatch } from '../src/watch.mjs'
|
|
16
|
+
import { parseFlags, slugify, stripSlash, exchangeToken, ensureClaude, writeJson, mcpConfigPath, configPath, chmodSafe, onPath, OV_DIR, fail, ok, info } from '../src/lib.mjs'
|
|
17
|
+
import { runWatch, installService } from '../src/watch.mjs'
|
|
18
18
|
|
|
19
19
|
const HERE = dirname(fileURLToPath(import.meta.url))
|
|
20
20
|
const VERSION = (() => { try { return JSON.parse(readFileSync(join(HERE, '..', 'package.json'), 'utf8')).version } catch { return '0.0.0' } })()
|
|
@@ -35,14 +35,19 @@ connect
|
|
|
35
35
|
|
|
36
36
|
connect --backend
|
|
37
37
|
Registers a BACKEND agent (created in OpenVisio → Agents → Connect your agent):
|
|
38
|
-
verifies the api-key + identifier against the org backend,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
verifies the api-key + identifier against the org backend, saves the credentials
|
|
39
|
+
(~/.openvisio/<agent>.json + a sourceable <agent>.env), and — when --ws is given —
|
|
40
|
+
installs openvisio-agent globally and sets up an ALWAYS-ON background listener
|
|
41
|
+
(launchd/systemd) that auto-starts on login, so @mentions/assignments are caught
|
|
42
|
+
even with no terminal open. Requests authenticate with the x-agent-api-key +
|
|
43
|
+
x-agent-identifier headers.
|
|
42
44
|
--ws <wss-url> API-Gateway WebSocket base (same as NEXT_PUBLIC_BACKEND_WS_URL)
|
|
43
45
|
— enables real-time autonomy (task:assigned / agent:mention).
|
|
44
46
|
--mcp-url <url> registers the openvisio-team MCP so the agent has tools to ACT
|
|
45
47
|
on those events. Needs Node >= 21 for the WebSocket.
|
|
48
|
+
--workdir <repo> the always-on listener may do real coding on a branch there.
|
|
49
|
+
--no-service skip the background service — just save config + print the
|
|
50
|
+
watch commands to run yourself.
|
|
46
51
|
|
|
47
52
|
watch
|
|
48
53
|
Runs the event-driven autonomy loop (reply to mentions, pick up tickets). Add
|
|
@@ -51,6 +56,28 @@ watch
|
|
|
51
56
|
|
|
52
57
|
Docs: https://www.npmjs.com/package/openvisio-agent`
|
|
53
58
|
|
|
59
|
+
// Register the `openvisio-team` MCP at USER (global) scope so it's available in
|
|
60
|
+
// every project without re-adding, and the credentials (baked into the headers)
|
|
61
|
+
// are sent on every call — no per-project prompt. Two gotchas handled here:
|
|
62
|
+
// 1. `claude mcp add` defaults to LOCAL (project) scope — pass `--scope user`.
|
|
63
|
+
// 2. `add` will NOT overwrite an existing same-named server, so a stale entry
|
|
64
|
+
// (old URL/auth) silently shadows a re-connect ("stuck on the old one").
|
|
65
|
+
// Remove it from BOTH scopes first, then add global.
|
|
66
|
+
function mcpReplace(claude, addArgs) {
|
|
67
|
+
spawnSync(claude, ['mcp', 'remove', 'openvisio-team', '-s', 'user'], { stdio: 'ignore' })
|
|
68
|
+
spawnSync(claude, ['mcp', 'remove', 'openvisio-team', '-s', 'local'], { stdio: 'ignore' })
|
|
69
|
+
spawnSync(claude, ['mcp', 'add', '--scope', 'user', ...addArgs], { stdio: 'ignore' })
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The persistent `openvisio-agent` command must exist for `watch` (and the
|
|
73
|
+
// background service) to work — an `npx` connect leaves nothing installed. Make
|
|
74
|
+
// the global install part of setup.
|
|
75
|
+
function ensureAgentInstalled() {
|
|
76
|
+
if (onPath('openvisio-agent')) return
|
|
77
|
+
info('Installing openvisio-agent globally (so `watch` and the always-on service have a stable command)…')
|
|
78
|
+
spawnSync('npm', ['i', '-g', 'openvisio-agent@latest'], { stdio: 'inherit', shell: process.platform === 'win32' })
|
|
79
|
+
}
|
|
80
|
+
|
|
54
81
|
async function runConnect({ positional, flags }) {
|
|
55
82
|
if (flags.backend) return runConnectBackend({ positional, flags })
|
|
56
83
|
const token = positional[0] || flags.token
|
|
@@ -67,8 +94,8 @@ async function runConnect({ positional, flags }) {
|
|
|
67
94
|
|
|
68
95
|
const claude = ensureClaude()
|
|
69
96
|
|
|
70
|
-
// Register with Claude Code
|
|
71
|
-
|
|
97
|
+
// Register with Claude Code — remove any stale entry first so a changed URL sticks.
|
|
98
|
+
mcpReplace(claude, ['--transport', 'http', 'openvisio-team', mcpUrl, '--header', `Authorization: Bearer ${key}`])
|
|
72
99
|
|
|
73
100
|
// A scoped MCP config (for the watcher's --strict-mcp-config) + a saved profile.
|
|
74
101
|
const mcpCfg = mcpConfigPath(slug)
|
|
@@ -125,7 +152,7 @@ async function runConnectBackend({ flags }) {
|
|
|
125
152
|
const claude = ensureClaude()
|
|
126
153
|
// Backend agents authenticate with the agent header pair, not a Bearer JWT.
|
|
127
154
|
const hdr = ['--header', `x-agent-api-key: ${apiKey}`, '--header', `x-agent-identifier: ${identifier}`]
|
|
128
|
-
|
|
155
|
+
mcpReplace(claude, ['--transport', 'http', 'openvisio-team', mcpUrl, ...hdr])
|
|
129
156
|
mcpConfig = mcpConfigPath(slug)
|
|
130
157
|
writeJson(mcpConfig, { mcpServers: { 'openvisio-team': { type: 'http', url: mcpUrl, headers: { 'x-agent-api-key': apiKey, 'x-agent-identifier': identifier } } } }, true)
|
|
131
158
|
}
|
|
@@ -151,18 +178,31 @@ async function runConnectBackend({ flags }) {
|
|
|
151
178
|
info()
|
|
152
179
|
info('The backend dispatches board tasks assigned to this agent. Every request it')
|
|
153
180
|
info('makes authenticates with the x-agent-api-key + x-agent-identifier headers.')
|
|
154
|
-
if (wsUrl) {
|
|
181
|
+
if (!wsUrl) {
|
|
182
|
+
info()
|
|
183
|
+
info('Tip: pass --ws <wss-url> and --mcp-url <url> to enable real-time autonomy —')
|
|
184
|
+
info(' the agent then reacts to task:assigned / agent:mention, always-on.')
|
|
185
|
+
return
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Real-time autonomy IS the point of a backend agent: install the command and a
|
|
189
|
+
// background service that auto-starts on login, so a mention is always caught —
|
|
190
|
+
// no terminal left open, survives reboot. Opt out with --no-service.
|
|
191
|
+
const workdir = flags.workdir === true ? process.cwd() : (flags.workdir ? String(flags.workdir) : '')
|
|
192
|
+
if (flags['no-service'] || process.platform === 'win32') {
|
|
193
|
+
ensureAgentInstalled()
|
|
155
194
|
info()
|
|
156
|
-
info('
|
|
157
|
-
info(
|
|
158
|
-
info(` openvisio-agent watch --name ${slug}
|
|
159
|
-
info(` openvisio-agent watch --name ${slug} --
|
|
160
|
-
if (!mcpUrl) info(' (add --mcp-url on connect to give the agent tools to ACT on those events.)')
|
|
195
|
+
if (process.platform === 'win32') info('Background auto-start isn\'t supported on Windows yet — run the listener yourself:')
|
|
196
|
+
else info('Real-time autonomy is ready. Start the always-on listener:')
|
|
197
|
+
info(` openvisio-agent watch --name ${slug} # run now, in this terminal`)
|
|
198
|
+
info(` openvisio-agent watch --name ${slug} --install # background, auto-start on login`)
|
|
161
199
|
} else {
|
|
162
200
|
info()
|
|
163
|
-
info('
|
|
164
|
-
|
|
201
|
+
info('Setting up the always-on autonomy listener (auto-starts on login, survives reboot)…')
|
|
202
|
+
installService({ slug, workdir })
|
|
203
|
+
ok('Your agent is now live — it will catch @mentions and assignments even with no terminal open.')
|
|
165
204
|
}
|
|
205
|
+
if (!mcpUrl) info('Note: no --mcp-url was given, so the agent hears events but has no tools to reply. Reconnect with --mcp-url to fix.')
|
|
166
206
|
}
|
|
167
207
|
|
|
168
208
|
async function main() {
|
package/package.json
CHANGED
package/src/watch.mjs
CHANGED
|
@@ -234,7 +234,7 @@ function loop({ host, key, claude, mcpConfig, workdir }) {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
// ── background service install (launchd / systemd) ───────────────────────────
|
|
237
|
-
function installService({ slug, workdir }) {
|
|
237
|
+
export function installService({ slug, workdir }) {
|
|
238
238
|
const binPath = onPath('openvisio-agent')
|
|
239
239
|
if (!binPath) {
|
|
240
240
|
info('Installing openvisio-agent globally so the background service has a stable path…')
|