notoken-core 1.6.0 → 1.8.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/config/ascii-art.json +12 -0
- package/config/chat-responses.json +1019 -0
- package/config/cheat-sheets.json +94 -0
- package/config/concept-clusters.json +31 -0
- package/config/daily-tips.json +105 -0
- package/config/entities.json +93 -0
- package/config/history-today.json +9762 -0
- package/config/image-prompts.json +20 -0
- package/config/intent-vectors.json +1 -0
- package/config/intents.json +5749 -85
- package/config/ollama-models.json +193 -0
- package/config/rules.json +32 -1
- package/config/startup-quotes.json +45 -0
- package/dist/automation/discordPatchright.d.ts +35 -0
- package/dist/automation/discordPatchright.js +437 -0
- package/dist/automation/discordSetup.d.ts +31 -0
- package/dist/automation/discordSetup.js +338 -0
- package/dist/automation/smAutomation.d.ts +82 -0
- package/dist/automation/smAutomation.js +448 -0
- package/dist/conversation/coreference.js +44 -4
- package/dist/conversation/pendingActions.d.ts +55 -0
- package/dist/conversation/pendingActions.js +127 -0
- package/dist/conversation/store.d.ts +72 -0
- package/dist/conversation/store.js +140 -1
- package/dist/conversation/topicTracker.d.ts +36 -0
- package/dist/conversation/topicTracker.js +141 -0
- package/dist/execution/ssh.d.ts +42 -1
- package/dist/execution/ssh.js +538 -3
- package/dist/handlers/executor.d.ts +2 -0
- package/dist/handlers/executor.js +4669 -31
- package/dist/index.d.ts +39 -5
- package/dist/index.js +56 -4
- package/dist/nlp/batchParser.d.ts +30 -0
- package/dist/nlp/batchParser.js +77 -0
- package/dist/nlp/conceptExpansion.d.ts +54 -0
- package/dist/nlp/conceptExpansion.js +136 -0
- package/dist/nlp/conceptRouter.d.ts +49 -0
- package/dist/nlp/conceptRouter.js +302 -0
- package/dist/nlp/confidenceCalibrator.d.ts +62 -0
- package/dist/nlp/confidenceCalibrator.js +116 -0
- package/dist/nlp/correctionLearner.d.ts +45 -0
- package/dist/nlp/correctionLearner.js +207 -0
- package/dist/nlp/entitySpellCorrect.d.ts +35 -0
- package/dist/nlp/entitySpellCorrect.js +141 -0
- package/dist/nlp/knowledgeGraph.d.ts +70 -0
- package/dist/nlp/knowledgeGraph.js +380 -0
- package/dist/nlp/llmFallback.d.ts +47 -0
- package/dist/nlp/llmFallback.js +175 -36
- package/dist/nlp/llmParser.d.ts +5 -1
- package/dist/nlp/llmParser.js +43 -24
- package/dist/nlp/multiClassifier.js +91 -6
- package/dist/nlp/multiIntent.d.ts +43 -0
- package/dist/nlp/multiIntent.js +154 -0
- package/dist/nlp/parseIntent.d.ts +6 -1
- package/dist/nlp/parseIntent.js +199 -6
- package/dist/nlp/ruleParser.js +348 -0
- package/dist/nlp/semanticSimilarity.d.ts +30 -0
- package/dist/nlp/semanticSimilarity.js +174 -0
- package/dist/nlp/vocabularyBuilder.d.ts +43 -0
- package/dist/nlp/vocabularyBuilder.js +224 -0
- package/dist/nlp/wikidata.d.ts +49 -0
- package/dist/nlp/wikidata.js +228 -0
- package/dist/policy/confirm.d.ts +10 -0
- package/dist/policy/confirm.js +39 -0
- package/dist/policy/safety.js +6 -4
- package/dist/types/intent.d.ts +8 -0
- package/dist/types/intent.js +1 -0
- package/dist/utils/achievements.d.ts +38 -0
- package/dist/utils/achievements.js +126 -0
- package/dist/utils/aliases.d.ts +5 -0
- package/dist/utils/aliases.js +39 -0
- package/dist/utils/analysis.js +71 -15
- package/dist/utils/bookmarks.d.ts +13 -0
- package/dist/utils/bookmarks.js +51 -0
- package/dist/utils/browser.d.ts +64 -0
- package/dist/utils/browser.js +364 -0
- package/dist/utils/commandHistory.d.ts +20 -0
- package/dist/utils/commandHistory.js +108 -0
- package/dist/utils/completer.d.ts +17 -0
- package/dist/utils/completer.js +79 -0
- package/dist/utils/config.js +32 -2
- package/dist/utils/dbQuery.d.ts +25 -0
- package/dist/utils/dbQuery.js +248 -0
- package/dist/utils/devTools.d.ts +35 -0
- package/dist/utils/devTools.js +95 -0
- package/dist/utils/discordDiag.d.ts +35 -0
- package/dist/utils/discordDiag.js +834 -0
- package/dist/utils/diskCleanup.d.ts +36 -0
- package/dist/utils/diskCleanup.js +775 -0
- package/dist/utils/entityResolver.d.ts +107 -0
- package/dist/utils/entityResolver.js +468 -0
- package/dist/utils/imageGen.d.ts +92 -0
- package/dist/utils/imageGen.js +2031 -0
- package/dist/utils/installTracker.d.ts +57 -0
- package/dist/utils/installTracker.js +160 -0
- package/dist/utils/multiExec.d.ts +21 -0
- package/dist/utils/multiExec.js +141 -0
- package/dist/utils/openclawDiag.d.ts +127 -0
- package/dist/utils/openclawDiag.js +1535 -0
- package/dist/utils/openclawLogParser.d.ts +65 -0
- package/dist/utils/openclawLogParser.js +168 -0
- package/dist/utils/output.js +4 -0
- package/dist/utils/platform.js +2 -1
- package/dist/utils/progressReporter.d.ts +50 -0
- package/dist/utils/progressReporter.js +58 -0
- package/dist/utils/projectDetect.d.ts +44 -0
- package/dist/utils/projectDetect.js +319 -0
- package/dist/utils/projectScanner.d.ts +44 -0
- package/dist/utils/projectScanner.js +312 -0
- package/dist/utils/shellCompat.d.ts +78 -0
- package/dist/utils/shellCompat.js +186 -0
- package/dist/utils/smartArchive.d.ts +16 -0
- package/dist/utils/smartArchive.js +172 -0
- package/dist/utils/smartRetry.d.ts +26 -0
- package/dist/utils/smartRetry.js +114 -0
- package/dist/utils/snippets.d.ts +13 -0
- package/dist/utils/snippets.js +53 -0
- package/dist/utils/stabilityMatrixManager.d.ts +80 -0
- package/dist/utils/stabilityMatrixManager.js +268 -0
- package/dist/utils/teachMode.d.ts +41 -0
- package/dist/utils/teachMode.js +100 -0
- package/dist/utils/timer.d.ts +22 -0
- package/dist/utils/timer.js +52 -0
- package/dist/utils/updater.d.ts +1 -0
- package/dist/utils/updater.js +1 -1
- package/dist/utils/userContext.d.ts +57 -0
- package/dist/utils/userContext.js +133 -0
- package/dist/utils/version.d.ts +20 -0
- package/dist/utils/version.js +212 -0
- package/package.json +6 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Log Parser — understand what's happening from openclaw logs.
|
|
3
|
+
*
|
|
4
|
+
* Parses JSON log lines from `openclaw logs --json` and extracts
|
|
5
|
+
* meaningful events for diagnostics, monitoring, and troubleshooting.
|
|
6
|
+
*/
|
|
7
|
+
export interface LogEntry {
|
|
8
|
+
type: "log" | "meta";
|
|
9
|
+
time: string;
|
|
10
|
+
level: "info" | "warn" | "error" | "debug";
|
|
11
|
+
subsystem?: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
export interface LogAnalysis {
|
|
15
|
+
/** Total log entries analyzed */
|
|
16
|
+
totalEntries: number;
|
|
17
|
+
/** Time range of logs */
|
|
18
|
+
timeRange: {
|
|
19
|
+
start: string;
|
|
20
|
+
end: string;
|
|
21
|
+
} | null;
|
|
22
|
+
/** Key events extracted */
|
|
23
|
+
events: Array<{
|
|
24
|
+
time: string;
|
|
25
|
+
type: string;
|
|
26
|
+
message: string;
|
|
27
|
+
severity: "info" | "warn" | "error";
|
|
28
|
+
}>;
|
|
29
|
+
/** Discord connection status */
|
|
30
|
+
discord: {
|
|
31
|
+
connected: boolean;
|
|
32
|
+
botName: string | null;
|
|
33
|
+
lastEvent: string | null;
|
|
34
|
+
rateLimited: boolean;
|
|
35
|
+
error4014: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** Gateway health */
|
|
38
|
+
gateway: {
|
|
39
|
+
started: boolean;
|
|
40
|
+
listening: boolean;
|
|
41
|
+
port: number | null;
|
|
42
|
+
model: string | null;
|
|
43
|
+
};
|
|
44
|
+
/** Auth issues */
|
|
45
|
+
auth: {
|
|
46
|
+
errors: string[];
|
|
47
|
+
refreshFailed: boolean;
|
|
48
|
+
tokenExpired: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** Errors and warnings */
|
|
51
|
+
errors: string[];
|
|
52
|
+
warnings: string[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse a single JSON log line.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseLogLine(line: string): LogEntry | null;
|
|
58
|
+
/**
|
|
59
|
+
* Analyze a batch of log lines and extract meaningful events.
|
|
60
|
+
*/
|
|
61
|
+
export declare function analyzeLogs(logText: string): LogAnalysis;
|
|
62
|
+
/**
|
|
63
|
+
* Format log analysis for display.
|
|
64
|
+
*/
|
|
65
|
+
export declare function formatLogAnalysis(analysis: LogAnalysis): string;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Log Parser — understand what's happening from openclaw logs.
|
|
3
|
+
*
|
|
4
|
+
* Parses JSON log lines from `openclaw logs --json` and extracts
|
|
5
|
+
* meaningful events for diagnostics, monitoring, and troubleshooting.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Parse a single JSON log line.
|
|
9
|
+
*/
|
|
10
|
+
export function parseLogLine(line) {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(line);
|
|
13
|
+
if (parsed.type === "meta")
|
|
14
|
+
return { type: "meta", time: "", level: "info", message: `Log file: ${parsed.file}` };
|
|
15
|
+
return {
|
|
16
|
+
type: "log",
|
|
17
|
+
time: parsed.time ?? "",
|
|
18
|
+
level: (parsed.level ?? "info"),
|
|
19
|
+
subsystem: parsed.subsystem,
|
|
20
|
+
message: parsed.message ?? "",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Analyze a batch of log lines and extract meaningful events.
|
|
29
|
+
*/
|
|
30
|
+
export function analyzeLogs(logText) {
|
|
31
|
+
const lines = logText.split("\n").filter(l => l.trim());
|
|
32
|
+
const entries = lines.map(parseLogLine).filter((e) => e !== null && e.type === "log");
|
|
33
|
+
const result = {
|
|
34
|
+
totalEntries: entries.length,
|
|
35
|
+
timeRange: null,
|
|
36
|
+
events: [],
|
|
37
|
+
discord: { connected: false, botName: null, lastEvent: null, rateLimited: false, error4014: false },
|
|
38
|
+
gateway: { started: false, listening: false, port: null, model: null },
|
|
39
|
+
auth: { errors: [], refreshFailed: false, tokenExpired: false },
|
|
40
|
+
errors: [],
|
|
41
|
+
warnings: [],
|
|
42
|
+
};
|
|
43
|
+
if (entries.length > 0) {
|
|
44
|
+
result.timeRange = { start: entries[0].time, end: entries[entries.length - 1].time };
|
|
45
|
+
}
|
|
46
|
+
for (const entry of entries) {
|
|
47
|
+
const msg = entry.message;
|
|
48
|
+
// Gateway events
|
|
49
|
+
if (msg.includes("listening on")) {
|
|
50
|
+
result.gateway.started = true;
|
|
51
|
+
result.gateway.listening = true;
|
|
52
|
+
const portMatch = msg.match(/:(\d+)/);
|
|
53
|
+
if (portMatch)
|
|
54
|
+
result.gateway.port = parseInt(portMatch[1]);
|
|
55
|
+
result.events.push({ time: entry.time, type: "gateway.start", message: "Gateway started", severity: "info" });
|
|
56
|
+
}
|
|
57
|
+
if (msg.includes("agent model:")) {
|
|
58
|
+
const modelMatch = msg.match(/agent model:\s*(\S+)/);
|
|
59
|
+
if (modelMatch)
|
|
60
|
+
result.gateway.model = modelMatch[1];
|
|
61
|
+
}
|
|
62
|
+
// Discord events
|
|
63
|
+
if (msg.includes("logged in to discord") || msg.includes("discord client ready")) {
|
|
64
|
+
result.discord.connected = true;
|
|
65
|
+
result.discord.lastEvent = "connected";
|
|
66
|
+
result.events.push({ time: entry.time, type: "discord.connected", message: "Discord bot connected", severity: "info" });
|
|
67
|
+
}
|
|
68
|
+
if (msg.includes("awaiting gateway readiness")) {
|
|
69
|
+
result.discord.lastEvent = "awaiting";
|
|
70
|
+
const botMatch = msg.match(/\((\S+)\)/);
|
|
71
|
+
if (botMatch)
|
|
72
|
+
result.discord.botName = botMatch[1];
|
|
73
|
+
}
|
|
74
|
+
if (msg.includes("starting provider")) {
|
|
75
|
+
const botMatch = msg.match(/@(\S+)\)/);
|
|
76
|
+
if (botMatch)
|
|
77
|
+
result.discord.botName = botMatch[1];
|
|
78
|
+
}
|
|
79
|
+
if (msg.includes("rate limit") || msg.includes("status=429")) {
|
|
80
|
+
result.discord.rateLimited = true;
|
|
81
|
+
result.discord.lastEvent = "rate_limited";
|
|
82
|
+
result.events.push({ time: entry.time, type: "discord.rate_limited", message: "Discord rate limited", severity: "warn" });
|
|
83
|
+
}
|
|
84
|
+
if (msg.includes("4014")) {
|
|
85
|
+
result.discord.error4014 = true;
|
|
86
|
+
result.events.push({ time: entry.time, type: "discord.error_4014", message: "Discord privileged intents error", severity: "error" });
|
|
87
|
+
}
|
|
88
|
+
// Auth events
|
|
89
|
+
if (msg.includes("Token refresh failed") || msg.includes("refresh_token_reused")) {
|
|
90
|
+
result.auth.refreshFailed = true;
|
|
91
|
+
result.auth.errors.push(msg.substring(0, 100));
|
|
92
|
+
result.events.push({ time: entry.time, type: "auth.refresh_failed", message: "Token refresh failed", severity: "error" });
|
|
93
|
+
}
|
|
94
|
+
if (msg.includes("unauthorized") || msg.includes("token missing") || msg.includes("token expired")) {
|
|
95
|
+
result.auth.tokenExpired = true;
|
|
96
|
+
result.auth.errors.push(msg.substring(0, 100));
|
|
97
|
+
}
|
|
98
|
+
// Model events
|
|
99
|
+
if (msg.includes("warmup failed")) {
|
|
100
|
+
result.events.push({ time: entry.time, type: "model.warmup_failed", message: msg.substring(0, 100), severity: "error" });
|
|
101
|
+
}
|
|
102
|
+
if (msg.includes("model fallback")) {
|
|
103
|
+
result.events.push({ time: entry.time, type: "model.fallback", message: msg.substring(0, 100), severity: "warn" });
|
|
104
|
+
}
|
|
105
|
+
// Agent events
|
|
106
|
+
if (msg.includes("lane task error")) {
|
|
107
|
+
result.events.push({ time: entry.time, type: "agent.error", message: msg.substring(0, 100), severity: "error" });
|
|
108
|
+
}
|
|
109
|
+
if (msg.includes("⇄ res ✓")) {
|
|
110
|
+
// Successful request
|
|
111
|
+
const durMatch = msg.match(/(\d+ms)/);
|
|
112
|
+
result.events.push({ time: entry.time, type: "request.success", message: `Request OK${durMatch ? ` (${durMatch[1]})` : ""}`, severity: "info" });
|
|
113
|
+
}
|
|
114
|
+
if (msg.includes("⇄ res ✗")) {
|
|
115
|
+
result.events.push({ time: entry.time, type: "request.error", message: msg.substring(0, 100), severity: "error" });
|
|
116
|
+
}
|
|
117
|
+
// Collect errors and warnings
|
|
118
|
+
if (entry.level === "error")
|
|
119
|
+
result.errors.push(msg.substring(0, 120));
|
|
120
|
+
if (entry.level === "warn")
|
|
121
|
+
result.warnings.push(msg.substring(0, 120));
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Format log analysis for display.
|
|
127
|
+
*/
|
|
128
|
+
export function formatLogAnalysis(analysis) {
|
|
129
|
+
const c = { reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m", green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", cyan: "\x1b[36m" };
|
|
130
|
+
const lines = [];
|
|
131
|
+
lines.push(`\n${c.bold}${c.cyan}── OpenClaw Log Analysis ──${c.reset}\n`);
|
|
132
|
+
lines.push(` ${c.dim}${analysis.totalEntries} log entries${analysis.timeRange ? ` (${analysis.timeRange.start} → ${analysis.timeRange.end})` : ""}${c.reset}`);
|
|
133
|
+
// Gateway
|
|
134
|
+
lines.push(`\n ${c.bold}Gateway:${c.reset} ${analysis.gateway.listening ? `${c.green}✓ running${c.reset}` : `${c.red}✗ not running${c.reset}`}${analysis.gateway.model ? ` | model: ${analysis.gateway.model}` : ""}`);
|
|
135
|
+
// Discord
|
|
136
|
+
if (analysis.discord.botName) {
|
|
137
|
+
const discordStatus = analysis.discord.connected ? `${c.green}✓ connected` :
|
|
138
|
+
analysis.discord.rateLimited ? `${c.yellow}⏳ rate limited` :
|
|
139
|
+
analysis.discord.error4014 ? `${c.red}✗ intents error (4014)` :
|
|
140
|
+
`${c.yellow}⏳ ${analysis.discord.lastEvent ?? "connecting"}`;
|
|
141
|
+
lines.push(` ${c.bold}Discord:${c.reset} ${discordStatus}${c.reset} (@${analysis.discord.botName})`);
|
|
142
|
+
}
|
|
143
|
+
// Auth
|
|
144
|
+
if (analysis.auth.errors.length > 0) {
|
|
145
|
+
lines.push(`\n ${c.bold}Auth Issues:${c.reset}`);
|
|
146
|
+
for (const err of analysis.auth.errors.slice(0, 3)) {
|
|
147
|
+
lines.push(` ${c.red}✗${c.reset} ${err}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Key events
|
|
151
|
+
const keyEvents = analysis.events.filter(e => e.severity !== "info").slice(-10);
|
|
152
|
+
if (keyEvents.length > 0) {
|
|
153
|
+
lines.push(`\n ${c.bold}Recent Issues:${c.reset}`);
|
|
154
|
+
for (const event of keyEvents) {
|
|
155
|
+
const icon = event.severity === "error" ? `${c.red}✗` : `${c.yellow}⚠`;
|
|
156
|
+
const time = event.time.split("T")[1]?.split(".")[0] ?? "";
|
|
157
|
+
lines.push(` ${icon}${c.reset} ${c.dim}${time}${c.reset} ${event.message}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Summary
|
|
161
|
+
if (analysis.errors.length === 0 && analysis.warnings.length === 0) {
|
|
162
|
+
lines.push(`\n ${c.green}✓ No errors or warnings in recent logs.${c.reset}`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
lines.push(`\n ${c.dim}${analysis.errors.length} error(s), ${analysis.warnings.length} warning(s)${c.reset}`);
|
|
166
|
+
}
|
|
167
|
+
return lines.join("\n");
|
|
168
|
+
}
|
package/dist/utils/output.js
CHANGED
|
@@ -3,6 +3,10 @@ export function formatParsedCommand(cmd) {
|
|
|
3
3
|
const { intent } = cmd;
|
|
4
4
|
lines.push(`Intent: ${intent.intent}`);
|
|
5
5
|
lines.push(`Confidence: ${(intent.confidence * 100).toFixed(0)}%`);
|
|
6
|
+
// Show Computer: Local/Remote so user knows where the command runs
|
|
7
|
+
const env = intent.fields.environment ?? "local";
|
|
8
|
+
const isLocal = env === "local" || env === "localhost" || env === "dev";
|
|
9
|
+
lines.push(`Computer: ${isLocal ? "\x1b[32mLocal\x1b[0m" : `\x1b[36mRemote (${env})\x1b[0m`}`);
|
|
6
10
|
const entries = Object.entries(intent.fields).filter(([, v]) => v !== undefined);
|
|
7
11
|
if (entries.length > 0) {
|
|
8
12
|
lines.push("Fields:");
|
package/dist/utils/platform.js
CHANGED
|
@@ -245,7 +245,8 @@ function tryExec(cmd) {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
function commandExists(cmd) {
|
|
248
|
-
|
|
248
|
+
const checkCmd = process.platform === "win32" ? `where ${cmd}` : `command -v ${cmd}`;
|
|
249
|
+
return tryExec(checkCmd) !== null;
|
|
249
250
|
}
|
|
250
251
|
function extractField(content, key) {
|
|
251
252
|
const match = content.match(new RegExp(`^${key}="?([^"\\n]*)"?`, "m"));
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Reporter — emit live progress events from executors.
|
|
3
|
+
*
|
|
4
|
+
* Allows handlers to report step-by-step progress that gets
|
|
5
|
+
* displayed in real-time to the user, even during background execution.
|
|
6
|
+
*
|
|
7
|
+
* Usage in a handler:
|
|
8
|
+
* reportProgress("Step 1/3: Checking ports...");
|
|
9
|
+
* reportProgress("Step 2/3: Scanning connections...");
|
|
10
|
+
* reportProgress("Step 3/3: Generating report...", 100);
|
|
11
|
+
*/
|
|
12
|
+
import { EventEmitter } from "node:events";
|
|
13
|
+
export interface ProgressEvent {
|
|
14
|
+
taskId: number;
|
|
15
|
+
intent: string;
|
|
16
|
+
message: string;
|
|
17
|
+
percent?: number;
|
|
18
|
+
step?: number;
|
|
19
|
+
totalSteps?: number;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}
|
|
22
|
+
declare class ProgressReporterClass extends EventEmitter {
|
|
23
|
+
private currentTaskId;
|
|
24
|
+
private currentIntent;
|
|
25
|
+
/** Set the current task context for progress reports. */
|
|
26
|
+
setContext(taskId: number, intent: string): void;
|
|
27
|
+
/** Report progress from inside a handler. */
|
|
28
|
+
report(message: string, opts?: {
|
|
29
|
+
percent?: number;
|
|
30
|
+
step?: number;
|
|
31
|
+
totalSteps?: number;
|
|
32
|
+
}): void;
|
|
33
|
+
/** Convenience: report a numbered step. */
|
|
34
|
+
step(current: number, total: number, message: string): void;
|
|
35
|
+
/** Report completion. */
|
|
36
|
+
done(message?: string): void;
|
|
37
|
+
}
|
|
38
|
+
/** Singleton progress reporter. */
|
|
39
|
+
export declare const progressReporter: ProgressReporterClass;
|
|
40
|
+
/**
|
|
41
|
+
* Convenience function for handlers to report progress.
|
|
42
|
+
* Import this in executor.ts handlers.
|
|
43
|
+
*/
|
|
44
|
+
export declare function reportProgress(message: string, opts?: {
|
|
45
|
+
percent?: number;
|
|
46
|
+
step?: number;
|
|
47
|
+
totalSteps?: number;
|
|
48
|
+
}): void;
|
|
49
|
+
export declare function reportStep(current: number, total: number, message: string): void;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Reporter — emit live progress events from executors.
|
|
3
|
+
*
|
|
4
|
+
* Allows handlers to report step-by-step progress that gets
|
|
5
|
+
* displayed in real-time to the user, even during background execution.
|
|
6
|
+
*
|
|
7
|
+
* Usage in a handler:
|
|
8
|
+
* reportProgress("Step 1/3: Checking ports...");
|
|
9
|
+
* reportProgress("Step 2/3: Scanning connections...");
|
|
10
|
+
* reportProgress("Step 3/3: Generating report...", 100);
|
|
11
|
+
*/
|
|
12
|
+
import { EventEmitter } from "node:events";
|
|
13
|
+
class ProgressReporterClass extends EventEmitter {
|
|
14
|
+
currentTaskId = 0;
|
|
15
|
+
currentIntent = "";
|
|
16
|
+
/** Set the current task context for progress reports. */
|
|
17
|
+
setContext(taskId, intent) {
|
|
18
|
+
this.currentTaskId = taskId;
|
|
19
|
+
this.currentIntent = intent;
|
|
20
|
+
}
|
|
21
|
+
/** Report progress from inside a handler. */
|
|
22
|
+
report(message, opts) {
|
|
23
|
+
const event = {
|
|
24
|
+
taskId: this.currentTaskId,
|
|
25
|
+
intent: this.currentIntent,
|
|
26
|
+
message,
|
|
27
|
+
percent: opts?.percent,
|
|
28
|
+
step: opts?.step,
|
|
29
|
+
totalSteps: opts?.totalSteps,
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
};
|
|
32
|
+
this.emit("progress", event);
|
|
33
|
+
}
|
|
34
|
+
/** Convenience: report a numbered step. */
|
|
35
|
+
step(current, total, message) {
|
|
36
|
+
this.report(`Step ${current}/${total}: ${message}`, {
|
|
37
|
+
step: current,
|
|
38
|
+
totalSteps: total,
|
|
39
|
+
percent: Math.round((current / total) * 100),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Report completion. */
|
|
43
|
+
done(message) {
|
|
44
|
+
this.report(message ?? "Done", { percent: 100 });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Singleton progress reporter. */
|
|
48
|
+
export const progressReporter = new ProgressReporterClass();
|
|
49
|
+
/**
|
|
50
|
+
* Convenience function for handlers to report progress.
|
|
51
|
+
* Import this in executor.ts handlers.
|
|
52
|
+
*/
|
|
53
|
+
export function reportProgress(message, opts) {
|
|
54
|
+
progressReporter.report(message, opts);
|
|
55
|
+
}
|
|
56
|
+
export function reportStep(current, total, message) {
|
|
57
|
+
progressReporter.step(current, total, message);
|
|
58
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart project detection and package manager resolution.
|
|
3
|
+
*
|
|
4
|
+
* Detects the project type in a directory and returns the correct
|
|
5
|
+
* install/update/build commands for that project's ecosystem.
|
|
6
|
+
*/
|
|
7
|
+
export interface DetectedProject {
|
|
8
|
+
type: string;
|
|
9
|
+
packageManager: string;
|
|
10
|
+
installCmd: string;
|
|
11
|
+
updateCmd: string;
|
|
12
|
+
buildCmd?: string;
|
|
13
|
+
lockFile?: string;
|
|
14
|
+
configFile: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detect all projects in a directory.
|
|
18
|
+
* Returns them in priority order (most specific first).
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectProjects(dir?: string): DetectedProject[];
|
|
21
|
+
/** Format project detection results for display. */
|
|
22
|
+
export declare function formatProjectDetection(projects: DetectedProject[]): string;
|
|
23
|
+
/** Get the install command for the primary project in cwd. */
|
|
24
|
+
export declare function getProjectInstallCmd(dir?: string): string | null;
|
|
25
|
+
/** Get the update command for the primary project in cwd. */
|
|
26
|
+
export declare function getProjectUpdateCmd(dir?: string): string | null;
|
|
27
|
+
export interface ProjectScripts {
|
|
28
|
+
packageManager: string;
|
|
29
|
+
scripts: Record<string, string>;
|
|
30
|
+
dependencies: string[];
|
|
31
|
+
devDependencies: string[];
|
|
32
|
+
name: string;
|
|
33
|
+
version: string;
|
|
34
|
+
}
|
|
35
|
+
/** Read package.json or composer.json and extract scripts, deps, and metadata. */
|
|
36
|
+
export declare function readProjectConfig(dir?: string): ProjectScripts | null;
|
|
37
|
+
/** Format package.json scripts for display. */
|
|
38
|
+
export declare function formatPackageScripts(info: ProjectScripts): string;
|
|
39
|
+
/** Get the run command for a named script. */
|
|
40
|
+
export declare function getScriptRunCmd(scriptName: string, dir?: string): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Get the system-level update command based on the detected platform.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getSystemUpdateCmd(): string;
|