uneven-ai 1.0.4 → 1.0.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/CHANGELOG.md +8 -0
- package/dist/cli/commands/init.js +2 -2
- package/dist/domain/entities/session.js +1 -1
- package/dist/domain/services/index-planner.d.ts.map +1 -1
- package/dist/domain/services/index-planner.js +1 -0
- package/dist/infrastructure/utils/config-loader.d.ts +7 -4
- package/dist/infrastructure/utils/config-loader.d.ts.map +1 -1
- package/dist/infrastructure/utils/config-loader.js +227 -4
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/uneven_core.node +0 -0
- package/prebuilds/linux-arm64/uneven_core.node +0 -0
- package/prebuilds/linux-x64/uneven_core.node +0 -0
- package/prebuilds/win32-x64/uneven_core.node +0 -0
- package/scripts/postinstall.cjs +1 -1
- package/prebuilds/darwin-x64/uneven_core.node +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@ All notable changes to Uneven AI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.5] - 2026-04-16
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **config**: `uneven.config.ts` changes now applied automatically on every command — no longer requires manual edit of `.uneven/config.json` or re-running `uneven init`
|
|
13
|
+
- **init**: default Gemini model changed from `gemini-2.0-flash` to `gemini-2.5-flash`
|
|
14
|
+
- **index-planner**: added `gemini-2.5-flash` pricing entry to cost estimation table
|
|
15
|
+
|
|
8
16
|
## [1.0.4] - 2026-04-16
|
|
9
17
|
|
|
10
18
|
### Fixed
|
|
@@ -48,9 +48,9 @@ function defaultModelFor(provider) {
|
|
|
48
48
|
ollama: 'llama3.2',
|
|
49
49
|
claude: 'claude-sonnet-4-6',
|
|
50
50
|
openai: 'gpt-4o-mini',
|
|
51
|
-
gemini: 'gemini-2.
|
|
51
|
+
gemini: 'gemini-2.5-flash',
|
|
52
52
|
};
|
|
53
|
-
return MAP[provider] ?? 'gemini-2.
|
|
53
|
+
return MAP[provider] ?? 'gemini-2.5-flash';
|
|
54
54
|
}
|
|
55
55
|
function makeConfig(provider, threads, gpuLayers) {
|
|
56
56
|
const model = defaultModelFor(provider);
|
|
@@ -11,7 +11,7 @@ import * as path from 'path';
|
|
|
11
11
|
import * as crypto from 'crypto';
|
|
12
12
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
13
13
|
const SESSION_FILE = '.uneven/session.json';
|
|
14
|
-
const UNEVEN_VERSION = '1.0.
|
|
14
|
+
const UNEVEN_VERSION = '1.0.5';
|
|
15
15
|
const STALE_THRESHOLD_MS = 60 * 60 * 1000; // 1 hour
|
|
16
16
|
const LOCK_TIMEOUT_MS = 30_000; // 30 seconds
|
|
17
17
|
const LOCK_DEBOUNCE_MS = 1_500; // 1.5 seconds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-planner.d.ts","sourceRoot":"","sources":["../../../src/domain/services/index-planner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"index-planner.d.ts","sourceRoot":"","sources":["../../../src/domain/services/index-planner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AA+C1D,eAAO,MAAM,sBAAsB,QAAkB,CAAA;AACrD,eAAO,MAAM,eAAe,QAA0B,CAAA;AAItD,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAO,MAAM,CAAA;IACrB,SAAS,EAAM,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,OAAO,EAAQ,OAAO,CAAA;IACtB,mEAAmE;IACnE,UAAU,EAAK,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAW,QAAQ,EAAE,CAAA;IAC1B,UAAU,EAAM,MAAM,CAAA;IACtB,UAAU,EAAM,QAAQ,EAAE,CAAA;IAC1B,aAAa,EAAG,QAAQ,EAAE,CAAA;IAC1B,WAAW,EAAK,MAAM,CAAA;IACtB,WAAW,EAAK,MAAM,CAAA;IACtB,2CAA2C;IAC3C,aAAa,EAAG,MAAM,CAAA;IACtB,qDAAqD;IACrD,YAAY,EAAI,MAAM,CAAA;IACtB,QAAQ,EAAQ,MAAM,CAAA;IACtB,KAAK,EAAW,MAAM,CAAA;IACtB,MAAM,EAAU,OAAO,CAAA;CACxB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAQ;gBAEhB,YAAY,SAAyB;IAIjD;;;OAGG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;YA4BzD,QAAQ;IAqBtB,OAAO,CAAC,WAAW;CAepB;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM7C"}
|
|
@@ -31,6 +31,7 @@ const COST_TABLE = [
|
|
|
31
31
|
{ provider: 'claude', modelPrefix: '*', usdPer1k: 0.003 },
|
|
32
32
|
// Gemini (Google)
|
|
33
33
|
{ provider: 'gemini', modelPrefix: 'text-embedding-004', usdPer1k: 0.000025 },
|
|
34
|
+
{ provider: 'gemini', modelPrefix: 'gemini-2.5-flash', usdPer1k: 0.000075 },
|
|
34
35
|
{ provider: 'gemini', modelPrefix: 'gemini-2.0-flash', usdPer1k: 0.000075 },
|
|
35
36
|
{ provider: 'gemini', modelPrefix: 'gemini-1.5-flash', usdPer1k: 0.000075 },
|
|
36
37
|
{ provider: 'gemini', modelPrefix: 'gemini-1.5-pro', usdPer1k: 0.00125 },
|
|
@@ -4,14 +4,17 @@
|
|
|
4
4
|
* Reads .uneven/config.json, written by `uneven init`.
|
|
5
5
|
* Falls back to safe defaults when the file is missing.
|
|
6
6
|
*
|
|
7
|
-
* Note: uneven.config.ts is the human-readable source of truth
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Note: uneven.config.ts is the human-readable source of truth. On every
|
|
8
|
+
* loadConfig() call the loader parses uneven.config.ts (if present) and
|
|
9
|
+
* syncs any changes into config.json — so edits to the TS file are always
|
|
10
|
+
* picked up without having to re-run `uneven init`.
|
|
10
11
|
*/
|
|
11
12
|
import type { UnevenConfig } from '../../../types/index.js';
|
|
12
13
|
/**
|
|
13
14
|
* Load Uneven config from .uneven/config.json.
|
|
14
|
-
*
|
|
15
|
+
* Automatically syncs uneven.config.ts → config.json first, so any edits
|
|
16
|
+
* to the TS file are reflected without re-running `uneven init`.
|
|
17
|
+
* Falls back to defaults if neither file exists (e.g. before `uneven init`).
|
|
15
18
|
*/
|
|
16
19
|
export declare function loadConfig(overrides?: Partial<UnevenConfig>): Promise<UnevenConfig>;
|
|
17
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/utils/config-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/utils/config-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAkO3D;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CA8BzF;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlE"}
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
* Reads .uneven/config.json, written by `uneven init`.
|
|
5
5
|
* Falls back to safe defaults when the file is missing.
|
|
6
6
|
*
|
|
7
|
-
* Note: uneven.config.ts is the human-readable source of truth
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Note: uneven.config.ts is the human-readable source of truth. On every
|
|
8
|
+
* loadConfig() call the loader parses uneven.config.ts (if present) and
|
|
9
|
+
* syncs any changes into config.json — so edits to the TS file are always
|
|
10
|
+
* picked up without having to re-run `uneven init`.
|
|
10
11
|
*/
|
|
11
12
|
import * as fs from 'fs/promises';
|
|
12
13
|
const CONFIG_FILE = '.uneven/config.json';
|
|
14
|
+
const TS_CONFIG_FILE = 'uneven.config.ts';
|
|
13
15
|
const DEFAULTS = {
|
|
14
16
|
brain: {
|
|
15
17
|
provider: 'local',
|
|
@@ -26,11 +28,232 @@ const DEFAULTS = {
|
|
|
26
28
|
watch: { terminal: 'npm run dev', autoFix: true, confirmBeforeFix: false, dirs: ['./src'] },
|
|
27
29
|
log: { path: './.uneven/log.md' },
|
|
28
30
|
};
|
|
31
|
+
// ─── uneven.config.ts parser ─────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Extract the body of a named object section from TypeScript source.
|
|
34
|
+
* Handles nested braces and quoted strings correctly.
|
|
35
|
+
* Returns null if the key is not found.
|
|
36
|
+
*/
|
|
37
|
+
function extractSection(src, key) {
|
|
38
|
+
const re = new RegExp(`\\b${key}\\s*:\\s*\\{`);
|
|
39
|
+
const m = re.exec(src);
|
|
40
|
+
if (!m)
|
|
41
|
+
return null;
|
|
42
|
+
let depth = 0;
|
|
43
|
+
let start = -1;
|
|
44
|
+
let inStr = false;
|
|
45
|
+
let strChar = '';
|
|
46
|
+
for (let i = m.index + m[0].length - 1; i < src.length; i++) {
|
|
47
|
+
const ch = src[i];
|
|
48
|
+
if (inStr) {
|
|
49
|
+
if (ch === strChar && src[i - 1] !== '\\')
|
|
50
|
+
inStr = false;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
54
|
+
inStr = true;
|
|
55
|
+
strChar = ch;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ch === '{') {
|
|
59
|
+
if (depth === 0)
|
|
60
|
+
start = i + 1;
|
|
61
|
+
depth++;
|
|
62
|
+
}
|
|
63
|
+
else if (ch === '}') {
|
|
64
|
+
depth--;
|
|
65
|
+
if (depth === 0)
|
|
66
|
+
return src.slice(start, i);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function strVal(section, key) {
|
|
72
|
+
const m = section.match(new RegExp(`\\b${key}\\s*:\\s*['"\`]([^'"\`]+)['"\`]`));
|
|
73
|
+
return m?.[1];
|
|
74
|
+
}
|
|
75
|
+
function numVal(section, key) {
|
|
76
|
+
const m = section.match(new RegExp(`\\b${key}\\s*:\\s*([\\d.]+)`));
|
|
77
|
+
return m ? parseFloat(m[1]) : undefined;
|
|
78
|
+
}
|
|
79
|
+
function boolVal(section, key) {
|
|
80
|
+
const m = section.match(new RegExp(`\\b${key}\\s*:\\s*(true|false)`));
|
|
81
|
+
return m ? m[1] === 'true' : undefined;
|
|
82
|
+
}
|
|
83
|
+
function arrVal(section, key) {
|
|
84
|
+
const m = section.match(new RegExp(`\\b${key}\\s*:\\s*\\[([^\\]]*)\\]`));
|
|
85
|
+
if (!m)
|
|
86
|
+
return undefined;
|
|
87
|
+
return m[1].split(',')
|
|
88
|
+
.map(s => s.trim().replace(/^['"`]|['"`]$/g, ''))
|
|
89
|
+
.filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Parse uneven.config.ts as text and return a partial config overlay.
|
|
93
|
+
* Only fields that are explicitly set in the TS file are included.
|
|
94
|
+
* Returns null if the file is absent or yields nothing parseable.
|
|
95
|
+
*/
|
|
96
|
+
async function parseConfigTs() {
|
|
97
|
+
let src;
|
|
98
|
+
try {
|
|
99
|
+
src = await fs.readFile(TS_CONFIG_FILE, 'utf-8');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const result = {};
|
|
105
|
+
// brain
|
|
106
|
+
const brainSrc = extractSection(src, 'brain');
|
|
107
|
+
if (brainSrc) {
|
|
108
|
+
const provider = strVal(brainSrc, 'provider');
|
|
109
|
+
const model = strVal(brainSrc, 'model');
|
|
110
|
+
const temp = numVal(brainSrc, 'temperature');
|
|
111
|
+
const maxTok = numVal(brainSrc, 'maxTokens');
|
|
112
|
+
if (provider ?? model ?? temp ?? maxTok) {
|
|
113
|
+
result.brain = { provider: provider, model: model };
|
|
114
|
+
if (temp !== undefined)
|
|
115
|
+
result.brain.temperature = temp;
|
|
116
|
+
if (maxTok !== undefined)
|
|
117
|
+
result.brain.maxTokens = maxTok;
|
|
118
|
+
const localSrc = extractSection(brainSrc, 'local');
|
|
119
|
+
if (localSrc) {
|
|
120
|
+
result.brain.local = {};
|
|
121
|
+
const threads = numVal(localSrc, 'threads');
|
|
122
|
+
const gpuLayers = numVal(localSrc, 'gpuLayers');
|
|
123
|
+
const unloadTimeout = numVal(localSrc, 'unloadTimeout');
|
|
124
|
+
if (threads !== undefined)
|
|
125
|
+
result.brain.local.threads = threads;
|
|
126
|
+
if (gpuLayers !== undefined)
|
|
127
|
+
result.brain.local.gpuLayers = gpuLayers;
|
|
128
|
+
if (unloadTimeout !== undefined)
|
|
129
|
+
result.brain.local.unloadTimeout = unloadTimeout;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// knowledge
|
|
134
|
+
const knowledgeSrc = extractSection(src, 'knowledge');
|
|
135
|
+
if (knowledgeSrc) {
|
|
136
|
+
const dirs = arrVal(knowledgeSrc, 'dirs');
|
|
137
|
+
const files = arrVal(knowledgeSrc, 'files');
|
|
138
|
+
const urls = arrVal(knowledgeSrc, 'urls');
|
|
139
|
+
if (dirs ?? files ?? urls) {
|
|
140
|
+
result.knowledge = {};
|
|
141
|
+
if (dirs)
|
|
142
|
+
result.knowledge.dirs = dirs;
|
|
143
|
+
if (files)
|
|
144
|
+
result.knowledge.files = files;
|
|
145
|
+
if (urls)
|
|
146
|
+
result.knowledge.urls = urls;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// watch
|
|
150
|
+
const watchSrc = extractSection(src, 'watch');
|
|
151
|
+
if (watchSrc) {
|
|
152
|
+
const terminal = strVal(watchSrc, 'terminal');
|
|
153
|
+
const autoFix = boolVal(watchSrc, 'autoFix');
|
|
154
|
+
const confirmBeforeFix = boolVal(watchSrc, 'confirmBeforeFix');
|
|
155
|
+
const alertOnly = boolVal(watchSrc, 'alertOnly');
|
|
156
|
+
const dirs = arrVal(watchSrc, 'dirs');
|
|
157
|
+
if (terminal ?? autoFix ?? confirmBeforeFix ?? alertOnly ?? dirs) {
|
|
158
|
+
result.watch = {};
|
|
159
|
+
if (terminal !== undefined)
|
|
160
|
+
result.watch.terminal = terminal;
|
|
161
|
+
if (autoFix !== undefined)
|
|
162
|
+
result.watch.autoFix = autoFix;
|
|
163
|
+
if (confirmBeforeFix !== undefined)
|
|
164
|
+
result.watch.confirmBeforeFix = confirmBeforeFix;
|
|
165
|
+
if (alertOnly !== undefined)
|
|
166
|
+
result.watch.alertOnly = alertOnly;
|
|
167
|
+
if (dirs)
|
|
168
|
+
result.watch.dirs = dirs;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// log
|
|
172
|
+
const logSrc = extractSection(src, 'log');
|
|
173
|
+
if (logSrc) {
|
|
174
|
+
const logPath = strVal(logSrc, 'path');
|
|
175
|
+
const append = boolVal(logSrc, 'append');
|
|
176
|
+
const includeTimestamp = boolVal(logSrc, 'includeTimestamp');
|
|
177
|
+
const includeDiff = boolVal(logSrc, 'includeDiff');
|
|
178
|
+
if (logPath ?? append ?? includeTimestamp ?? includeDiff) {
|
|
179
|
+
result.log = {};
|
|
180
|
+
if (logPath !== undefined)
|
|
181
|
+
result.log.path = logPath;
|
|
182
|
+
if (append !== undefined)
|
|
183
|
+
result.log.append = append;
|
|
184
|
+
if (includeTimestamp !== undefined)
|
|
185
|
+
result.log.includeTimestamp = includeTimestamp;
|
|
186
|
+
if (includeDiff !== undefined)
|
|
187
|
+
result.log.includeDiff = includeDiff;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// pentester (top-level scalar fields only; nested objects are rare to change)
|
|
191
|
+
const pentesterSrc = extractSection(src, 'pentester');
|
|
192
|
+
if (pentesterSrc) {
|
|
193
|
+
const enabled = boolVal(pentesterSrc, 'enabled');
|
|
194
|
+
const mode = strVal(pentesterSrc, 'mode');
|
|
195
|
+
const severity = strVal(pentesterSrc, 'severity');
|
|
196
|
+
if (enabled ?? mode ?? severity) {
|
|
197
|
+
result.pentester = {};
|
|
198
|
+
if (enabled !== undefined)
|
|
199
|
+
result.pentester.enabled = enabled;
|
|
200
|
+
if (mode)
|
|
201
|
+
result.pentester.mode = mode;
|
|
202
|
+
if (severity)
|
|
203
|
+
result.pentester.severity = severity;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Parse uneven.config.ts and sync any changes into .uneven/config.json.
|
|
210
|
+
* Called automatically at the top of loadConfig() — the user never has to
|
|
211
|
+
* re-run `uneven init` just because they edited the TS config file.
|
|
212
|
+
*/
|
|
213
|
+
async function syncConfigFromTs() {
|
|
214
|
+
const overlay = await parseConfigTs();
|
|
215
|
+
if (!overlay)
|
|
216
|
+
return;
|
|
217
|
+
let current = {};
|
|
218
|
+
let currentJson = '';
|
|
219
|
+
try {
|
|
220
|
+
currentJson = await fs.readFile(CONFIG_FILE, 'utf-8');
|
|
221
|
+
current = JSON.parse(currentJson);
|
|
222
|
+
}
|
|
223
|
+
catch { /* config.json absent — will be created */ }
|
|
224
|
+
const merged = {
|
|
225
|
+
brain: {
|
|
226
|
+
...DEFAULTS.brain,
|
|
227
|
+
...current.brain,
|
|
228
|
+
...overlay.brain,
|
|
229
|
+
local: {
|
|
230
|
+
...DEFAULTS.brain.local,
|
|
231
|
+
...current.brain?.local,
|
|
232
|
+
...overlay.brain?.local,
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
knowledge: { ...DEFAULTS.knowledge, ...current.knowledge, ...overlay.knowledge },
|
|
236
|
+
watch: { ...DEFAULTS.watch, ...current.watch, ...overlay.watch },
|
|
237
|
+
log: { ...DEFAULTS.log, ...current.log, ...overlay.log },
|
|
238
|
+
...((overlay.pentester ?? current.pentester)
|
|
239
|
+
? { pentester: { ...current.pentester, ...overlay.pentester } }
|
|
240
|
+
: {}),
|
|
241
|
+
};
|
|
242
|
+
const mergedJson = JSON.stringify(merged, null, 2);
|
|
243
|
+
if (mergedJson !== currentJson) {
|
|
244
|
+
await fs.mkdir('.uneven', { recursive: true });
|
|
245
|
+
await fs.writeFile(CONFIG_FILE, mergedJson);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
29
249
|
/**
|
|
30
250
|
* Load Uneven config from .uneven/config.json.
|
|
31
|
-
*
|
|
251
|
+
* Automatically syncs uneven.config.ts → config.json first, so any edits
|
|
252
|
+
* to the TS file are reflected without re-running `uneven init`.
|
|
253
|
+
* Falls back to defaults if neither file exists (e.g. before `uneven init`).
|
|
32
254
|
*/
|
|
33
255
|
export async function loadConfig(overrides) {
|
|
256
|
+
await syncConfigFromTs();
|
|
34
257
|
let config;
|
|
35
258
|
try {
|
|
36
259
|
const raw = await fs.readFile(CONFIG_FILE, 'utf-8');
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -27,7 +27,7 @@ const prebuildPath = path.join(root, `prebuilds/${platformKey}/uneven_core.node`
|
|
|
27
27
|
const binaryExists = fs.existsSync(prebuildPath)
|
|
28
28
|
|
|
29
29
|
if (!binaryExists) {
|
|
30
|
-
const supported = ['linux-x64', 'linux-arm64', 'darwin-
|
|
30
|
+
const supported = ['linux-x64', 'linux-arm64', 'darwin-arm64', 'win32-x64']
|
|
31
31
|
|
|
32
32
|
if (!supported.includes(platformKey)) {
|
|
33
33
|
console.warn(`\n[uneven-ai] ⚠ Platform '${platformKey}' is not officially supported.`)
|
|
Binary file
|