@orion-agents/orion-code 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -0
- package/README.md +73 -14
- package/README.zh-CN.md +63 -13
- package/bin/orion +15 -4
- package/dist/cli.js +51 -172
- package/dist/cli.js.map +1 -1
- package/dist/commands/model-command-handlers.d.ts +2 -2
- package/dist/commands/model-command-handlers.d.ts.map +1 -1
- package/dist/commands/model-command-handlers.js +113 -32
- package/dist/commands/model-command-handlers.js.map +1 -1
- package/dist/commands/session-command-handlers.d.ts +1 -1
- package/dist/commands/session-command-handlers.d.ts.map +1 -1
- package/dist/commands/session-command-handlers.js +121 -16
- package/dist/commands/session-command-handlers.js.map +1 -1
- package/dist/commands/types.d.ts +14 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/agent-loop.d.ts +2 -0
- package/dist/runtime/agent-loop.d.ts.map +1 -1
- package/dist/runtime/agent-loop.js +4 -3
- package/dist/runtime/agent-loop.js.map +1 -1
- package/dist/runtime/agent-runtime-controller.d.ts +32 -1
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +250 -31
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-runner.d.ts +3 -0
- package/dist/runtime/agent-runtime-runner.d.ts.map +1 -1
- package/dist/runtime/goal-runtime-coordinator.d.ts +6 -0
- package/dist/runtime/goal-runtime-coordinator.d.ts.map +1 -1
- package/dist/runtime/goal-runtime-coordinator.js +5 -0
- package/dist/runtime/goal-runtime-coordinator.js.map +1 -1
- package/dist/runtime/legacy-thread-materializer.d.ts +18 -0
- package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -1
- package/dist/runtime/legacy-thread-materializer.js +27 -12
- package/dist/runtime/legacy-thread-materializer.js.map +1 -1
- package/dist/runtime/orion-runtime-v1.d.ts +3 -0
- package/dist/runtime/orion-runtime-v1.d.ts.map +1 -1
- package/dist/runtime/orion-runtime-v1.js +8 -1
- package/dist/runtime/orion-runtime-v1.js.map +1 -1
- package/dist/runtime/orion-session-runner.d.ts +7 -1
- package/dist/runtime/orion-session-runner.d.ts.map +1 -1
- package/dist/runtime/orion-session-runner.js +35 -3
- package/dist/runtime/orion-session-runner.js.map +1 -1
- package/dist/runtime/product-bootstrap.d.ts +22 -0
- package/dist/runtime/product-bootstrap.d.ts.map +1 -0
- package/dist/runtime/product-bootstrap.js +374 -0
- package/dist/runtime/product-bootstrap.js.map +1 -0
- package/dist/runtime/product-orion-runtime.d.ts +2 -1
- package/dist/runtime/product-orion-runtime.d.ts.map +1 -1
- package/dist/runtime/product-orion-runtime.js +114 -16
- package/dist/runtime/product-orion-runtime.js.map +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.js +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -1
- package/dist/runtime/release-receipts.d.ts +63 -2
- package/dist/runtime/release-receipts.d.ts.map +1 -1
- package/dist/runtime/release-receipts.js +298 -7
- package/dist/runtime/release-receipts.js.map +1 -1
- package/dist/runtime/session-history-recovery.d.ts +19 -0
- package/dist/runtime/session-history-recovery.d.ts.map +1 -0
- package/dist/runtime/session-history-recovery.js +45 -0
- package/dist/runtime/session-history-recovery.js.map +1 -0
- package/dist/runtime/step-snapshot.d.ts.map +1 -1
- package/dist/runtime/step-snapshot.js +22 -2
- package/dist/runtime/step-snapshot.js.map +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js +5 -2
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/thread-event-store.d.ts +27 -0
- package/dist/runtime/thread-event-store.d.ts.map +1 -1
- package/dist/runtime/thread-event-store.js +119 -17
- package/dist/runtime/thread-event-store.js.map +1 -1
- package/dist/runtime/thread-projection.d.ts +10 -0
- package/dist/runtime/thread-projection.d.ts.map +1 -1
- package/dist/runtime/thread-projection.js +40 -0
- package/dist/runtime/thread-projection.js.map +1 -1
- package/dist/runtime/thread-runtime.d.ts +3 -1
- package/dist/runtime/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/thread-runtime.js +6 -0
- package/dist/runtime/thread-runtime.js.map +1 -1
- package/dist/runtime/thread-session-view.d.ts +88 -0
- package/dist/runtime/thread-session-view.d.ts.map +1 -0
- package/dist/runtime/thread-session-view.js +327 -0
- package/dist/runtime/thread-session-view.js.map +1 -0
- package/dist/runtime/thread-ui-adapter.d.ts +4 -0
- package/dist/runtime/thread-ui-adapter.d.ts.map +1 -1
- package/dist/runtime/thread-ui-adapter.js +193 -5
- package/dist/runtime/thread-ui-adapter.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +37 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js +1 -0
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/runtime/ui-view-model.d.ts +3 -0
- package/dist/runtime/ui-view-model.d.ts.map +1 -1
- package/dist/runtime/ui-view-model.js +10 -3
- package/dist/runtime/ui-view-model.js.map +1 -1
- package/dist/services/file-lock.d.ts.map +1 -1
- package/dist/services/file-lock.js +42 -17
- package/dist/services/file-lock.js.map +1 -1
- package/dist/services/global-config.d.ts +25 -0
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js +373 -5
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/session-storage.d.ts +67 -0
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +327 -61
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/settings-coordinator.d.ts +174 -0
- package/dist/services/settings-coordinator.d.ts.map +1 -0
- package/dist/services/settings-coordinator.js +605 -0
- package/dist/services/settings-coordinator.js.map +1 -0
- package/dist/services/settings-document-repository.d.ts +138 -0
- package/dist/services/settings-document-repository.d.ts.map +1 -0
- package/dist/services/settings-document-repository.js +551 -0
- package/dist/services/settings-document-repository.js.map +1 -0
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +7 -0
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/tools/web.js +1 -1
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-ui/chrome-view-model.d.ts.map +1 -1
- package/dist/tui-ui/chrome-view-model.js +21 -7
- package/dist/tui-ui/chrome-view-model.js.map +1 -1
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +13 -0
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +7 -0
- package/dist/tui-ui/state.js.map +1 -1
- package/dist/web/event-hub.d.ts +39 -0
- package/dist/web/event-hub.d.ts.map +1 -0
- package/dist/web/event-hub.js +263 -0
- package/dist/web/event-hub.js.map +1 -0
- package/dist/web/index.d.ts +6 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +28 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/launch.d.ts +9 -0
- package/dist/web/launch.d.ts.map +1 -0
- package/dist/web/launch.js +64 -0
- package/dist/web/launch.js.map +1 -0
- package/dist/web/protocol.d.ts +346 -0
- package/dist/web/protocol.d.ts.map +1 -0
- package/dist/web/protocol.js +348 -0
- package/dist/web/protocol.js.map +1 -0
- package/dist/web/server.d.ts +20 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +498 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/workbench-controller.d.ts +63 -0
- package/dist/web/workbench-controller.d.ts.map +1 -0
- package/dist/web/workbench-controller.js +774 -0
- package/dist/web/workbench-controller.js.map +1 -0
- package/dist/web-client/assets/index-BAEO71Gp.css +1 -0
- package/dist/web-client/assets/index-DSkFy7gM.js +13 -0
- package/dist/web-client/index.html +16 -0
- package/docs/architecture/v0.3.0-web-api.yaml +1309 -0
- package/docs/migration/v0.2.2-to-v0.3.0-settings.md +114 -0
- package/docs/migration/v0.2.2-to-v0.3.0.md +55 -0
- package/docs/orion.example.json +9 -2
- package/docs/plan/v0.3.0-node-runtime-compatibility-plan.md +57 -0
- package/docs/plan/v0.3.0-settings-integration-plan.md +740 -0
- package/docs/plan/v0.3.0-web-workbench-plan.md +325 -0
- package/docs/readme.md +12 -1
- package/npm-shrinkwrap.json +1777 -424
- package/package.json +33 -9
|
@@ -37,6 +37,20 @@ function processIsAlive(pid) {
|
|
|
37
37
|
return error.code === 'EPERM';
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
function shouldAttemptStaleRecovery(lockPath, staleMs) {
|
|
41
|
+
let observed;
|
|
42
|
+
try {
|
|
43
|
+
observed = (0, fs_1.statSync)(lockPath);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const owner = readOwner(lockPath);
|
|
49
|
+
if (!owner)
|
|
50
|
+
return false;
|
|
51
|
+
const lastActivity = Math.max(observed.mtimeMs, owner.createdAt);
|
|
52
|
+
return Date.now() - lastActivity > staleMs && !processIsAlive(owner.pid);
|
|
53
|
+
}
|
|
40
54
|
function recoverStaleLock(lockPath, staleMs, options = {}) {
|
|
41
55
|
let firstStat;
|
|
42
56
|
try {
|
|
@@ -169,10 +183,11 @@ function acquirePrimitiveLock(lockPath, options) {
|
|
|
169
183
|
}
|
|
170
184
|
}
|
|
171
185
|
function withRecoverySentinel(lockPath, options, operation) {
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
186
|
+
// Stale recovery passes through this short-lived sentinel, so two recovery
|
|
187
|
+
// contenders cannot both move the same observed main lock. Healthy owners
|
|
188
|
+
// publish and release by token without taking this secondary lock: making a
|
|
189
|
+
// release queue behind ordinary waiters can starve the owner and turn normal
|
|
190
|
+
// high-contention writes into deterministic timeouts.
|
|
176
191
|
const sentinelPath = `${lockPath}${RECOVERY_SUFFIX}`;
|
|
177
192
|
const sentinel = acquirePrimitiveLock(sentinelPath, options);
|
|
178
193
|
try {
|
|
@@ -185,14 +200,27 @@ function withRecoverySentinel(lockPath, options, operation) {
|
|
|
185
200
|
function acquireLock(lockPath, options) {
|
|
186
201
|
const deadline = Date.now() + options.waitMs;
|
|
187
202
|
while (true) {
|
|
203
|
+
// Atomic no-replace publication is safe without the recovery sentinel.
|
|
204
|
+
// Contenders for a healthy live lock must not repeatedly seize the
|
|
205
|
+
// sentinel, otherwise they can starve the actual owner when it needs the
|
|
206
|
+
// sentinel to release the main lock. An already-published sentinel still
|
|
207
|
+
// owns the transition and must be honored, including malformed legacy
|
|
208
|
+
// sentinels that intentionally fail closed during their grace period.
|
|
209
|
+
const sentinelExists = (0, fs_1.existsSync)(`${lockPath}${RECOVERY_SUFFIX}`);
|
|
210
|
+
if (!sentinelExists) {
|
|
211
|
+
const published = createLock(lockPath);
|
|
212
|
+
if (published)
|
|
213
|
+
return published;
|
|
214
|
+
}
|
|
188
215
|
const remainingMs = Math.max(0, deadline - Date.now());
|
|
189
216
|
let owner = null;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (!owner && recoverStaleLock(lockPath, options.staleMs)) {
|
|
217
|
+
if (sentinelExists || shouldAttemptStaleRecovery(lockPath, options.staleMs)) {
|
|
218
|
+
withRecoverySentinel(lockPath, { ...options, waitMs: remainingMs }, () => {
|
|
193
219
|
owner = createLock(lockPath);
|
|
194
|
-
|
|
195
|
-
|
|
220
|
+
if (!owner && recoverStaleLock(lockPath, options.staleMs))
|
|
221
|
+
owner = createLock(lockPath);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
196
224
|
if (owner)
|
|
197
225
|
return owner;
|
|
198
226
|
if (Date.now() >= deadline)
|
|
@@ -213,14 +241,11 @@ function withFileLockSync(targetPath, operation, options = {}) {
|
|
|
213
241
|
return operation();
|
|
214
242
|
}
|
|
215
243
|
finally {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
catch (error) {
|
|
222
|
-
(0, debug_log_1.debugError)('file-lock.release', error, lockPath);
|
|
223
|
-
}
|
|
244
|
+
// The owner token makes release conditional on the exact published lock.
|
|
245
|
+
// A live owner is never eligible for stale recovery, and stale recovery
|
|
246
|
+
// serializes its own check/rename path, so release must not contend for the
|
|
247
|
+
// recovery sentinel with processes that are merely waiting for this lock.
|
|
248
|
+
releaseOwnedLock(lockPath, owner, 'file-lock.release');
|
|
224
249
|
}
|
|
225
250
|
}
|
|
226
251
|
//# sourceMappingURL=file-lock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/services/file-lock.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/services/file-lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,15 @@ export interface ProjectConfig {
|
|
|
32
32
|
}
|
|
33
33
|
/** How to handle tool permission checks that request interactive confirmation. */
|
|
34
34
|
export type ToolConfirmationPolicy = 'ask' | 'allow' | 'deny';
|
|
35
|
+
/** Browser appearance preferences persisted in the canonical global document. */
|
|
36
|
+
export interface WebAppearanceConfigV1 {
|
|
37
|
+
theme?: 'system' | 'light' | 'dark';
|
|
38
|
+
motion?: 'system' | 'reduced';
|
|
39
|
+
}
|
|
40
|
+
/** Web-only preferences. Runtime/session state deliberately does not live here. */
|
|
41
|
+
export interface WebConfigV1 {
|
|
42
|
+
appearance?: WebAppearanceConfigV1;
|
|
43
|
+
}
|
|
35
44
|
/**
|
|
36
45
|
* OS-level isolation requested for shell command execution.
|
|
37
46
|
* `none` is the default and reproduces pre-sandbox behaviour exactly.
|
|
@@ -176,6 +185,8 @@ export interface GlobalConfig {
|
|
|
176
185
|
webSearch?: WebSearchMcpConfig;
|
|
177
186
|
/** Terminal UI configuration. */
|
|
178
187
|
ui?: UIConfig;
|
|
188
|
+
/** Browser UI configuration. */
|
|
189
|
+
web?: WebConfigV1;
|
|
179
190
|
/** Additional user-managed skills roots. */
|
|
180
191
|
skills?: SkillsConfig;
|
|
181
192
|
/** Agent-loop guardrails. */
|
|
@@ -190,6 +201,20 @@ export interface GlobalConfig {
|
|
|
190
201
|
firstStartTime?: string;
|
|
191
202
|
projects?: Record<string, ProjectConfig>;
|
|
192
203
|
}
|
|
204
|
+
/** A parsed canonical config document, including forward-compatible unknown fields. */
|
|
205
|
+
export type GlobalConfigDocument = Record<string, unknown>;
|
|
206
|
+
/** Raised only by the strict Settings path; the legacy startup loader remains tolerant. */
|
|
207
|
+
export declare class GlobalConfigDocumentValidationError extends Error {
|
|
208
|
+
readonly field: string;
|
|
209
|
+
constructor(field: string);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Validate the complete known schema without normalizing or dropping unknown
|
|
213
|
+
* fields. Settings mutations must call this before writing their raw clone.
|
|
214
|
+
*/
|
|
215
|
+
export declare function validateGlobalConfigDocumentStrict(value: unknown): asserts value is GlobalConfigDocument;
|
|
216
|
+
/** Parse exact file bytes through the strict Settings validator. */
|
|
217
|
+
export declare function parseGlobalConfigDocumentStrict(content: string | Buffer): GlobalConfigDocument;
|
|
193
218
|
interface LegacyUsageFields {
|
|
194
219
|
totalSessions?: unknown;
|
|
195
220
|
totalTokens?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-config.d.ts","sourceRoot":"","sources":["../../src/services/global-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"global-config.d.ts","sourceRoot":"","sources":["../../src/services/global-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* Environment variable overrides use ORION_CODE_ prefix.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.updateTokenStats = exports.incrementSessionCount = void 0;
|
|
9
|
+
exports.updateTokenStats = exports.incrementSessionCount = exports.GlobalConfigDocumentValidationError = void 0;
|
|
10
|
+
exports.validateGlobalConfigDocumentStrict = validateGlobalConfigDocumentStrict;
|
|
11
|
+
exports.parseGlobalConfigDocumentStrict = parseGlobalConfigDocumentStrict;
|
|
10
12
|
exports.loadGlobalConfig = loadGlobalConfig;
|
|
11
13
|
exports.saveGlobalConfig = saveGlobalConfig;
|
|
12
14
|
exports.updateGlobalConfig = updateGlobalConfig;
|
|
@@ -24,6 +26,7 @@ const config_dir_1 = require("./config-dir");
|
|
|
24
26
|
const atomic_write_1 = require("./atomic-write");
|
|
25
27
|
const file_lock_1 = require("./file-lock");
|
|
26
28
|
const effort_1 = require("./effort");
|
|
29
|
+
const model_registry_1 = require("./model-registry");
|
|
27
30
|
// ============================================================================
|
|
28
31
|
// 默认配置
|
|
29
32
|
// ============================================================================
|
|
@@ -33,6 +36,323 @@ const DEFAULT_CONFIG = {
|
|
|
33
36
|
toolConfirmation: 'allow',
|
|
34
37
|
};
|
|
35
38
|
const CONFIG_SCHEMA_VERSION = 1;
|
|
39
|
+
/** Raised only by the strict Settings path; the legacy startup loader remains tolerant. */
|
|
40
|
+
class GlobalConfigDocumentValidationError extends Error {
|
|
41
|
+
constructor(field) {
|
|
42
|
+
super(`Invalid Orion configuration field: ${field}`);
|
|
43
|
+
this.field = field;
|
|
44
|
+
this.name = 'GlobalConfigDocumentValidationError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.GlobalConfigDocumentValidationError = GlobalConfigDocumentValidationError;
|
|
48
|
+
function isRecord(value) {
|
|
49
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
50
|
+
}
|
|
51
|
+
function invalidField(field) {
|
|
52
|
+
throw new GlobalConfigDocumentValidationError(field);
|
|
53
|
+
}
|
|
54
|
+
function validateOptionalString(record, key, field, allowEmpty = true) {
|
|
55
|
+
const value = record[key];
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
return;
|
|
58
|
+
if (typeof value !== 'string' || (!allowEmpty && value.trim().length === 0))
|
|
59
|
+
invalidField(field);
|
|
60
|
+
}
|
|
61
|
+
function validateOptionalStringArray(record, key, field) {
|
|
62
|
+
const value = record[key];
|
|
63
|
+
if (value === undefined)
|
|
64
|
+
return;
|
|
65
|
+
if (!Array.isArray(value) || !value.every(item => typeof item === 'string'))
|
|
66
|
+
invalidField(field);
|
|
67
|
+
}
|
|
68
|
+
function validateOptionalBoolean(record, key, field) {
|
|
69
|
+
const value = record[key];
|
|
70
|
+
if (value !== undefined && typeof value !== 'boolean')
|
|
71
|
+
invalidField(field);
|
|
72
|
+
}
|
|
73
|
+
function validateOptionalPositiveInteger(record, key, field) {
|
|
74
|
+
const value = record[key];
|
|
75
|
+
if (value !== undefined && (!Number.isSafeInteger(value) || Number(value) <= 0)) {
|
|
76
|
+
invalidField(field);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function validateSandboxDocument(value, field) {
|
|
80
|
+
if (value === undefined)
|
|
81
|
+
return;
|
|
82
|
+
if (!isRecord(value))
|
|
83
|
+
invalidField(field);
|
|
84
|
+
if (value.profile !== undefined &&
|
|
85
|
+
value.profile !== 'none' &&
|
|
86
|
+
value.profile !== 'read-only' &&
|
|
87
|
+
value.profile !== 'workspace-write') {
|
|
88
|
+
invalidField(`${field}.profile`);
|
|
89
|
+
}
|
|
90
|
+
if (value.backend !== undefined &&
|
|
91
|
+
value.backend !== 'auto' &&
|
|
92
|
+
value.backend !== 'seatbelt' &&
|
|
93
|
+
value.backend !== 'bubblewrap' &&
|
|
94
|
+
value.backend !== 'docker') {
|
|
95
|
+
invalidField(`${field}.backend`);
|
|
96
|
+
}
|
|
97
|
+
validateOptionalBoolean(value, 'allowNetwork', `${field}.allowNetwork`);
|
|
98
|
+
validateOptionalStringArray(value, 'writableRoots', `${field}.writableRoots`);
|
|
99
|
+
validateOptionalString(value, 'image', `${field}.image`);
|
|
100
|
+
}
|
|
101
|
+
function validateProjectDocument(value) {
|
|
102
|
+
if (!isRecord(value))
|
|
103
|
+
invalidField('projects.*');
|
|
104
|
+
validateOptionalStringArray(value, 'allowedTools', 'projects.*.allowedTools');
|
|
105
|
+
validateOptionalString(value, 'compactInstructions', 'projects.*.compactInstructions');
|
|
106
|
+
validateSandboxDocument(value.sandbox, 'projects.*.sandbox');
|
|
107
|
+
validateOptionalString(value, 'lastSessionId', 'projects.*.lastSessionId');
|
|
108
|
+
validateOptionalString(value, 'lastModel', 'projects.*.lastModel');
|
|
109
|
+
validateOptionalBoolean(value, 'hasTrustDialogAccepted', 'projects.*.hasTrustDialogAccepted');
|
|
110
|
+
if (value.defaultEffort !== undefined && !(0, effort_1.isEffortPreference)(value.defaultEffort)) {
|
|
111
|
+
invalidField('projects.*.defaultEffort');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function validatePricing(value, field) {
|
|
115
|
+
if (!isRecord(value))
|
|
116
|
+
invalidField(field);
|
|
117
|
+
for (const key of ['input', 'output']) {
|
|
118
|
+
if (typeof value[key] !== 'number' || !Number.isFinite(value[key]) || value[key] < 0) {
|
|
119
|
+
invalidField(`${field}.${key}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (value.cachedInput !== undefined &&
|
|
123
|
+
(typeof value.cachedInput !== 'number' ||
|
|
124
|
+
!Number.isFinite(value.cachedInput) ||
|
|
125
|
+
value.cachedInput < 0)) {
|
|
126
|
+
invalidField(`${field}.cachedInput`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Validate the complete known schema without normalizing or dropping unknown
|
|
131
|
+
* fields. Settings mutations must call this before writing their raw clone.
|
|
132
|
+
*/
|
|
133
|
+
function validateGlobalConfigDocumentStrict(value) {
|
|
134
|
+
if (!isRecord(value))
|
|
135
|
+
invalidField('$');
|
|
136
|
+
if (value.schemaVersion !== undefined && value.schemaVersion !== CONFIG_SCHEMA_VERSION) {
|
|
137
|
+
invalidField('schemaVersion');
|
|
138
|
+
}
|
|
139
|
+
validateOptionalString(value, 'apiKey', 'apiKey');
|
|
140
|
+
validateOptionalString(value, 'apiBaseUrl', 'apiBaseUrl');
|
|
141
|
+
validateOptionalString(value, 'defaultModel', 'defaultModel', false);
|
|
142
|
+
validateOptionalString(value, 'fallbackModel', 'fallbackModel', false);
|
|
143
|
+
validateOptionalString(value, 'userId', 'userId', false);
|
|
144
|
+
validateOptionalString(value, 'firstStartTime', 'firstStartTime', false);
|
|
145
|
+
validateOptionalStringArray(value, 'allowedTools', 'allowedTools');
|
|
146
|
+
if (value.toolConfirmation !== undefined &&
|
|
147
|
+
value.toolConfirmation !== 'ask' &&
|
|
148
|
+
value.toolConfirmation !== 'allow' &&
|
|
149
|
+
value.toolConfirmation !== 'deny') {
|
|
150
|
+
invalidField('toolConfirmation');
|
|
151
|
+
}
|
|
152
|
+
if (value.defaultEffort !== undefined && !(0, effort_1.isEffortPreference)(value.defaultEffort)) {
|
|
153
|
+
invalidField('defaultEffort');
|
|
154
|
+
}
|
|
155
|
+
validateSandboxDocument(value.sandbox, 'sandbox');
|
|
156
|
+
if (value.projects !== undefined) {
|
|
157
|
+
if (!isRecord(value.projects))
|
|
158
|
+
invalidField('projects');
|
|
159
|
+
for (const project of Object.values(value.projects))
|
|
160
|
+
validateProjectDocument(project);
|
|
161
|
+
}
|
|
162
|
+
if (value.web !== undefined) {
|
|
163
|
+
if (!isRecord(value.web))
|
|
164
|
+
invalidField('web');
|
|
165
|
+
if (value.web.appearance !== undefined) {
|
|
166
|
+
if (!isRecord(value.web.appearance))
|
|
167
|
+
invalidField('web.appearance');
|
|
168
|
+
const { theme, motion } = value.web.appearance;
|
|
169
|
+
if (theme !== undefined && theme !== 'system' && theme !== 'light' && theme !== 'dark') {
|
|
170
|
+
invalidField('web.appearance.theme');
|
|
171
|
+
}
|
|
172
|
+
if (motion !== undefined && motion !== 'system' && motion !== 'reduced') {
|
|
173
|
+
invalidField('web.appearance.motion');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (value.ui !== undefined) {
|
|
178
|
+
if (!isRecord(value.ui))
|
|
179
|
+
invalidField('ui');
|
|
180
|
+
const { renderer, confirmations, theme, motion } = value.ui;
|
|
181
|
+
if (renderer !== undefined && renderer !== 'terminal' && renderer !== 'tui') {
|
|
182
|
+
invalidField('ui.renderer');
|
|
183
|
+
}
|
|
184
|
+
if (confirmations !== undefined &&
|
|
185
|
+
confirmations !== 'config' &&
|
|
186
|
+
confirmations !== 'interactive') {
|
|
187
|
+
invalidField('ui.confirmations');
|
|
188
|
+
}
|
|
189
|
+
if (theme !== undefined && !TUI_THEME_PREFERENCES.has(theme)) {
|
|
190
|
+
invalidField('ui.theme');
|
|
191
|
+
}
|
|
192
|
+
if (motion !== undefined && !TUI_MOTION_PREFERENCES.has(motion)) {
|
|
193
|
+
invalidField('ui.motion');
|
|
194
|
+
}
|
|
195
|
+
validateOptionalBoolean(value.ui, 'mascot', 'ui.mascot');
|
|
196
|
+
validateOptionalStringArray(value.ui, 'statusLine', 'ui.statusLine');
|
|
197
|
+
if (value.ui.keymap !== undefined && !isRecord(value.ui.keymap))
|
|
198
|
+
invalidField('ui.keymap');
|
|
199
|
+
}
|
|
200
|
+
if (value.webSearch !== undefined) {
|
|
201
|
+
if (!isRecord(value.webSearch))
|
|
202
|
+
invalidField('webSearch');
|
|
203
|
+
for (const key of [
|
|
204
|
+
'provider',
|
|
205
|
+
'endpoint',
|
|
206
|
+
'apiKey',
|
|
207
|
+
'toolName',
|
|
208
|
+
'apiKeyHeader',
|
|
209
|
+
'apiKeyQueryParam',
|
|
210
|
+
]) {
|
|
211
|
+
validateOptionalString(value.webSearch, key, `webSearch.${key}`);
|
|
212
|
+
}
|
|
213
|
+
validateOptionalPositiveInteger(value.webSearch, 'timeoutMs', 'webSearch.timeoutMs');
|
|
214
|
+
if (value.webSearch.authType !== undefined &&
|
|
215
|
+
!['bearer', 'header', 'query', 'none'].includes(String(value.webSearch.authType))) {
|
|
216
|
+
invalidField('webSearch.authType');
|
|
217
|
+
}
|
|
218
|
+
if (value.webSearch.headers !== undefined) {
|
|
219
|
+
if (!isRecord(value.webSearch.headers) ||
|
|
220
|
+
!Object.values(value.webSearch.headers).every(header => typeof header === 'string')) {
|
|
221
|
+
invalidField('webSearch.headers');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (value.skills !== undefined) {
|
|
226
|
+
if (!isRecord(value.skills))
|
|
227
|
+
invalidField('skills');
|
|
228
|
+
validateOptionalStringArray(value.skills, 'paths', 'skills.paths');
|
|
229
|
+
}
|
|
230
|
+
if (value.agentLoop !== undefined) {
|
|
231
|
+
if (!isRecord(value.agentLoop))
|
|
232
|
+
invalidField('agentLoop');
|
|
233
|
+
if (value.agentLoop.budget !== undefined) {
|
|
234
|
+
if (!isRecord(value.agentLoop.budget))
|
|
235
|
+
invalidField('agentLoop.budget');
|
|
236
|
+
for (const key of [
|
|
237
|
+
'maxLlmRequestsPerUserTurn',
|
|
238
|
+
'maxToolCallsPerUserTurn',
|
|
239
|
+
'maxReadOnlyFragmentation',
|
|
240
|
+
'maxModelVisibleToolBytes',
|
|
241
|
+
]) {
|
|
242
|
+
validateOptionalPositiveInteger(value.agentLoop.budget, key, `agentLoop.budget.${key}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (value.subagents !== undefined) {
|
|
247
|
+
if (!isRecord(value.subagents))
|
|
248
|
+
invalidField('subagents');
|
|
249
|
+
if (value.subagents.mode !== undefined &&
|
|
250
|
+
value.subagents.mode !== 'off' &&
|
|
251
|
+
value.subagents.mode !== 'explicit' &&
|
|
252
|
+
value.subagents.mode !== 'auto') {
|
|
253
|
+
invalidField('subagents.mode');
|
|
254
|
+
}
|
|
255
|
+
for (const key of [
|
|
256
|
+
'maxParallel',
|
|
257
|
+
'maxTasksPerTurn',
|
|
258
|
+
'maxTurnsPerTask',
|
|
259
|
+
'maxModelRequestsPerTask',
|
|
260
|
+
'maxModelRequestsPerTurn',
|
|
261
|
+
'maxToolCallsPerTask',
|
|
262
|
+
'timeoutMs',
|
|
263
|
+
]) {
|
|
264
|
+
validateOptionalPositiveInteger(value.subagents, key, `subagents.${key}`);
|
|
265
|
+
}
|
|
266
|
+
if (value.subagents.roles !== undefined) {
|
|
267
|
+
if (!Array.isArray(value.subagents.roles) ||
|
|
268
|
+
!value.subagents.roles.every(role => ['research', 'review', 'test-investigate'].includes(String(role)))) {
|
|
269
|
+
invalidField('subagents.roles');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (value.cost !== undefined) {
|
|
274
|
+
if (!isRecord(value.cost))
|
|
275
|
+
invalidField('cost');
|
|
276
|
+
if (value.cost.defaultPricing !== undefined) {
|
|
277
|
+
validatePricing(value.cost.defaultPricing, 'cost.defaultPricing');
|
|
278
|
+
}
|
|
279
|
+
if (value.cost.modelPricing !== undefined) {
|
|
280
|
+
if (!isRecord(value.cost.modelPricing))
|
|
281
|
+
invalidField('cost.modelPricing');
|
|
282
|
+
for (const pricing of Object.values(value.cost.modelPricing)) {
|
|
283
|
+
validatePricing(pricing, 'cost.modelPricing.*');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const hasProviders = value.providers !== undefined;
|
|
288
|
+
const hasModels = value.models !== undefined;
|
|
289
|
+
if (hasProviders || hasModels) {
|
|
290
|
+
if (!Array.isArray(value.providers) || !value.providers.every(isRecord)) {
|
|
291
|
+
invalidField('providers');
|
|
292
|
+
}
|
|
293
|
+
if (!Array.isArray(value.models) || !value.models.every(isRecord))
|
|
294
|
+
invalidField('models');
|
|
295
|
+
for (const provider of value.providers) {
|
|
296
|
+
validateOptionalString(provider, 'id', 'providers.*.id', false);
|
|
297
|
+
validateOptionalString(provider, 'baseUrl', 'providers.*.baseUrl', false);
|
|
298
|
+
validateOptionalString(provider, 'apiKey', 'providers.*.apiKey', false);
|
|
299
|
+
validateOptionalString(provider, 'displayName', 'providers.*.displayName');
|
|
300
|
+
if (typeof provider.id !== 'string' ||
|
|
301
|
+
typeof provider.baseUrl !== 'string' ||
|
|
302
|
+
typeof provider.apiKey !== 'string') {
|
|
303
|
+
invalidField('providers');
|
|
304
|
+
}
|
|
305
|
+
if (provider.protocol !== 'openai-completions' &&
|
|
306
|
+
provider.protocol !== 'anthropic-messages') {
|
|
307
|
+
invalidField('providers.*.protocol');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
for (const model of value.models) {
|
|
311
|
+
validateOptionalString(model, 'id', 'models.*.id', false);
|
|
312
|
+
validateOptionalString(model, 'displayName', 'models.*.displayName');
|
|
313
|
+
validateOptionalString(model, 'provider', 'models.*.provider', false);
|
|
314
|
+
validateOptionalString(model, 'model', 'models.*.model', false);
|
|
315
|
+
if (typeof model.id !== 'string' ||
|
|
316
|
+
typeof model.provider !== 'string' ||
|
|
317
|
+
typeof model.model !== 'string') {
|
|
318
|
+
invalidField('models');
|
|
319
|
+
}
|
|
320
|
+
validateOptionalPositiveInteger(model, 'contextWindow', 'models.*.contextWindow');
|
|
321
|
+
validateOptionalPositiveInteger(model, 'maxOutputTokens', 'models.*.maxOutputTokens');
|
|
322
|
+
validateOptionalStringArray(model, 'aliases', 'models.*.aliases');
|
|
323
|
+
validateOptionalBoolean(model, 'enabled', 'models.*.enabled');
|
|
324
|
+
validateOptionalBoolean(model, 'reasoning', 'models.*.reasoning');
|
|
325
|
+
if (model.temperatureMode !== undefined &&
|
|
326
|
+
model.temperatureMode !== 'supported' &&
|
|
327
|
+
model.temperatureMode !== 'unsupported') {
|
|
328
|
+
invalidField('models.*.temperatureMode');
|
|
329
|
+
}
|
|
330
|
+
if (model.cost !== undefined)
|
|
331
|
+
validatePricing(model.cost, 'models.*.cost');
|
|
332
|
+
}
|
|
333
|
+
let validation;
|
|
334
|
+
try {
|
|
335
|
+
validation = (0, model_registry_1.buildRegistry)(value);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
invalidField('providers/models');
|
|
339
|
+
}
|
|
340
|
+
if (!validation.valid)
|
|
341
|
+
invalidField('providers/models');
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/** Parse exact file bytes through the strict Settings validator. */
|
|
345
|
+
function parseGlobalConfigDocumentStrict(content) {
|
|
346
|
+
let parsed;
|
|
347
|
+
try {
|
|
348
|
+
parsed = JSON.parse(typeof content === 'string' ? content : content.toString('utf8'));
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
invalidField('$json');
|
|
352
|
+
}
|
|
353
|
+
validateGlobalConfigDocumentStrict(parsed);
|
|
354
|
+
return parsed;
|
|
355
|
+
}
|
|
36
356
|
const TUI_THEME_PREFERENCES = new Set([
|
|
37
357
|
'orion-pixel',
|
|
38
358
|
'classic',
|
|
@@ -114,6 +434,32 @@ function sanitizeUiConfig(value) {
|
|
|
114
434
|
}
|
|
115
435
|
return Object.keys(ui).length > 0 ? ui : undefined;
|
|
116
436
|
}
|
|
437
|
+
function sanitizeWebConfig(value) {
|
|
438
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
439
|
+
return undefined;
|
|
440
|
+
const raw = value;
|
|
441
|
+
// Preserve forward-compatible Web fields while sanitizing the owned subtree.
|
|
442
|
+
const sanitized = { ...raw };
|
|
443
|
+
if (raw.appearance && typeof raw.appearance === 'object' && !Array.isArray(raw.appearance)) {
|
|
444
|
+
const appearance = { ...raw.appearance };
|
|
445
|
+
if (appearance.theme !== 'system' &&
|
|
446
|
+
appearance.theme !== 'light' &&
|
|
447
|
+
appearance.theme !== 'dark') {
|
|
448
|
+
delete appearance.theme;
|
|
449
|
+
}
|
|
450
|
+
if (appearance.motion !== 'system' && appearance.motion !== 'reduced') {
|
|
451
|
+
delete appearance.motion;
|
|
452
|
+
}
|
|
453
|
+
if (Object.keys(appearance).length > 0)
|
|
454
|
+
sanitized.appearance = appearance;
|
|
455
|
+
else
|
|
456
|
+
delete sanitized.appearance;
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
delete sanitized.appearance;
|
|
460
|
+
}
|
|
461
|
+
return sanitized;
|
|
462
|
+
}
|
|
117
463
|
function sanitizeSandboxConfig(value) {
|
|
118
464
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
119
465
|
return undefined;
|
|
@@ -169,7 +515,7 @@ function sanitizeProjectConfig(value) {
|
|
|
169
515
|
return sanitized;
|
|
170
516
|
}
|
|
171
517
|
function sanitizeGlobalConfig(config) {
|
|
172
|
-
const { ui, totalSessions: _totalSessions, totalTokens: _totalTokens, totalCost: _totalCost, ...rest } = config;
|
|
518
|
+
const { ui, web, totalSessions: _totalSessions, totalTokens: _totalTokens, totalCost: _totalCost, ...rest } = config;
|
|
173
519
|
void _totalSessions;
|
|
174
520
|
void _totalTokens;
|
|
175
521
|
void _totalCost;
|
|
@@ -198,6 +544,9 @@ function sanitizeGlobalConfig(config) {
|
|
|
198
544
|
const persistedUi = sanitizeUiConfig(ui);
|
|
199
545
|
if (persistedUi)
|
|
200
546
|
sanitized.ui = persistedUi;
|
|
547
|
+
const persistedWeb = sanitizeWebConfig(web);
|
|
548
|
+
if (persistedWeb)
|
|
549
|
+
sanitized.web = persistedWeb;
|
|
201
550
|
return sanitized;
|
|
202
551
|
}
|
|
203
552
|
// ============================================================================
|
|
@@ -289,10 +638,29 @@ function recordFirstStartTime() {
|
|
|
289
638
|
(0, config_dir_1.ensureConfigDir)();
|
|
290
639
|
const path = (0, config_dir_1.getGlobalConfigPath)();
|
|
291
640
|
(0, file_lock_1.withFileLockSync)(path, () => {
|
|
292
|
-
|
|
293
|
-
if (
|
|
294
|
-
|
|
641
|
+
let document;
|
|
642
|
+
if ((0, fs_1.existsSync)(path)) {
|
|
643
|
+
try {
|
|
644
|
+
document = parseGlobalConfigDocumentStrict((0, fs_1.readFileSync)(path));
|
|
645
|
+
}
|
|
646
|
+
catch {
|
|
647
|
+
// Startup metadata is optional. Never let the tolerant compatibility
|
|
648
|
+
// loader turn an invalid user document into defaults and overwrite it.
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
295
651
|
}
|
|
652
|
+
else {
|
|
653
|
+
document = { schemaVersion: CONFIG_SCHEMA_VERSION };
|
|
654
|
+
}
|
|
655
|
+
if (typeof document.firstStartTime === 'string' && document.firstStartTime.trim())
|
|
656
|
+
return;
|
|
657
|
+
const candidate = {
|
|
658
|
+
...document,
|
|
659
|
+
schemaVersion: document.schemaVersion ?? CONFIG_SCHEMA_VERSION,
|
|
660
|
+
firstStartTime: new Date().toISOString(),
|
|
661
|
+
};
|
|
662
|
+
validateGlobalConfigDocumentStrict(candidate);
|
|
663
|
+
(0, atomic_write_1.atomicWriteFileSync)(path, JSON.stringify(candidate, null, 2), { mode: 0o600, fsync: true });
|
|
296
664
|
}, { waitMs: 10000 });
|
|
297
665
|
}
|
|
298
666
|
var usage_state_1 = require("./usage-state");
|