@almyty/acp-server 1.0.3 → 1.0.5
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/dist/index.js +43 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,45 +24,19 @@ if (args.some((a) => HELP_FLAGS.includes(a)) || args.length === 0) {
|
|
|
24
24
|
const text = `
|
|
25
25
|
@almyty/acp-server — Expose any almyty agent via the Agent Client Protocol
|
|
26
26
|
|
|
27
|
-
Connects an almyty agent to ACP-compatible clients (Zed, JetBrains AI,
|
|
28
|
-
Toad, and others) over ndjson stdio. The server proxies all requests to
|
|
29
|
-
the almyty backend REST API.
|
|
30
|
-
|
|
31
27
|
Usage:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
almyty-acp <agent>
|
|
29
|
+
almyty-acp my-agent
|
|
30
|
+
almyty-acp acme/my-agent
|
|
35
31
|
|
|
36
32
|
Authentication:
|
|
37
|
-
npx @almyty/auth login
|
|
33
|
+
npx @almyty/auth login
|
|
38
34
|
|
|
39
35
|
Environment:
|
|
40
|
-
ALMYTY_URL
|
|
41
|
-
ALMYTY_TOKEN
|
|
42
|
-
|
|
43
|
-
Client configuration:
|
|
44
|
-
|
|
45
|
-
Zed (settings.json):
|
|
46
|
-
{
|
|
47
|
-
"agent": {
|
|
48
|
-
"profiles": {
|
|
49
|
-
"almyty": {
|
|
50
|
-
"provider": "agent-client-protocol",
|
|
51
|
-
"binary": {
|
|
52
|
-
"name": "npx",
|
|
53
|
-
"args": ["-y", "@almyty/acp-server", "my-agent"]
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
JetBrains (AI Assistant settings):
|
|
61
|
-
Binary path: npx
|
|
62
|
-
Arguments: -y @almyty/acp-server my-agent
|
|
36
|
+
ALMYTY_URL Backend URL (default: https://api.almyty.com)
|
|
37
|
+
ALMYTY_TOKEN API key (or auto-read from ~/.almyty/credentials.json)
|
|
63
38
|
|
|
64
|
-
|
|
65
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}' | npx @almyty/acp-server my-agent
|
|
39
|
+
Docs: https://docs.almyty.com/cli/acp-server
|
|
66
40
|
`;
|
|
67
41
|
// Write help to stdout (not stderr) so piping works
|
|
68
42
|
process.stdout.write(text.trimStart());
|
|
@@ -71,7 +45,7 @@ Client configuration:
|
|
|
71
45
|
// Filter out any flags, take the first positional arg as the agent identifier
|
|
72
46
|
const agentArg = args.find((a) => !a.startsWith('-'));
|
|
73
47
|
if (!agentArg) {
|
|
74
|
-
process.stderr.write('Error: Agent name or
|
|
48
|
+
process.stderr.write('Error: Agent name or slug is required.\nUsage: almyty-acp <agent>\n');
|
|
75
49
|
process.exit(1);
|
|
76
50
|
}
|
|
77
51
|
// ── Main ─────────────────────────────────────────────────────────
|
|
@@ -84,33 +58,51 @@ async function main() {
|
|
|
84
58
|
process.exit(1);
|
|
85
59
|
}
|
|
86
60
|
const proxy = new AlmytyProxy(creds.url, creds.token);
|
|
87
|
-
// Resolve agent:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
61
|
+
// Resolve agent. Accepts:
|
|
62
|
+
// my-agent slug
|
|
63
|
+
// acme/my-agent org/slug
|
|
64
|
+
// My Agent display name
|
|
65
|
+
// 550e8400-... UUID
|
|
66
|
+
let agentId;
|
|
67
|
+
const ref = agentArg;
|
|
68
|
+
const hasSlash = ref.includes('/');
|
|
69
|
+
const orgPrefix = hasSlash ? ref.split('/')[0] : undefined;
|
|
70
|
+
const agentRef = hasSlash ? ref.split('/').slice(1).join('/') : ref;
|
|
71
|
+
// 1. Try UUID direct lookup
|
|
72
|
+
const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(agentRef);
|
|
73
|
+
if (isUUID) {
|
|
74
|
+
try {
|
|
75
|
+
const agent = await proxy.getAgent(agentRef);
|
|
76
|
+
agentId = agent.id;
|
|
77
|
+
process.stderr.write(`[acp] ${agent.name} (${agent.mode})\n`);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
process.stderr.write(`Error: Agent not found: ${agentRef}\n`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
93
83
|
}
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
// 2. List agents and match by slug, name, or slug-ified name
|
|
85
|
+
if (!agentId) {
|
|
96
86
|
try {
|
|
97
87
|
const agents = await proxy.listAgents();
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
a.slug
|
|
88
|
+
const slugify = (s) => s.toLowerCase().replace(/\s+/g, '-');
|
|
89
|
+
const needle = slugify(agentRef);
|
|
90
|
+
const match = agents.find((a) => {
|
|
91
|
+
const aSlug = a.slug || slugify(a.name);
|
|
92
|
+
return aSlug === needle || a.name === agentRef || slugify(a.name) === needle || a.id === agentRef;
|
|
93
|
+
});
|
|
102
94
|
if (match) {
|
|
103
95
|
agentId = match.id;
|
|
104
|
-
process.stderr.write(`[acp]
|
|
96
|
+
process.stderr.write(`[acp] ${match.name} (${match.mode})\n`);
|
|
105
97
|
}
|
|
106
98
|
else {
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
const available = agents.map((a) => a.slug || a.name.toLowerCase().replace(/\s+/g, '-')).join(', ');
|
|
100
|
+
process.stderr.write(`Error: Agent "${ref}" not found.\nAvailable: ${available || '(none)'}\n`);
|
|
109
101
|
process.exit(1);
|
|
110
102
|
}
|
|
111
103
|
}
|
|
112
|
-
catch (
|
|
113
|
-
process.stderr.write(`Error: Could not resolve agent "${
|
|
104
|
+
catch (err) {
|
|
105
|
+
process.stderr.write(`Error: Could not resolve agent "${ref}": ${err}\n`);
|
|
114
106
|
process.exit(1);
|
|
115
107
|
}
|
|
116
108
|
}
|