aiden-runtime 4.1.5 → 4.5.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/README.md +250 -847
- package/dist/api/server.js +32 -5
- package/dist/cli/v4/aidenCLI.js +351 -53
- package/dist/cli/v4/callbacks.js +170 -0
- package/dist/cli/v4/chatSession.js +138 -3
- package/dist/cli/v4/commands/_runtimeToggleHelpers.js +92 -0
- package/dist/cli/v4/commands/browserDepth.js +45 -0
- package/dist/cli/v4/commands/cron.js +264 -0
- package/dist/cli/v4/commands/daemon.js +541 -0
- package/dist/cli/v4/commands/daemonStatus.js +253 -0
- package/dist/cli/v4/commands/help.js +7 -0
- package/dist/cli/v4/commands/index.js +20 -1
- package/dist/cli/v4/commands/runs.js +203 -0
- package/dist/cli/v4/commands/sandbox.js +48 -0
- package/dist/cli/v4/commands/suggestions.js +68 -0
- package/dist/cli/v4/commands/tce.js +41 -0
- package/dist/cli/v4/commands/trigger.js +378 -0
- package/dist/cli/v4/commands/update.js +95 -3
- package/dist/cli/v4/daemonAgentBuilder.js +142 -0
- package/dist/cli/v4/defaultSoul.js +1 -1
- package/dist/cli/v4/display/capabilityCard.js +26 -0
- package/dist/cli/v4/display.js +18 -8
- package/dist/cli/v4/replyRenderer.js +31 -23
- package/dist/cli/v4/updateBootPrompt.js +170 -0
- package/dist/core/playwrightBridge.js +129 -0
- package/dist/core/v4/aidenAgent.js +308 -4
- package/dist/core/v4/browserState.js +436 -0
- package/dist/core/v4/checkpoint.js +79 -0
- package/dist/core/v4/daemon/bootstrap.js +604 -0
- package/dist/core/v4/daemon/cleanShutdown.js +154 -0
- package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
- package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
- package/dist/core/v4/daemon/cron/migration.js +199 -0
- package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
- package/dist/core/v4/daemon/daemonConfig.js +90 -0
- package/dist/core/v4/daemon/db/connection.js +106 -0
- package/dist/core/v4/daemon/db/migrations.js +296 -0
- package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
- package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
- package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
- package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
- package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
- package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
- package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
- package/dist/core/v4/daemon/dispatcher/index.js +53 -0
- package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
- package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
- package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
- package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
- package/dist/core/v4/daemon/drain.js +156 -0
- package/dist/core/v4/daemon/eventLoopLag.js +73 -0
- package/dist/core/v4/daemon/health.js +159 -0
- package/dist/core/v4/daemon/idempotencyStore.js +204 -0
- package/dist/core/v4/daemon/index.js +179 -0
- package/dist/core/v4/daemon/instanceTracker.js +99 -0
- package/dist/core/v4/daemon/resourceRegistry.js +150 -0
- package/dist/core/v4/daemon/restartCode.js +32 -0
- package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
- package/dist/core/v4/daemon/runStore.js +114 -0
- package/dist/core/v4/daemon/runtimeLock.js +167 -0
- package/dist/core/v4/daemon/signals.js +50 -0
- package/dist/core/v4/daemon/supervisor.js +272 -0
- package/dist/core/v4/daemon/triggerBus.js +279 -0
- package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
- package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
- package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
- package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
- package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
- package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
- package/dist/core/v4/daemon/triggers/email/index.js +332 -0
- package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
- package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
- package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
- package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
- package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
- package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
- package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
- package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
- package/dist/core/v4/daemon/triggers/webhook.js +376 -0
- package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
- package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
- package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
- package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
- package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
- package/dist/core/v4/daemon/types.js +15 -0
- package/dist/core/v4/dockerSession.js +461 -0
- package/dist/core/v4/dryRun.js +117 -0
- package/dist/core/v4/failureClassifier.js +779 -0
- package/dist/core/v4/recoveryReport.js +449 -0
- package/dist/core/v4/runtimeToggles.js +187 -0
- package/dist/core/v4/sandboxConfig.js +285 -0
- package/dist/core/v4/sandboxFs.js +316 -0
- package/dist/core/v4/suggestionCatalog.js +41 -0
- package/dist/core/v4/suggestionEngine.js +210 -0
- package/dist/core/v4/toolRegistry.js +18 -0
- package/dist/core/v4/turnState.js +587 -0
- package/dist/core/v4/update/checkUpdate.js +63 -3
- package/dist/core/v4/update/installMethodDetect.js +115 -0
- package/dist/core/v4/update/registryClient.js +121 -0
- package/dist/core/v4/update/skipState.js +75 -0
- package/dist/core/v4/verifier.js +448 -0
- package/dist/core/version.js +1 -1
- package/dist/tools/v4/browser/_observer.js +224 -0
- package/dist/tools/v4/browser/browserBlocker.js +396 -0
- package/dist/tools/v4/browser/browserClick.js +18 -1
- package/dist/tools/v4/browser/browserClose.js +18 -1
- package/dist/tools/v4/browser/browserExtract.js +5 -1
- package/dist/tools/v4/browser/browserFill.js +17 -1
- package/dist/tools/v4/browser/browserGetUrl.js +5 -1
- package/dist/tools/v4/browser/browserNavigate.js +16 -1
- package/dist/tools/v4/browser/browserScreenshot.js +5 -1
- package/dist/tools/v4/browser/browserScroll.js +18 -1
- package/dist/tools/v4/browser/browserType.js +17 -1
- package/dist/tools/v4/browser/captchaCheck.js +5 -1
- package/dist/tools/v4/executeCode.js +1 -0
- package/dist/tools/v4/files/fileCopy.js +56 -2
- package/dist/tools/v4/files/fileDelete.js +38 -1
- package/dist/tools/v4/files/fileList.js +12 -1
- package/dist/tools/v4/files/fileMove.js +59 -2
- package/dist/tools/v4/files/filePatch.js +43 -1
- package/dist/tools/v4/files/fileRead.js +12 -1
- package/dist/tools/v4/files/fileWrite.js +41 -1
- package/dist/tools/v4/index.js +71 -58
- package/dist/tools/v4/memory/memoryAdd.js +14 -0
- package/dist/tools/v4/memory/memoryRemove.js +14 -0
- package/dist/tools/v4/memory/memoryReplace.js +15 -0
- package/dist/tools/v4/memory/sessionSummary.js +12 -0
- package/dist/tools/v4/process/processKill.js +19 -0
- package/dist/tools/v4/process/processList.js +1 -0
- package/dist/tools/v4/process/processLogRead.js +1 -0
- package/dist/tools/v4/process/processSpawn.js +13 -0
- package/dist/tools/v4/process/processWait.js +1 -0
- package/dist/tools/v4/sessions/recallSession.js +1 -0
- package/dist/tools/v4/sessions/sessionList.js +1 -0
- package/dist/tools/v4/sessions/sessionSearch.js +1 -0
- package/dist/tools/v4/skills/lookupToolSchema.js +2 -0
- package/dist/tools/v4/skills/skillManage.js +13 -0
- package/dist/tools/v4/skills/skillView.js +1 -0
- package/dist/tools/v4/skills/skillsList.js +1 -0
- package/dist/tools/v4/subagent/subagentFanout.js +1 -0
- package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
- package/dist/tools/v4/system/appClose.js +13 -0
- package/dist/tools/v4/system/appInput.js +13 -0
- package/dist/tools/v4/system/appLaunch.js +13 -0
- package/dist/tools/v4/system/clipboardRead.js +1 -0
- package/dist/tools/v4/system/clipboardWrite.js +14 -0
- package/dist/tools/v4/system/mediaKey.js +12 -0
- package/dist/tools/v4/system/mediaSessions.js +1 -0
- package/dist/tools/v4/system/mediaTransport.js +13 -0
- package/dist/tools/v4/system/naturalEvents.js +1 -0
- package/dist/tools/v4/system/nowPlaying.js +1 -0
- package/dist/tools/v4/system/osProcessList.js +1 -0
- package/dist/tools/v4/system/screenshot.js +1 -0
- package/dist/tools/v4/system/systemInfo.js +1 -0
- package/dist/tools/v4/system/volumeSet.js +17 -0
- package/dist/tools/v4/terminal/shellExec.js +81 -9
- package/dist/tools/v4/web/deepResearch.js +1 -0
- package/dist/tools/v4/web/openUrl.js +1 -0
- package/dist/tools/v4/web/webFetch.js +1 -0
- package/dist/tools/v4/web/webPage.js +1 -0
- package/dist/tools/v4/web/webSearch.js +1 -0
- package/dist/tools/v4/web/youtubeSearch.js +1 -0
- package/package.json +7 -1
|
@@ -38,12 +38,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.compareVersions = compareVersions;
|
|
41
|
+
exports.updateCacheFile = updateCacheFile;
|
|
41
42
|
exports.checkForUpdate = checkForUpdate;
|
|
42
43
|
exports.formatUpdateLine = formatUpdateLine;
|
|
43
44
|
const node_fs_1 = require("node:fs");
|
|
44
45
|
const node_path_1 = __importDefault(require("node:path"));
|
|
45
46
|
const REGISTRY_URL = 'https://registry.npmjs.org/aiden-runtime/latest';
|
|
46
|
-
|
|
47
|
+
// v4.5 update system — TTL bumped 6h → 24h per spec. The old 6h
|
|
48
|
+
// supported the firstRun loud-warn UX; the new interactive boot
|
|
49
|
+
// prompt makes the prompt itself the prominent surface, so we can
|
|
50
|
+
// relax the refresh cadence.
|
|
51
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
47
52
|
const REGISTRY_TIMEOUT_MS = 4000;
|
|
48
53
|
/** Cache file path. Co-located with other Aiden home dotfiles. */
|
|
49
54
|
function defaultCacheFile(paths) {
|
|
@@ -109,6 +114,28 @@ async function writeCache(file, cache) {
|
|
|
109
114
|
/* swallow — cache write is best-effort */
|
|
110
115
|
}
|
|
111
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* v4.5 update system — public cache writer for the skip-state +
|
|
119
|
+
* release-notes machinery. `mutate` receives the current cache
|
|
120
|
+
* (or a fresh empty shell when none exists) and returns the new
|
|
121
|
+
* cache content; this function persists. Used by:
|
|
122
|
+
*
|
|
123
|
+
* - `/update skip <v>` slash command (writes skippedVersion)
|
|
124
|
+
* - boot prompt path (writes skippedVersion on 'n')
|
|
125
|
+
* - registry probe path (writes releaseNotes / releaseUrl)
|
|
126
|
+
*
|
|
127
|
+
* Never throws — best-effort I/O.
|
|
128
|
+
*/
|
|
129
|
+
async function updateCacheFile(paths, mutate) {
|
|
130
|
+
const file = defaultCacheFile(paths);
|
|
131
|
+
const current = (await readCache(file)) ?? {
|
|
132
|
+
ts: 0,
|
|
133
|
+
latest: null,
|
|
134
|
+
installed: '',
|
|
135
|
+
};
|
|
136
|
+
const next = mutate(current);
|
|
137
|
+
await writeCache(file, next);
|
|
138
|
+
}
|
|
112
139
|
/** Default fetch wrapper with a 4-second AbortController timeout. */
|
|
113
140
|
async function defaultFetch(url) {
|
|
114
141
|
const controller = new AbortController();
|
|
@@ -152,6 +179,7 @@ async function checkForUpdate(opts) {
|
|
|
152
179
|
updateAvailable: false,
|
|
153
180
|
fromCache: false,
|
|
154
181
|
firstRun: false,
|
|
182
|
+
skipped: false,
|
|
155
183
|
};
|
|
156
184
|
}
|
|
157
185
|
const cacheFile = opts.cacheFile ?? defaultCacheFile(opts.paths);
|
|
@@ -161,12 +189,22 @@ async function checkForUpdate(opts) {
|
|
|
161
189
|
const firstRun = cached === null;
|
|
162
190
|
if (cached && now - cached.ts < ttl && cached.installed === installed) {
|
|
163
191
|
const updateAvailable = cached.latest !== null && safeCompare(cached.latest, installed) > 0;
|
|
192
|
+
// v4.5 — surface skip-state lazily so the boot prompt can decide
|
|
193
|
+
// whether to render the box at all. The compare is cheap; we
|
|
194
|
+
// avoid pulling skipState.ts module-level to keep this file's
|
|
195
|
+
// dep graph minimal.
|
|
196
|
+
const skipped = typeof cached.skippedVersion === 'string' &&
|
|
197
|
+
cached.latest !== null &&
|
|
198
|
+
safeCompare(cached.skippedVersion, cached.latest) >= 0;
|
|
164
199
|
return {
|
|
165
200
|
installed,
|
|
166
201
|
latest: cached.latest,
|
|
167
202
|
updateAvailable,
|
|
168
203
|
fromCache: true,
|
|
169
204
|
firstRun: false,
|
|
205
|
+
releaseNotes: cached.releaseNotes,
|
|
206
|
+
releaseUrl: cached.releaseUrl,
|
|
207
|
+
skipped,
|
|
170
208
|
};
|
|
171
209
|
}
|
|
172
210
|
let latest = null;
|
|
@@ -178,9 +216,31 @@ async function checkForUpdate(opts) {
|
|
|
178
216
|
catch {
|
|
179
217
|
latest = null;
|
|
180
218
|
}
|
|
181
|
-
|
|
219
|
+
// v4.5 — preserve skippedVersion + release-notes across cache
|
|
220
|
+
// refreshes. The fresh probe overwrites the {ts, latest, installed}
|
|
221
|
+
// triple; everything else carries forward from the prior cache.
|
|
222
|
+
await writeCache(cacheFile, {
|
|
223
|
+
ts: now,
|
|
224
|
+
latest,
|
|
225
|
+
installed,
|
|
226
|
+
releaseNotes: cached?.releaseNotes,
|
|
227
|
+
releaseUrl: cached?.releaseUrl,
|
|
228
|
+
skippedVersion: cached?.skippedVersion,
|
|
229
|
+
});
|
|
182
230
|
const updateAvailable = latest !== null && safeCompare(latest, installed) > 0;
|
|
183
|
-
|
|
231
|
+
const skipped = typeof cached?.skippedVersion === 'string' &&
|
|
232
|
+
latest !== null &&
|
|
233
|
+
safeCompare(cached.skippedVersion, latest) >= 0;
|
|
234
|
+
return {
|
|
235
|
+
installed,
|
|
236
|
+
latest,
|
|
237
|
+
updateAvailable,
|
|
238
|
+
fromCache: false,
|
|
239
|
+
firstRun,
|
|
240
|
+
releaseNotes: cached?.releaseNotes,
|
|
241
|
+
releaseUrl: cached?.releaseUrl,
|
|
242
|
+
skipped,
|
|
243
|
+
};
|
|
184
244
|
}
|
|
185
245
|
/** Wrap `compareVersions` so unparseable strings don't blow up the boot path. */
|
|
186
246
|
function safeCompare(a, b) {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* core/v4/update/installMethodDetect.ts — v4.5 update system.
|
|
10
|
+
*
|
|
11
|
+
* Identify how the user installed Aiden so the update path can do
|
|
12
|
+
* the right thing without false promises:
|
|
13
|
+
*
|
|
14
|
+
* npm-global — `npm install -g aiden-runtime`
|
|
15
|
+
* → run `npm install -g aiden-runtime@<v>`
|
|
16
|
+
* npm-local — local install in a project's node_modules
|
|
17
|
+
* → run `npm install aiden-runtime@<v>` in that
|
|
18
|
+
* project (printed to user; we don't dispatch
|
|
19
|
+
* a project-local install from the global path)
|
|
20
|
+
* npx — running via `npx aiden-runtime`
|
|
21
|
+
* → tell user to re-run with the new version pinned
|
|
22
|
+
* standalone-binary — packaged binary (aiden-releases artefact)
|
|
23
|
+
* → point at the GitHub releases page
|
|
24
|
+
* unknown — fallback: print the install command verbatim
|
|
25
|
+
*
|
|
26
|
+
* Pure detection logic — no I/O, no spawning. Caller dispatches.
|
|
27
|
+
*/
|
|
28
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
29
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.detectInstallMethod = detectInstallMethod;
|
|
33
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
34
|
+
const NPX_CACHE_HINT = /[/\\]_npx[/\\]/;
|
|
35
|
+
const NPM_GLOBAL_HINTS = [
|
|
36
|
+
/[/\\]npm[/\\]node_modules[/\\]aiden-runtime\b/,
|
|
37
|
+
/[/\\]npm-global[/\\]/,
|
|
38
|
+
/[/\\]\.nvm[/\\]versions[/\\]node[/\\][^/\\]+[/\\]lib[/\\]node_modules\b/,
|
|
39
|
+
/Program Files[/\\]nodejs[/\\]node_modules[/\\]aiden-runtime\b/i,
|
|
40
|
+
];
|
|
41
|
+
function inferDirs(input) {
|
|
42
|
+
return {
|
|
43
|
+
execPath: input.execPath ?? process.execPath,
|
|
44
|
+
moduleDir: input.moduleDir ?? (typeof __dirname === 'string' ? __dirname : ''),
|
|
45
|
+
argvScript: input.argvScript ?? (process.argv[1] ?? ''),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Pure detection. Order matters — npx and standalone-binary are
|
|
50
|
+
* checked first because they have distinctive path markers; npm
|
|
51
|
+
* variants are detected by their node_modules location.
|
|
52
|
+
*/
|
|
53
|
+
function detectInstallMethod(input = {}) {
|
|
54
|
+
const { moduleDir, argvScript } = inferDirs(input);
|
|
55
|
+
const platform = input.platform ?? process.platform;
|
|
56
|
+
const env = input.env ?? process.env;
|
|
57
|
+
void platform;
|
|
58
|
+
// npx — running from npm's npx cache directory.
|
|
59
|
+
if (NPX_CACHE_HINT.test(moduleDir) || NPX_CACHE_HINT.test(argvScript)) {
|
|
60
|
+
return {
|
|
61
|
+
method: 'npx',
|
|
62
|
+
inProcessInstallSupported: false,
|
|
63
|
+
description: 'running via npx (no installed copy to update)',
|
|
64
|
+
updateCommand: (v) => `npx aiden-runtime@${v} # re-run the CLI with the pinned version`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Standalone binary — env var set by the release scripts when
|
|
68
|
+
// packaging via pkg / nexe / similar. Future-proof; no current
|
|
69
|
+
// releases set it, so we don't accidentally classify a normal
|
|
70
|
+
// node install as standalone.
|
|
71
|
+
if (env.AIDEN_STANDALONE_BINARY === '1') {
|
|
72
|
+
return {
|
|
73
|
+
method: 'standalone-binary',
|
|
74
|
+
inProcessInstallSupported: false,
|
|
75
|
+
description: 'standalone binary install (not from npm)',
|
|
76
|
+
updateCommand: (_v) => 'Download the latest release from https://github.com/taracodlabs/aiden/releases',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// npm-global — moduleDir / argvScript live under a global
|
|
80
|
+
// node_modules path.
|
|
81
|
+
const haystack = `${moduleDir} ${argvScript}`;
|
|
82
|
+
if (NPM_GLOBAL_HINTS.some((rx) => rx.test(haystack))) {
|
|
83
|
+
return {
|
|
84
|
+
method: 'npm-global',
|
|
85
|
+
inProcessInstallSupported: true,
|
|
86
|
+
description: 'global npm install (aiden-runtime)',
|
|
87
|
+
updateCommand: (v) => `npm install -g aiden-runtime@${v}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// npm-local — `node_modules/aiden-runtime/` somewhere in the
|
|
91
|
+
// moduleDir's ancestry but NOT under npm/global paths above.
|
|
92
|
+
if (/[/\\]node_modules[/\\]aiden-runtime\b/.test(moduleDir) ||
|
|
93
|
+
/[/\\]node_modules[/\\]aiden-runtime\b/.test(argvScript)) {
|
|
94
|
+
// Walk up to find the project root (parent of `node_modules`).
|
|
95
|
+
const idx = moduleDir.search(/[/\\]node_modules[/\\]aiden-runtime\b/);
|
|
96
|
+
const projectRoot = idx >= 0 ? moduleDir.slice(0, idx) : '<project>';
|
|
97
|
+
return {
|
|
98
|
+
method: 'npm-local',
|
|
99
|
+
inProcessInstallSupported: false,
|
|
100
|
+
description: `local npm install in project (${node_path_1.default.basename(projectRoot)})`,
|
|
101
|
+
updateCommand: (v) => `cd ${projectRoot} && npm install aiden-runtime@${v}`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Unknown — fallback to the verbatim global-install command. The
|
|
105
|
+
// user sees it; we don't spawn. Most accurate default for a
|
|
106
|
+
// fresh `npx tsx cli/v4/aidenCLI.ts` dev-mode invocation, which
|
|
107
|
+
// is also the path the maintainer (and many CI environments)
|
|
108
|
+
// use day-to-day.
|
|
109
|
+
return {
|
|
110
|
+
method: 'unknown',
|
|
111
|
+
inProcessInstallSupported: false,
|
|
112
|
+
description: 'install method not detected (running from source?)',
|
|
113
|
+
updateCommand: (v) => `npm install -g aiden-runtime@${v} # if installed via npm, otherwise see docs`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* core/v4/update/registryClient.ts — v4.5 update system.
|
|
10
|
+
*
|
|
11
|
+
* Q-U1(c) two-source strategy:
|
|
12
|
+
*
|
|
13
|
+
* 1. npm registry — `registry.npmjs.org/aiden-runtime/latest` →
|
|
14
|
+
* `{ version, dist.tarball, _id, ... }`. No auth, fast, the
|
|
15
|
+
* authoritative source for "what's the newest published version".
|
|
16
|
+
*
|
|
17
|
+
* 2. GitHub releases — `api.github.com/repos/taracodlabs/aiden/
|
|
18
|
+
* releases/latest` → rich markdown body for the user-facing
|
|
19
|
+
* "What's new" line. Optional; falls through gracefully when
|
|
20
|
+
* anonymous-rate-limited or the repo doesn't mirror npm tags.
|
|
21
|
+
*
|
|
22
|
+
* Both fetches share a 4-second timeout per request. Network failure
|
|
23
|
+
* on either side returns null rather than throwing — the boot prompt
|
|
24
|
+
* just won't include release-notes context when we couldn't fetch it.
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.fetchUpdateInfo = fetchUpdateInfo;
|
|
28
|
+
exports.firstLineOf = firstLineOf;
|
|
29
|
+
const NPM_REGISTRY_URL = 'https://registry.npmjs.org/aiden-runtime/latest';
|
|
30
|
+
const GITHUB_RELEASES_URL = 'https://api.github.com/repos/taracodlabs/aiden/releases/latest';
|
|
31
|
+
const REGISTRY_TIMEOUT_MS = 4000;
|
|
32
|
+
/**
|
|
33
|
+
* Probe both sources in parallel. Returns whatever succeeded; either
|
|
34
|
+
* (or both) may be null on network failure.
|
|
35
|
+
*/
|
|
36
|
+
async function fetchUpdateInfo(opts = {}) {
|
|
37
|
+
const npmFetch = opts.npmFetch ?? (() => defaultNpmFetch(opts.timeoutMs));
|
|
38
|
+
const githubFetch = opts.githubFetch ?? (() => defaultGithubFetch(opts.timeoutMs));
|
|
39
|
+
const [probe, notes] = await Promise.all([
|
|
40
|
+
npmFetch().catch(() => null),
|
|
41
|
+
githubFetch().catch(() => null),
|
|
42
|
+
]);
|
|
43
|
+
return { probe, notes };
|
|
44
|
+
}
|
|
45
|
+
// ── Default fetchers ──────────────────────────────────────────────────────
|
|
46
|
+
async function defaultNpmFetch(timeoutMs = REGISTRY_TIMEOUT_MS) {
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
49
|
+
try {
|
|
50
|
+
const res = await fetch(NPM_REGISTRY_URL, {
|
|
51
|
+
headers: {
|
|
52
|
+
Accept: 'application/json',
|
|
53
|
+
'User-Agent': 'aiden-runtime update check',
|
|
54
|
+
},
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok)
|
|
58
|
+
return null;
|
|
59
|
+
const json = (await res.json());
|
|
60
|
+
if (typeof json.version !== 'string')
|
|
61
|
+
return null;
|
|
62
|
+
return {
|
|
63
|
+
version: json.version,
|
|
64
|
+
tarballUrl: typeof json.dist?.tarball === 'string' ? json.dist.tarball : undefined,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function defaultGithubFetch(timeoutMs = REGISTRY_TIMEOUT_MS) {
|
|
75
|
+
const controller = new AbortController();
|
|
76
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetch(GITHUB_RELEASES_URL, {
|
|
79
|
+
headers: {
|
|
80
|
+
Accept: 'application/vnd.github+json',
|
|
81
|
+
'User-Agent': 'aiden-runtime update check',
|
|
82
|
+
},
|
|
83
|
+
signal: controller.signal,
|
|
84
|
+
});
|
|
85
|
+
// 404 = repo doesn't expose releases yet; 403 = anonymous rate limit.
|
|
86
|
+
// Both → null + boot proceeds without notes.
|
|
87
|
+
if (!res.ok)
|
|
88
|
+
return null;
|
|
89
|
+
const json = (await res.json());
|
|
90
|
+
if (typeof json.tag_name !== 'string')
|
|
91
|
+
return null;
|
|
92
|
+
const body = typeof json.body === 'string' ? json.body : '';
|
|
93
|
+
return {
|
|
94
|
+
tag: json.tag_name,
|
|
95
|
+
url: typeof json.html_url === 'string' ? json.html_url : '',
|
|
96
|
+
blurb: firstLineOf(body, 120),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** First non-blank line of a multi-line string, truncated to maxChars. */
|
|
107
|
+
function firstLineOf(text, maxChars) {
|
|
108
|
+
if (typeof text !== 'string' || text.length === 0)
|
|
109
|
+
return '';
|
|
110
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
111
|
+
const line = raw.trim();
|
|
112
|
+
// Skip markdown heading lines (`## What's new` etc.) so the blurb
|
|
113
|
+
// is actually descriptive prose, not a section heading.
|
|
114
|
+
if (line.length === 0 || line.startsWith('#'))
|
|
115
|
+
continue;
|
|
116
|
+
if (line.length <= maxChars)
|
|
117
|
+
return line;
|
|
118
|
+
return line.slice(0, maxChars - 1) + '…';
|
|
119
|
+
}
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* core/v4/update/skipState.ts — v4.5 update system.
|
|
10
|
+
*
|
|
11
|
+
* Persistent "user said no thanks to this update" memory. Q-U7(b)
|
|
12
|
+
* semantics: a single `skippedVersion` slot meaning "stop nagging
|
|
13
|
+
* about THIS version; resume when something newer ships."
|
|
14
|
+
*
|
|
15
|
+
* Store: 4.5.1 → prompt for 4.5.1 suppressed
|
|
16
|
+
* prompt for 4.5.2 fires (4.5.2 > 4.5.1)
|
|
17
|
+
*
|
|
18
|
+
* Per-version-list (skip multiple specific versions) is v4.6
|
|
19
|
+
* polish if real usage shows people want it.
|
|
20
|
+
*
|
|
21
|
+
* Storage: piggyback on the existing `.update_check.json` cache so
|
|
22
|
+
* we don't add a second dotfile. The cache file already lives at
|
|
23
|
+
* `<aiden-home>/.update_check.json` (created by checkUpdate.ts).
|
|
24
|
+
*
|
|
25
|
+
* Pure module — every function takes the cache content as input
|
|
26
|
+
* and returns the new content. The actual disk read/write stays
|
|
27
|
+
* inside checkUpdate.ts to keep one source of truth for the cache
|
|
28
|
+
* lifecycle.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.isVersionSkipped = isVersionSkipped;
|
|
32
|
+
exports.applySkip = applySkip;
|
|
33
|
+
exports.clearSkip = clearSkip;
|
|
34
|
+
const checkUpdate_1 = require("./checkUpdate");
|
|
35
|
+
/**
|
|
36
|
+
* Is `latest` suppressed by the user's prior skip choice?
|
|
37
|
+
*
|
|
38
|
+
* skip empty → never suppress
|
|
39
|
+
* skip = latest → suppress
|
|
40
|
+
* skip < latest → don't suppress (newer version available)
|
|
41
|
+
* skip > latest → suppress (defensive — user already passed
|
|
42
|
+
* this version; treat as still-skipped)
|
|
43
|
+
*
|
|
44
|
+
* Returns false when either input is empty/unparseable — never
|
|
45
|
+
* silently swallow a "should-have-prompted".
|
|
46
|
+
*/
|
|
47
|
+
function isVersionSkipped(skippedVersion, latest) {
|
|
48
|
+
if (!skippedVersion || !latest)
|
|
49
|
+
return false;
|
|
50
|
+
try {
|
|
51
|
+
const cmp = (0, checkUpdate_1.compareVersions)(skippedVersion, latest);
|
|
52
|
+
return cmp >= 0;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Unparseable version on either side → fail safe to "not skipped"
|
|
56
|
+
// so the user gets the prompt rather than silent suppression.
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Update the cache content with a fresh skipped version. Pure —
|
|
62
|
+
* caller persists.
|
|
63
|
+
*/
|
|
64
|
+
function applySkip(cache, version) {
|
|
65
|
+
return { ...cache, skippedVersion: version };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Clear the skipped-version slot — user typed `/update auto on` or
|
|
69
|
+
* explicitly opted back in. Pure.
|
|
70
|
+
*/
|
|
71
|
+
function clearSkip(cache) {
|
|
72
|
+
const next = { ...cache };
|
|
73
|
+
delete next.skippedVersion;
|
|
74
|
+
return next;
|
|
75
|
+
}
|