agent-manifest 3.2.0 → 3.3.0
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/cli.js +58 -7
- package/dist/discovery/service.js +37 -12
- package/dist/index.js +22 -1
- package/dist/parser/intent-classifier.js +1 -1
- package/dist/parser/openapi-parser.js +156 -0
- package/dist/parser/prisma-parser.js +198 -0
- package/dist/parser/remix-parser.js +158 -0
- package/dist/parser/socketio-parser.js +169 -0
- package/dist/parser/sse-parser.js +141 -0
- package/dist/parser/trpc-parser.js +192 -0
- package/dist/parser/websocket-parser.js +168 -0
- package/package.json +1 -1
- package/schema/agent.schema.json +1 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WebSocketParser = void 0;
|
|
37
|
+
exports.looksLikeWebSocketFile = looksLikeWebSocketFile;
|
|
38
|
+
const ts_morph_1 = require("ts-morph");
|
|
39
|
+
const intent_classifier_1 = require("./intent-classifier");
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
/**
|
|
42
|
+
* Parses raw WebSocket servers (the `ws` npm package) and extracts
|
|
43
|
+
* message type handlers as agent actions.
|
|
44
|
+
*
|
|
45
|
+
* Detects:
|
|
46
|
+
* // ws library
|
|
47
|
+
* const wss = new WebSocketServer({ port: 8080 })
|
|
48
|
+
* wss.on('connection', (ws) => {
|
|
49
|
+
* ws.on('message', (data) => {
|
|
50
|
+
* const { type, payload } = JSON.parse(data)
|
|
51
|
+
* if (type === 'ping') { ... }
|
|
52
|
+
* switch (type) { case 'chat': ... }
|
|
53
|
+
* })
|
|
54
|
+
* })
|
|
55
|
+
*
|
|
56
|
+
* When individual message types are discriminated by a `type` / `action`
|
|
57
|
+
* string field, each branch is emitted as a separate action. Otherwise
|
|
58
|
+
* a single `ws_message` action is emitted for the whole handler.
|
|
59
|
+
*/
|
|
60
|
+
class WebSocketParser {
|
|
61
|
+
project;
|
|
62
|
+
constructor(sharedProject) {
|
|
63
|
+
this.project = sharedProject ?? new ts_morph_1.Project({
|
|
64
|
+
compilerOptions: { allowJs: true, checkJs: false },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async parseFile(filePath, projectPath) {
|
|
68
|
+
const sourceFile = this.project.addSourceFileAtPath(filePath);
|
|
69
|
+
const relativePath = './' + path.relative(projectPath, filePath).replace(/\\/g, '/');
|
|
70
|
+
const actions = [];
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
sourceFile.forEachDescendant(node => {
|
|
73
|
+
if (!ts_morph_1.Node.isCallExpression(node))
|
|
74
|
+
return;
|
|
75
|
+
const expr = node.getExpression();
|
|
76
|
+
if (!ts_morph_1.Node.isPropertyAccessExpression(expr))
|
|
77
|
+
return;
|
|
78
|
+
if (expr.getName() !== 'on')
|
|
79
|
+
return;
|
|
80
|
+
const args = node.getArguments();
|
|
81
|
+
if (args.length < 2)
|
|
82
|
+
return;
|
|
83
|
+
const eventArg = args[0];
|
|
84
|
+
if (!ts_morph_1.Node.isStringLiteral(eventArg))
|
|
85
|
+
return;
|
|
86
|
+
if (eventArg.getLiteralValue() !== 'message')
|
|
87
|
+
return;
|
|
88
|
+
const handler = args[1];
|
|
89
|
+
if (!ts_morph_1.Node.isArrowFunction(handler) && !ts_morph_1.Node.isFunctionExpression(handler))
|
|
90
|
+
return;
|
|
91
|
+
// Try to detect discriminated message types inside the handler body
|
|
92
|
+
const messageTypes = this.extractMessageTypes(handler);
|
|
93
|
+
if (messageTypes.length > 0) {
|
|
94
|
+
for (const msgType of messageTypes) {
|
|
95
|
+
if (seen.has(msgType))
|
|
96
|
+
continue;
|
|
97
|
+
seen.add(msgType);
|
|
98
|
+
const safety = (0, intent_classifier_1.classifySafety)({ name: msgType, type: 'socket' });
|
|
99
|
+
actions.push({
|
|
100
|
+
name: msgType,
|
|
101
|
+
description: `WebSocket message type: ${msgType}`,
|
|
102
|
+
intent: (0, intent_classifier_1.inferIntent)(msgType),
|
|
103
|
+
type: 'socket',
|
|
104
|
+
location: relativePath,
|
|
105
|
+
socketEvent: msgType,
|
|
106
|
+
safety,
|
|
107
|
+
agentSafe: (0, intent_classifier_1.deriveAgentSafe)(safety),
|
|
108
|
+
requiredAuth: (0, intent_classifier_1.inferActionAuth)({ safety, type: 'socket' }),
|
|
109
|
+
inputs: { type: { type: 'string', required: true }, payload: { type: 'object', required: false } },
|
|
110
|
+
outputs: { type: 'object' },
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Generic message handler — emit a single action
|
|
116
|
+
const name = 'ws_message';
|
|
117
|
+
if (!seen.has(name)) {
|
|
118
|
+
seen.add(name);
|
|
119
|
+
actions.push({
|
|
120
|
+
name,
|
|
121
|
+
description: 'Raw WebSocket message handler',
|
|
122
|
+
intent: 'util.action',
|
|
123
|
+
type: 'socket',
|
|
124
|
+
location: relativePath,
|
|
125
|
+
socketEvent: 'message',
|
|
126
|
+
safety: 'write',
|
|
127
|
+
agentSafe: true,
|
|
128
|
+
requiredAuth: (0, intent_classifier_1.inferActionAuth)({ safety: 'write', type: 'socket' }),
|
|
129
|
+
inputs: { data: { type: 'string', required: true } },
|
|
130
|
+
outputs: { type: 'object' },
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return actions;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Look inside the message handler body for discriminated type patterns:
|
|
139
|
+
* if (type === 'chat') → extracts 'chat'
|
|
140
|
+
* switch (type) { case 'ping': → extracts 'ping'
|
|
141
|
+
* if (msg.type === 'join') → extracts 'join'
|
|
142
|
+
*/
|
|
143
|
+
extractMessageTypes(handler) {
|
|
144
|
+
const types = [];
|
|
145
|
+
const body = handler.getBody?.();
|
|
146
|
+
if (!body)
|
|
147
|
+
return types;
|
|
148
|
+
const text = body.getText();
|
|
149
|
+
// switch (type) { case 'value': ... }
|
|
150
|
+
for (const match of text.matchAll(/case\s+['"`]([^'"`]+)['"`]\s*:/g)) {
|
|
151
|
+
types.push(match[1]);
|
|
152
|
+
}
|
|
153
|
+
// if (type === 'value') or if (msg.type === 'value')
|
|
154
|
+
for (const match of text.matchAll(/(?:type|action|event)\s*(?:===?|==)\s*['"`]([^'"`]+)['"`]/g)) {
|
|
155
|
+
if (!types.includes(match[1]))
|
|
156
|
+
types.push(match[1]);
|
|
157
|
+
}
|
|
158
|
+
// Filter out framework noise
|
|
159
|
+
return types.filter(t => t !== 'message' && t !== 'error' && t !== 'close' && t !== 'open');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.WebSocketParser = WebSocketParser;
|
|
163
|
+
function looksLikeWebSocketFile(content) {
|
|
164
|
+
return (content.includes('WebSocketServer') ||
|
|
165
|
+
content.includes('new WebSocket.Server') ||
|
|
166
|
+
(content.includes("'ws'") && content.includes(".on('message'")) ||
|
|
167
|
+
(content.includes('"ws"') && content.includes('.on("message"')));
|
|
168
|
+
}
|
package/package.json
CHANGED