@neuvybe/jarvis 0.1.1 → 0.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/index.js +25 -157
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,75 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} catch {
|
|
17
|
-
return "[unserializable meta]";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
var Logger = class {
|
|
21
|
-
level;
|
|
22
|
-
constructor(level = "info") {
|
|
23
|
-
this.level = level;
|
|
24
|
-
}
|
|
25
|
-
setLevel(level) {
|
|
26
|
-
this.level = level;
|
|
27
|
-
}
|
|
28
|
-
getLevel() {
|
|
29
|
-
return this.level;
|
|
30
|
-
}
|
|
31
|
-
debug(message, meta) {
|
|
32
|
-
this.emit("debug", message, meta);
|
|
33
|
-
}
|
|
34
|
-
info(message, meta) {
|
|
35
|
-
this.emit("info", message, meta);
|
|
36
|
-
}
|
|
37
|
-
warn(message, meta) {
|
|
38
|
-
this.emit("warn", message, meta);
|
|
39
|
-
}
|
|
40
|
-
error(message, meta) {
|
|
41
|
-
this.emit("error", message, meta);
|
|
42
|
-
}
|
|
43
|
-
emit(level, message, meta) {
|
|
44
|
-
if (ORDER[level] < ORDER[this.level])
|
|
45
|
-
return;
|
|
46
|
-
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
47
|
-
const tag = `[${ts}] ${level.toUpperCase()}`;
|
|
48
|
-
const line = meta !== void 0 ? `${tag} ${message} ${formatMeta(meta)}` : `${tag} ${message}`;
|
|
49
|
-
if (level === "error") {
|
|
50
|
-
console.error(line);
|
|
51
|
-
} else if (level === "warn") {
|
|
52
|
-
console.warn(line);
|
|
53
|
-
} else {
|
|
54
|
-
console.log(line);
|
|
2
|
+
import{readFileSync as M}from"node:fs";var v={debug:0,info:1,warn:2,error:3};function k(r){try{return JSON.stringify(r,(e,t)=>t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t)}catch{return"[unserializable meta]"}}var m=class{level;constructor(e="info"){this.level=e}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){this.emit("debug",e,t)}info(e,t){this.emit("info",e,t)}warn(e,t){this.emit("warn",e,t)}error(e,t){this.emit("error",e,t)}emit(e,t,o){if(v[e]<v[this.level])return;let a=`[${new Date().toISOString()}] ${e.toUpperCase()}`,s=o!==void 0?`${a} ${t} ${k(o)}`:`${a} ${t}`;e==="error"?console.error(s):e==="warn"?console.warn(s):console.log(s)}},n=new m;import{execSync as y,spawnSync as S}from"node:child_process";import{existsSync as $}from"node:fs";import{join as j}from"node:path";function u(r,e){let t=a=>(a.split("-")[0]??"").split(".").map(s=>Number.parseInt(s,10)||0),o=t(r),c=t(e);for(let a=0;a<Math.max(o.length,c.length);a++){let s=o[a]??0,i=c[a]??0;if(s!==i)return s>i}return!1}var p=class{constructor(e){this.currentVersion=e}currentVersion;packageName="@neuvybe/jarvis";registryTimeoutMs=3e3;safeVersion=/^[0-9A-Za-z.\-+]+$/;npmCmd(){return process.platform==="win32"?"npm.cmd":"npm"}async fetchLatest(){try{let e=await fetch(`https://registry.npmjs.org/${this.packageName}/latest`,{headers:{accept:"application/json"},signal:AbortSignal.timeout(this.registryTimeoutMs)});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}async status(){n.info(`jarvis ${this.currentVersion}`);let e=await this.fetchLatest();return e===null?n.info("could not check for updates (offline?)"):u(e,this.currentVersion)?n.info(`upgrade available: ${this.currentVersion} -> ${e} (run: jarvis upgrade)`):n.info("up to date"),0}async upgrade(){n.info("checking for updates...");let e=await this.fetchLatest();if(e===null)return n.warn("could not reach the npm registry; try again later"),1;if(!u(e,this.currentVersion))return n.info(`already on the latest version (${this.currentVersion})`),0;if(!this.safeVersion.test(e))return n.error(`refusing to install unexpected version string: ${e}`),1;n.info(`upgrading ${this.currentVersion} -> ${e}...`),await this.stopCore();let t=`${this.npmCmd()} install -g ${this.packageName}@${e}`;try{y(t,{stdio:"inherit"})}catch{return n.error(`upgrade failed; run manually: ${this.npmCmd()} install -g ${this.packageName}@latest`),1}let o=this.resolveFreshEntrypoint();return o===null?(n.info(`upgraded to ${e}. run "jarvis --version" to confirm.`),0):(n.info("verifying the freshly installed jarvis..."),S(process.execPath,[o,"--version"],{stdio:"inherit"}).status!==0?(n.warn('upgrade installed but the fresh entrypoint exited abnormally; run "jarvis --version" to confirm'),1):(n.info(`upgraded to ${e}.`),0))}async stopCore(){return n.debug("stop-core hook: no daemon in v0.1; nothing to stop (proposal 0013 fills this in)"),Promise.resolve()}resolveFreshEntrypoint(){try{let e=y(`${this.npmCmd()} root -g`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(!e)return null;let t=j(e,this.packageName,"dist","index.js");return $(t)?t:null}catch{return null}}};import{spawn as N}from"node:child_process";import{existsSync as A,readFileSync as O,writeFileSync as P}from"node:fs";import{mkdirSync as x}from"node:fs";import{homedir as C}from"node:os";import{join as w,resolve as V}from"node:path";var g=class{envOverride="JARVIS_HOME";dirName=".jarvis";dir(){let e=process.env[this.envOverride]?.trim();return e?V(e):w(C(),this.dirName)}resolve(...e){return w(this.dir(),...e)}ensureDir(){let e=this.dir();return x(e,{recursive:!0,mode:448}),e}},b=new g;var d=class{constructor(e,t=b){this.currentVersion=e;this.home=t}currentVersion;home;packageName="@neuvybe/jarvis";cacheFile="update-check.json";ttlMs=360*60*1e3;cachePath(){return this.home.resolve(this.cacheFile)}read(){let e=this.cachePath();if(!A(e))return null;try{let t=JSON.parse(O(e,"utf8"));return typeof t.lastCheckedAt=="number"&&typeof t.latestVersion=="string"?{lastCheckedAt:t.lastCheckedAt,latestVersion:t.latestVersion}:null}catch{return null}}write(e,t){let o={lastCheckedAt:t,latestVersion:e};try{this.home.ensureDir(),P(this.cachePath(),JSON.stringify(o))}catch{}}isStale(e){let t=this.read();return!t||e-t.lastCheckedAt>this.ttlMs}notice(){let e=this.read();return!e||!u(e.latestVersion,this.currentVersion)?null:L(`upgrade available: ${this.currentVersion} -> ${e.latestVersion} (run: jarvis upgrade)`)}refreshInBackground(){try{let e=this.cachePath();this.home.ensureDir();let t=`
|
|
3
|
+
import { writeFileSync } from 'node:fs';
|
|
4
|
+
try {
|
|
5
|
+
const res = await fetch('https://registry.npmjs.org/${this.packageName}/latest', {
|
|
6
|
+
headers: { accept: 'application/json' },
|
|
7
|
+
signal: AbortSignal.timeout(5000),
|
|
8
|
+
});
|
|
9
|
+
if (res.ok) {
|
|
10
|
+
const data = await res.json();
|
|
11
|
+
if (typeof data.version === 'string') {
|
|
12
|
+
writeFileSync(${JSON.stringify(e)}, JSON.stringify({
|
|
13
|
+
lastCheckedAt: Date.now(),
|
|
14
|
+
latestVersion: data.version,
|
|
15
|
+
}));
|
|
55
16
|
}
|
|
56
17
|
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// src/index.ts
|
|
61
|
-
var COMMANDS = [
|
|
62
|
-
"init",
|
|
63
|
-
"start",
|
|
64
|
-
"stop",
|
|
65
|
-
"restart",
|
|
66
|
-
"status",
|
|
67
|
-
"doctor",
|
|
68
|
-
"devices",
|
|
69
|
-
"upgrade",
|
|
70
|
-
"config"
|
|
71
|
-
];
|
|
72
|
-
var USAGE = `jarvis - voice-first personal agent
|
|
18
|
+
} catch {}
|
|
19
|
+
`;N(process.execPath,["--input-type=module","-e",t],{detached:!0,stdio:"ignore"}).unref()}catch{n.debug("background update check skipped (could not refresh cache)")}}};function L(r){return process.stdout.isTTY?`\x1B[2m${r}\x1B[0m`:r}var F=["init","start","stop","restart","status","doctor","devices","upgrade","config"],f=`jarvis - voice-first personal agent
|
|
73
20
|
|
|
74
21
|
Usage:
|
|
75
22
|
jarvis [options] Start a Jarvis session (primary activation)
|
|
@@ -80,10 +27,10 @@ Commands:
|
|
|
80
27
|
start Start the local core service
|
|
81
28
|
stop Stop the local core service
|
|
82
29
|
restart Restart the local core service
|
|
83
|
-
status Show
|
|
30
|
+
status Show version and check for updates
|
|
84
31
|
doctor Run diagnostics
|
|
85
32
|
devices List audio devices
|
|
86
|
-
upgrade Upgrade the installed CLI
|
|
33
|
+
upgrade Upgrade the installed CLI to the latest published version
|
|
87
34
|
config Inspect/edit configuration
|
|
88
35
|
|
|
89
36
|
Options:
|
|
@@ -92,92 +39,13 @@ Options:
|
|
|
92
39
|
--text, --no-voice Force text-only operation
|
|
93
40
|
-h, --help Print usage
|
|
94
41
|
-v, --version Print version
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8");
|
|
99
|
-
const parsed = JSON.parse(raw);
|
|
100
|
-
return typeof parsed.version === "string" ? parsed.version : "0.0.0";
|
|
101
|
-
} catch {
|
|
102
|
-
return "0.0.0";
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function isLogLevel(value) {
|
|
106
|
-
return value === "debug" || value === "info" || value === "warn" || value === "error";
|
|
107
|
-
}
|
|
108
|
-
var STUB_MESSAGES = {
|
|
109
|
-
init: "initializing...",
|
|
110
|
-
start: "starting...",
|
|
111
|
-
stop: "stopping...",
|
|
112
|
-
restart: "restarting...",
|
|
113
|
-
status: "status: not implemented yet",
|
|
114
|
-
doctor: "running diagnostics...",
|
|
115
|
-
devices: "listing devices...",
|
|
116
|
-
upgrade: "checking for upgrades...",
|
|
117
|
-
config: "config: not implemented yet"
|
|
118
|
-
};
|
|
119
|
-
function run(argv) {
|
|
120
|
-
let command;
|
|
121
|
-
let project;
|
|
122
|
-
let textOnly = false;
|
|
123
|
-
let wantHelp = false;
|
|
124
|
-
let wantVersion = false;
|
|
125
|
-
for (let i = 0; i < argv.length; i++) {
|
|
126
|
-
const arg = argv[i];
|
|
127
|
-
if (arg === "-h" || arg === "--help") {
|
|
128
|
-
wantHelp = true;
|
|
129
|
-
} else if (arg === "-v" || arg === "--version") {
|
|
130
|
-
wantVersion = true;
|
|
131
|
-
} else if (arg === "--text" || arg === "--no-voice") {
|
|
132
|
-
textOnly = true;
|
|
133
|
-
} else if (arg === "--log-level") {
|
|
134
|
-
const value = argv[++i];
|
|
135
|
-
if (value === void 0 || !isLogLevel(value)) {
|
|
136
|
-
process.stderr.write("error: --log-level expects one of debug|info|warn|error\n");
|
|
137
|
-
return 1;
|
|
138
|
-
}
|
|
139
|
-
logger.setLevel(value);
|
|
140
|
-
} else if (arg === "--project") {
|
|
141
|
-
const value = argv[++i];
|
|
142
|
-
if (value === void 0) {
|
|
143
|
-
process.stderr.write("error: --project expects a path\n");
|
|
144
|
-
return 1;
|
|
145
|
-
}
|
|
146
|
-
project = value;
|
|
147
|
-
} else if (arg.startsWith("-")) {
|
|
148
|
-
process.stderr.write(`error: unknown option '${arg}'
|
|
42
|
+
`;function h(){try{let r=M(new URL("../package.json",import.meta.url),"utf8"),e=JSON.parse(r);return typeof e.version=="string"?e.version:"0.0.0"}catch{return"0.0.0"}}function E(r){return r==="debug"||r==="info"||r==="warn"||r==="error"}var D={init:"initializing...",start:"starting...",stop:"stopping...",restart:"restarting...",doctor:"running diagnostics...",devices:"listing devices...",config:"config: not implemented yet"};async function J(r){let e,t,o=!1,c=!1,a=!1;for(let s=0;s<r.length;s++){let i=r[s];if(i==="-h"||i==="--help")c=!0;else if(i==="-v"||i==="--version")a=!0;else if(i==="--text"||i==="--no-voice")o=!0;else if(i==="--log-level"){let l=r[++s];if(l===void 0||!E(l))return process.stderr.write(`error: --log-level expects one of debug|info|warn|error
|
|
43
|
+
`),1;n.setLevel(l)}else if(i==="--project"){let l=r[++s];if(l===void 0)return process.stderr.write(`error: --project expects a path
|
|
44
|
+
`),1;t=l}else{if(i.startsWith("-"))return process.stderr.write(`error: unknown option '${i}'
|
|
149
45
|
|
|
150
|
-
${
|
|
151
|
-
return 1;
|
|
152
|
-
} else if (command === void 0) {
|
|
153
|
-
command = arg;
|
|
154
|
-
} else {
|
|
155
|
-
process.stderr.write(`error: unexpected argument '${arg}'
|
|
46
|
+
${f}`),1;if(e===void 0)e=i;else return process.stderr.write(`error: unexpected argument '${i}'
|
|
156
47
|
|
|
157
|
-
${
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (wantVersion) {
|
|
162
|
-
process.stdout.write(`${readVersion()}
|
|
163
|
-
`);
|
|
164
|
-
return 0;
|
|
165
|
-
}
|
|
166
|
-
if (wantHelp) {
|
|
167
|
-
process.stdout.write(USAGE);
|
|
168
|
-
return 0;
|
|
169
|
-
}
|
|
170
|
-
if (command === void 0) {
|
|
171
|
-
logger.info("activating...", { project: project ?? process.cwd(), textOnly });
|
|
172
|
-
return 0;
|
|
173
|
-
}
|
|
174
|
-
if (!COMMANDS.includes(command)) {
|
|
175
|
-
process.stderr.write(`error: unknown command '${command}'
|
|
48
|
+
${f}`),1}}if(a)return process.stdout.write(`${h()}
|
|
49
|
+
`),0;if(c)return process.stdout.write(f),0;if(e===void 0){let s=new d(h()),i=s.notice();return i!==null&&n.info(i),s.isStale(Date.now())&&s.refreshInBackground(),n.info("activating...",{project:t??process.cwd(),textOnly:o}),0}return F.includes(e)?e==="status"?new p(h()).status():e==="upgrade"?new p(h()).upgrade():(n.info(D[e]),0):(process.stderr.write(`error: unknown command '${e}'
|
|
176
50
|
|
|
177
|
-
${
|
|
178
|
-
return 1;
|
|
179
|
-
}
|
|
180
|
-
logger.info(STUB_MESSAGES[command]);
|
|
181
|
-
return 0;
|
|
182
|
-
}
|
|
183
|
-
process.exitCode = run(process.argv.slice(2));
|
|
51
|
+
${f}`),1)}try{process.exitCode=await J(process.argv.slice(2))}catch(r){n.error("jarvis failed",{error:r}),process.exitCode=1}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuvybe/jarvis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Jarvis - a voice-first personal agent (CLI).",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dev": "tsx --conditions=development --env-file-if-exists=../../.env watch src/index.ts",
|
|
29
29
|
"start": "tsx --conditions=development --env-file-if-exists=../../.env src/index.ts",
|
|
30
30
|
"build": "tsc -b",
|
|
31
|
-
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js",
|
|
31
|
+
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --minify --legal-comments=none --outfile=dist/index.js",
|
|
32
32
|
"clean": "tsc -b --clean"
|
|
33
33
|
}
|
|
34
34
|
}
|