aiden-runtime 3.16.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/LICENSE +661 -0
- package/README.md +465 -0
- package/config/devos.config.json +186 -0
- package/config/hardware.json +9 -0
- package/config/model-selection.json +7 -0
- package/config/setup-complete.json +20 -0
- package/dist/api/routes/computerUse.js +112 -0
- package/dist/api/server.js +6870 -0
- package/dist/bin/npx-init.js +71 -0
- package/dist/coordination/commandGate.js +115 -0
- package/dist/coordination/livePulse.js +127 -0
- package/dist/core/agentLoop.js +2718 -0
- package/dist/core/agentShield.js +231 -0
- package/dist/core/aidenIdentity.js +215 -0
- package/dist/core/aidenPersonality.js +166 -0
- package/dist/core/aidenSdk.js +374 -0
- package/dist/core/asyncTasks.js +82 -0
- package/dist/core/auditTrail.js +61 -0
- package/dist/core/auxiliaryClient.js +114 -0
- package/dist/core/bgLLM.js +108 -0
- package/dist/core/bm25.js +68 -0
- package/dist/core/callbackSystem.js +64 -0
- package/dist/core/channels/adapter.js +6 -0
- package/dist/core/channels/discord.js +173 -0
- package/dist/core/channels/email.js +253 -0
- package/dist/core/channels/imessage.js +164 -0
- package/dist/core/channels/manager.js +96 -0
- package/dist/core/channels/signal.js +140 -0
- package/dist/core/channels/slack.js +139 -0
- package/dist/core/channels/twilio.js +144 -0
- package/dist/core/channels/webhook.js +186 -0
- package/dist/core/channels/whatsapp.js +185 -0
- package/dist/core/clarifyBus.js +75 -0
- package/dist/core/codeInterpreter.js +82 -0
- package/dist/core/computerControl.js +439 -0
- package/dist/core/conversationMemory.js +334 -0
- package/dist/core/costTracker.js +221 -0
- package/dist/core/cronManager.js +217 -0
- package/dist/core/deepKB.js +77 -0
- package/dist/core/doctor.js +279 -0
- package/dist/core/dreamEngine.js +334 -0
- package/dist/core/entityGraph.js +169 -0
- package/dist/core/eventBus.js +16 -0
- package/dist/core/evolutionAnalyzer.js +153 -0
- package/dist/core/executionLoop.js +309 -0
- package/dist/core/executor.js +224 -0
- package/dist/core/failureAnalyzer.js +166 -0
- package/dist/core/fastPathExpansion.js +82 -0
- package/dist/core/faultEngine.js +106 -0
- package/dist/core/featureGates.js +70 -0
- package/dist/core/fileIngestion.js +113 -0
- package/dist/core/gateway.js +97 -0
- package/dist/core/goalTracker.js +75 -0
- package/dist/core/growthEngine.js +168 -0
- package/dist/core/hardwareDetector.js +98 -0
- package/dist/core/hooks.js +45 -0
- package/dist/core/httpKeepalive.js +46 -0
- package/dist/core/hybridSearch.js +101 -0
- package/dist/core/importers.js +164 -0
- package/dist/core/instinctSystem.js +223 -0
- package/dist/core/knowledgeBase.js +351 -0
- package/dist/core/learningMemory.js +121 -0
- package/dist/core/lessonsBrowser.js +125 -0
- package/dist/core/licenseManager.js +399 -0
- package/dist/core/logBuffer.js +85 -0
- package/dist/core/machineId.js +87 -0
- package/dist/core/mcpClient.js +442 -0
- package/dist/core/memoryDistiller.js +165 -0
- package/dist/core/memoryExtractor.js +212 -0
- package/dist/core/memoryIds.js +213 -0
- package/dist/core/memoryPreamble.js +113 -0
- package/dist/core/memoryQuery.js +136 -0
- package/dist/core/memoryRecall.js +140 -0
- package/dist/core/memoryStrategy.js +201 -0
- package/dist/core/messageValidator.js +85 -0
- package/dist/core/modelDiscovery.js +108 -0
- package/dist/core/modelRouter.js +118 -0
- package/dist/core/morningBriefing.js +203 -0
- package/dist/core/multiGoalValidator.js +51 -0
- package/dist/core/parallelExecutor.js +43 -0
- package/dist/core/passiveSkillObserver.js +204 -0
- package/dist/core/paths.js +57 -0
- package/dist/core/patternDetector.js +83 -0
- package/dist/core/planResponseRepair.js +64 -0
- package/dist/core/planTool.js +111 -0
- package/dist/core/playwrightBridge.js +356 -0
- package/dist/core/pluginSystem.js +121 -0
- package/dist/core/privateMode.js +85 -0
- package/dist/core/reactLoop.js +156 -0
- package/dist/core/recipeEngine.js +166 -0
- package/dist/core/responseCache.js +128 -0
- package/dist/core/runSandbox.js +132 -0
- package/dist/core/sandboxRunner.js +200 -0
- package/dist/core/scheduler.js +543 -0
- package/dist/core/secretScanner.js +49 -0
- package/dist/core/semanticMemory.js +223 -0
- package/dist/core/sessionMemory.js +259 -0
- package/dist/core/sessionRouter.js +91 -0
- package/dist/core/sessionSearch.js +163 -0
- package/dist/core/setupWizard.js +225 -0
- package/dist/core/skillImporter.js +303 -0
- package/dist/core/skillLibrary.js +144 -0
- package/dist/core/skillLoader.js +471 -0
- package/dist/core/skillTeacher.js +352 -0
- package/dist/core/skillValidator.js +210 -0
- package/dist/core/skillWriter.js +384 -0
- package/dist/core/slashAsTool.js +226 -0
- package/dist/core/spawnManager.js +197 -0
- package/dist/core/statusVerbs.js +43 -0
- package/dist/core/swarmManager.js +109 -0
- package/dist/core/taskQueue.js +119 -0
- package/dist/core/taskRecovery.js +128 -0
- package/dist/core/taskState.js +168 -0
- package/dist/core/telegramBot.js +152 -0
- package/dist/core/todoManager.js +70 -0
- package/dist/core/toolNameRepair.js +71 -0
- package/dist/core/toolRegistry.js +2730 -0
- package/dist/core/tools/calendarTool.js +98 -0
- package/dist/core/tools/companyFilingsTool.js +98 -0
- package/dist/core/tools/gmailTool.js +87 -0
- package/dist/core/tools/marketDataTool.js +135 -0
- package/dist/core/tools/socialResearchTool.js +121 -0
- package/dist/core/truthCheck.js +57 -0
- package/dist/core/updateChecker.js +74 -0
- package/dist/core/userCognitionProfile.js +238 -0
- package/dist/core/userProfile.js +341 -0
- package/dist/core/version.js +5 -0
- package/dist/core/visionAnalyze.js +161 -0
- package/dist/core/voice/audio.js +187 -0
- package/dist/core/voice/stt.js +226 -0
- package/dist/core/voice/tts.js +310 -0
- package/dist/core/voiceInput.js +118 -0
- package/dist/core/voiceOutput.js +130 -0
- package/dist/core/webSearch.js +326 -0
- package/dist/core/workflowTracker.js +72 -0
- package/dist/core/workspaceMemory.js +54 -0
- package/dist/core/youtubeTranscript.js +224 -0
- package/dist/integrations/computerUse/apiRegistry.js +113 -0
- package/dist/integrations/computerUse/screenAgent.js +203 -0
- package/dist/integrations/computerUse/visionLoop.js +296 -0
- package/dist/memory/memoryLayers.js +143 -0
- package/dist/providers/boa.js +93 -0
- package/dist/providers/cerebras.js +70 -0
- package/dist/providers/custom.js +89 -0
- package/dist/providers/gemini.js +82 -0
- package/dist/providers/groq.js +92 -0
- package/dist/providers/index.js +149 -0
- package/dist/providers/nvidia.js +70 -0
- package/dist/providers/ollama.js +99 -0
- package/dist/providers/openrouter.js +74 -0
- package/dist/providers/router.js +497 -0
- package/dist/providers/types.js +6 -0
- package/dist/security/browserVault.js +129 -0
- package/dist/security/dataGuard.js +89 -0
- package/dist/tools/eonetTool.js +72 -0
- package/dist/types/computerUse.js +2 -0
- package/dist/types/executor.js +2 -0
- package/dist-bundle/cli.js +357859 -0
- package/package.json +256 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.validateLicense = validateLicense;
|
|
11
|
+
exports.getCurrentLicense = getCurrentLicense;
|
|
12
|
+
exports.isPro = isPro;
|
|
13
|
+
exports.clearLicense = clearLicense;
|
|
14
|
+
exports.startLicenseRefresh = startLicenseRefresh;
|
|
15
|
+
exports.verifyInstall = verifyInstall;
|
|
16
|
+
exports.registerEmail = registerEmail;
|
|
17
|
+
exports.activateLicense = activateLicense;
|
|
18
|
+
exports.verifyLicense = verifyLicense;
|
|
19
|
+
exports.getLicenseStatus = getLicenseStatus;
|
|
20
|
+
exports.deactivateLicense = deactivateLicense;
|
|
21
|
+
// core/licenseManager.ts — Pro license validation + offline grace period
|
|
22
|
+
//
|
|
23
|
+
// Strategy:
|
|
24
|
+
// - validateLicense(key) — contacts the license server, caches result locally
|
|
25
|
+
// - isPro() — true if cached license is valid and not expired
|
|
26
|
+
// - 7-day offline grace — if server is unreachable, cached license works for 7 days
|
|
27
|
+
// - 12-hour background refresh — keeps the cached license fresh silently
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const paths_1 = require("./paths");
|
|
31
|
+
const https_1 = __importDefault(require("https"));
|
|
32
|
+
const machineId_1 = require("./machineId");
|
|
33
|
+
// Shared HTTPS agent for all license-server calls.
|
|
34
|
+
// Cloudflare certificates can trigger CERT_NOT_YET_VALID in Node.js's Undici
|
|
35
|
+
// due to clock-skew or cert pre-issuance timing; the cert IS valid per the OS
|
|
36
|
+
// trust store (curl passes). Scoped to license server only — other requests unaffected.
|
|
37
|
+
const licenseAgent = new https_1.default.Agent({ rejectUnauthorized: false });
|
|
38
|
+
/**
|
|
39
|
+
* Low-level HTTPS POST to the license server using Node's https module
|
|
40
|
+
* (not built-in fetch) so we can attach the custom agent.
|
|
41
|
+
*/
|
|
42
|
+
async function licensePost(urlPath, body, timeoutMs = 10000) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const data = JSON.stringify(body);
|
|
45
|
+
const base = new URL(LICENSE_SERVER);
|
|
46
|
+
const req = https_1.default.request({
|
|
47
|
+
hostname: base.hostname,
|
|
48
|
+
port: base.port ? Number(base.port) : 443,
|
|
49
|
+
path: urlPath,
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: {
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
'Content-Length': Buffer.byteLength(data),
|
|
54
|
+
},
|
|
55
|
+
agent: licenseAgent,
|
|
56
|
+
timeout: timeoutMs,
|
|
57
|
+
}, (res) => {
|
|
58
|
+
let raw = '';
|
|
59
|
+
res.on('data', (chunk) => { raw += chunk; });
|
|
60
|
+
res.on('end', () => {
|
|
61
|
+
try {
|
|
62
|
+
resolve(JSON.parse(raw));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
reject(new Error('Invalid JSON response'));
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
req.on('error', reject);
|
|
70
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
|
|
71
|
+
req.write(data);
|
|
72
|
+
req.end();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// ── Config ────────────────────────────────────────────────────
|
|
76
|
+
const LICENSE_FILE = path_1.default.join(process.cwd(), 'workspace', 'license.json');
|
|
77
|
+
const LICENSE_SERVER = 'https://api.taracod.com';
|
|
78
|
+
const DIST_SERVER = 'https://api.taracod.com';
|
|
79
|
+
const OFFLINE_GRACE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
80
|
+
const REFRESH_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours
|
|
81
|
+
const VALIDATE_TIMEOUT = 8 * 1000; // 8-second network timeout
|
|
82
|
+
// ── Defaults ──────────────────────────────────────────────────
|
|
83
|
+
const FREE_LICENSE = {
|
|
84
|
+
key: '',
|
|
85
|
+
valid: false,
|
|
86
|
+
tier: 'free',
|
|
87
|
+
email: '',
|
|
88
|
+
expiry: 0,
|
|
89
|
+
lastChecked: 0,
|
|
90
|
+
};
|
|
91
|
+
// ── File I/O ──────────────────────────────────────────────────
|
|
92
|
+
function loadCached() {
|
|
93
|
+
try {
|
|
94
|
+
if (!fs_1.default.existsSync(LICENSE_FILE))
|
|
95
|
+
return null;
|
|
96
|
+
return JSON.parse(fs_1.default.readFileSync(LICENSE_FILE, 'utf-8'));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function saveCached(data) {
|
|
103
|
+
try {
|
|
104
|
+
const dir = path_1.default.dirname(LICENSE_FILE);
|
|
105
|
+
if (!fs_1.default.existsSync(dir))
|
|
106
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
107
|
+
// NTFS-safe: write to .tmp then rename (fall back to direct write)
|
|
108
|
+
const tmp = LICENSE_FILE + '.tmp';
|
|
109
|
+
fs_1.default.writeFileSync(tmp, JSON.stringify(data, null, 2));
|
|
110
|
+
try {
|
|
111
|
+
fs_1.default.renameSync(tmp, LICENSE_FILE);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
fs_1.default.writeFileSync(LICENSE_FILE, JSON.stringify(data, null, 2));
|
|
115
|
+
try {
|
|
116
|
+
fs_1.default.unlinkSync(tmp);
|
|
117
|
+
}
|
|
118
|
+
catch { }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error('[License] Failed to save cache:', e.message);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ── Network validation ────────────────────────────────────────
|
|
126
|
+
async function fetchValidation(key) {
|
|
127
|
+
try {
|
|
128
|
+
const json = await licensePost('/validate', { key }, VALIDATE_TIMEOUT);
|
|
129
|
+
if (json.valid) {
|
|
130
|
+
return {
|
|
131
|
+
key,
|
|
132
|
+
valid: true,
|
|
133
|
+
tier: json.tier || 'pro',
|
|
134
|
+
email: json.email || '',
|
|
135
|
+
expiry: json.expiry || 0,
|
|
136
|
+
lastChecked: Date.now(),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
return {
|
|
141
|
+
...FREE_LICENSE,
|
|
142
|
+
key,
|
|
143
|
+
lastChecked: Date.now(),
|
|
144
|
+
error: json.error || 'Invalid license',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
throw new Error(e.message || 'Network error');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ── Public API ────────────────────────────────────────────────
|
|
153
|
+
/**
|
|
154
|
+
* Validate a license key against the server.
|
|
155
|
+
* Saves the result to workspace/license.json.
|
|
156
|
+
* On network failure, throws — caller handles gracefully.
|
|
157
|
+
*/
|
|
158
|
+
async function validateLicense(key) {
|
|
159
|
+
const cleanKey = key.trim().toUpperCase();
|
|
160
|
+
if (!/^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$/.test(cleanKey)) {
|
|
161
|
+
return { ...FREE_LICENSE, key: cleanKey, error: 'Invalid key format (expected XXXXX-XXXXX-XXXXX-XXXXX)' };
|
|
162
|
+
}
|
|
163
|
+
const result = await fetchValidation(cleanKey);
|
|
164
|
+
saveCached(result);
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Return the current license from cache.
|
|
169
|
+
* Does NOT make a network request.
|
|
170
|
+
*/
|
|
171
|
+
function getCurrentLicense() {
|
|
172
|
+
return loadCached() || { ...FREE_LICENSE };
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Returns true if the user has a valid, non-expired Pro license.
|
|
176
|
+
* Respects 7-day offline grace period if server is unreachable.
|
|
177
|
+
*/
|
|
178
|
+
function isPro() {
|
|
179
|
+
const cached = loadCached();
|
|
180
|
+
if (!cached || !cached.valid || cached.tier !== 'pro')
|
|
181
|
+
return false;
|
|
182
|
+
// Check expiry (0 = lifetime)
|
|
183
|
+
if (cached.expiry !== 0 && Date.now() > cached.expiry)
|
|
184
|
+
return false;
|
|
185
|
+
// Check if last server validation was within the grace period
|
|
186
|
+
const age = Date.now() - (cached.lastChecked || 0);
|
|
187
|
+
if (age > OFFLINE_GRACE_MS) {
|
|
188
|
+
console.log('[License] Grace period exceeded — license needs re-validation');
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Clear the cached license (user logs out of Pro).
|
|
195
|
+
*/
|
|
196
|
+
function clearLicense() {
|
|
197
|
+
try {
|
|
198
|
+
if (fs_1.default.existsSync(LICENSE_FILE)) {
|
|
199
|
+
fs_1.default.unlinkSync(LICENSE_FILE);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (e) {
|
|
203
|
+
console.error('[License] Failed to clear cache:', e.message);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Start a background 12-hour license refresh.
|
|
208
|
+
* Call once on server startup — silently keeps the cache fresh.
|
|
209
|
+
*/
|
|
210
|
+
function startLicenseRefresh() {
|
|
211
|
+
const refresh = async () => {
|
|
212
|
+
const cached = loadCached();
|
|
213
|
+
if (!cached || !cached.key || !cached.valid)
|
|
214
|
+
return; // nothing to refresh
|
|
215
|
+
try {
|
|
216
|
+
const updated = await fetchValidation(cached.key);
|
|
217
|
+
saveCached(updated);
|
|
218
|
+
if (!updated.valid) {
|
|
219
|
+
console.log('[License] Background refresh: license no longer valid');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Network failure — offline grace handles it, no log spam needed
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
// Initial refresh 30 seconds after boot (avoids blocking startup)
|
|
227
|
+
setTimeout(refresh, 30 * 1000);
|
|
228
|
+
// Then every 12 hours
|
|
229
|
+
setInterval(refresh, REFRESH_INTERVAL);
|
|
230
|
+
}
|
|
231
|
+
// ── Sprint 20: Distribution control + machine binding ─────────
|
|
232
|
+
/**
|
|
233
|
+
* Verify that this email+machine combination is allowed to run.
|
|
234
|
+
* Called on startup. On network failure, allows (offline users not blocked).
|
|
235
|
+
*/
|
|
236
|
+
async function verifyInstall(email) {
|
|
237
|
+
try {
|
|
238
|
+
const machineId = (0, machineId_1.getMachineId)();
|
|
239
|
+
const data = await licensePost('/verify-install', { email, machineId }, 8000);
|
|
240
|
+
return { allowed: data.allowed === true, reason: data.reason };
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// Network failure — don't block offline users
|
|
244
|
+
return { allowed: true };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Register an email address for early access.
|
|
249
|
+
* Returns a human-readable message to display to the user.
|
|
250
|
+
*/
|
|
251
|
+
async function registerEmail(email) {
|
|
252
|
+
try {
|
|
253
|
+
const data = await licensePost('/register', { email }, 8000);
|
|
254
|
+
return {
|
|
255
|
+
success: true,
|
|
256
|
+
message: data.message || 'Check your email for the download link',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
260
|
+
return { success: false, message: e.message };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// ══════════════════════════════════════════════════════════════
|
|
264
|
+
// Pro License System (AIDEN-PRO-xxxxxx-xxxxxx-xxxxxx format)
|
|
265
|
+
// Uses api.taracod.com endpoints: /license/activate, /verify, /deactivate
|
|
266
|
+
// Cache stored at %APPDATA%/devos-ai/license.json (separate from old cache)
|
|
267
|
+
// ══════════════════════════════════════════════════════════════
|
|
268
|
+
const PRO_LICENSE_FILE = path_1.default.join((0, paths_1.getUserDataDir)(), 'license.json');
|
|
269
|
+
const PRO_CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours
|
|
270
|
+
const API_BASE = LICENSE_SERVER; // already 'https://api.taracod.com'
|
|
271
|
+
// ── Cache I/O ─────────────────────────────────────────────────
|
|
272
|
+
function loadProCache() {
|
|
273
|
+
try {
|
|
274
|
+
if (fs_1.default.existsSync(PRO_LICENSE_FILE)) {
|
|
275
|
+
return JSON.parse(fs_1.default.readFileSync(PRO_LICENSE_FILE, 'utf-8'));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch { }
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
function saveProCache(cache) {
|
|
282
|
+
try {
|
|
283
|
+
const dir = path_1.default.dirname(PRO_LICENSE_FILE);
|
|
284
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
285
|
+
const tmp = PRO_LICENSE_FILE + '.tmp';
|
|
286
|
+
fs_1.default.writeFileSync(tmp, JSON.stringify(cache, null, 2));
|
|
287
|
+
try {
|
|
288
|
+
fs_1.default.renameSync(tmp, PRO_LICENSE_FILE);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
fs_1.default.writeFileSync(PRO_LICENSE_FILE, JSON.stringify(cache, null, 2));
|
|
292
|
+
try {
|
|
293
|
+
fs_1.default.unlinkSync(tmp);
|
|
294
|
+
}
|
|
295
|
+
catch { }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch (e) {
|
|
299
|
+
console.error('[License] Failed to save Pro cache:', e.message);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// ── Public Pro API ────────────────────────────────────────────
|
|
303
|
+
/**
|
|
304
|
+
* Activate a Pro license key on this machine.
|
|
305
|
+
* Stores the result in %APPDATA%/devos-ai/license.json.
|
|
306
|
+
*/
|
|
307
|
+
async function activateLicense(key) {
|
|
308
|
+
const machineId = (0, machineId_1.getMachineId)();
|
|
309
|
+
const machineName = (0, machineId_1.getMachineName)();
|
|
310
|
+
try {
|
|
311
|
+
const data = await licensePost('/license/activate', { key, machineId, machineName });
|
|
312
|
+
if (data.activated) {
|
|
313
|
+
saveProCache({
|
|
314
|
+
key,
|
|
315
|
+
valid: true,
|
|
316
|
+
plan: data.plan || 'pro_monthly',
|
|
317
|
+
expiresAt: data.expiresAt || '',
|
|
318
|
+
features: data.features || {},
|
|
319
|
+
lastVerified: Date.now(),
|
|
320
|
+
});
|
|
321
|
+
return { success: true, plan: data.plan };
|
|
322
|
+
}
|
|
323
|
+
return { success: false, error: data.error || 'Activation failed' };
|
|
324
|
+
}
|
|
325
|
+
catch (e) {
|
|
326
|
+
return { success: false, error: `Network error: ${e.message}` };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Verify the current Pro license against the server (24-hour cache).
|
|
331
|
+
* Falls back to cached data when offline if license has not expired.
|
|
332
|
+
*/
|
|
333
|
+
async function verifyLicense() {
|
|
334
|
+
const cache = loadProCache();
|
|
335
|
+
if (!cache?.key)
|
|
336
|
+
return { isPro: false };
|
|
337
|
+
// Serve from cache if verified within 24 hours
|
|
338
|
+
if (cache.valid && Date.now() - cache.lastVerified < PRO_CACHE_DURATION) {
|
|
339
|
+
return { isPro: true, plan: cache.plan, features: cache.features, expiresAt: cache.expiresAt };
|
|
340
|
+
}
|
|
341
|
+
// Re-verify with server
|
|
342
|
+
try {
|
|
343
|
+
const machineId = (0, machineId_1.getMachineId)();
|
|
344
|
+
const data = await licensePost('/license/verify', { key: cache.key, machineId });
|
|
345
|
+
cache.valid = data.valid;
|
|
346
|
+
cache.lastVerified = Date.now();
|
|
347
|
+
if (data.valid) {
|
|
348
|
+
cache.plan = data.plan || cache.plan;
|
|
349
|
+
cache.features = data.features || cache.features;
|
|
350
|
+
cache.expiresAt = data.expiresAt || cache.expiresAt;
|
|
351
|
+
}
|
|
352
|
+
saveProCache(cache);
|
|
353
|
+
return data.valid
|
|
354
|
+
? { isPro: true, plan: cache.plan, features: cache.features, expiresAt: cache.expiresAt }
|
|
355
|
+
: { isPro: false };
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// Offline — trust cache if license has not expired
|
|
359
|
+
if (cache.valid && cache.expiresAt && new Date(cache.expiresAt) > new Date()) {
|
|
360
|
+
return { isPro: true, plan: cache.plan, features: cache.features, expiresAt: cache.expiresAt };
|
|
361
|
+
}
|
|
362
|
+
return { isPro: false };
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Synchronous status check from cache only — no network request.
|
|
367
|
+
*/
|
|
368
|
+
function getLicenseStatus() {
|
|
369
|
+
const cache = loadProCache();
|
|
370
|
+
if (!cache?.valid)
|
|
371
|
+
return { isPro: false };
|
|
372
|
+
if (cache.expiresAt && new Date(cache.expiresAt) < new Date())
|
|
373
|
+
return { isPro: false };
|
|
374
|
+
return { isPro: true, plan: cache.plan, expiresAt: cache.expiresAt, features: cache.features };
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Deactivate this machine from the Pro license.
|
|
378
|
+
* Removes the local cache file on success.
|
|
379
|
+
*/
|
|
380
|
+
async function deactivateLicense() {
|
|
381
|
+
const cache = loadProCache();
|
|
382
|
+
if (!cache?.key)
|
|
383
|
+
return false;
|
|
384
|
+
const machineId = (0, machineId_1.getMachineId)();
|
|
385
|
+
try {
|
|
386
|
+
const data = await licensePost('/license/deactivate', { key: cache.key, machineId });
|
|
387
|
+
if (data.deactivated) {
|
|
388
|
+
try {
|
|
389
|
+
fs_1.default.unlinkSync(PRO_LICENSE_FILE);
|
|
390
|
+
}
|
|
391
|
+
catch { }
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.logBuffer = exports.LogBuffer = void 0;
|
|
8
|
+
// ── LogBuffer class ────────────────────────────────────────────
|
|
9
|
+
class LogBuffer {
|
|
10
|
+
constructor(maxSize = 500) {
|
|
11
|
+
this.entries = [];
|
|
12
|
+
this.maxSize = maxSize;
|
|
13
|
+
}
|
|
14
|
+
add(entry) {
|
|
15
|
+
this.entries.push(entry);
|
|
16
|
+
if (this.entries.length > this.maxSize) {
|
|
17
|
+
this.entries.shift(); // drop oldest
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Return the most-recent `n` entries (default: all). */
|
|
21
|
+
getRecent(n) {
|
|
22
|
+
if (n === undefined || n >= this.entries.length)
|
|
23
|
+
return [...this.entries];
|
|
24
|
+
return this.entries.slice(this.entries.length - n);
|
|
25
|
+
}
|
|
26
|
+
clear() {
|
|
27
|
+
this.entries = [];
|
|
28
|
+
}
|
|
29
|
+
get size() {
|
|
30
|
+
return this.entries.length;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.LogBuffer = LogBuffer;
|
|
34
|
+
// ── Singleton ─────────────────────────────────────────────────
|
|
35
|
+
exports.logBuffer = new LogBuffer(500);
|
|
36
|
+
// ── Console.log interception ──────────────────────────────────
|
|
37
|
+
// Patches console.log / warn / error so every call is also
|
|
38
|
+
// stored in logBuffer. The original method is still called.
|
|
39
|
+
//
|
|
40
|
+
// Format recognised: "[Tag] rest of message"
|
|
41
|
+
// Anything matching that pattern has its Tag extracted as the
|
|
42
|
+
// `source`. All other messages use source "System".
|
|
43
|
+
const _TAG_RE = /^\[([^\]]{1,30})\]\s*/;
|
|
44
|
+
function extractSource(msg) {
|
|
45
|
+
const m = msg.match(_TAG_RE);
|
|
46
|
+
if (m)
|
|
47
|
+
return { source: m[1], message: msg.slice(m[0].length) };
|
|
48
|
+
return { source: 'System', message: msg };
|
|
49
|
+
}
|
|
50
|
+
function classifyLevel(consoleMethod, msg) {
|
|
51
|
+
if (consoleMethod === 'error')
|
|
52
|
+
return 'error';
|
|
53
|
+
if (consoleMethod === 'warn')
|
|
54
|
+
return 'warn';
|
|
55
|
+
const lower = msg.toLowerCase();
|
|
56
|
+
if (lower.includes('error') || lower.includes('fail'))
|
|
57
|
+
return 'error';
|
|
58
|
+
if (lower.includes('warn'))
|
|
59
|
+
return 'warn';
|
|
60
|
+
if (lower.includes('debug') || lower.includes('trace'))
|
|
61
|
+
return 'debug';
|
|
62
|
+
return 'info';
|
|
63
|
+
}
|
|
64
|
+
function intercept(method) {
|
|
65
|
+
const original = console[method].bind(console);
|
|
66
|
+
console[method] = (...args) => {
|
|
67
|
+
original(...args); // always pass through
|
|
68
|
+
try {
|
|
69
|
+
const raw = args.map(a => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ');
|
|
70
|
+
const { source, message } = extractSource(raw);
|
|
71
|
+
exports.logBuffer.add({
|
|
72
|
+
timestamp: new Date().toISOString(),
|
|
73
|
+
level: classifyLevel(method, raw),
|
|
74
|
+
source,
|
|
75
|
+
message,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// never let buffer errors crash the process
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
intercept('log');
|
|
84
|
+
intercept('warn');
|
|
85
|
+
intercept('error');
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.getMachineId = getMachineId;
|
|
11
|
+
exports.getMachineName = getMachineName;
|
|
12
|
+
// core/machineId.ts — Hardware-bound machine identifier
|
|
13
|
+
//
|
|
14
|
+
// Derives a stable, anonymised ID from multiple hardware identifiers
|
|
15
|
+
// (CPU, disk, baseboard, OS serial) via wmic with PowerShell fallback.
|
|
16
|
+
// All values are one-way hashed — raw hardware IDs never leave the machine.
|
|
17
|
+
//
|
|
18
|
+
// Strategy:
|
|
19
|
+
// 1. Try wmic for each hardware value (fast, widely available)
|
|
20
|
+
// 2. Fall back to PowerShell CimInstance if wmic is missing/disabled (Win 11)
|
|
21
|
+
// 3. Final fallback: hostname + username hash (cross-platform)
|
|
22
|
+
const child_process_1 = require("child_process");
|
|
23
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
24
|
+
const os_1 = __importDefault(require("os"));
|
|
25
|
+
// ── Internal helpers ──────────────────────────────────────────
|
|
26
|
+
function tryWmic(query) {
|
|
27
|
+
try {
|
|
28
|
+
const out = (0, child_process_1.execSync)(`wmic ${query} /value`, {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
timeout: 3000,
|
|
31
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
32
|
+
});
|
|
33
|
+
const match = out.match(/=([^\r\n]+)/);
|
|
34
|
+
const val = match?.[1]?.trim() || '';
|
|
35
|
+
return val === 'To Be Filled By O.E.M.' ? '' : val;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function tryPowerShell(expression) {
|
|
42
|
+
try {
|
|
43
|
+
const out = (0, child_process_1.execSync)(`powershell -NoProfile -NonInteractive -Command "${expression}"`, { encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
44
|
+
const val = out.trim();
|
|
45
|
+
return val === 'To Be Filled By O.E.M.' ? '' : val;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Try wmic first; fall back to PowerShell if wmic returns nothing. */
|
|
52
|
+
function getHardwareValue(wmicQuery, psExpression) {
|
|
53
|
+
const v = tryWmic(wmicQuery);
|
|
54
|
+
if (v)
|
|
55
|
+
return v;
|
|
56
|
+
return tryPowerShell(psExpression);
|
|
57
|
+
}
|
|
58
|
+
// ── Public API ────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Returns a stable, anonymised 20-char machine ID (prefix: mch_).
|
|
61
|
+
* Derived from CPU + disk + baseboard + OS serial — all SHA-256 hashed.
|
|
62
|
+
*/
|
|
63
|
+
function getMachineId() {
|
|
64
|
+
try {
|
|
65
|
+
const cpuId = getHardwareValue('cpu get ProcessorId', '(Get-CimInstance Win32_Processor | Select-Object -First 1).ProcessorId');
|
|
66
|
+
const diskId = getHardwareValue('diskdrive get SerialNumber', '(Get-CimInstance Win32_DiskDrive | Select-Object -First 1).SerialNumber');
|
|
67
|
+
const boardId = getHardwareValue('baseboard get SerialNumber', '(Get-CimInstance Win32_BaseBoard).SerialNumber');
|
|
68
|
+
const winId = getHardwareValue('os get SerialNumber', '(Get-CimInstance Win32_OperatingSystem).SerialNumber');
|
|
69
|
+
const combined = `${cpuId}|${diskId}|${boardId}|${winId}`;
|
|
70
|
+
// If we got at least one real hardware value, use it
|
|
71
|
+
if (combined !== '|||') {
|
|
72
|
+
return 'mch_' + crypto_1.default.createHash('sha256').update(combined).digest('hex').slice(0, 16);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// fall through to fallback
|
|
77
|
+
}
|
|
78
|
+
// Fallback: hostname + username (cross-platform, Linux/macOS safe)
|
|
79
|
+
const fallback = `${os_1.default.hostname()}-${os_1.default.userInfo().username}`;
|
|
80
|
+
return 'mch_' + crypto_1.default.createHash('sha256').update(fallback).digest('hex').slice(0, 16);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Returns the human-readable machine name (COMPUTERNAME env var or os.hostname()).
|
|
84
|
+
*/
|
|
85
|
+
function getMachineName() {
|
|
86
|
+
return process.env.COMPUTERNAME || os_1.default.hostname();
|
|
87
|
+
}
|