@openagents-org/agent-launcher 0.2.130 → 0.2.132
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/package.json +1 -1
- package/registry.json +7 -5
- package/src/adapters/base.js +130 -7
- package/src/adapters/claude.js +342 -255
- package/src/adapters/cursor.js +27 -8
- package/src/adapters/workspace-prompt.js +133 -28
- package/src/cli.js +85 -0
- package/src/daemon.js +12 -3
- package/src/github-client.js +165 -0
- package/src/index.js +13 -1
- package/src/installer.js +151 -19
- package/src/mcp-server.js +279 -91
- package/src/paths.js +31 -3
- package/src/registry.js +4 -4
- package/src/skill-catalog.js +125 -0
- package/src/tui.js +1 -16
- package/src/update-check.js +5 -25
- package/src/workspace-client.js +101 -6
package/src/tui.js
CHANGED
|
@@ -120,25 +120,10 @@ function describeHealth(health) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
function loadCatalog(connector) {
|
|
123
|
-
const { execSync } = require('child_process');
|
|
124
123
|
const entries = connector.registry.getCatalogSync();
|
|
125
124
|
return entries.map(e => {
|
|
126
125
|
let installed = false;
|
|
127
|
-
|
|
128
|
-
// If a verify command exists, use it for accurate detection
|
|
129
|
-
const verifyCmd = IS_WINDOWS ? (e.install && e.install.verify_win) : (e.install && e.install.verify);
|
|
130
|
-
if (verifyCmd) {
|
|
131
|
-
try { execSync(verifyCmd, { stdio: 'ignore', timeout: 5000 }); installed = true; } catch {}
|
|
132
|
-
} else {
|
|
133
|
-
try { const { whichBinary } = require('./paths'); installed = !!whichBinary((e.install && e.install.binary) || e.name); } catch {}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!installed) {
|
|
137
|
-
try {
|
|
138
|
-
const f = path.join(connector._configDir, 'installed_agents.json');
|
|
139
|
-
if (fs.existsSync(f)) installed = !!JSON.parse(fs.readFileSync(f, 'utf-8'))[e.name];
|
|
140
|
-
} catch {}
|
|
141
|
-
}
|
|
126
|
+
try { installed = !!connector.installer.getInstallInfo(e.name).installed; } catch {}
|
|
142
127
|
return {
|
|
143
128
|
name: e.name,
|
|
144
129
|
label: e.label || e.name,
|
package/src/update-check.js
CHANGED
|
@@ -17,7 +17,7 @@ const { execSync, spawnSync } = require('child_process');
|
|
|
17
17
|
|
|
18
18
|
const PKG_NAME = '@openagents-org/agent-launcher';
|
|
19
19
|
const CACHE_FILE = path.join(os.homedir(), '.openagents', '.update-check.json');
|
|
20
|
-
const CACHE_TTL_MS =
|
|
20
|
+
const CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes
|
|
21
21
|
|
|
22
22
|
function currentVersion() {
|
|
23
23
|
return require('../package.json').version;
|
|
@@ -161,8 +161,8 @@ function promptYes(question, timeoutMs = 30000) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
|
-
* Check
|
|
165
|
-
*
|
|
164
|
+
* Check and print a warning if a newer version is available.
|
|
165
|
+
* Never prompts or auto-updates — users run `agn update` explicitly.
|
|
166
166
|
*/
|
|
167
167
|
async function notifyAndMaybeUpdate() {
|
|
168
168
|
let info;
|
|
@@ -170,29 +170,9 @@ async function notifyAndMaybeUpdate() {
|
|
|
170
170
|
if (!info || !info.isNewer) return;
|
|
171
171
|
|
|
172
172
|
process.stderr.write(
|
|
173
|
-
`\n[launcher] Update available: ${info.current} → ${info.latest}\n`
|
|
173
|
+
`\n[launcher] Update available: ${info.current} → ${info.latest}\n` +
|
|
174
|
+
'[launcher] Run `agn update` to upgrade.\n\n'
|
|
174
175
|
);
|
|
175
|
-
|
|
176
|
-
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
177
|
-
if (!interactive) {
|
|
178
|
-
process.stderr.write(
|
|
179
|
-
'[launcher] Run `agn update` (or re-run install.sh) to upgrade.\n\n'
|
|
180
|
-
);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const accepted = await promptYes('[launcher] Update now? [Y/n] ');
|
|
185
|
-
if (!accepted) {
|
|
186
|
-
process.stderr.write('[launcher] Skipped. Run `agn update` later to upgrade.\n\n');
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const ok = runUpdate();
|
|
191
|
-
if (ok) {
|
|
192
|
-
process.stderr.write(`[launcher] Updated to ${info.latest}. Re-run your command.\n`);
|
|
193
|
-
process.exit(0);
|
|
194
|
-
}
|
|
195
|
-
process.stderr.write('[launcher] Update failed — continuing with current version.\n\n');
|
|
196
176
|
}
|
|
197
177
|
|
|
198
178
|
module.exports = {
|
package/src/workspace-client.js
CHANGED
|
@@ -271,7 +271,7 @@ class WorkspaceClient {
|
|
|
271
271
|
* Poll for pending messages targeted at an agent via GET /v1/events.
|
|
272
272
|
* Returns { messages, cursor } where cursor is the last event ID.
|
|
273
273
|
*/
|
|
274
|
-
async pollPending(workspaceId, agentName, token, { after, limit =
|
|
274
|
+
async pollPending(workspaceId, agentName, token, { after, limit = 500 } = {}) {
|
|
275
275
|
const params = new URLSearchParams({
|
|
276
276
|
network: workspaceId,
|
|
277
277
|
type: 'workspace.message.posted',
|
|
@@ -333,7 +333,28 @@ class WorkspaceClient {
|
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
|
|
336
|
+
const composing = !!(result && result.composing);
|
|
337
|
+
return { messages, cursor, composing };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Get the workspace's top-level metadata via GET /v1/workspaces/{id}.
|
|
342
|
+
*
|
|
343
|
+
* Returns the full data block from the backend — adapters care about
|
|
344
|
+
* `browserEnabled` today, but more keys may be surfaced over time. On
|
|
345
|
+
* error, returns null so callers can fall back to defaults rather than
|
|
346
|
+
* crashing.
|
|
347
|
+
*/
|
|
348
|
+
async getWorkspaceMetadata(workspaceId, token) {
|
|
349
|
+
try {
|
|
350
|
+
const data = await this._get(
|
|
351
|
+
`/v1/workspaces/${workspaceId}`,
|
|
352
|
+
this._wsHeaders(token),
|
|
353
|
+
);
|
|
354
|
+
return data.data || data || {};
|
|
355
|
+
} catch {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
337
358
|
}
|
|
338
359
|
|
|
339
360
|
/**
|
|
@@ -412,6 +433,7 @@ class WorkspaceClient {
|
|
|
412
433
|
agentName: (a.address || '').replace('openagents:', ''),
|
|
413
434
|
role: a.role || 'member',
|
|
414
435
|
status: a.status || 'offline',
|
|
436
|
+
enabledSkills: a.enabled_skills || null,
|
|
415
437
|
}));
|
|
416
438
|
}
|
|
417
439
|
|
|
@@ -606,17 +628,22 @@ class WorkspaceClient {
|
|
|
606
628
|
|
|
607
629
|
// ── Routines ──
|
|
608
630
|
|
|
609
|
-
async createRoutine(workspaceId, channelName, token, { name, message, hour, minute, days, source } = {}) {
|
|
631
|
+
async createRoutine(workspaceId, channelName, token, { name, message, context, hour, minute, days, interval_minutes, source } = {}) {
|
|
610
632
|
const body = {
|
|
611
633
|
name,
|
|
612
634
|
message,
|
|
613
|
-
|
|
614
|
-
minute,
|
|
635
|
+
context: context || '',
|
|
615
636
|
network: workspaceId,
|
|
616
637
|
channel: channelName,
|
|
617
638
|
source: source || 'openagents:unknown',
|
|
618
639
|
};
|
|
619
|
-
if (
|
|
640
|
+
if (interval_minutes != null) {
|
|
641
|
+
body.interval_minutes = interval_minutes;
|
|
642
|
+
} else {
|
|
643
|
+
body.hour = hour;
|
|
644
|
+
body.minute = minute;
|
|
645
|
+
if (days) body.days = days;
|
|
646
|
+
}
|
|
620
647
|
const data = await this._post('/v1/routines', body, this._wsHeaders(token));
|
|
621
648
|
return data.data || data;
|
|
622
649
|
}
|
|
@@ -633,6 +660,74 @@ class WorkspaceClient {
|
|
|
633
660
|
return data.data || data;
|
|
634
661
|
}
|
|
635
662
|
|
|
663
|
+
// ── Notifications ──
|
|
664
|
+
|
|
665
|
+
async createNotification(workspaceId, token, { title, message, priority, channel, source } = {}) {
|
|
666
|
+
const body = {
|
|
667
|
+
title,
|
|
668
|
+
message,
|
|
669
|
+
priority: priority || 'normal',
|
|
670
|
+
network: workspaceId,
|
|
671
|
+
source: source || 'openagents:unknown',
|
|
672
|
+
};
|
|
673
|
+
if (channel) body.channel = channel;
|
|
674
|
+
const data = await this._post('/v1/notifications', body, this._wsHeaders(token));
|
|
675
|
+
return data.data || data;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
async listNotifications(workspaceId, token, { limit = 50 } = {}) {
|
|
679
|
+
const params = new URLSearchParams({
|
|
680
|
+
network: workspaceId,
|
|
681
|
+
limit: String(limit),
|
|
682
|
+
});
|
|
683
|
+
const data = await this._get(`/v1/notifications?${params}`, this._wsHeaders(token));
|
|
684
|
+
return data.data || data;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// ── Knowledge Base ──
|
|
688
|
+
|
|
689
|
+
async listKnowledge(workspaceId, token, { limit = 100 } = {}) {
|
|
690
|
+
const params = new URLSearchParams({
|
|
691
|
+
network: workspaceId,
|
|
692
|
+
limit: String(limit),
|
|
693
|
+
});
|
|
694
|
+
const data = await this._get(`/v1/knowledge?${params}`, this._wsHeaders(token));
|
|
695
|
+
return data.data || data;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
async getKnowledge(workspaceId, token, entryId) {
|
|
699
|
+
const params = new URLSearchParams({ network: workspaceId });
|
|
700
|
+
const data = await this._get(`/v1/knowledge/${entryId}?${params}`, this._wsHeaders(token));
|
|
701
|
+
return data.data || data;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
async getKnowledgeBySlug(workspaceId, token, slug) {
|
|
705
|
+
const params = new URLSearchParams({ network: workspaceId });
|
|
706
|
+
const data = await this._get(`/v1/knowledge/by-slug/${slug}?${params}`, this._wsHeaders(token));
|
|
707
|
+
return data.data || data;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
async createKnowledge(workspaceId, token, { title, content, description, source } = {}) {
|
|
711
|
+
const body = { title, content, network: workspaceId, source: source || 'openagents:unknown' };
|
|
712
|
+
if (description) body.description = description;
|
|
713
|
+
const data = await this._post('/v1/knowledge', body, this._wsHeaders(token));
|
|
714
|
+
return data.data || data;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
async updateKnowledge(workspaceId, token, entryId, { title, content, description, source } = {}) {
|
|
718
|
+
const body = { network: workspaceId, source: source || 'openagents:unknown' };
|
|
719
|
+
if (title !== undefined) body.title = title;
|
|
720
|
+
if (content !== undefined) body.content = content;
|
|
721
|
+
if (description !== undefined) body.description = description;
|
|
722
|
+
const data = await this._put(`/v1/knowledge/${entryId}`, body, this._wsHeaders(token));
|
|
723
|
+
return data.data || data;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
async deleteKnowledge(workspaceId, token, entryId) {
|
|
727
|
+
const data = await this._delete(`/v1/knowledge/${entryId}`, this._wsHeaders(token), workspaceId);
|
|
728
|
+
return data.data || data;
|
|
729
|
+
}
|
|
730
|
+
|
|
636
731
|
// ── Internal helpers ──
|
|
637
732
|
|
|
638
733
|
/**
|