notoken-core 1.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.
- package/config/file-hints.json +255 -0
- package/config/hosts.json +14 -0
- package/config/intents.json +3920 -0
- package/config/playbooks.json +112 -0
- package/config/rules.json +100 -0
- package/dist/agents/agentSpawner.d.ts +56 -0
- package/dist/agents/agentSpawner.js +180 -0
- package/dist/agents/planner.d.ts +40 -0
- package/dist/agents/planner.js +175 -0
- package/dist/agents/playbookRunner.d.ts +45 -0
- package/dist/agents/playbookRunner.js +120 -0
- package/dist/agents/taskRunner.d.ts +61 -0
- package/dist/agents/taskRunner.js +142 -0
- package/dist/context/history.d.ts +36 -0
- package/dist/context/history.js +115 -0
- package/dist/conversation/coreference.d.ts +27 -0
- package/dist/conversation/coreference.js +147 -0
- package/dist/conversation/secrets.d.ts +43 -0
- package/dist/conversation/secrets.js +129 -0
- package/dist/conversation/store.d.ts +94 -0
- package/dist/conversation/store.js +184 -0
- package/dist/execution/git.d.ts +11 -0
- package/dist/execution/git.js +146 -0
- package/dist/execution/ssh.d.ts +2 -0
- package/dist/execution/ssh.js +17 -0
- package/dist/handlers/executor.d.ts +8 -0
- package/dist/handlers/executor.js +216 -0
- package/dist/healing/claudeHealer.d.ts +17 -0
- package/dist/healing/claudeHealer.js +300 -0
- package/dist/healing/patchPromoter.d.ts +25 -0
- package/dist/healing/patchPromoter.js +118 -0
- package/dist/healing/ruleBuilder.d.ts +5 -0
- package/dist/healing/ruleBuilder.js +111 -0
- package/dist/healing/ruleRepairer.d.ts +8 -0
- package/dist/healing/ruleRepairer.js +29 -0
- package/dist/healing/ruleValidator.d.ts +22 -0
- package/dist/healing/ruleValidator.js +145 -0
- package/dist/healing/runHealer.d.ts +11 -0
- package/dist/healing/runHealer.js +74 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +62 -0
- package/dist/intents/catalog.d.ts +4 -0
- package/dist/intents/catalog.js +7 -0
- package/dist/nlp/disambiguate.d.ts +2 -0
- package/dist/nlp/disambiguate.js +46 -0
- package/dist/nlp/fuzzyResolver.d.ts +14 -0
- package/dist/nlp/fuzzyResolver.js +108 -0
- package/dist/nlp/llmFallback.d.ts +63 -0
- package/dist/nlp/llmFallback.js +338 -0
- package/dist/nlp/llmParser.d.ts +8 -0
- package/dist/nlp/llmParser.js +118 -0
- package/dist/nlp/multiClassifier.d.ts +39 -0
- package/dist/nlp/multiClassifier.js +181 -0
- package/dist/nlp/parseIntent.d.ts +2 -0
- package/dist/nlp/parseIntent.js +34 -0
- package/dist/nlp/ruleParser.d.ts +2 -0
- package/dist/nlp/ruleParser.js +234 -0
- package/dist/nlp/semantic.d.ts +104 -0
- package/dist/nlp/semantic.js +419 -0
- package/dist/nlp/uncertainty.d.ts +42 -0
- package/dist/nlp/uncertainty.js +103 -0
- package/dist/parsers/apacheParser.d.ts +50 -0
- package/dist/parsers/apacheParser.js +152 -0
- package/dist/parsers/bindParser.d.ts +40 -0
- package/dist/parsers/bindParser.js +189 -0
- package/dist/parsers/envFile.d.ts +39 -0
- package/dist/parsers/envFile.js +128 -0
- package/dist/parsers/fileFinder.d.ts +30 -0
- package/dist/parsers/fileFinder.js +226 -0
- package/dist/parsers/index.d.ts +27 -0
- package/dist/parsers/index.js +193 -0
- package/dist/parsers/jsonParser.d.ts +16 -0
- package/dist/parsers/jsonParser.js +57 -0
- package/dist/parsers/nginxParser.d.ts +47 -0
- package/dist/parsers/nginxParser.js +161 -0
- package/dist/parsers/passwd.d.ts +25 -0
- package/dist/parsers/passwd.js +41 -0
- package/dist/parsers/shadow.d.ts +23 -0
- package/dist/parsers/shadow.js +50 -0
- package/dist/parsers/yamlParser.d.ts +13 -0
- package/dist/parsers/yamlParser.js +54 -0
- package/dist/policy/confirm.d.ts +2 -0
- package/dist/policy/confirm.js +29 -0
- package/dist/policy/safety.d.ts +4 -0
- package/dist/policy/safety.js +32 -0
- package/dist/types/intent.d.ts +205 -0
- package/dist/types/intent.js +32 -0
- package/dist/types/rules.d.ts +237 -0
- package/dist/types/rules.js +50 -0
- package/dist/utils/analysis.d.ts +25 -0
- package/dist/utils/analysis.js +307 -0
- package/dist/utils/autoBackup.d.ts +43 -0
- package/dist/utils/autoBackup.js +144 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.js +32 -0
- package/dist/utils/dirAnalysis.d.ts +23 -0
- package/dist/utils/dirAnalysis.js +192 -0
- package/dist/utils/explain.d.ts +8 -0
- package/dist/utils/explain.js +145 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.js +29 -0
- package/dist/utils/output.d.ts +2 -0
- package/dist/utils/output.js +26 -0
- package/dist/utils/paths.d.ts +26 -0
- package/dist/utils/paths.js +47 -0
- package/dist/utils/permissions.d.ts +64 -0
- package/dist/utils/permissions.js +298 -0
- package/dist/utils/platform.d.ts +53 -0
- package/dist/utils/platform.js +253 -0
- package/dist/utils/smartFile.d.ts +29 -0
- package/dist/utils/smartFile.js +188 -0
- package/dist/utils/spinner.d.ts +53 -0
- package/dist/utils/spinner.js +140 -0
- package/dist/utils/verbose.d.ts +27 -0
- package/dist/utils/verbose.js +131 -0
- package/dist/utils/wslPaths.d.ts +31 -0
- package/dist/utils/wslPaths.js +145 -0
- package/package.json +39 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ParsedCommand } from "../types/intent.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a verbose, human-friendly restatement of the parsed command.
|
|
4
|
+
*
|
|
5
|
+
* Example output:
|
|
6
|
+
*
|
|
7
|
+
* I understand you want to:
|
|
8
|
+
* Action: restart nginx
|
|
9
|
+
* Environment: prod
|
|
10
|
+
* Risk: high — confirmation required
|
|
11
|
+
* Command: sudo systemctl restart nginx && ...
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatVerbose(parsed: ParsedCommand): string;
|
|
14
|
+
/**
|
|
15
|
+
* Format a background task notification.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatTaskNotification(id: number, name: string, status: "completed" | "failed", duration?: number): string;
|
|
18
|
+
/**
|
|
19
|
+
* Format the background jobs list.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatJobsList(tasks: Array<{
|
|
22
|
+
id: number;
|
|
23
|
+
rawText: string;
|
|
24
|
+
status: string;
|
|
25
|
+
startedAt: Date;
|
|
26
|
+
completedAt?: Date;
|
|
27
|
+
}>): string;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { getIntentDef } from "./config.js";
|
|
2
|
+
const c = {
|
|
3
|
+
reset: "\x1b[0m",
|
|
4
|
+
bold: "\x1b[1m",
|
|
5
|
+
dim: "\x1b[2m",
|
|
6
|
+
green: "\x1b[32m",
|
|
7
|
+
yellow: "\x1b[33m",
|
|
8
|
+
red: "\x1b[31m",
|
|
9
|
+
cyan: "\x1b[36m",
|
|
10
|
+
magenta: "\x1b[35m",
|
|
11
|
+
white: "\x1b[37m",
|
|
12
|
+
};
|
|
13
|
+
const RISK_COLOR = {
|
|
14
|
+
low: c.green,
|
|
15
|
+
medium: c.yellow,
|
|
16
|
+
high: c.red,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Generate a verbose, human-friendly restatement of the parsed command.
|
|
20
|
+
*
|
|
21
|
+
* Example output:
|
|
22
|
+
*
|
|
23
|
+
* I understand you want to:
|
|
24
|
+
* Action: restart nginx
|
|
25
|
+
* Environment: prod
|
|
26
|
+
* Risk: high — confirmation required
|
|
27
|
+
* Command: sudo systemctl restart nginx && ...
|
|
28
|
+
*/
|
|
29
|
+
export function formatVerbose(parsed) {
|
|
30
|
+
const { intent } = parsed;
|
|
31
|
+
const def = getIntentDef(intent.intent);
|
|
32
|
+
const lines = [];
|
|
33
|
+
lines.push(`${c.bold}I understand you want to:${c.reset}`);
|
|
34
|
+
lines.push("");
|
|
35
|
+
// Action description
|
|
36
|
+
if (def) {
|
|
37
|
+
lines.push(` ${c.cyan}Action:${c.reset} ${def.description}`);
|
|
38
|
+
}
|
|
39
|
+
lines.push(` ${c.cyan}Intent:${c.reset} ${c.bold}${intent.intent}${c.reset}`);
|
|
40
|
+
lines.push(` ${c.cyan}Confidence:${c.reset} ${formatConfidence(intent.confidence)}`);
|
|
41
|
+
// Fields
|
|
42
|
+
// Fields — show explicit values, skip internal/empty ones
|
|
43
|
+
const fields = Object.entries(intent.fields).filter(([k, v]) => v !== undefined && v !== "" && k !== "logPath");
|
|
44
|
+
if (fields.length > 0) {
|
|
45
|
+
lines.push("");
|
|
46
|
+
for (const [key, value] of fields) {
|
|
47
|
+
const label = key.charAt(0).toUpperCase() + key.slice(1);
|
|
48
|
+
lines.push(` ${c.cyan}${label}:${c.reset}${" ".repeat(Math.max(1, 12 - label.length))}${c.bold}${value}${c.reset}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Risk + confirmation
|
|
52
|
+
if (def) {
|
|
53
|
+
const riskColor = RISK_COLOR[def.riskLevel] ?? c.white;
|
|
54
|
+
const confirm = def.requiresConfirmation ? " — confirmation required" : "";
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push(` ${c.cyan}Risk:${c.reset} ${riskColor}${def.riskLevel}${confirm}${c.reset}`);
|
|
57
|
+
}
|
|
58
|
+
// Show the resolved command template
|
|
59
|
+
if (def) {
|
|
60
|
+
const command = previewCommand(def, intent.fields);
|
|
61
|
+
if (command.length < 120) {
|
|
62
|
+
lines.push(` ${c.cyan}Command:${c.reset} ${c.dim}${command}${c.reset}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
lines.push(` ${c.cyan}Command:${c.reset} ${c.dim}${command.slice(0, 117)}...${c.reset}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Warnings
|
|
69
|
+
if (parsed.needsClarification) {
|
|
70
|
+
lines.push("");
|
|
71
|
+
lines.push(` ${c.yellow}⚠ Clarification needed${c.reset}`);
|
|
72
|
+
if (parsed.missingFields.length > 0) {
|
|
73
|
+
lines.push(` Missing: ${parsed.missingFields.join(", ")}`);
|
|
74
|
+
}
|
|
75
|
+
for (const a of parsed.ambiguousFields) {
|
|
76
|
+
lines.push(` ${a.field}: did you mean ${a.candidates.join(" or ")}?`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return lines.join("\n");
|
|
80
|
+
}
|
|
81
|
+
function formatConfidence(conf) {
|
|
82
|
+
const pct = (conf * 100).toFixed(0);
|
|
83
|
+
if (conf >= 0.8)
|
|
84
|
+
return `${c.green}${pct}%${c.reset}`;
|
|
85
|
+
if (conf >= 0.6)
|
|
86
|
+
return `${c.yellow}${pct}%${c.reset}`;
|
|
87
|
+
return `${c.red}${pct}%${c.reset}`;
|
|
88
|
+
}
|
|
89
|
+
function previewCommand(def, fields) {
|
|
90
|
+
let cmd = def.command;
|
|
91
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
92
|
+
if (value !== undefined && value !== null) {
|
|
93
|
+
cmd = cmd.replaceAll(`{{${key}}}`, String(value));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const [name, fieldDef] of Object.entries(def.fields)) {
|
|
97
|
+
if (fieldDef.default !== undefined) {
|
|
98
|
+
cmd = cmd.replaceAll(`{{${name}}}`, String(fieldDef.default));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
cmd = cmd.replace(/\{\{[a-zA-Z_]+\}\}/g, "").trim();
|
|
102
|
+
return cmd;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format a background task notification.
|
|
106
|
+
*/
|
|
107
|
+
export function formatTaskNotification(id, name, status, duration) {
|
|
108
|
+
const icon = status === "completed" ? `${c.green}✓${c.reset}` : `${c.red}✗${c.reset}`;
|
|
109
|
+
const dur = duration ? ` (${(duration / 1000).toFixed(1)}s)` : "";
|
|
110
|
+
return `\n${icon} ${c.dim}[bg #${id}]${c.reset} ${name} ${status}${dur}`;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format the background jobs list.
|
|
114
|
+
*/
|
|
115
|
+
export function formatJobsList(tasks) {
|
|
116
|
+
if (tasks.length === 0)
|
|
117
|
+
return `${c.dim}No background tasks.${c.reset}`;
|
|
118
|
+
const lines = [];
|
|
119
|
+
lines.push(`${c.bold}Background tasks:${c.reset}`);
|
|
120
|
+
for (const t of tasks) {
|
|
121
|
+
const statusColor = t.status === "running" ? c.cyan :
|
|
122
|
+
t.status === "completed" ? c.green :
|
|
123
|
+
t.status === "failed" ? c.red :
|
|
124
|
+
c.yellow;
|
|
125
|
+
const duration = t.completedAt
|
|
126
|
+
? `${((t.completedAt.getTime() - t.startedAt.getTime()) / 1000).toFixed(1)}s`
|
|
127
|
+
: `${((Date.now() - t.startedAt.getTime()) / 1000).toFixed(0)}s...`;
|
|
128
|
+
lines.push(` ${c.dim}#${t.id}${c.reset} ${statusColor}${t.status.padEnd(10)}${c.reset} ${t.rawText} ${c.dim}(${duration})${c.reset}`);
|
|
129
|
+
}
|
|
130
|
+
return lines.join("\n");
|
|
131
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows/WSL path support.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Detecting WSL environment
|
|
6
|
+
* - Converting between Windows (C:\Users\...) and Linux (/mnt/c/Users/...) paths
|
|
7
|
+
* - Resolving ~ and %USERPROFILE% across platforms
|
|
8
|
+
* - Path normalization for cross-platform commands
|
|
9
|
+
*/
|
|
10
|
+
declare const isWSL: any;
|
|
11
|
+
declare const isWindows: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Convert a Windows path to WSL Linux path.
|
|
14
|
+
* C:\Users\dino\docs → /mnt/c/Users/dino/docs
|
|
15
|
+
*/
|
|
16
|
+
export declare function winToLinux(winPath: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Convert a WSL Linux path to Windows path.
|
|
19
|
+
* /mnt/c/Users/dino/docs → C:\Users\dino\docs
|
|
20
|
+
*/
|
|
21
|
+
export declare function linuxToWin(linuxPath: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Normalize a path for the current platform.
|
|
24
|
+
* Accepts either Windows or Linux format, returns appropriate format.
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizePath(inputPath: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Get common user directories in the correct format.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getUserDirs(): Record<string, string>;
|
|
31
|
+
export { isWSL, isWindows };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows/WSL path support.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Detecting WSL environment
|
|
6
|
+
* - Converting between Windows (C:\Users\...) and Linux (/mnt/c/Users/...) paths
|
|
7
|
+
* - Resolving ~ and %USERPROFILE% across platforms
|
|
8
|
+
* - Path normalization for cross-platform commands
|
|
9
|
+
*/
|
|
10
|
+
import { execSync } from "node:child_process";
|
|
11
|
+
import { platform as osPlatform } from "node:os";
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
const isWSL = osPlatform() === "linux" && (process.env.WSL_DISTRO_NAME !== undefined ||
|
|
14
|
+
process.env.WSLENV !== undefined ||
|
|
15
|
+
(() => { try {
|
|
16
|
+
return require("os").release().toLowerCase().includes("microsoft");
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
} })());
|
|
21
|
+
const isWindows = osPlatform() === "win32";
|
|
22
|
+
/**
|
|
23
|
+
* Convert a Windows path to WSL Linux path.
|
|
24
|
+
* C:\Users\dino\docs → /mnt/c/Users/dino/docs
|
|
25
|
+
*/
|
|
26
|
+
export function winToLinux(winPath) {
|
|
27
|
+
if (!winPath)
|
|
28
|
+
return winPath;
|
|
29
|
+
// Already a Linux path
|
|
30
|
+
if (winPath.startsWith("/"))
|
|
31
|
+
return winPath;
|
|
32
|
+
// Try wslpath if available (most reliable)
|
|
33
|
+
if (isWSL) {
|
|
34
|
+
try {
|
|
35
|
+
return execSync(`wslpath -u ${JSON.stringify(winPath)}`, { encoding: "utf-8", timeout: 3000 }).trim();
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
39
|
+
// Manual conversion: C:\Users\... → /mnt/c/Users/...
|
|
40
|
+
const match = winPath.match(/^([A-Za-z]):[\\\/](.*)/);
|
|
41
|
+
if (match) {
|
|
42
|
+
const drive = match[1].toLowerCase();
|
|
43
|
+
const rest = match[2].replace(/\\/g, "/");
|
|
44
|
+
return `/mnt/${drive}/${rest}`;
|
|
45
|
+
}
|
|
46
|
+
// UNC path: \\server\share → /mnt/server/share (approximation)
|
|
47
|
+
if (winPath.startsWith("\\\\")) {
|
|
48
|
+
return winPath.replace(/\\/g, "/").replace(/^\/\//, "/mnt/");
|
|
49
|
+
}
|
|
50
|
+
return winPath;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Convert a WSL Linux path to Windows path.
|
|
54
|
+
* /mnt/c/Users/dino/docs → C:\Users\dino\docs
|
|
55
|
+
*/
|
|
56
|
+
export function linuxToWin(linuxPath) {
|
|
57
|
+
if (!linuxPath)
|
|
58
|
+
return linuxPath;
|
|
59
|
+
// Already a Windows path
|
|
60
|
+
if (/^[A-Za-z]:/.test(linuxPath))
|
|
61
|
+
return linuxPath;
|
|
62
|
+
// Try wslpath if available
|
|
63
|
+
if (isWSL) {
|
|
64
|
+
try {
|
|
65
|
+
return execSync(`wslpath -w ${JSON.stringify(linuxPath)}`, { encoding: "utf-8", timeout: 3000 }).trim();
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
}
|
|
69
|
+
// Manual: /mnt/c/Users/... → C:\Users\...
|
|
70
|
+
const match = linuxPath.match(/^\/mnt\/([a-z])\/(.*)/);
|
|
71
|
+
if (match) {
|
|
72
|
+
const drive = match[1].toUpperCase();
|
|
73
|
+
const rest = match[2].replace(/\//g, "\\");
|
|
74
|
+
return `${drive}:\\${rest}`;
|
|
75
|
+
}
|
|
76
|
+
return linuxPath;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Normalize a path for the current platform.
|
|
80
|
+
* Accepts either Windows or Linux format, returns appropriate format.
|
|
81
|
+
*/
|
|
82
|
+
export function normalizePath(inputPath) {
|
|
83
|
+
if (!inputPath)
|
|
84
|
+
return inputPath;
|
|
85
|
+
// Expand ~ to home directory
|
|
86
|
+
if (inputPath.startsWith("~")) {
|
|
87
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
88
|
+
inputPath = resolve(home, inputPath.slice(2));
|
|
89
|
+
}
|
|
90
|
+
// Expand %USERPROFILE% (Windows env var)
|
|
91
|
+
if (inputPath.includes("%USERPROFILE%")) {
|
|
92
|
+
const profile = process.env.USERPROFILE || process.env.HOME || "";
|
|
93
|
+
inputPath = inputPath.replace(/%USERPROFILE%/gi, profile);
|
|
94
|
+
}
|
|
95
|
+
// On WSL: convert Windows paths to Linux paths
|
|
96
|
+
if (isWSL && /^[A-Za-z]:/.test(inputPath)) {
|
|
97
|
+
return winToLinux(inputPath);
|
|
98
|
+
}
|
|
99
|
+
// On Windows: convert Linux-style /mnt/c paths
|
|
100
|
+
if (isWindows && inputPath.startsWith("/mnt/")) {
|
|
101
|
+
return linuxToWin(inputPath);
|
|
102
|
+
}
|
|
103
|
+
return inputPath;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get common user directories in the correct format.
|
|
107
|
+
*/
|
|
108
|
+
export function getUserDirs() {
|
|
109
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
110
|
+
if (isWindows) {
|
|
111
|
+
const profile = process.env.USERPROFILE || "";
|
|
112
|
+
return {
|
|
113
|
+
home: profile,
|
|
114
|
+
documents: resolve(profile, "Documents"),
|
|
115
|
+
downloads: resolve(profile, "Downloads"),
|
|
116
|
+
desktop: resolve(profile, "Desktop"),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (isWSL) {
|
|
120
|
+
// In WSL, get both Linux home and Windows home
|
|
121
|
+
const winHome = tryExec("wslpath -u \"$(cmd.exe /c 'echo %USERPROFILE%' 2>/dev/null | tr -d '\\r')\"");
|
|
122
|
+
return {
|
|
123
|
+
home,
|
|
124
|
+
documents: winHome ? `${winHome}/Documents` : resolve(home, "Documents"),
|
|
125
|
+
downloads: winHome ? `${winHome}/Downloads` : resolve(home, "Downloads"),
|
|
126
|
+
desktop: winHome ? `${winHome}/Desktop` : resolve(home, "Desktop"),
|
|
127
|
+
winHome: winHome || "",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
home,
|
|
132
|
+
documents: resolve(home, "Documents"),
|
|
133
|
+
downloads: resolve(home, "Downloads"),
|
|
134
|
+
desktop: resolve(home, "Desktop"),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export { isWSL, isWindows };
|
|
138
|
+
function tryExec(cmd) {
|
|
139
|
+
try {
|
|
140
|
+
return execSync(cmd, { encoding: "utf-8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).trim() || null;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "notoken-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared engine for notoken — NLP parsing, execution, detection, analysis",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Dino Bartolome",
|
|
8
|
+
"homepage": "https://notoken.sh",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/offset25/notoken-cli",
|
|
12
|
+
"directory": "packages/core"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"files": ["dist/", "config/"],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"compromise": "^14.15.0",
|
|
26
|
+
"dotenv": "^17.3.1",
|
|
27
|
+
"simple-git": "^3.33.0",
|
|
28
|
+
"yaml": "^2.8.3",
|
|
29
|
+
"zod": "^3.22.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.0.0",
|
|
33
|
+
"typescript": "^5.3.0",
|
|
34
|
+
"vitest": "^1.6.1"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
}
|
|
39
|
+
}
|