@aria_asi/cli 0.2.3 → 0.2.5
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/bin/aria.js +28 -1
- package/dist/aria-connector/src/onboarding-wizard.d.ts.map +1 -1
- package/dist/aria-connector/src/onboarding-wizard.js +15 -26
- package/dist/aria-connector/src/onboarding-wizard.js.map +1 -1
- package/dist/aria-connector/src/self-update.d.ts +22 -0
- package/dist/aria-connector/src/self-update.d.ts.map +1 -0
- package/dist/aria-connector/src/self-update.js +162 -0
- package/dist/aria-connector/src/self-update.js.map +1 -0
- package/package.json +1 -1
- package/src/onboarding-wizard.ts +15 -27
- package/src/self-update.ts +169 -0
package/bin/aria.js
CHANGED
|
@@ -8,6 +8,16 @@ import { AriaChat } from '../dist/aria-connector/src/chat.js';
|
|
|
8
8
|
import { checkHarnessHealth } from '../dist/aria-connector/src/harness-client.js';
|
|
9
9
|
import { login, status, logout, revoke } from '../dist/aria-connector/src/auth-commands.js';
|
|
10
10
|
import { installHooks } from '../dist/aria-connector/src/install-hooks.js';
|
|
11
|
+
import { maybePrintUpdateNotice, checkForUpdate } from '../dist/aria-connector/src/self-update.js';
|
|
12
|
+
|
|
13
|
+
// ── Self-update notice (non-blocking, rate-limited once per 24h) ──
|
|
14
|
+
// Fires-and-forgets — the registry check runs in parallel with command
|
|
15
|
+
// dispatch and prints a one-line notice on stderr if newer version available.
|
|
16
|
+
// Hamza 2026-04-26: continuous overnight improvement reaches clients via
|
|
17
|
+
// this primitive. Kill-switch: ARIA_SELF_UPDATE=off env.
|
|
18
|
+
if (process.env.ARIA_SELF_UPDATE !== 'off') {
|
|
19
|
+
maybePrintUpdateNotice().catch(() => {});
|
|
20
|
+
}
|
|
11
21
|
|
|
12
22
|
// ── Auth + install subcommands — handled BEFORE the chat flow.
|
|
13
23
|
// Hamza 2026-04-26: license-aware CLI for client-tonight ship +
|
|
@@ -16,7 +26,24 @@ import { installHooks } from '../dist/aria-connector/src/install-hooks.js';
|
|
|
16
26
|
const command = process.argv[2];
|
|
17
27
|
const args = process.argv.slice(3);
|
|
18
28
|
|
|
19
|
-
if (command === '
|
|
29
|
+
if (command === 'check-update') {
|
|
30
|
+
// Force a check + print result, bypassing the 24h rate limit
|
|
31
|
+
checkForUpdate({ force: true }).then((result) => {
|
|
32
|
+
if (!result.ok) {
|
|
33
|
+
console.error(`I couldn't check for updates: ${result.reason}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
if (result.updateAvailable) {
|
|
37
|
+
console.log(` ${result.message}`);
|
|
38
|
+
} else {
|
|
39
|
+
console.log(` You're on the latest version (${result.current}). Nothing to do.`);
|
|
40
|
+
}
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}).catch((err) => {
|
|
43
|
+
console.error(`I hit an unexpected error checking for updates: ${err && err.message ? err.message : err}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
46
|
+
} else if (command === 'install-hooks') {
|
|
20
47
|
const force = args.includes('--force');
|
|
21
48
|
const harnessUrlIdx = args.indexOf('--harness-url');
|
|
22
49
|
const harnessUrl = harnessUrlIdx >= 0 && args[harnessUrlIdx + 1] ? args[harnessUrlIdx + 1] : undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-wizard.d.ts","sourceRoot":"","sources":["../../../src/onboarding-wizard.ts"],"names":[],"mappings":"AAoEA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"onboarding-wizard.d.ts","sourceRoot":"","sources":["../../../src/onboarding-wizard.ts"],"names":[],"mappings":"AAoEA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA8HpF"}
|
|
@@ -71,28 +71,11 @@ export async function runOnboardingWizard() {
|
|
|
71
71
|
console.log(" That doesn't look like a valid email. Try again.");
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
// ── Step 2:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
console.log(" Tenant name needs to be lowercase letters/digits/hyphens, 2-41 chars.");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// ── Step 3: tier ──
|
|
83
|
-
let tier = 'free';
|
|
84
|
-
let tierAnswer = '';
|
|
85
|
-
while (!['free', 'pro', 'enterprise', ''].includes(tierAnswer)) {
|
|
86
|
-
tierAnswer = (await prompt(rl, ' Tier [free / pro / enterprise] (default: free): ')).toLowerCase();
|
|
87
|
-
if (tierAnswer === '')
|
|
88
|
-
tierAnswer = 'free';
|
|
89
|
-
if (!['free', 'pro', 'enterprise'].includes(tierAnswer)) {
|
|
90
|
-
console.log(" I only know free, pro, or enterprise.");
|
|
91
|
-
tierAnswer = '';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
tier = tierAnswer;
|
|
95
|
-
// ── Step 4: LLM provider ──
|
|
74
|
+
// ── Step 2: LLM provider ──
|
|
75
|
+
// tenant_id is auto-generated server-side from email domain + random
|
|
76
|
+
// suffix; no client prompt needed. tier defaults to 'pro' per
|
|
77
|
+
// current pricing policy (Hamza 2026-04-26: "set any new memory for
|
|
78
|
+
// now to pro"). Both moved out of the wizard for minimal-friction UX.
|
|
96
79
|
const providerOptions = ['anthropic', 'openai', 'deepseek', 'google', 'openrouter', 'ollama'];
|
|
97
80
|
let provider = '';
|
|
98
81
|
while (!providerOptions.includes(provider)) {
|
|
@@ -125,7 +108,9 @@ export async function runOnboardingWizard() {
|
|
|
125
108
|
const resp = await fetch(`${HARNESS_URL}/api/onboarding/self-issue`, {
|
|
126
109
|
method: 'POST',
|
|
127
110
|
headers: { 'Content-Type': 'application/json' },
|
|
128
|
-
|
|
111
|
+
// tenant_id omitted — server auto-generates from email domain.
|
|
112
|
+
// tier omitted — server defaults to 'pro'.
|
|
113
|
+
body: JSON.stringify({ email, provider, llm_key: llmKey }),
|
|
129
114
|
});
|
|
130
115
|
response = await resp.json();
|
|
131
116
|
if (!resp.ok || !response.ok || !response.license) {
|
|
@@ -141,13 +126,16 @@ export async function runOnboardingWizard() {
|
|
|
141
126
|
// ── Step 7: persist license ──
|
|
142
127
|
if (!existsSync(ARIA_DIR))
|
|
143
128
|
mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
129
|
+
// tenant_id is whatever the server auto-generated (or what the caller
|
|
130
|
+
// passed). Read it back from the license claims.
|
|
131
|
+
const serverTenantId = response.claims?.tenant_id ?? response.license.jti;
|
|
144
132
|
const licenseRecord = {
|
|
145
133
|
...response.claims,
|
|
146
134
|
harnessToken: response.license.token,
|
|
147
135
|
jti: response.license.jti,
|
|
148
136
|
tier: response.license.tier,
|
|
149
137
|
exp: response.claims?.exp,
|
|
150
|
-
sub: response.claims?.sub ??
|
|
138
|
+
sub: response.claims?.sub ?? serverTenantId,
|
|
151
139
|
email,
|
|
152
140
|
issuedAt: new Date().toISOString(),
|
|
153
141
|
};
|
|
@@ -158,7 +146,7 @@ export async function runOnboardingWizard() {
|
|
|
158
146
|
const validatedProvider = provider;
|
|
159
147
|
const configRecord = {
|
|
160
148
|
model: { provider: validatedProvider, model: defaultModelFor(validatedProvider), apiKey: llmKey },
|
|
161
|
-
tenantId,
|
|
149
|
+
tenantId: serverTenantId,
|
|
162
150
|
email,
|
|
163
151
|
};
|
|
164
152
|
writeFileSync(CONFIG_PATH, JSON.stringify(configRecord, null, 2) + '\n', { mode: 0o600 });
|
|
@@ -175,7 +163,8 @@ export async function runOnboardingWizard() {
|
|
|
175
163
|
}
|
|
176
164
|
rl.close();
|
|
177
165
|
console.log('');
|
|
178
|
-
console.log(` You're set up. License jti: ${response.license.jti}, tier: ${tier}, provider: ${provider}.`);
|
|
166
|
+
console.log(` You're set up. License jti: ${response.license.jti}, tier: ${response.license.tier}, provider: ${provider}.`);
|
|
167
|
+
console.log(` Your tenant id is: ${serverTenantId}`);
|
|
179
168
|
console.log(" Open a fresh Claude Code session — every Bash, Edit, Write, and Stop event now runs through my cognition gates.");
|
|
180
169
|
console.log(" Or talk to me directly: just type 'aria' again.");
|
|
181
170
|
console.log('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-wizard.js","sourceRoot":"","sources":["../../../src/onboarding-wizard.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"onboarding-wizard.js","sourceRoot":"","sources":["../../../src/onboarding-wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface UpdateCheckResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
current?: string;
|
|
4
|
+
latest?: string;
|
|
5
|
+
updateAvailable?: boolean;
|
|
6
|
+
message?: string;
|
|
7
|
+
reason?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Check the registry for the latest @aria_asi/cli version. Rate-limited
|
|
11
|
+
* to once per CHECK_INTERVAL_MS (24h) via a timestamp file in ~/.aria.
|
|
12
|
+
* Caller can pass force=true to bypass the rate limit (used by `aria check-update`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function checkForUpdate(opts?: {
|
|
15
|
+
force?: boolean;
|
|
16
|
+
}): Promise<UpdateCheckResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Convenience: check + print the notice if available. Non-blocking, silent
|
|
19
|
+
* on errors. Called from bin/aria.js on startup.
|
|
20
|
+
*/
|
|
21
|
+
export declare function maybePrintUpdateNotice(): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=self-update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-update.d.ts","sourceRoot":"","sources":["../../../src/self-update.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiDD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqD/F;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ5D"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// self-update — checks the npm registry for newer @aria_asi/cli versions
|
|
2
|
+
// and surfaces a one-line notice. Doesn't auto-install (clients control
|
|
3
|
+
// their tooling); just informs.
|
|
4
|
+
//
|
|
5
|
+
// Direction: Hamza 2026-04-26 — "does the package auto update when we
|
|
6
|
+
// enhance it on our enhance? so we can continually improve all night using
|
|
7
|
+
// arias background work we should imrpove to do that once we finish".
|
|
8
|
+
// This is the primitive that closes the overnight-improvement loop:
|
|
9
|
+
// Aria publishes 0.2.5 / 0.3.0 / etc.; clients see the notice on their
|
|
10
|
+
// next `aria <cmd>` invocation; they upgrade with one command.
|
|
11
|
+
//
|
|
12
|
+
// Doctrine bindings:
|
|
13
|
+
// - feedback_no_demos.md — real overnight evolution, real registry check
|
|
14
|
+
// - feedback_no_timeouts_doctrine.md — fetch with no AbortSignal.timeout;
|
|
15
|
+
// use bare try/catch, real-error-driven backpressure
|
|
16
|
+
// - project_phase_10_endless_army_orchestration.md — continuous shipping
|
|
17
|
+
// is the Phase 10 north star; self-update is its delivery mechanism
|
|
18
|
+
//
|
|
19
|
+
// Behavior:
|
|
20
|
+
// - Reads installed version from package.json (resolved via import.meta.url
|
|
21
|
+
// walk to find the package root)
|
|
22
|
+
// - Reads ~/.aria/last-update-check timestamp; if checked <24h ago, skip
|
|
23
|
+
// - GET registry.npmjs.org/@aria_asi/cli for latest dist-tag
|
|
24
|
+
// - semver-compare; if newer, return {updateAvailable: true, latest, current, message}
|
|
25
|
+
// - Write timestamp on every check (success or skip-due-to-rate-limit)
|
|
26
|
+
// - Failures are silent (network down, registry blip — never block CLI startup)
|
|
27
|
+
//
|
|
28
|
+
// Privacy: the request to npmjs only sends User-Agent (npm registry public).
|
|
29
|
+
// No client identity, no telemetry beyond what the public registry already logs.
|
|
30
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
31
|
+
import { homedir } from 'node:os';
|
|
32
|
+
import { join, dirname } from 'node:path';
|
|
33
|
+
import { fileURLToPath } from 'node:url';
|
|
34
|
+
const ARIA_DIR = join(homedir(), '.aria');
|
|
35
|
+
const LAST_CHECK_PATH = join(ARIA_DIR, 'last-update-check');
|
|
36
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
37
|
+
const REGISTRY_URL = 'https://registry.npmjs.org/@aria_asi%2Fcli';
|
|
38
|
+
/**
|
|
39
|
+
* Find the package's own version by walking up from this file's runtime
|
|
40
|
+
* path until we hit the package.json with name @aria_asi/cli.
|
|
41
|
+
*/
|
|
42
|
+
function findInstalledVersion() {
|
|
43
|
+
try {
|
|
44
|
+
const here = fileURLToPath(import.meta.url);
|
|
45
|
+
let cur = dirname(here);
|
|
46
|
+
for (let i = 0; i < 8; i++) {
|
|
47
|
+
const pkgPath = join(cur, 'package.json');
|
|
48
|
+
if (existsSync(pkgPath)) {
|
|
49
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
50
|
+
if (pkg.name === '@aria_asi/cli' && typeof pkg.version === 'string') {
|
|
51
|
+
return pkg.version;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const parent = dirname(cur);
|
|
55
|
+
if (parent === cur)
|
|
56
|
+
break;
|
|
57
|
+
cur = parent;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch { /* fall through */ }
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Compare semver strings — returns 1 if a>b, -1 if a<b, 0 if equal.
|
|
65
|
+
* Pre-release suffixes (e.g. 0.2.4-beta) sort lower than the same base.
|
|
66
|
+
*/
|
|
67
|
+
function compareSemver(a, b) {
|
|
68
|
+
const parse = (s) => {
|
|
69
|
+
const [main, ...preParts] = s.split('-');
|
|
70
|
+
const nums = main.split('.').map((n) => parseInt(n, 10));
|
|
71
|
+
while (nums.length < 3)
|
|
72
|
+
nums.push(0);
|
|
73
|
+
return { nums, pre: preParts.join('-') };
|
|
74
|
+
};
|
|
75
|
+
const pa = parse(a);
|
|
76
|
+
const pb = parse(b);
|
|
77
|
+
for (let i = 0; i < 3; i++) {
|
|
78
|
+
if (pa.nums[i] > pb.nums[i])
|
|
79
|
+
return 1;
|
|
80
|
+
if (pa.nums[i] < pb.nums[i])
|
|
81
|
+
return -1;
|
|
82
|
+
}
|
|
83
|
+
// Equal numerics — pre-release sorts before release
|
|
84
|
+
if (pa.pre && !pb.pre)
|
|
85
|
+
return -1;
|
|
86
|
+
if (!pa.pre && pb.pre)
|
|
87
|
+
return 1;
|
|
88
|
+
return pa.pre.localeCompare(pb.pre);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check the registry for the latest @aria_asi/cli version. Rate-limited
|
|
92
|
+
* to once per CHECK_INTERVAL_MS (24h) via a timestamp file in ~/.aria.
|
|
93
|
+
* Caller can pass force=true to bypass the rate limit (used by `aria check-update`).
|
|
94
|
+
*/
|
|
95
|
+
export async function checkForUpdate(opts = {}) {
|
|
96
|
+
const current = findInstalledVersion();
|
|
97
|
+
if (!current) {
|
|
98
|
+
return { ok: false, reason: 'could not resolve installed version' };
|
|
99
|
+
}
|
|
100
|
+
// Rate-limit check
|
|
101
|
+
if (!opts.force && existsSync(LAST_CHECK_PATH)) {
|
|
102
|
+
try {
|
|
103
|
+
const ts = parseInt(readFileSync(LAST_CHECK_PATH, 'utf-8').trim(), 10);
|
|
104
|
+
if (!isNaN(ts) && Date.now() - ts < CHECK_INTERVAL_MS) {
|
|
105
|
+
return { ok: true, current, reason: 'rate-limited (checked within last 24h)' };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch { /* malformed timestamp — re-check */ }
|
|
109
|
+
}
|
|
110
|
+
// Fetch registry
|
|
111
|
+
let latest;
|
|
112
|
+
try {
|
|
113
|
+
const resp = await fetch(REGISTRY_URL, {
|
|
114
|
+
headers: { 'Accept': 'application/json' },
|
|
115
|
+
});
|
|
116
|
+
if (!resp.ok) {
|
|
117
|
+
// Don't update timestamp on failure — retry next invocation
|
|
118
|
+
return { ok: false, current, reason: `registry returned ${resp.status}` };
|
|
119
|
+
}
|
|
120
|
+
const data = await resp.json();
|
|
121
|
+
latest = data['dist-tags']?.latest ?? '';
|
|
122
|
+
if (!latest) {
|
|
123
|
+
return { ok: false, current, reason: 'registry response missing dist-tags.latest' };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
return { ok: false, current, reason: `network error: ${err.message}` };
|
|
128
|
+
}
|
|
129
|
+
// Update timestamp on successful check
|
|
130
|
+
try {
|
|
131
|
+
if (!existsSync(ARIA_DIR))
|
|
132
|
+
mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
133
|
+
writeFileSync(LAST_CHECK_PATH, String(Date.now()) + '\n', { mode: 0o600 });
|
|
134
|
+
}
|
|
135
|
+
catch { /* timestamp write is best-effort */ }
|
|
136
|
+
const cmp = compareSemver(latest, current);
|
|
137
|
+
if (cmp <= 0) {
|
|
138
|
+
return { ok: true, current, latest, updateAvailable: false };
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
ok: true,
|
|
142
|
+
current,
|
|
143
|
+
latest,
|
|
144
|
+
updateAvailable: true,
|
|
145
|
+
message: `I have an update: v${latest} (you're on v${current}). Run 'npm update -g @aria_asi/cli' when you have a minute.`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Convenience: check + print the notice if available. Non-blocking, silent
|
|
150
|
+
* on errors. Called from bin/aria.js on startup.
|
|
151
|
+
*/
|
|
152
|
+
export async function maybePrintUpdateNotice() {
|
|
153
|
+
try {
|
|
154
|
+
const result = await checkForUpdate();
|
|
155
|
+
if (result.ok && result.updateAvailable && result.message) {
|
|
156
|
+
// Print to stderr so it doesn't pollute stdout-piped CLI output
|
|
157
|
+
process.stderr.write(` ${result.message}\n`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch { /* never block startup */ }
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=self-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../../src/self-update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/onboarding-wizard.ts
CHANGED
|
@@ -89,29 +89,11 @@ export async function runOnboardingWizard(): Promise<{ ok: boolean; error?: stri
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
// ── Step 2:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
console.log(" Tenant name needs to be lowercase letters/digits/hyphens, 2-41 chars.");
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// ── Step 3: tier ──
|
|
102
|
-
let tier: Tier = 'free';
|
|
103
|
-
let tierAnswer = '';
|
|
104
|
-
while (!['free', 'pro', 'enterprise', ''].includes(tierAnswer)) {
|
|
105
|
-
tierAnswer = (await prompt(rl, ' Tier [free / pro / enterprise] (default: free): ')).toLowerCase();
|
|
106
|
-
if (tierAnswer === '') tierAnswer = 'free';
|
|
107
|
-
if (!['free', 'pro', 'enterprise'].includes(tierAnswer)) {
|
|
108
|
-
console.log(" I only know free, pro, or enterprise.");
|
|
109
|
-
tierAnswer = '';
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
tier = tierAnswer as Tier;
|
|
113
|
-
|
|
114
|
-
// ── Step 4: LLM provider ──
|
|
92
|
+
// ── Step 2: LLM provider ──
|
|
93
|
+
// tenant_id is auto-generated server-side from email domain + random
|
|
94
|
+
// suffix; no client prompt needed. tier defaults to 'pro' per
|
|
95
|
+
// current pricing policy (Hamza 2026-04-26: "set any new memory for
|
|
96
|
+
// now to pro"). Both moved out of the wizard for minimal-friction UX.
|
|
115
97
|
const providerOptions: Provider[] = ['anthropic', 'openai', 'deepseek', 'google', 'openrouter', 'ollama'];
|
|
116
98
|
let provider: Provider | '' = '';
|
|
117
99
|
while (!providerOptions.includes(provider as Provider)) {
|
|
@@ -143,7 +125,9 @@ export async function runOnboardingWizard(): Promise<{ ok: boolean; error?: stri
|
|
|
143
125
|
const resp = await fetch(`${HARNESS_URL}/api/onboarding/self-issue`, {
|
|
144
126
|
method: 'POST',
|
|
145
127
|
headers: { 'Content-Type': 'application/json' },
|
|
146
|
-
|
|
128
|
+
// tenant_id omitted — server auto-generates from email domain.
|
|
129
|
+
// tier omitted — server defaults to 'pro'.
|
|
130
|
+
body: JSON.stringify({ email, provider, llm_key: llmKey }),
|
|
147
131
|
});
|
|
148
132
|
response = await resp.json() as SelfIssueResponse;
|
|
149
133
|
if (!resp.ok || !response.ok || !response.license) {
|
|
@@ -158,13 +142,16 @@ export async function runOnboardingWizard(): Promise<{ ok: boolean; error?: stri
|
|
|
158
142
|
|
|
159
143
|
// ── Step 7: persist license ──
|
|
160
144
|
if (!existsSync(ARIA_DIR)) mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
145
|
+
// tenant_id is whatever the server auto-generated (or what the caller
|
|
146
|
+
// passed). Read it back from the license claims.
|
|
147
|
+
const serverTenantId = (response.claims?.tenant_id as string | undefined) ?? response.license.jti;
|
|
161
148
|
const licenseRecord = {
|
|
162
149
|
...response.claims,
|
|
163
150
|
harnessToken: response.license.token,
|
|
164
151
|
jti: response.license.jti,
|
|
165
152
|
tier: response.license.tier,
|
|
166
153
|
exp: response.claims?.exp,
|
|
167
|
-
sub: response.claims?.sub ??
|
|
154
|
+
sub: response.claims?.sub ?? serverTenantId,
|
|
168
155
|
email,
|
|
169
156
|
issuedAt: new Date().toISOString(),
|
|
170
157
|
};
|
|
@@ -176,7 +163,7 @@ export async function runOnboardingWizard(): Promise<{ ok: boolean; error?: stri
|
|
|
176
163
|
const validatedProvider = provider as Provider;
|
|
177
164
|
const configRecord = {
|
|
178
165
|
model: { provider: validatedProvider, model: defaultModelFor(validatedProvider), apiKey: llmKey },
|
|
179
|
-
tenantId,
|
|
166
|
+
tenantId: serverTenantId,
|
|
180
167
|
email,
|
|
181
168
|
};
|
|
182
169
|
writeFileSync(CONFIG_PATH, JSON.stringify(configRecord, null, 2) + '\n', { mode: 0o600 });
|
|
@@ -195,7 +182,8 @@ export async function runOnboardingWizard(): Promise<{ ok: boolean; error?: stri
|
|
|
195
182
|
rl.close();
|
|
196
183
|
|
|
197
184
|
console.log('');
|
|
198
|
-
console.log(` You're set up. License jti: ${response.license.jti}, tier: ${tier}, provider: ${provider}.`);
|
|
185
|
+
console.log(` You're set up. License jti: ${response.license.jti}, tier: ${response.license.tier}, provider: ${provider}.`);
|
|
186
|
+
console.log(` Your tenant id is: ${serverTenantId}`);
|
|
199
187
|
console.log(" Open a fresh Claude Code session — every Bash, Edit, Write, and Stop event now runs through my cognition gates.");
|
|
200
188
|
console.log(" Or talk to me directly: just type 'aria' again.");
|
|
201
189
|
console.log('');
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// self-update — checks the npm registry for newer @aria_asi/cli versions
|
|
2
|
+
// and surfaces a one-line notice. Doesn't auto-install (clients control
|
|
3
|
+
// their tooling); just informs.
|
|
4
|
+
//
|
|
5
|
+
// Direction: Hamza 2026-04-26 — "does the package auto update when we
|
|
6
|
+
// enhance it on our enhance? so we can continually improve all night using
|
|
7
|
+
// arias background work we should imrpove to do that once we finish".
|
|
8
|
+
// This is the primitive that closes the overnight-improvement loop:
|
|
9
|
+
// Aria publishes 0.2.5 / 0.3.0 / etc.; clients see the notice on their
|
|
10
|
+
// next `aria <cmd>` invocation; they upgrade with one command.
|
|
11
|
+
//
|
|
12
|
+
// Doctrine bindings:
|
|
13
|
+
// - feedback_no_demos.md — real overnight evolution, real registry check
|
|
14
|
+
// - feedback_no_timeouts_doctrine.md — fetch with no AbortSignal.timeout;
|
|
15
|
+
// use bare try/catch, real-error-driven backpressure
|
|
16
|
+
// - project_phase_10_endless_army_orchestration.md — continuous shipping
|
|
17
|
+
// is the Phase 10 north star; self-update is its delivery mechanism
|
|
18
|
+
//
|
|
19
|
+
// Behavior:
|
|
20
|
+
// - Reads installed version from package.json (resolved via import.meta.url
|
|
21
|
+
// walk to find the package root)
|
|
22
|
+
// - Reads ~/.aria/last-update-check timestamp; if checked <24h ago, skip
|
|
23
|
+
// - GET registry.npmjs.org/@aria_asi/cli for latest dist-tag
|
|
24
|
+
// - semver-compare; if newer, return {updateAvailable: true, latest, current, message}
|
|
25
|
+
// - Write timestamp on every check (success or skip-due-to-rate-limit)
|
|
26
|
+
// - Failures are silent (network down, registry blip — never block CLI startup)
|
|
27
|
+
//
|
|
28
|
+
// Privacy: the request to npmjs only sends User-Agent (npm registry public).
|
|
29
|
+
// No client identity, no telemetry beyond what the public registry already logs.
|
|
30
|
+
|
|
31
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
32
|
+
import { homedir } from 'node:os';
|
|
33
|
+
import { join, dirname, resolve } from 'node:path';
|
|
34
|
+
import { fileURLToPath } from 'node:url';
|
|
35
|
+
|
|
36
|
+
const ARIA_DIR = join(homedir(), '.aria');
|
|
37
|
+
const LAST_CHECK_PATH = join(ARIA_DIR, 'last-update-check');
|
|
38
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
39
|
+
const REGISTRY_URL = 'https://registry.npmjs.org/@aria_asi%2Fcli';
|
|
40
|
+
|
|
41
|
+
export interface UpdateCheckResult {
|
|
42
|
+
ok: boolean;
|
|
43
|
+
current?: string;
|
|
44
|
+
latest?: string;
|
|
45
|
+
updateAvailable?: boolean;
|
|
46
|
+
message?: string;
|
|
47
|
+
reason?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Find the package's own version by walking up from this file's runtime
|
|
52
|
+
* path until we hit the package.json with name @aria_asi/cli.
|
|
53
|
+
*/
|
|
54
|
+
function findInstalledVersion(): string | null {
|
|
55
|
+
try {
|
|
56
|
+
const here = fileURLToPath(import.meta.url);
|
|
57
|
+
let cur = dirname(here);
|
|
58
|
+
for (let i = 0; i < 8; i++) {
|
|
59
|
+
const pkgPath = join(cur, 'package.json');
|
|
60
|
+
if (existsSync(pkgPath)) {
|
|
61
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
62
|
+
if (pkg.name === '@aria_asi/cli' && typeof pkg.version === 'string') {
|
|
63
|
+
return pkg.version;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const parent = dirname(cur);
|
|
67
|
+
if (parent === cur) break;
|
|
68
|
+
cur = parent;
|
|
69
|
+
}
|
|
70
|
+
} catch {/* fall through */}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Compare semver strings — returns 1 if a>b, -1 if a<b, 0 if equal.
|
|
76
|
+
* Pre-release suffixes (e.g. 0.2.4-beta) sort lower than the same base.
|
|
77
|
+
*/
|
|
78
|
+
function compareSemver(a: string, b: string): number {
|
|
79
|
+
const parse = (s: string): { nums: number[]; pre: string } => {
|
|
80
|
+
const [main, ...preParts] = s.split('-');
|
|
81
|
+
const nums = main.split('.').map((n) => parseInt(n, 10));
|
|
82
|
+
while (nums.length < 3) nums.push(0);
|
|
83
|
+
return { nums, pre: preParts.join('-') };
|
|
84
|
+
};
|
|
85
|
+
const pa = parse(a);
|
|
86
|
+
const pb = parse(b);
|
|
87
|
+
for (let i = 0; i < 3; i++) {
|
|
88
|
+
if (pa.nums[i] > pb.nums[i]) return 1;
|
|
89
|
+
if (pa.nums[i] < pb.nums[i]) return -1;
|
|
90
|
+
}
|
|
91
|
+
// Equal numerics — pre-release sorts before release
|
|
92
|
+
if (pa.pre && !pb.pre) return -1;
|
|
93
|
+
if (!pa.pre && pb.pre) return 1;
|
|
94
|
+
return pa.pre.localeCompare(pb.pre);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Check the registry for the latest @aria_asi/cli version. Rate-limited
|
|
99
|
+
* to once per CHECK_INTERVAL_MS (24h) via a timestamp file in ~/.aria.
|
|
100
|
+
* Caller can pass force=true to bypass the rate limit (used by `aria check-update`).
|
|
101
|
+
*/
|
|
102
|
+
export async function checkForUpdate(opts: { force?: boolean } = {}): Promise<UpdateCheckResult> {
|
|
103
|
+
const current = findInstalledVersion();
|
|
104
|
+
if (!current) {
|
|
105
|
+
return { ok: false, reason: 'could not resolve installed version' };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Rate-limit check
|
|
109
|
+
if (!opts.force && existsSync(LAST_CHECK_PATH)) {
|
|
110
|
+
try {
|
|
111
|
+
const ts = parseInt(readFileSync(LAST_CHECK_PATH, 'utf-8').trim(), 10);
|
|
112
|
+
if (!isNaN(ts) && Date.now() - ts < CHECK_INTERVAL_MS) {
|
|
113
|
+
return { ok: true, current, reason: 'rate-limited (checked within last 24h)' };
|
|
114
|
+
}
|
|
115
|
+
} catch {/* malformed timestamp — re-check */}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Fetch registry
|
|
119
|
+
let latest: string;
|
|
120
|
+
try {
|
|
121
|
+
const resp = await fetch(REGISTRY_URL, {
|
|
122
|
+
headers: { 'Accept': 'application/json' },
|
|
123
|
+
});
|
|
124
|
+
if (!resp.ok) {
|
|
125
|
+
// Don't update timestamp on failure — retry next invocation
|
|
126
|
+
return { ok: false, current, reason: `registry returned ${resp.status}` };
|
|
127
|
+
}
|
|
128
|
+
const data = await resp.json() as { 'dist-tags'?: Record<string, string> };
|
|
129
|
+
latest = data['dist-tags']?.latest ?? '';
|
|
130
|
+
if (!latest) {
|
|
131
|
+
return { ok: false, current, reason: 'registry response missing dist-tags.latest' };
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
return { ok: false, current, reason: `network error: ${(err as Error).message}` };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Update timestamp on successful check
|
|
138
|
+
try {
|
|
139
|
+
if (!existsSync(ARIA_DIR)) mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
140
|
+
writeFileSync(LAST_CHECK_PATH, String(Date.now()) + '\n', { mode: 0o600 });
|
|
141
|
+
} catch {/* timestamp write is best-effort */}
|
|
142
|
+
|
|
143
|
+
const cmp = compareSemver(latest, current);
|
|
144
|
+
if (cmp <= 0) {
|
|
145
|
+
return { ok: true, current, latest, updateAvailable: false };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
ok: true,
|
|
150
|
+
current,
|
|
151
|
+
latest,
|
|
152
|
+
updateAvailable: true,
|
|
153
|
+
message: `I have an update: v${latest} (you're on v${current}). Run 'npm update -g @aria_asi/cli' when you have a minute.`,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Convenience: check + print the notice if available. Non-blocking, silent
|
|
159
|
+
* on errors. Called from bin/aria.js on startup.
|
|
160
|
+
*/
|
|
161
|
+
export async function maybePrintUpdateNotice(): Promise<void> {
|
|
162
|
+
try {
|
|
163
|
+
const result = await checkForUpdate();
|
|
164
|
+
if (result.ok && result.updateAvailable && result.message) {
|
|
165
|
+
// Print to stderr so it doesn't pollute stdout-piped CLI output
|
|
166
|
+
process.stderr.write(` ${result.message}\n`);
|
|
167
|
+
}
|
|
168
|
+
} catch {/* never block startup */}
|
|
169
|
+
}
|