opc-agent 1.4.0 → 2.0.1
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/CHANGELOG.md +25 -0
- package/README.md +91 -32
- package/dist/channels/email.d.ts +32 -26
- package/dist/channels/email.js +239 -62
- package/dist/channels/feishu.d.ts +21 -6
- package/dist/channels/feishu.js +225 -126
- package/dist/channels/telegram.d.ts +30 -9
- package/dist/channels/telegram.js +125 -33
- package/dist/channels/websocket.d.ts +46 -3
- package/dist/channels/websocket.js +306 -37
- package/dist/channels/wechat.d.ts +33 -13
- package/dist/channels/wechat.js +229 -42
- package/dist/cli.js +1127 -19
- package/dist/core/a2a.d.ts +17 -0
- package/dist/core/a2a.js +43 -1
- package/dist/core/agent.d.ts +39 -0
- package/dist/core/agent.js +228 -3
- package/dist/core/runtime.d.ts +7 -0
- package/dist/core/runtime.js +205 -2
- package/dist/core/sandbox.d.ts +26 -0
- package/dist/core/sandbox.js +117 -0
- package/dist/core/scheduler.d.ts +52 -0
- package/dist/core/scheduler.js +168 -0
- package/dist/core/subagent.d.ts +28 -0
- package/dist/core/subagent.js +65 -0
- package/dist/core/workflow-graph.d.ts +93 -0
- package/dist/core/workflow-graph.js +247 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +134 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.js +183 -0
- package/dist/eval/index.d.ts +65 -0
- package/dist/eval/index.js +191 -0
- package/dist/index.d.ts +37 -6
- package/dist/index.js +75 -3
- package/dist/plugins/content-filter.d.ts +7 -0
- package/dist/plugins/content-filter.js +25 -0
- package/dist/plugins/index.d.ts +42 -0
- package/dist/plugins/index.js +108 -2
- package/dist/plugins/logger.d.ts +6 -0
- package/dist/plugins/logger.js +20 -0
- package/dist/plugins/rate-limiter.d.ts +7 -0
- package/dist/plugins/rate-limiter.js +35 -0
- package/dist/protocols/a2a/client.d.ts +25 -0
- package/dist/protocols/a2a/client.js +115 -0
- package/dist/protocols/a2a/index.d.ts +6 -0
- package/dist/protocols/a2a/index.js +12 -0
- package/dist/protocols/a2a/server.d.ts +41 -0
- package/dist/protocols/a2a/server.js +295 -0
- package/dist/protocols/a2a/types.d.ts +91 -0
- package/dist/protocols/a2a/types.js +15 -0
- package/dist/protocols/a2a/utils.d.ts +6 -0
- package/dist/protocols/a2a/utils.js +47 -0
- package/dist/protocols/agui/client.d.ts +10 -0
- package/dist/protocols/agui/client.js +75 -0
- package/dist/protocols/agui/index.d.ts +4 -0
- package/dist/protocols/agui/index.js +25 -0
- package/dist/protocols/agui/server.d.ts +37 -0
- package/dist/protocols/agui/server.js +191 -0
- package/dist/protocols/agui/types.d.ts +107 -0
- package/dist/protocols/agui/types.js +17 -0
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.js +19 -0
- package/dist/protocols/mcp/agent-tools.d.ts +11 -0
- package/dist/protocols/mcp/agent-tools.js +129 -0
- package/dist/protocols/mcp/index.d.ts +5 -0
- package/dist/protocols/mcp/index.js +11 -0
- package/dist/protocols/mcp/server.d.ts +31 -0
- package/dist/protocols/mcp/server.js +248 -0
- package/dist/protocols/mcp/types.d.ts +92 -0
- package/dist/protocols/mcp/types.js +17 -0
- package/dist/providers/index.d.ts +5 -1
- package/dist/providers/index.js +16 -9
- package/dist/publish/index.d.ts +45 -0
- package/dist/publish/index.js +350 -0
- package/dist/schema/oad.d.ts +859 -67
- package/dist/schema/oad.js +47 -3
- package/dist/security/approval.d.ts +36 -0
- package/dist/security/approval.js +113 -0
- package/dist/security/index.d.ts +4 -0
- package/dist/security/index.js +8 -0
- package/dist/security/keys.d.ts +16 -0
- package/dist/security/keys.js +117 -0
- package/dist/skills/auto-learn.d.ts +28 -0
- package/dist/skills/auto-learn.js +257 -0
- package/dist/studio/server.d.ts +63 -0
- package/dist/studio/server.js +625 -0
- package/dist/studio-ui/index.html +662 -0
- package/dist/telemetry/index.d.ts +93 -0
- package/dist/telemetry/index.js +285 -0
- package/dist/tools/builtin/datetime.d.ts +3 -0
- package/dist/tools/builtin/datetime.js +44 -0
- package/dist/tools/builtin/file.d.ts +3 -0
- package/dist/tools/builtin/file.js +151 -0
- package/dist/tools/builtin/index.d.ts +15 -0
- package/dist/tools/builtin/index.js +30 -0
- package/dist/tools/builtin/shell.d.ts +3 -0
- package/dist/tools/builtin/shell.js +43 -0
- package/dist/tools/builtin/web.d.ts +3 -0
- package/dist/tools/builtin/web.js +37 -0
- package/dist/tools/mcp-client.d.ts +24 -0
- package/dist/tools/mcp-client.js +119 -0
- package/package.json +5 -3
- package/scripts/install.ps1 +31 -0
- package/scripts/install.sh +40 -0
- package/src/channels/email.ts +351 -177
- package/src/channels/feishu.ts +349 -236
- package/src/channels/telegram.ts +212 -90
- package/src/channels/websocket.ts +399 -87
- package/src/channels/wechat.ts +329 -149
- package/src/cli.ts +1201 -20
- package/src/core/a2a.ts +60 -0
- package/src/core/agent.ts +420 -152
- package/src/core/runtime.ts +174 -0
- package/src/core/sandbox.ts +143 -0
- package/src/core/scheduler.ts +187 -0
- package/src/core/subagent.ts +98 -0
- package/src/core/workflow-graph.ts +365 -0
- package/src/daemon.ts +96 -0
- package/src/doctor.ts +156 -0
- package/src/eval/index.ts +211 -0
- package/src/eval/suites/basic.json +16 -0
- package/src/eval/suites/memory.json +12 -0
- package/src/eval/suites/safety.json +14 -0
- package/src/index.ts +65 -6
- package/src/plugins/content-filter.ts +23 -0
- package/src/plugins/index.ts +133 -2
- package/src/plugins/logger.ts +18 -0
- package/src/plugins/rate-limiter.ts +38 -0
- package/src/protocols/a2a/client.ts +132 -0
- package/src/protocols/a2a/index.ts +8 -0
- package/src/protocols/a2a/server.ts +333 -0
- package/src/protocols/a2a/types.ts +88 -0
- package/src/protocols/a2a/utils.ts +50 -0
- package/src/protocols/agui/client.ts +83 -0
- package/src/protocols/agui/index.ts +4 -0
- package/src/protocols/agui/server.ts +218 -0
- package/src/protocols/agui/types.ts +153 -0
- package/src/protocols/index.ts +2 -0
- package/src/protocols/mcp/agent-tools.ts +134 -0
- package/src/protocols/mcp/index.ts +8 -0
- package/src/protocols/mcp/server.ts +262 -0
- package/src/protocols/mcp/types.ts +69 -0
- package/src/providers/index.ts +354 -339
- package/src/publish/index.ts +376 -0
- package/src/schema/oad.ts +204 -154
- package/src/security/approval.ts +131 -0
- package/src/security/index.ts +3 -0
- package/src/security/keys.ts +87 -0
- package/src/skills/auto-learn.ts +262 -0
- package/src/studio/server.ts +629 -0
- package/src/studio-ui/index.html +662 -0
- package/src/telemetry/index.ts +324 -0
- package/src/tools/builtin/datetime.ts +41 -0
- package/src/tools/builtin/file.ts +107 -0
- package/src/tools/builtin/index.ts +28 -0
- package/src/tools/builtin/shell.ts +43 -0
- package/src/tools/builtin/web.ts +35 -0
- package/src/tools/mcp-client.ts +131 -0
- package/src/types/agent-workstation.d.ts +2 -0
- package/tests/a2a-protocol.test.ts +285 -0
- package/tests/agui-protocol.test.ts +246 -0
- package/tests/auto-learn.test.ts +105 -0
- package/tests/builtin-tools.test.ts +83 -0
- package/tests/channels/discord.test.ts +79 -0
- package/tests/channels/email.test.ts +148 -0
- package/tests/channels/feishu.test.ts +123 -0
- package/tests/channels/telegram.test.ts +129 -0
- package/tests/channels/websocket.test.ts +53 -0
- package/tests/channels/wechat.test.ts +170 -0
- package/tests/chat-cli.test.ts +160 -0
- package/tests/cli.test.ts +46 -0
- package/tests/daemon.test.ts +135 -0
- package/tests/deepbrain-wire.test.ts +234 -0
- package/tests/doctor.test.ts +38 -0
- package/tests/eval.test.ts +173 -0
- package/tests/init-role.test.ts +124 -0
- package/tests/mcp-client.test.ts +92 -0
- package/tests/mcp-server.test.ts +178 -0
- package/tests/plugin-a2a-enhanced.test.ts +230 -0
- package/tests/publish.test.ts +231 -0
- package/tests/scheduler.test.ts +200 -0
- package/tests/security-enhanced.test.ts +233 -0
- package/tests/skill-learner.test.ts +161 -0
- package/tests/studio.test.ts +229 -0
- package/tests/subagent.test.ts +193 -0
- package/tests/telegram-discord.test.ts +60 -0
- package/tests/telemetry.test.ts +186 -0
- package/tests/tools/builtin-extended.test.ts +138 -0
- package/tests/workflow-graph.test.ts +279 -0
- package/tutorial/customer-service-agent/README.md +612 -0
- package/tutorial/customer-service-agent/SOUL.md +26 -0
- package/tutorial/customer-service-agent/agent.yaml +63 -0
- package/tutorial/customer-service-agent/package.json +19 -0
- package/tutorial/customer-service-agent/src/index.ts +69 -0
- package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
- package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
- package/tutorial/customer-service-agent/tsconfig.json +14 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webTool = void 0;
|
|
4
|
+
exports.webTool = {
|
|
5
|
+
name: 'web_fetch',
|
|
6
|
+
description: 'Fetch content from a URL',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
url: { type: 'string' },
|
|
11
|
+
method: { type: 'string', enum: ['GET', 'POST'], default: 'GET' },
|
|
12
|
+
maxLength: { type: 'number', default: 5000 },
|
|
13
|
+
},
|
|
14
|
+
required: ['url'],
|
|
15
|
+
},
|
|
16
|
+
async execute(input) {
|
|
17
|
+
const url = input.url;
|
|
18
|
+
const method = input.method || 'GET';
|
|
19
|
+
const maxLength = input.maxLength || 5000;
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(url, { method, signal: AbortSignal.timeout(15000) });
|
|
22
|
+
const text = await response.text();
|
|
23
|
+
const truncated = text.length > maxLength ? text.slice(0, maxLength) + '\n...[truncated]' : text;
|
|
24
|
+
return {
|
|
25
|
+
content: `Status: ${response.status}\n\n${truncated}`,
|
|
26
|
+
isError: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
return {
|
|
31
|
+
content: `Fetch error: ${err instanceof Error ? err.message : String(err)}`,
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MCPToolDefinition, MCPToolResult } from './mcp';
|
|
2
|
+
export interface MCPServerConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
command: string;
|
|
5
|
+
args?: string[];
|
|
6
|
+
env?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export declare class MCPClient {
|
|
9
|
+
private process;
|
|
10
|
+
private config;
|
|
11
|
+
private nextId;
|
|
12
|
+
private pending;
|
|
13
|
+
private buffer;
|
|
14
|
+
private connected;
|
|
15
|
+
connect(config: MCPServerConfig): Promise<void>;
|
|
16
|
+
private processBuffer;
|
|
17
|
+
private sendRequest;
|
|
18
|
+
private sendNotification;
|
|
19
|
+
listTools(): Promise<MCPToolDefinition[]>;
|
|
20
|
+
callTool(name: string, input: Record<string, unknown>): Promise<MCPToolResult>;
|
|
21
|
+
disconnect(): Promise<void>;
|
|
22
|
+
isConnected(): boolean;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=mcp-client.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCPClient = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
class MCPClient {
|
|
6
|
+
process = null;
|
|
7
|
+
config = null;
|
|
8
|
+
nextId = 1;
|
|
9
|
+
pending = new Map();
|
|
10
|
+
buffer = '';
|
|
11
|
+
connected = false;
|
|
12
|
+
async connect(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.process = (0, child_process_1.spawn)(config.command, config.args ?? [], {
|
|
15
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
16
|
+
env: { ...process.env, ...config.env },
|
|
17
|
+
});
|
|
18
|
+
this.process.stdout.on('data', (data) => {
|
|
19
|
+
this.buffer += data.toString();
|
|
20
|
+
this.processBuffer();
|
|
21
|
+
});
|
|
22
|
+
this.process.on('error', (err) => {
|
|
23
|
+
for (const [, p] of this.pending)
|
|
24
|
+
p.reject(err);
|
|
25
|
+
this.pending.clear();
|
|
26
|
+
});
|
|
27
|
+
this.process.on('exit', () => {
|
|
28
|
+
this.connected = false;
|
|
29
|
+
for (const [, p] of this.pending)
|
|
30
|
+
p.reject(new Error('MCP server exited'));
|
|
31
|
+
this.pending.clear();
|
|
32
|
+
});
|
|
33
|
+
// Send initialize
|
|
34
|
+
await this.sendRequest('initialize', {
|
|
35
|
+
protocolVersion: '2024-11-05',
|
|
36
|
+
capabilities: {},
|
|
37
|
+
clientInfo: { name: 'opc-agent', version: '0.7.0' },
|
|
38
|
+
});
|
|
39
|
+
// Send initialized notification
|
|
40
|
+
this.sendNotification('notifications/initialized', {});
|
|
41
|
+
this.connected = true;
|
|
42
|
+
}
|
|
43
|
+
processBuffer() {
|
|
44
|
+
const lines = this.buffer.split('\n');
|
|
45
|
+
this.buffer = lines.pop() ?? '';
|
|
46
|
+
for (const line of lines) {
|
|
47
|
+
const trimmed = line.trim();
|
|
48
|
+
if (!trimmed)
|
|
49
|
+
continue;
|
|
50
|
+
try {
|
|
51
|
+
const msg = JSON.parse(trimmed);
|
|
52
|
+
if (msg.id !== undefined && this.pending.has(msg.id)) {
|
|
53
|
+
const p = this.pending.get(msg.id);
|
|
54
|
+
this.pending.delete(msg.id);
|
|
55
|
+
if (msg.error) {
|
|
56
|
+
p.reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
p.resolve(msg.result);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch { /* skip non-JSON lines */ }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
sendRequest(method, params) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
if (!this.process?.stdin?.writable) {
|
|
69
|
+
reject(new Error('MCP server not connected'));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const id = this.nextId++;
|
|
73
|
+
this.pending.set(id, { resolve, reject });
|
|
74
|
+
const msg = JSON.stringify({ jsonrpc: '2.0', method, params: params ?? {}, id });
|
|
75
|
+
this.process.stdin.write(msg + '\n');
|
|
76
|
+
// Timeout after 30s
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
if (this.pending.has(id)) {
|
|
79
|
+
this.pending.delete(id);
|
|
80
|
+
reject(new Error(`MCP request timed out: ${method}`));
|
|
81
|
+
}
|
|
82
|
+
}, 30000);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
sendNotification(method, params) {
|
|
86
|
+
if (!this.process?.stdin?.writable)
|
|
87
|
+
return;
|
|
88
|
+
const msg = JSON.stringify({ jsonrpc: '2.0', method, params });
|
|
89
|
+
this.process.stdin.write(msg + '\n');
|
|
90
|
+
}
|
|
91
|
+
async listTools() {
|
|
92
|
+
const result = await this.sendRequest('tools/list');
|
|
93
|
+
return (result.tools ?? []).map((t) => ({
|
|
94
|
+
name: t.name,
|
|
95
|
+
description: t.description ?? '',
|
|
96
|
+
inputSchema: t.inputSchema ?? {},
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
async callTool(name, input) {
|
|
100
|
+
const result = await this.sendRequest('tools/call', { name, arguments: input });
|
|
101
|
+
const content = (result.content ?? [])
|
|
102
|
+
.map((c) => c.text ?? JSON.stringify(c))
|
|
103
|
+
.join('\n');
|
|
104
|
+
return { content, isError: result.isError ?? false };
|
|
105
|
+
}
|
|
106
|
+
async disconnect() {
|
|
107
|
+
if (this.process) {
|
|
108
|
+
this.process.kill();
|
|
109
|
+
this.process = null;
|
|
110
|
+
}
|
|
111
|
+
this.connected = false;
|
|
112
|
+
this.pending.clear();
|
|
113
|
+
}
|
|
114
|
+
isConnected() {
|
|
115
|
+
return this.connected;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.MCPClient = MCPClient;
|
|
119
|
+
//# sourceMappingURL=mcp-client.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opc-agent",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Open Agent Framework — Build, test, and run AI Agents for business workstations",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
+
"postbuild": "xcopy /E /I /Y src\\studio-ui dist\\studio-ui",
|
|
12
13
|
"test": "vitest run",
|
|
13
14
|
"dev": "tsc --watch",
|
|
14
15
|
"lint": "tsc --noEmit",
|
|
@@ -31,6 +32,7 @@
|
|
|
31
32
|
"url": "https://github.com/Deepleaper/opc-agent.git"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
35
|
+
"agent-workstation": "^1.2.1",
|
|
34
36
|
"agentkits": "^0.1.0",
|
|
35
37
|
"commander": "^12.0.0",
|
|
36
38
|
"express": "^4.21.0",
|
|
@@ -44,7 +46,7 @@
|
|
|
44
46
|
"@types/node": "^20.11.0",
|
|
45
47
|
"@types/ws": "^8.18.1",
|
|
46
48
|
"typescript": "^5.5.0",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
+
"vitepress": "^1.5.0",
|
|
50
|
+
"vitest": "^2.0.0"
|
|
49
51
|
}
|
|
50
52
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# OPC Agent — Windows installer
|
|
2
|
+
# Usage: irm https://raw.githubusercontent.com/Deepleaper/opc-agent/main/scripts/install.ps1 | iex
|
|
3
|
+
|
|
4
|
+
Write-Host "🤖 Installing OPC Agent..." -ForegroundColor Cyan
|
|
5
|
+
|
|
6
|
+
# Check Node.js
|
|
7
|
+
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
|
|
8
|
+
Write-Host "❌ Node.js is required. Install from https://nodejs.org (v18+)" -ForegroundColor Red
|
|
9
|
+
exit 1
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$nodeVer = (node -v) -replace 'v','' -split '\.' | Select-Object -First 1
|
|
13
|
+
if ([int]$nodeVer -lt 18) {
|
|
14
|
+
Write-Host "❌ Node.js 18+ required (found $(node -v))" -ForegroundColor Red
|
|
15
|
+
exit 1
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Write-Host "📦 Installing opc-agent globally..."
|
|
19
|
+
npm install -g opc-agent
|
|
20
|
+
|
|
21
|
+
Write-Host "`n✅ OPC Agent installed!" -ForegroundColor Green
|
|
22
|
+
Write-Host @"
|
|
23
|
+
|
|
24
|
+
Quick start:
|
|
25
|
+
opc init my-agent
|
|
26
|
+
cd my-agent
|
|
27
|
+
npm install
|
|
28
|
+
opc chat
|
|
29
|
+
|
|
30
|
+
Run 'opc doctor' to check your environment.
|
|
31
|
+
"@
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# OPC Agent — One-line installer
|
|
3
|
+
# Usage: curl -fsSL https://raw.githubusercontent.com/Deepleaper/opc-agent/main/scripts/install.sh | bash
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "🤖 Installing OPC Agent..."
|
|
8
|
+
|
|
9
|
+
# Check Node.js
|
|
10
|
+
if ! command -v node &> /dev/null; then
|
|
11
|
+
echo "❌ Node.js is required. Install from https://nodejs.org (v18+)"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
16
|
+
if [ "$NODE_VERSION" -lt 18 ]; then
|
|
17
|
+
echo "❌ Node.js 18+ required (found v$(node -v))"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Install globally
|
|
22
|
+
echo "📦 Installing opc-agent globally..."
|
|
23
|
+
npm install -g opc-agent
|
|
24
|
+
|
|
25
|
+
# Verify
|
|
26
|
+
if command -v opc &> /dev/null; then
|
|
27
|
+
echo ""
|
|
28
|
+
echo "✅ OPC Agent installed successfully!"
|
|
29
|
+
echo ""
|
|
30
|
+
echo "Quick start:"
|
|
31
|
+
echo " opc init my-agent"
|
|
32
|
+
echo " cd my-agent"
|
|
33
|
+
echo " npm install"
|
|
34
|
+
echo " opc chat"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Run 'opc doctor' to check your environment."
|
|
37
|
+
else
|
|
38
|
+
echo "⚠️ Installed but 'opc' command not found in PATH."
|
|
39
|
+
echo "Try: npx opc-agent --help"
|
|
40
|
+
fi
|