openvisio-agent 0.3.1 → 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 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, then saves the
39
- credentials (~/.openvisio/<agent>.json + a sourceable <agent>.env). The backend
40
- dispatches board tasks to the agent; requests authenticate with the
41
- x-agent-api-key + x-agent-identifier headers.
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
@@ -64,6 +69,15 @@ function mcpReplace(claude, addArgs) {
64
69
  spawnSync(claude, ['mcp', 'add', '--scope', 'user', ...addArgs], { stdio: 'ignore' })
65
70
  }
66
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
+
67
81
  async function runConnect({ positional, flags }) {
68
82
  if (flags.backend) return runConnectBackend({ positional, flags })
69
83
  const token = positional[0] || flags.token
@@ -164,18 +178,31 @@ async function runConnectBackend({ flags }) {
164
178
  info()
165
179
  info('The backend dispatches board tasks assigned to this agent. Every request it')
166
180
  info('makes authenticates with the x-agent-api-key + x-agent-identifier headers.')
167
- 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()
168
194
  info()
169
- info('Real-time autonomy is ready. Let it react to assignments + @mentions live:')
170
- info(` openvisio-agent watch --name ${slug} # run now, in this terminal`)
171
- info(` openvisio-agent watch --name ${slug} --install # background, on login`)
172
- info(` openvisio-agent watch --name ${slug} --workdir <repo> # allow real coding on a branch`)
173
- 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`)
174
199
  } else {
175
200
  info()
176
- info('Tip: pass --ws <wss-url> and --mcp-url <url> to enable real-time autonomy')
177
- info(' (the agent reacts to task:assigned / agent:mention over a WebSocket).')
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.')
178
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.')
179
206
  }
180
207
 
181
208
  async function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openvisio-agent",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Connect your coding agent (Claude Code) to an OpenVisio team — MCP tools + optional autonomy — in one command. No shell scripts.",
5
5
  "type": "module",
6
6
  "bin": {
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…')