pi-harness-runtime 1.1.198 → 1.1.199
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/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/file-copy-helper/src/index.ts +1 -0
- package/packages/file-copy-helper/src/intent-detector.ts +393 -0
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Detector - Routes user requests to appropriate modules
|
|
3
|
+
*
|
|
4
|
+
* Detects user intent from keywords and activates relevant modules.
|
|
5
|
+
* DEBUG: All events logged to /tmp/intent-detector-debug.log (NOT TUI)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExtensionAPI, InputEvent, InputEventResult } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import * as fs from "fs";
|
|
10
|
+
|
|
11
|
+
// Debug log file
|
|
12
|
+
const DEBUG_LOG = "/tmp/intent-detector-debug.log";
|
|
13
|
+
|
|
14
|
+
function debugLog(label: string, data?: unknown): void {
|
|
15
|
+
const timestamp = new Date().toISOString();
|
|
16
|
+
const entry = `[${timestamp}] [${label}] ${data ? JSON.stringify(data, null, 2) : ""}\n`;
|
|
17
|
+
try {
|
|
18
|
+
fs.appendFileSync(DEBUG_LOG, entry);
|
|
19
|
+
} catch {
|
|
20
|
+
// Silently fail
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Intent types
|
|
25
|
+
export type IntentType =
|
|
26
|
+
| "rea" // Reverse engineering / app analysis
|
|
27
|
+
| "file_copy" // Mimic, clone, copy files
|
|
28
|
+
| "code_review" // Review code
|
|
29
|
+
| "security" // Security audit
|
|
30
|
+
| "general"; // Default
|
|
31
|
+
|
|
32
|
+
// Intent result
|
|
33
|
+
export interface IntentResult {
|
|
34
|
+
type: IntentType;
|
|
35
|
+
confidence: number; // 0-1
|
|
36
|
+
keywords: string[]; // Matched keywords
|
|
37
|
+
module: string; // Module to activate
|
|
38
|
+
guidance?: string; // Optional brief guidance
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// REA Keywords - Reverse Engineering / App Analysis
|
|
42
|
+
const REA_KEYWORDS = [
|
|
43
|
+
// English
|
|
44
|
+
"reverse engineer",
|
|
45
|
+
"reverse engineering",
|
|
46
|
+
"rea",
|
|
47
|
+
"analyze binary",
|
|
48
|
+
"decompile",
|
|
49
|
+
"disassemble",
|
|
50
|
+
"inspect binary",
|
|
51
|
+
"understand how",
|
|
52
|
+
"replicate app",
|
|
53
|
+
"clone app",
|
|
54
|
+
"copy app",
|
|
55
|
+
"mimic app",
|
|
56
|
+
// Chinese
|
|
57
|
+
"逆向",
|
|
58
|
+
"逆向工程",
|
|
59
|
+
"反编译",
|
|
60
|
+
"分析二进制",
|
|
61
|
+
"克隆应用",
|
|
62
|
+
"复制应用",
|
|
63
|
+
// Common patterns
|
|
64
|
+
"see a feature",
|
|
65
|
+
"understand.*binary",
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
// File Copy Keywords
|
|
69
|
+
const FILE_COPY_KEYWORDS = [
|
|
70
|
+
// English
|
|
71
|
+
"mimic",
|
|
72
|
+
"clone",
|
|
73
|
+
"replicate",
|
|
74
|
+
"copy file",
|
|
75
|
+
"copy folder",
|
|
76
|
+
"copy from",
|
|
77
|
+
"migrate",
|
|
78
|
+
"deploy",
|
|
79
|
+
"sync to",
|
|
80
|
+
// Chinese
|
|
81
|
+
"克隆",
|
|
82
|
+
"复制",
|
|
83
|
+
"迁移",
|
|
84
|
+
// Code patterns
|
|
85
|
+
"cp -r",
|
|
86
|
+
"sudo cp",
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
// Code Review Keywords
|
|
90
|
+
const CODE_REVIEW_KEYWORDS = [
|
|
91
|
+
"review code",
|
|
92
|
+
"review this",
|
|
93
|
+
"audit",
|
|
94
|
+
"check for bugs",
|
|
95
|
+
"security audit",
|
|
96
|
+
"find vulnerabilities",
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
// Security Keywords
|
|
100
|
+
const SECURITY_KEYWORDS = [
|
|
101
|
+
"security",
|
|
102
|
+
"vulnerability",
|
|
103
|
+
"exploit",
|
|
104
|
+
"attack",
|
|
105
|
+
"pentest",
|
|
106
|
+
"penetration test",
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Detect user intent from text using keyword matching
|
|
111
|
+
*/
|
|
112
|
+
function keywordDetect(text: string): { type: IntentType; keywords: string[] } {
|
|
113
|
+
const lower = text.toLowerCase();
|
|
114
|
+
const matchedKeywords: string[] = [];
|
|
115
|
+
|
|
116
|
+
// Check REA keywords (highest priority for reverse engineering)
|
|
117
|
+
for (const keyword of REA_KEYWORDS) {
|
|
118
|
+
if (keyword.startsWith("^")) {
|
|
119
|
+
if (new RegExp(keyword, "i").test(text)) {
|
|
120
|
+
matchedKeywords.push(keyword);
|
|
121
|
+
}
|
|
122
|
+
} else if (lower.includes(keyword.toLowerCase())) {
|
|
123
|
+
matchedKeywords.push(keyword);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (matchedKeywords.length > 0) {
|
|
127
|
+
return { type: "rea", keywords: matchedKeywords };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Check File Copy keywords
|
|
131
|
+
matchedKeywords.length = 0;
|
|
132
|
+
for (const keyword of FILE_COPY_KEYWORDS) {
|
|
133
|
+
if (lower.includes(keyword.toLowerCase())) {
|
|
134
|
+
matchedKeywords.push(keyword);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (matchedKeywords.length > 0) {
|
|
138
|
+
return { type: "file_copy", keywords: matchedKeywords };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check Code Review keywords
|
|
142
|
+
matchedKeywords.length = 0;
|
|
143
|
+
for (const keyword of CODE_REVIEW_KEYWORDS) {
|
|
144
|
+
if (lower.includes(keyword.toLowerCase())) {
|
|
145
|
+
matchedKeywords.push(keyword);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (matchedKeywords.length > 0) {
|
|
149
|
+
return { type: "code_review", keywords: matchedKeywords };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Check Security keywords
|
|
153
|
+
matchedKeywords.length = 0;
|
|
154
|
+
for (const keyword of SECURITY_KEYWORDS) {
|
|
155
|
+
if (lower.includes(keyword.toLowerCase())) {
|
|
156
|
+
matchedKeywords.push(keyword);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (matchedKeywords.length > 0) {
|
|
160
|
+
return { type: "security", keywords: matchedKeywords };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { type: "general", keywords: [] };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Jev-based intent classifier for ambiguous cases
|
|
168
|
+
*/
|
|
169
|
+
async function jevClassify(
|
|
170
|
+
_text: string,
|
|
171
|
+
baseIntent: IntentType,
|
|
172
|
+
keywords: string[],
|
|
173
|
+
): Promise<{ confirmed: boolean; confidence: number; reasoning: string }> {
|
|
174
|
+
// For clear cases (high keyword count), skip Jev
|
|
175
|
+
if (keywords.length >= 2) {
|
|
176
|
+
return {
|
|
177
|
+
confirmed: true,
|
|
178
|
+
confidence: Math.min(1, keywords.length * 0.3),
|
|
179
|
+
reasoning: `Strong keyword match: ${keywords.join(", ")}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// For ambiguous cases, use Jev judgment
|
|
184
|
+
// This would integrate with the JevJudge from jev-judge package
|
|
185
|
+
// For now, return based on single keyword presence
|
|
186
|
+
|
|
187
|
+
if (baseIntent === "rea") {
|
|
188
|
+
return {
|
|
189
|
+
confirmed: keywords.length >= 1,
|
|
190
|
+
confidence: 0.5,
|
|
191
|
+
reasoning: "Single REA keyword detected - confirming with context",
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (baseIntent === "file_copy") {
|
|
196
|
+
return {
|
|
197
|
+
confirmed: keywords.length >= 1,
|
|
198
|
+
confidence: 0.5,
|
|
199
|
+
reasoning: "Single file copy keyword detected - confirming with context",
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
confirmed: false,
|
|
205
|
+
confidence: 0,
|
|
206
|
+
reasoning: "No clear intent detected",
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Detect user intent from text
|
|
212
|
+
*/
|
|
213
|
+
async function detectIntent(text: string): Promise<IntentResult> {
|
|
214
|
+
// Step 1: Keyword-based detection
|
|
215
|
+
const { type, keywords } = keywordDetect(text);
|
|
216
|
+
|
|
217
|
+
// Step 2: Jev-based confirmation for ambiguous cases
|
|
218
|
+
const jevResult = await jevClassify(text, type, keywords);
|
|
219
|
+
|
|
220
|
+
if (!jevResult.confirmed) {
|
|
221
|
+
return {
|
|
222
|
+
type: "general",
|
|
223
|
+
confidence: 0,
|
|
224
|
+
keywords: [],
|
|
225
|
+
module: "default",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Step 3: Build result based on confirmed intent
|
|
230
|
+
const confidence = jevResult.confidence || Math.min(1, keywords.length * 0.3);
|
|
231
|
+
|
|
232
|
+
if (type === "rea") {
|
|
233
|
+
return {
|
|
234
|
+
type: "rea",
|
|
235
|
+
confidence,
|
|
236
|
+
keywords,
|
|
237
|
+
module: "@pi-harness/rea",
|
|
238
|
+
guidance: "REA: Use Hopper/Ghidra/IDA for binary analysis. Check https://github.com/morluto/rea",
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (type === "file_copy") {
|
|
243
|
+
return {
|
|
244
|
+
type: "file_copy",
|
|
245
|
+
confidence,
|
|
246
|
+
keywords,
|
|
247
|
+
module: "@pi-harness/file-copy-helper",
|
|
248
|
+
guidance: "COPY: Use sudo cp instead of reading files first",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (type === "code_review") {
|
|
253
|
+
return {
|
|
254
|
+
type: "code_review",
|
|
255
|
+
confidence,
|
|
256
|
+
keywords,
|
|
257
|
+
module: "@pi-harness/code-review",
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (type === "security") {
|
|
262
|
+
return {
|
|
263
|
+
type: "security",
|
|
264
|
+
confidence,
|
|
265
|
+
keywords,
|
|
266
|
+
module: "@pi-harness/security-auditor",
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
type: "general",
|
|
272
|
+
confidence: 0,
|
|
273
|
+
keywords: [],
|
|
274
|
+
module: "default",
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Get REA knowledge base reference
|
|
280
|
+
*/
|
|
281
|
+
function getREAKnowledge(): string {
|
|
282
|
+
return `
|
|
283
|
+
## REA Integration - Reverse Engineering
|
|
284
|
+
|
|
285
|
+
When user requests reverse engineering or app analysis:
|
|
286
|
+
|
|
287
|
+
1. **Check REA capabilities**: https://github.com/morluto/rea
|
|
288
|
+
|
|
289
|
+
2. **Analysis Providers Available**:
|
|
290
|
+
- Hopper Disassembler (macOS native)
|
|
291
|
+
- Ghidra (cross-platform)
|
|
292
|
+
- IDA Pro (commercial)
|
|
293
|
+
- Pwntools (ELF/binary analysis)
|
|
294
|
+
- Browser CDP (web app inspection)
|
|
295
|
+
- Android APK (JADX decompilation)
|
|
296
|
+
|
|
297
|
+
3. **Key REA Workflow**:
|
|
298
|
+
- Setup REA MCP server with agent
|
|
299
|
+
- Agent asks "analyze this binary"
|
|
300
|
+
- REA routes to appropriate provider
|
|
301
|
+
- Evidence recorded to InvestigationRecords
|
|
302
|
+
- Agent summarizes findings
|
|
303
|
+
|
|
304
|
+
4. **No binary?** Use browser inspection:
|
|
305
|
+
- CDP for web apps
|
|
306
|
+
- Source maps for JS
|
|
307
|
+
- AST analysis for bundles
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Get file copy guidance
|
|
313
|
+
*/
|
|
314
|
+
function getFileCopyGuidance(): string {
|
|
315
|
+
return `
|
|
316
|
+
## File Copy - Use sudo cp
|
|
317
|
+
|
|
318
|
+
When user asks to mimic/clone/copy files:
|
|
319
|
+
|
|
320
|
+
1. **DO NOT read source files** - just copy directly
|
|
321
|
+
2. **Use sudo cp** - preserves permissions
|
|
322
|
+
3. **Copy recursively** with -r for folders
|
|
323
|
+
|
|
324
|
+
Examples:
|
|
325
|
+
\`\`\`bash
|
|
326
|
+
sudo cp /source/file.ts /dest/file.ts
|
|
327
|
+
sudo cp -r /source/folder/ /dest/folder/
|
|
328
|
+
\`\`\`
|
|
329
|
+
|
|
330
|
+
**STOP**: No read/cat/expand needed. Copy preserves everything.
|
|
331
|
+
`;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Register the intent detector extension
|
|
336
|
+
*/
|
|
337
|
+
export function registerIntentDetector(pi: ExtensionAPI): void {
|
|
338
|
+
// Clear debug log on startup
|
|
339
|
+
fs.writeFileSync(DEBUG_LOG, `[${new Date().toISOString()}] === INTENT DETECTOR STARTED ===\n`);
|
|
340
|
+
|
|
341
|
+
debugLog("INIT", "Intent detector registered");
|
|
342
|
+
|
|
343
|
+
// Listen to input events
|
|
344
|
+
pi.on("input", async (event: InputEvent): Promise<InputEventResult | undefined> => {
|
|
345
|
+
// Only process user input
|
|
346
|
+
if (event.source !== "interactive") {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const text = event.text.trim();
|
|
351
|
+
if (!text || text.length < 5) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Detect intent with Jev classification
|
|
356
|
+
const intent = await detectIntent(text);
|
|
357
|
+
debugLog("DETECTED", intent);
|
|
358
|
+
|
|
359
|
+
// If high confidence, inject guidance
|
|
360
|
+
if (intent.confidence >= 0.5 && intent.type !== "general") {
|
|
361
|
+
let guidance = "";
|
|
362
|
+
|
|
363
|
+
if (intent.type === "rea") {
|
|
364
|
+
guidance = getREAKnowledge();
|
|
365
|
+
} else if (intent.type === "file_copy") {
|
|
366
|
+
guidance = getFileCopyGuidance();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (guidance) {
|
|
370
|
+
debugLog("INJECT_GUIDANCE", { type: intent.type, confidence: intent.confidence });
|
|
371
|
+
return {
|
|
372
|
+
action: "transform",
|
|
373
|
+
text: text + guidance,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return;
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
// Broadcast intent for other modules
|
|
382
|
+
pi.on("input", async (event: InputEvent) => {
|
|
383
|
+
if (event.source !== "interactive") return;
|
|
384
|
+
|
|
385
|
+
const intent = await detectIntent(event.text);
|
|
386
|
+
debugLog("BROADCAST_INTENT", intent);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Default export
|
|
391
|
+
export default function intentDetectorExtension(pi: ExtensionAPI): void {
|
|
392
|
+
registerIntentDetector(pi);
|
|
393
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/provider-router",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.199",
|
|
4
4
|
"description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/provider-router.js",
|