notoken-core 1.6.0 → 2.0.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.
Files changed (99) hide show
  1. package/config/chat-responses.json +767 -0
  2. package/config/concept-clusters.json +31 -0
  3. package/config/entities.json +93 -0
  4. package/config/image-prompts.json +20 -0
  5. package/config/intent-vectors.json +1 -0
  6. package/config/intents.json +4946 -83
  7. package/config/ollama-models.json +193 -0
  8. package/config/rules.json +32 -1
  9. package/dist/automation/discordPatchright.d.ts +35 -0
  10. package/dist/automation/discordPatchright.js +424 -0
  11. package/dist/automation/discordSetup.d.ts +31 -0
  12. package/dist/automation/discordSetup.js +338 -0
  13. package/dist/conversation/coreference.js +44 -4
  14. package/dist/conversation/pendingActions.d.ts +55 -0
  15. package/dist/conversation/pendingActions.js +127 -0
  16. package/dist/conversation/store.d.ts +72 -0
  17. package/dist/conversation/store.js +140 -1
  18. package/dist/conversation/topicTracker.d.ts +36 -0
  19. package/dist/conversation/topicTracker.js +141 -0
  20. package/dist/execution/ssh.d.ts +42 -1
  21. package/dist/execution/ssh.js +532 -3
  22. package/dist/handlers/executor.js +3981 -16
  23. package/dist/index.d.ts +25 -3
  24. package/dist/index.js +36 -2
  25. package/dist/nlp/batchParser.d.ts +30 -0
  26. package/dist/nlp/batchParser.js +77 -0
  27. package/dist/nlp/conceptExpansion.d.ts +54 -0
  28. package/dist/nlp/conceptExpansion.js +136 -0
  29. package/dist/nlp/conceptRouter.d.ts +49 -0
  30. package/dist/nlp/conceptRouter.js +302 -0
  31. package/dist/nlp/confidenceCalibrator.d.ts +62 -0
  32. package/dist/nlp/confidenceCalibrator.js +116 -0
  33. package/dist/nlp/correctionLearner.d.ts +45 -0
  34. package/dist/nlp/correctionLearner.js +207 -0
  35. package/dist/nlp/entitySpellCorrect.d.ts +35 -0
  36. package/dist/nlp/entitySpellCorrect.js +141 -0
  37. package/dist/nlp/knowledgeGraph.d.ts +70 -0
  38. package/dist/nlp/knowledgeGraph.js +380 -0
  39. package/dist/nlp/llmFallback.js +28 -1
  40. package/dist/nlp/multiClassifier.js +91 -6
  41. package/dist/nlp/multiIntent.d.ts +43 -0
  42. package/dist/nlp/multiIntent.js +154 -0
  43. package/dist/nlp/parseIntent.d.ts +6 -1
  44. package/dist/nlp/parseIntent.js +180 -5
  45. package/dist/nlp/ruleParser.js +315 -0
  46. package/dist/nlp/semanticSimilarity.d.ts +30 -0
  47. package/dist/nlp/semanticSimilarity.js +174 -0
  48. package/dist/nlp/vocabularyBuilder.d.ts +43 -0
  49. package/dist/nlp/vocabularyBuilder.js +224 -0
  50. package/dist/nlp/wikidata.d.ts +49 -0
  51. package/dist/nlp/wikidata.js +228 -0
  52. package/dist/policy/confirm.d.ts +10 -0
  53. package/dist/policy/confirm.js +39 -0
  54. package/dist/policy/safety.js +6 -4
  55. package/dist/utils/aliases.d.ts +5 -0
  56. package/dist/utils/aliases.js +39 -0
  57. package/dist/utils/analysis.js +71 -15
  58. package/dist/utils/browser.d.ts +64 -0
  59. package/dist/utils/browser.js +364 -0
  60. package/dist/utils/commandHistory.d.ts +20 -0
  61. package/dist/utils/commandHistory.js +108 -0
  62. package/dist/utils/completer.d.ts +17 -0
  63. package/dist/utils/completer.js +79 -0
  64. package/dist/utils/config.js +32 -2
  65. package/dist/utils/dbQuery.d.ts +25 -0
  66. package/dist/utils/dbQuery.js +248 -0
  67. package/dist/utils/discordDiag.d.ts +35 -0
  68. package/dist/utils/discordDiag.js +826 -0
  69. package/dist/utils/diskCleanup.d.ts +36 -0
  70. package/dist/utils/diskCleanup.js +775 -0
  71. package/dist/utils/entityResolver.d.ts +107 -0
  72. package/dist/utils/entityResolver.js +468 -0
  73. package/dist/utils/imageGen.d.ts +92 -0
  74. package/dist/utils/imageGen.js +2031 -0
  75. package/dist/utils/installTracker.d.ts +57 -0
  76. package/dist/utils/installTracker.js +160 -0
  77. package/dist/utils/multiExec.d.ts +21 -0
  78. package/dist/utils/multiExec.js +141 -0
  79. package/dist/utils/openclawDiag.d.ts +29 -0
  80. package/dist/utils/openclawDiag.js +1035 -0
  81. package/dist/utils/output.js +4 -0
  82. package/dist/utils/platform.js +2 -1
  83. package/dist/utils/progressReporter.d.ts +50 -0
  84. package/dist/utils/progressReporter.js +58 -0
  85. package/dist/utils/projectDetect.d.ts +44 -0
  86. package/dist/utils/projectDetect.js +319 -0
  87. package/dist/utils/projectScanner.d.ts +44 -0
  88. package/dist/utils/projectScanner.js +312 -0
  89. package/dist/utils/shellCompat.d.ts +78 -0
  90. package/dist/utils/shellCompat.js +186 -0
  91. package/dist/utils/smartArchive.d.ts +16 -0
  92. package/dist/utils/smartArchive.js +172 -0
  93. package/dist/utils/smartRetry.d.ts +26 -0
  94. package/dist/utils/smartRetry.js +114 -0
  95. package/dist/utils/updater.d.ts +1 -0
  96. package/dist/utils/updater.js +1 -1
  97. package/dist/utils/version.d.ts +20 -0
  98. package/dist/utils/version.js +212 -0
  99. package/package.json +6 -3
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Install Tracker.
3
+ *
4
+ * Tracks what NoToken has installed so it can cleanly uninstall later.
5
+ * Persisted to ~/.notoken/install-history.json
6
+ *
7
+ * Records:
8
+ * - What was installed (tool name, engine, package)
9
+ * - Where it was installed (path, drive)
10
+ * - When it was installed
11
+ * - How it was installed (npm, git clone, docker pull, apt, brew, winget)
12
+ * - Dependencies that were also installed
13
+ */
14
+ export interface InstalledItem {
15
+ name: string;
16
+ type: "tool" | "engine" | "model" | "docker-image" | "system-package" | "build-tools";
17
+ method: "npm" | "git-clone" | "docker-pull" | "apt" | "dnf" | "brew" | "winget" | "curl" | "pip";
18
+ path?: string;
19
+ size?: string;
20
+ version?: string;
21
+ installedAt: string;
22
+ dependencies?: string[];
23
+ uninstallCmd?: string;
24
+ notes?: string;
25
+ }
26
+ export interface InstallHistory {
27
+ items: InstalledItem[];
28
+ lastUpdated: string;
29
+ }
30
+ /**
31
+ * Record that something was installed.
32
+ */
33
+ export declare function trackInstall(item: Omit<InstalledItem, "installedAt">): void;
34
+ /**
35
+ * Get all installed items.
36
+ */
37
+ export declare function getInstallHistory(): InstalledItem[];
38
+ /**
39
+ * Get installed items by type.
40
+ */
41
+ export declare function getInstalledByType(type: InstalledItem["type"]): InstalledItem[];
42
+ /**
43
+ * Get a specific installed item.
44
+ */
45
+ export declare function getInstalledItem(name: string): InstalledItem | undefined;
46
+ /**
47
+ * Remove an item from tracking (after uninstall).
48
+ */
49
+ export declare function untrackInstall(name: string): void;
50
+ /**
51
+ * Format install history for display.
52
+ */
53
+ export declare function formatInstallHistory(): string;
54
+ /**
55
+ * Generate uninstall commands for an item.
56
+ */
57
+ export declare function getUninstallSteps(name: string): string[];
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Install Tracker.
3
+ *
4
+ * Tracks what NoToken has installed so it can cleanly uninstall later.
5
+ * Persisted to ~/.notoken/install-history.json
6
+ *
7
+ * Records:
8
+ * - What was installed (tool name, engine, package)
9
+ * - Where it was installed (path, drive)
10
+ * - When it was installed
11
+ * - How it was installed (npm, git clone, docker pull, apt, brew, winget)
12
+ * - Dependencies that were also installed
13
+ */
14
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
15
+ import { resolve } from "node:path";
16
+ import { USER_HOME } from "./paths.js";
17
+ const HISTORY_FILE = resolve(USER_HOME, "install-history.json");
18
+ function loadHistory() {
19
+ try {
20
+ if (existsSync(HISTORY_FILE)) {
21
+ return JSON.parse(readFileSync(HISTORY_FILE, "utf-8"));
22
+ }
23
+ }
24
+ catch { }
25
+ return { items: [], lastUpdated: new Date().toISOString() };
26
+ }
27
+ function saveHistory(history) {
28
+ try {
29
+ mkdirSync(USER_HOME, { recursive: true });
30
+ history.lastUpdated = new Date().toISOString();
31
+ writeFileSync(HISTORY_FILE, JSON.stringify(history, null, 2));
32
+ }
33
+ catch { }
34
+ }
35
+ /**
36
+ * Record that something was installed.
37
+ */
38
+ export function trackInstall(item) {
39
+ const history = loadHistory();
40
+ // Don't duplicate — update if same name+type exists
41
+ const existing = history.items.findIndex(i => i.name === item.name && i.type === item.type);
42
+ const entry = { ...item, installedAt: new Date().toISOString() };
43
+ if (existing >= 0) {
44
+ history.items[existing] = entry;
45
+ }
46
+ else {
47
+ history.items.push(entry);
48
+ }
49
+ saveHistory(history);
50
+ }
51
+ /**
52
+ * Get all installed items.
53
+ */
54
+ export function getInstallHistory() {
55
+ return loadHistory().items;
56
+ }
57
+ /**
58
+ * Get installed items by type.
59
+ */
60
+ export function getInstalledByType(type) {
61
+ return loadHistory().items.filter(i => i.type === type);
62
+ }
63
+ /**
64
+ * Get a specific installed item.
65
+ */
66
+ export function getInstalledItem(name) {
67
+ return loadHistory().items.find(i => i.name === name);
68
+ }
69
+ /**
70
+ * Remove an item from tracking (after uninstall).
71
+ */
72
+ export function untrackInstall(name) {
73
+ const history = loadHistory();
74
+ history.items = history.items.filter(i => i.name !== name);
75
+ saveHistory(history);
76
+ }
77
+ /**
78
+ * Format install history for display.
79
+ */
80
+ export function formatInstallHistory() {
81
+ const c = {
82
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
83
+ green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", cyan: "\x1b[36m",
84
+ };
85
+ const items = getInstallHistory();
86
+ if (items.length === 0)
87
+ return `${c.dim}No installations tracked by NoToken.${c.reset}`;
88
+ const lines = [];
89
+ lines.push(`${c.bold}NoToken Install History${c.reset} (${items.length} items)\n`);
90
+ // Group by type
91
+ const grouped = new Map();
92
+ for (const item of items) {
93
+ const list = grouped.get(item.type) ?? [];
94
+ list.push(item);
95
+ grouped.set(item.type, list);
96
+ }
97
+ for (const [type, typeItems] of grouped) {
98
+ lines.push(`${c.bold}${type}:${c.reset}`);
99
+ for (const item of typeItems) {
100
+ const ver = item.version ? ` v${item.version}` : "";
101
+ const size = item.size ? ` (${item.size})` : "";
102
+ const path = item.path ? `\n ${c.dim}${item.path}${c.reset}` : "";
103
+ const method = `${c.dim}via ${item.method}${c.reset}`;
104
+ const date = new Date(item.installedAt).toLocaleDateString();
105
+ lines.push(` ${c.green}✓${c.reset} ${c.bold}${item.name}${c.reset}${ver}${size} — ${method} ${c.dim}${date}${c.reset}${path}`);
106
+ if (item.uninstallCmd) {
107
+ lines.push(` ${c.dim}Uninstall: ${item.uninstallCmd}${c.reset}`);
108
+ }
109
+ }
110
+ lines.push("");
111
+ }
112
+ return lines.join("\n");
113
+ }
114
+ /**
115
+ * Generate uninstall commands for an item.
116
+ */
117
+ export function getUninstallSteps(name) {
118
+ const item = getInstalledItem(name);
119
+ if (!item)
120
+ return [];
121
+ const steps = [];
122
+ switch (item.method) {
123
+ case "npm":
124
+ steps.push(`npm uninstall -g ${name}`);
125
+ break;
126
+ case "git-clone":
127
+ if (item.path)
128
+ steps.push(`rm -rf "${item.path}"`);
129
+ break;
130
+ case "docker-pull":
131
+ steps.push(`docker rmi ${name}`);
132
+ steps.push(`docker rm -f sd-webui 2>/dev/null`);
133
+ break;
134
+ case "apt":
135
+ steps.push(`sudo apt-get remove -y ${name}`);
136
+ break;
137
+ case "dnf":
138
+ steps.push(`sudo dnf remove -y ${name}`);
139
+ break;
140
+ case "brew":
141
+ steps.push(`brew uninstall ${name}`);
142
+ break;
143
+ case "winget":
144
+ steps.push(`winget uninstall ${name}`);
145
+ break;
146
+ case "pip":
147
+ if (item.path)
148
+ steps.push(`rm -rf "${item.path}"`);
149
+ break;
150
+ case "curl":
151
+ if (item.path)
152
+ steps.push(`rm -f "${item.path}"`);
153
+ break;
154
+ }
155
+ // Clean up dependencies
156
+ if (item.dependencies?.length) {
157
+ steps.push(`# Dependencies installed: ${item.dependencies.join(", ")}`);
158
+ }
159
+ return steps;
160
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Multi-environment execution.
3
+ *
4
+ * Detects phrases like "on all servers", "everywhere", "on prod and staging"
5
+ * and executes the resolved command on each target environment sequentially.
6
+ */
7
+ import type { DynamicIntent } from "../types/intent.js";
8
+ /**
9
+ * Detect whether the user's raw text targets multiple environments.
10
+ *
11
+ * Returns an array of environment names, or `null` if the text does not
12
+ * indicate multi-environment execution.
13
+ */
14
+ export declare function detectMultiTarget(rawText: string): string[] | null;
15
+ /**
16
+ * Execute an intent's command on each of the given environments sequentially,
17
+ * printing progress along the way.
18
+ *
19
+ * Returns a formatted summary string.
20
+ */
21
+ export declare function executeMulti(intent: DynamicIntent, environments: string[]): Promise<string>;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Multi-environment execution.
3
+ *
4
+ * Detects phrases like "on all servers", "everywhere", "on prod and staging"
5
+ * and executes the resolved command on each target environment sequentially.
6
+ */
7
+ import { loadHosts, getIntentDef } from "./config.js";
8
+ import { runRemoteCommand } from "../execution/ssh.js";
9
+ // ─── Detection ──────────────────────────────────────────────────────────────
10
+ /** Phrases that mean "all configured environments". */
11
+ const ALL_PATTERNS = [
12
+ /\bon all servers\b/i,
13
+ /\bon all environments\b/i,
14
+ /\ball servers\b/i,
15
+ /\ball environments\b/i,
16
+ /\beverywhere\b/i,
17
+ /\bon all\b/i,
18
+ ];
19
+ /**
20
+ * "on X and Y" / "on X, Y, and Z" — extract specific environment names.
21
+ * Must come after a preposition like "on" or "across".
22
+ */
23
+ const SPECIFIC_PATTERN = /\b(?:on|across|for)\s+([\w]+(?:\s*(?:,\s*|\band\b\s*)[\w]+)+)/i;
24
+ /**
25
+ * Detect whether the user's raw text targets multiple environments.
26
+ *
27
+ * Returns an array of environment names, or `null` if the text does not
28
+ * indicate multi-environment execution.
29
+ */
30
+ export function detectMultiTarget(rawText) {
31
+ const hosts = loadHosts();
32
+ const knownEnvs = Object.keys(hosts);
33
+ // 1. Check for "all" patterns
34
+ for (const pattern of ALL_PATTERNS) {
35
+ if (pattern.test(rawText)) {
36
+ return knownEnvs.length > 0 ? knownEnvs : null;
37
+ }
38
+ }
39
+ // 2. Check for "on X and Y" with specific names
40
+ const match = SPECIFIC_PATTERN.exec(rawText);
41
+ if (match) {
42
+ const envList = match[1]
43
+ .split(/\s*(?:,\s*|\band\b\s*)+/)
44
+ .map((e) => e.trim().toLowerCase())
45
+ .filter(Boolean);
46
+ // Only count environments that are actually configured
47
+ const valid = envList.filter((e) => knownEnvs.includes(e));
48
+ if (valid.length > 1) {
49
+ return valid;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ /**
55
+ * Execute an intent's command on each of the given environments sequentially,
56
+ * printing progress along the way.
57
+ *
58
+ * Returns a formatted summary string.
59
+ */
60
+ export async function executeMulti(intent, environments) {
61
+ const def = getIntentDef(intent.intent);
62
+ if (!def) {
63
+ throw new Error(`No intent definition found for: ${intent.intent}`);
64
+ }
65
+ const cc = {
66
+ reset: "\x1b[0m",
67
+ bold: "\x1b[1m",
68
+ dim: "\x1b[2m",
69
+ green: "\x1b[32m",
70
+ yellow: "\x1b[33m",
71
+ red: "\x1b[31m",
72
+ cyan: "\x1b[36m",
73
+ };
74
+ const command = interpolateFields(def.command, intent.fields);
75
+ console.log(`\n${cc.bold}${cc.cyan}── Multi-environment: ${environments.join(", ")} ──${cc.reset}`);
76
+ console.log(`${cc.dim}Command: ${command}${cc.reset}\n`);
77
+ const results = [];
78
+ for (let i = 0; i < environments.length; i++) {
79
+ const env = environments[i];
80
+ const label = `[${i + 1}/${environments.length}] ${env}`;
81
+ process.stderr.write(` ${cc.cyan}${label}${cc.reset} ... `);
82
+ const start = Date.now();
83
+ let output;
84
+ let success;
85
+ try {
86
+ output = await runRemoteCommand(env, command);
87
+ success = true;
88
+ process.stderr.write(`${cc.green}OK${cc.reset} (${Date.now() - start}ms)\n`);
89
+ }
90
+ catch (err) {
91
+ output = err instanceof Error ? err.message : String(err);
92
+ success = false;
93
+ process.stderr.write(`${cc.red}FAIL${cc.reset} (${Date.now() - start}ms)\n`);
94
+ }
95
+ results.push({
96
+ environment: env,
97
+ success,
98
+ output: output.trim(),
99
+ durationMs: Date.now() - start,
100
+ });
101
+ }
102
+ // ── Summary ──
103
+ return formatSummary(results, cc);
104
+ }
105
+ // ─── Helpers ────────────────────────────────────────────────────────────────
106
+ function interpolateFields(template, fields) {
107
+ let cmd = template;
108
+ for (const [key, value] of Object.entries(fields)) {
109
+ if (value !== undefined && value !== null) {
110
+ cmd = cmd.replaceAll(`{{${key}}}`, String(value));
111
+ }
112
+ }
113
+ // Remove any remaining placeholders
114
+ cmd = cmd.replace(/\{\{[a-zA-Z_]+\}\}/g, "");
115
+ return cmd.trim();
116
+ }
117
+ function formatSummary(results, cc) {
118
+ const lines = [];
119
+ const passed = results.filter((r) => r.success).length;
120
+ const failed = results.length - passed;
121
+ lines.push(`\n${cc.bold}── Summary ──${cc.reset} ${cc.green}${passed} passed${cc.reset}` +
122
+ (failed > 0 ? ` ${cc.red}${failed} failed${cc.reset}` : ""));
123
+ lines.push("");
124
+ for (const r of results) {
125
+ const icon = r.success
126
+ ? `${cc.green}✓${cc.reset}`
127
+ : `${cc.red}✗${cc.reset}`;
128
+ const dur = `${cc.dim}(${r.durationMs}ms)${cc.reset}`;
129
+ lines.push(` ${icon} ${cc.bold}${r.environment}${cc.reset} ${dur}`);
130
+ // Show first few lines of output (truncated)
131
+ const outputLines = r.output.split("\n").filter(Boolean);
132
+ const preview = outputLines.slice(0, 3);
133
+ for (const line of preview) {
134
+ lines.push(` ${cc.dim}${line}${cc.reset}`);
135
+ }
136
+ if (outputLines.length > 3) {
137
+ lines.push(` ${cc.dim}... (${outputLines.length - 3} more lines)${cc.reset}`);
138
+ }
139
+ }
140
+ return lines.join("\n");
141
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * OpenClaw advanced diagnostics.
3
+ *
4
+ * Runs a multi-step check:
5
+ * 1. Is the gateway process running?
6
+ * 2. Is the HTTP health endpoint responding?
7
+ * 3. Can we reach the WebSocket gateway?
8
+ * 4. What channels are configured (Telegram, Discord, Matrix)?
9
+ * 5. Are channels connected and healthy?
10
+ * 6. What's the config state?
11
+ * 7. Any errors in recent logs?
12
+ */
13
+ /**
14
+ * Quick connectivity check — escalates from simplest to most thorough.
15
+ * Used for "can you talk to openclaw?" / "is openclaw reachable?"
16
+ *
17
+ * Steps:
18
+ * 1. Is the process alive? (ps aux — instant)
19
+ * 2. Does the health endpoint respond? (curl — fast)
20
+ * 3. Can the CLI communicate? (openclaw health — slower)
21
+ *
22
+ * Stops at the first failure and reports what's wrong.
23
+ */
24
+ export declare function quickConnectivityCheck(runRemote?: (cmd: string) => Promise<string>): Promise<string>;
25
+ export declare function diagnoseOpenclaw(isRemote: boolean, runRemote?: (cmd: string) => Promise<string>): Promise<string>;
26
+ /**
27
+ * Apply auto-fixes from the last diagnosis.
28
+ */
29
+ export declare function autoFixOpenclaw(runRemote?: (cmd: string) => Promise<string>): Promise<string>;