sneakoscope 8.1.2 → 8.2.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 +96 -58
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +5 -51
- package/dist/cli/command-manifest-lite.js +2 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/global-mode-router.js +1 -1
- package/dist/cli/install-helpers-codex-lb-config.js +112 -914
- package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
- package/dist/cli/install-helpers-install-support.js +4 -20
- package/dist/cli/install-helpers.js +36 -2716
- package/dist/cli/router.js +9 -9
- package/dist/commands/bridge-command-output.js +111 -0
- package/dist/commands/bridge.js +320 -0
- package/dist/commands/codex-app.js +39 -123
- package/dist/commands/doctor-helpers.js +380 -0
- package/dist/commands/doctor-profile.js +3 -0
- package/dist/commands/doctor.js +114 -873
- package/dist/commands/mad-sks.js +0 -4
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/agents/agent-effort-policy.js +11 -21
- package/dist/core/agents/agent-recursion-guard.js +26 -0
- package/dist/core/agents/agent-runner-codex-exec.js +7 -9
- package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
- package/dist/core/architecture-hardening/state/state-service.js +49 -13
- package/dist/core/auto-review.js +15 -9
- package/dist/core/codex/codex-config-guard.js +8 -0
- package/dist/core/codex-adapter.js +8 -10
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
- package/dist/core/codex-app/codex-app-launcher.js +10 -12
- package/dist/core/codex-app/codex-app-restart.js +10 -12
- package/dist/core/codex-app/menubar/constants.js +2 -5
- package/dist/core/codex-app/menubar/global-install.js +3 -2
- package/dist/core/codex-app/menubar/installer/result.js +23 -0
- package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
- package/dist/core/codex-app/menubar/installer.js +5 -96
- package/dist/core/codex-app/menubar/migration.js +1 -42
- package/dist/core/codex-app/openrouter-provider.js +0 -78
- package/dist/core/codex-app.js +97 -360
- package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
- package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
- package/dist/core/codex-control/codex-task-runner.js +16 -60
- package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
- package/dist/core/codex-exec-output-schema.js +11 -13
- package/dist/core/codex-lb/bridge-contracts.js +2 -0
- package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
- package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
- package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
- package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
- package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
- package/dist/core/codex-lb/capability-runner.js +505 -201
- package/dist/core/codex-lb/codex-lb-env.js +179 -12
- package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
- package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
- package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
- package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
- package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
- package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
- package/dist/core/codex-lb/combined-catalog.js +12 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
- package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
- package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
- package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
- package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
- package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
- package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
- package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
- package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
- package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
- package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
- package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
- package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
- package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
- package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
- package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
- package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
- package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
- package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
- package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
- package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
- package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
- package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
- package/dist/core/codex-lb/desktop-controller.js +2 -1730
- package/dist/core/codex-lb/desktop-service.js +462 -627
- package/dist/core/codex-lb/migration-receipt.js +560 -118
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
- package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
- package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
- package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
- package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
- package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
- package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
- package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
- package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
- package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
- package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
- package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
- package/dist/core/codex-lb/provider-credentials/types.js +1 -0
- package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
- package/dist/core/codex-lb/provider-credentials.js +5 -0
- package/dist/core/codex-lb/provider-registry.js +323 -0
- package/dist/core/codex-lb/provider-route-policy.js +118 -0
- package/dist/core/codex-lb/request-route-resolver.js +172 -0
- package/dist/core/codex-lb/route-index.js +148 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/check-command.js +3 -10
- package/dist/core/commands/gate-result-contract.js +10 -14
- package/dist/core/commands/intent-normalization/normalizer.js +1 -1
- package/dist/core/commands/mad-sks-command.js +2 -6
- package/dist/core/commands/release-command.js +11 -1
- package/dist/core/commands/telegram-command.js +46 -6
- package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
- package/dist/core/doctor/skill-legacy-surface.js +5 -5
- package/dist/core/evidence/v2/evidence-key.js +30 -3
- package/dist/core/feature-fixtures.js +8 -1
- package/dist/core/feature-registry.js +3 -2
- package/dist/core/hooks-runtime/stop-finalization.js +11 -1
- package/dist/core/hooks-runtime/subagent-context.js +15 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +73 -87
- package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
- package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
- package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
- package/dist/core/imagegen/imagegen-capability.js +43 -151
- package/dist/core/init/skills/filesystem.js +89 -0
- package/dist/core/init/skills/inventory.js +97 -0
- package/dist/core/init/skills/manifest.js +151 -0
- package/dist/core/init/skills.js +5 -325
- package/dist/core/init.js +0 -63
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
- package/dist/core/policy/latest-version-guidance.js +15 -2
- package/dist/core/preflight/parallel-preflight-engine.js +27 -51
- package/dist/core/provider/provider-badge.js +9 -4
- package/dist/core/provider/provider-context.js +57 -107
- package/dist/core/providers/openrouter/openrouter-account.js +3 -1
- package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
- package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
- package/dist/core/release/gate-manifest.js +0 -1
- package/dist/core/release/main-push-guard.js +13 -0
- package/dist/core/release/main-push-receipt.js +11 -0
- package/dist/core/release/physical-release-gates.js +664 -61
- package/dist/core/release/publish-preflight.js +3 -3
- package/dist/core/release/release-gate-batch-runner.js +19 -6
- package/dist/core/release/release-gate-dag.js +33 -6
- package/dist/core/release/release-gate-node.js +1 -3
- package/dist/core/release/release-gate-output-contract.js +55 -0
- package/dist/core/release/release-pack-contract.js +1 -1
- package/dist/core/release/release-pack-receipt.js +209 -8
- package/dist/core/release/release-real-contract.js +1 -1
- package/dist/core/release/stage-publish.js +106 -28
- package/dist/core/retention/temp-lease.js +204 -0
- package/dist/core/retention.js +18 -195
- package/dist/core/routes.js +1 -2
- package/dist/core/safety/intent-contract/intent-contract.js +3 -3
- package/dist/core/subagents/naruto-host-credentials.js +6 -1
- package/dist/core/subagents/official-subagent-config.js +27 -9
- package/dist/core/subagents/official-subagent-runner.js +14 -31
- package/dist/core/subagents/wave-lifecycle.js +36 -8
- package/dist/core/subagents/wave-parent-guidance.js +2 -1
- package/dist/core/telegram/doctor.js +2 -2
- package/dist/core/telegram/liveness.js +10 -4
- package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
- package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
- package/dist/core/update/update-migration-state/session-state-split.js +247 -0
- package/dist/core/update/update-migration-state/simple-stages.js +46 -0
- package/dist/core/update/update-migration-state.js +4 -481
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
- package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
- package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
- package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-runtime-schemas.js +7 -2
- package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
- package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
- package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
- package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
- package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
- package/dist/scripts/desktop-bridge-transport-client.js +116 -0
- package/dist/scripts/desktop-bridge-unification-check.js +276 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
- package/dist/scripts/gate-policy-audit-check.js +52 -2
- package/dist/scripts/provider-badge-context-check.js +55 -12
- package/dist/scripts/publish-preflight.js +1 -2
- package/dist/scripts/release-affected-selector-check.js +1 -2
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +9 -0
- package/dist/scripts/release-gate-dag-runner-check.js +6 -0
- package/dist/scripts/release-gate-dag-runner.js +4 -2
- package/dist/scripts/release-metadata-check.js +16 -3
- package/dist/scripts/release-pack-receipt.js +29 -6
- package/dist/scripts/release-physical-gates-check.js +39 -0
- package/dist/scripts/release-real-check.js +7 -5
- package/package.json +6 -8
- package/release-gates.v2.json +156 -157
- package/runtime-required-scripts.json +11 -11
- package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
- package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
- package/schemas/release/release-gate-node.schema.json +2 -3
- package/dist/cli/codex-lb-setup-warning-output.js +0 -17
- package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
- package/dist/commands/codex-lb.js +0 -1232
- package/dist/core/architecture-hardening/migration/migration.js +0 -111
- package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
- package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
- package/dist/core/codex-app/child-policy/child-policy.js +0 -35
- package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
- package/dist/core/codex-app/glm-model-profile.js +0 -1
- package/dist/core/codex-app/glm-profile-installer.js +0 -191
- package/dist/core/codex-app/glm-profile-schema.js +0 -42
- package/dist/core/codex-app/multi-provider-router.js +0 -391
- package/dist/core/codex-app/openrouter-activate.js +0 -405
- package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
- package/dist/core/codex-app/provider-child-policy.js +0 -64
- package/dist/core/codex-app/provider-mode.js +0 -91
- package/dist/core/codex-app/provider-session-policy.js +0 -85
- package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
- package/dist/core/codex-lb/codex-lb-setup.js +0 -293
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
- package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
- package/dist/core/codex-lb/desktop-mode.js +0 -32
- package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
- package/dist/core/codex-lb/legacy-migration.js +0 -576
- package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
- package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
- package/dist/core/codex-lb/routing-truth.js +0 -327
- package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import fsp from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { writeJsonAtomic } from '../../fsx.js';
|
|
4
|
-
import { validateArchitectureConfiguration } from '../contracts/contracts.js';
|
|
5
4
|
export const ARCHITECTURE_STATE_SCHEMA = 'sks.architecture-state.v1';
|
|
5
|
+
export const APPLY_RECEIPTS_SCHEMA = 'sks.apply-receipts.v1';
|
|
6
|
+
export const APPLY_STAGE_RECEIPT_SCHEMA = 'sks.apply-stage-receipt.v1';
|
|
6
7
|
export const APPLY_STAGE_ORDER = [
|
|
7
8
|
'config_saved',
|
|
8
9
|
'proxy_applied',
|
|
@@ -21,18 +22,18 @@ export class ArchitectureStateService {
|
|
|
21
22
|
this.receiptPath = path.join(this.root, 'apply-receipt.json');
|
|
22
23
|
}
|
|
23
24
|
async stage(configuration) {
|
|
24
|
-
const validated =
|
|
25
|
+
const validated = cloneJsonState(configuration);
|
|
25
26
|
await fsp.mkdir(this.root, { recursive: true, mode: 0o700 });
|
|
26
27
|
await writeJsonAtomic(this.draftPath, validated, { mode: 0o600 });
|
|
27
28
|
return validated;
|
|
28
29
|
}
|
|
29
30
|
async commit(ports, now = () => new Date()) {
|
|
30
|
-
const draft = await
|
|
31
|
+
const draft = await readState(this.draftPath);
|
|
31
32
|
if (!draft)
|
|
32
33
|
return { ok: false, status: 'failed', receipts: [], blocker: 'state_draft_missing' };
|
|
33
34
|
const receipts = APPLY_STAGE_ORDER.map((stage) => receipt(stage, 'pending', null, now));
|
|
34
35
|
const persist = async () => {
|
|
35
|
-
await writeJsonAtomic(this.receiptPath, { schema:
|
|
36
|
+
await writeJsonAtomic(this.receiptPath, { schema: APPLY_RECEIPTS_SCHEMA, stages: receipts }, { mode: 0o600 });
|
|
36
37
|
};
|
|
37
38
|
await persist();
|
|
38
39
|
const runStage = async (stage, action) => {
|
|
@@ -76,10 +77,10 @@ export class ArchitectureStateService {
|
|
|
76
77
|
throw error;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
async read(
|
|
80
|
+
async read() {
|
|
80
81
|
const [draft, lastKnownGood, receipts] = await Promise.all([
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
readState(this.draftPath),
|
|
83
|
+
readState(this.lastKnownGoodPath),
|
|
83
84
|
readReceipts(this.receiptPath)
|
|
84
85
|
]);
|
|
85
86
|
return {
|
|
@@ -87,7 +88,6 @@ export class ArchitectureStateService {
|
|
|
87
88
|
draft,
|
|
88
89
|
last_known_good: lastKnownGood,
|
|
89
90
|
receipts,
|
|
90
|
-
existing_session: existingSession,
|
|
91
91
|
new_session_default: lastKnownGood
|
|
92
92
|
};
|
|
93
93
|
}
|
|
@@ -99,7 +99,7 @@ class StateApplyError extends Error {
|
|
|
99
99
|
this.code = code;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
async function
|
|
102
|
+
async function readState(file) {
|
|
103
103
|
let raw;
|
|
104
104
|
try {
|
|
105
105
|
raw = await fsp.readFile(file, 'utf8');
|
|
@@ -109,12 +109,12 @@ async function readConfiguration(file) {
|
|
|
109
109
|
return null;
|
|
110
110
|
throw error;
|
|
111
111
|
}
|
|
112
|
-
return
|
|
112
|
+
return cloneJsonState(JSON.parse(raw));
|
|
113
113
|
}
|
|
114
114
|
async function readReceipts(file) {
|
|
115
115
|
try {
|
|
116
116
|
const parsed = JSON.parse(await fsp.readFile(file, 'utf8'));
|
|
117
|
-
if (parsed.schema !==
|
|
117
|
+
if (parsed.schema !== APPLY_RECEIPTS_SCHEMA || !Array.isArray(parsed.stages))
|
|
118
118
|
return [];
|
|
119
119
|
return parsed.stages.filter(isReceipt);
|
|
120
120
|
}
|
|
@@ -126,7 +126,7 @@ async function readReceipts(file) {
|
|
|
126
126
|
}
|
|
127
127
|
function receipt(stage, status, reasonCode, now) {
|
|
128
128
|
return {
|
|
129
|
-
schema:
|
|
129
|
+
schema: APPLY_STAGE_RECEIPT_SCHEMA,
|
|
130
130
|
stage,
|
|
131
131
|
status,
|
|
132
132
|
reason_code: reasonCode,
|
|
@@ -143,12 +143,48 @@ function isReceipt(value) {
|
|
|
143
143
|
if (!value || typeof value !== 'object')
|
|
144
144
|
return false;
|
|
145
145
|
const row = value;
|
|
146
|
-
return row.schema ===
|
|
146
|
+
return row.schema === APPLY_STAGE_RECEIPT_SCHEMA
|
|
147
147
|
&& APPLY_STAGE_ORDER.includes(row.stage)
|
|
148
148
|
&& ['pending', 'running', 'succeeded', 'failed'].includes(String(row.status))
|
|
149
149
|
&& (row.reason_code === null || typeof row.reason_code === 'string')
|
|
150
150
|
&& typeof row.updated_at === 'string';
|
|
151
151
|
}
|
|
152
|
+
function cloneJsonState(value) {
|
|
153
|
+
validateJsonValue(value, true, new Set());
|
|
154
|
+
return JSON.parse(JSON.stringify(value));
|
|
155
|
+
}
|
|
156
|
+
function validateJsonValue(value, root, ancestors) {
|
|
157
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
158
|
+
return;
|
|
159
|
+
if (typeof value === 'number') {
|
|
160
|
+
if (Number.isFinite(value))
|
|
161
|
+
return;
|
|
162
|
+
throw new StateApplyError('state_configuration_not_json_safe');
|
|
163
|
+
}
|
|
164
|
+
if (typeof value !== 'object')
|
|
165
|
+
throw new StateApplyError('state_configuration_not_json_safe');
|
|
166
|
+
if (root && Array.isArray(value))
|
|
167
|
+
throw new StateApplyError('state_configuration_not_json_object');
|
|
168
|
+
if (ancestors.has(value))
|
|
169
|
+
throw new StateApplyError('state_configuration_not_json_safe');
|
|
170
|
+
ancestors.add(value);
|
|
171
|
+
if (Array.isArray(value)) {
|
|
172
|
+
for (const entry of value)
|
|
173
|
+
validateJsonValue(entry, false, ancestors);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const prototype = Object.getPrototypeOf(value);
|
|
177
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
178
|
+
throw new StateApplyError('state_configuration_not_json_safe');
|
|
179
|
+
}
|
|
180
|
+
if (Reflect.ownKeys(value).some((key) => typeof key === 'symbol')) {
|
|
181
|
+
throw new StateApplyError('state_configuration_not_json_safe');
|
|
182
|
+
}
|
|
183
|
+
for (const entry of Object.values(value))
|
|
184
|
+
validateJsonValue(entry, false, ancestors);
|
|
185
|
+
}
|
|
186
|
+
ancestors.delete(value);
|
|
187
|
+
}
|
|
152
188
|
function safeFailureCode(error) {
|
|
153
189
|
const candidate = error instanceof Error ? error.message : '';
|
|
154
190
|
return /^[a-z][a-z0-9_]{2,99}$/.test(candidate) ? candidate : 'state_apply_failed';
|
package/dist/core/auto-review.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
3
4
|
import { ensureDir, exists, readText, writeTextAtomic } from './fsx.js';
|
|
4
5
|
import { writeCodexConfigGuarded } from './codex/codex-config-guard.js';
|
|
5
6
|
import { inspectConfinedPath, removeManagedPathVerified } from './managed-path-safety.js';
|
|
6
7
|
import { RETIRED_AUTO_REVIEW_POLICY_TEXTS, RETIRED_SKS_CONFIG_PROFILE_NAMES } from './doctor/retired-auto-review-config.js';
|
|
7
|
-
import { retiredGlmDesktopProfileBody } from './codex-app/openrouter-provider.js';
|
|
8
8
|
import { escapeRegExp } from './text/regex.js';
|
|
9
9
|
export { RETIRED_SKS_CONFIG_PROFILE_NAMES } from './doctor/retired-auto-review-config.js';
|
|
10
10
|
export const AUTO_REVIEW_REVIEWER = 'auto_review';
|
|
@@ -201,7 +201,8 @@ export function reconcileRetiredSksConfigText(text) {
|
|
|
201
201
|
}
|
|
202
202
|
export function isSksGeneratedRetiredProfileText(text) {
|
|
203
203
|
const normalized = normalizeGeneratedProfileText(text);
|
|
204
|
-
return managedRetiredProfileBodies().has(normalized)
|
|
204
|
+
return managedRetiredProfileBodies().has(normalized)
|
|
205
|
+
|| HISTORICAL_OPENROUTER_PROFILE_SHA256.has(sha256(normalized));
|
|
205
206
|
}
|
|
206
207
|
export function buildMadHighLaunchProfileNoWrite(opts = {}) {
|
|
207
208
|
const env = opts.env || process.env;
|
|
@@ -461,12 +462,17 @@ function managedRetiredProfileBodies() {
|
|
|
461
462
|
'approval_policy = "on-request"',
|
|
462
463
|
'sandbox_mode = "workspace-write"',
|
|
463
464
|
'model_reasoning_effort = "medium"'
|
|
464
|
-
].join('\n')
|
|
465
|
-
retiredGlmDesktopProfileBody('none'),
|
|
466
|
-
retiredGlmDesktopProfileBody('minimal'),
|
|
467
|
-
retiredGlmDesktopProfileBody('low'),
|
|
468
|
-
retiredGlmDesktopProfileBody('medium'),
|
|
469
|
-
retiredGlmDesktopProfileBody('high'),
|
|
470
|
-
retiredGlmDesktopProfileBody('xhigh')
|
|
465
|
+
].join('\n')
|
|
471
466
|
].map(normalizeGeneratedProfileText));
|
|
472
467
|
}
|
|
468
|
+
const HISTORICAL_OPENROUTER_PROFILE_SHA256 = new Set([
|
|
469
|
+
'8405d346127e87805f284caa6c2f20a67cbd96595c4f3b194a46212c650837c4',
|
|
470
|
+
'ff97ebf844785bdd21e5b28dd109ec5684873fe52e75386c1bd1bd19c7cedcc8',
|
|
471
|
+
'be337e958e9379e72ccf8dd5576c1e4d8d348c338cebc4d68690bfb9d94a3048',
|
|
472
|
+
'feb9f6be9e4596a2a897f3c6b5b735fa838e64227a0fba1051d1ac93c0613e8c',
|
|
473
|
+
'0a482903a52392434f3746451166ad54e95053e6777c5013edf9fec2da23692e',
|
|
474
|
+
'364fbce652087e4ae8284bdb51e664e9c4e37eafee146123c68d5a6fb036c347'
|
|
475
|
+
]);
|
|
476
|
+
function sha256(text) {
|
|
477
|
+
return createHash('sha256').update(text).digest('hex');
|
|
478
|
+
}
|
|
@@ -5,6 +5,7 @@ import { appendJsonl, ensureDir, nowIso, readText, sha256, writeTextAtomic } fro
|
|
|
5
5
|
import { diffCodexAppUiSnapshots, snapshotCodexAppUiState } from '../codex-app/codex-app-ui-state-snapshot.js';
|
|
6
6
|
import { cleanupCodexConfigBackups, validateCodexConfigRoundTrip } from './codex-config-toml.js';
|
|
7
7
|
import { escapeRegExp } from '../text/regex.js';
|
|
8
|
+
import { withFileLock } from '../locks/file-lock.js';
|
|
8
9
|
export const SKS_MANAGED_CODEX_CONFIG_MARKER = '# SKS-MANAGED-CODEX-CONFIG';
|
|
9
10
|
const FAST_FEATURE_KEYS = [
|
|
10
11
|
'fast_mode',
|
|
@@ -21,6 +22,13 @@ const FAST_FEATURE_KEYS = [
|
|
|
21
22
|
];
|
|
22
23
|
export async function writeCodexConfigGuarded(input) {
|
|
23
24
|
const configPath = path.resolve(input.configPath);
|
|
25
|
+
return withFileLock({
|
|
26
|
+
lockPath: `${configPath}.lock`,
|
|
27
|
+
timeoutMs: 10_000,
|
|
28
|
+
staleMs: 60_000
|
|
29
|
+
}, () => writeCodexConfigGuardedUnlocked(input, configPath));
|
|
30
|
+
}
|
|
31
|
+
async function writeCodexConfigGuardedUnlocked(input, configPath) {
|
|
24
32
|
const root = path.resolve(input.root || process.cwd());
|
|
25
33
|
const cause = input.cause || 'codex-config';
|
|
26
34
|
const before = input.before === undefined ? String(await readText(configPath, '')) : String(input.before || '');
|
|
@@ -3,7 +3,7 @@ import { runProcess } from './fsx.js';
|
|
|
3
3
|
import { preserveCodexModelArgs } from './codex-model-guard.js';
|
|
4
4
|
import { managedProxyEnvForChild } from './codex/managed-proxy-env.js';
|
|
5
5
|
import { resolveCodexRuntime } from './codex-runtime/resolve-codex-runtime.js';
|
|
6
|
-
import {
|
|
6
|
+
import { desktopBridgeLaunchBlockedProcessResult, withDesktopBridgeCliLaunchGuard } from './codex-control/desktop-bridge-launch-guard.js';
|
|
7
7
|
import { prepareCodexAppServerRuntimeEnv } from './codex-control/codex-app-server-runtime-env.js';
|
|
8
8
|
export async function findCodexBinary() {
|
|
9
9
|
const resolved = await resolveCodexRuntime({
|
|
@@ -41,18 +41,16 @@ export function buildCodexExecArgs({ root, prompt, outputFile, json = true, prof
|
|
|
41
41
|
args.push(prompt);
|
|
42
42
|
return args;
|
|
43
43
|
}
|
|
44
|
-
export async function runCodexExec({ root, recoveryRoot = root, prompt, outputFile, json = true, profile = null, extraArgs = [], onStdout, onStderr, logDir = null, stdoutFile = null, stderrFile = null, maxBufferBytes = 256 * 1024, timeoutMs = null, env = process.env, codexBin = null, findCodexBinaryImpl = findCodexBinary, runProcessImpl = runProcess, prepareCodexRuntimeEnvImpl = prepareCodexAppServerRuntimeEnv
|
|
44
|
+
export async function runCodexExec({ root, recoveryRoot = root, prompt, outputFile, json = true, profile = null, extraArgs = [], onStdout, onStderr, logDir = null, stdoutFile = null, stderrFile = null, maxBufferBytes = 256 * 1024, timeoutMs = null, env = process.env, codexBin = null, findCodexBinaryImpl = findCodexBinary, runProcessImpl = runProcess, prepareCodexRuntimeEnvImpl = prepareCodexAppServerRuntimeEnv }) {
|
|
45
45
|
const args = buildCodexExecArgs({ root, prompt, outputFile, json, profile, extraArgs });
|
|
46
46
|
const effectiveTimeoutMs = Number(timeoutMs || process.env.SKS_CODEX_TIMEOUT_MS || process.env.DCODEX_CODEX_TIMEOUT_MS || 30 * 60 * 1000);
|
|
47
47
|
const recoveryArgs = args.slice(1, -1);
|
|
48
48
|
const runtimeEnv = await prepareCodexRuntimeEnvImpl({ env });
|
|
49
|
-
const guarded = await
|
|
49
|
+
const guarded = await withDesktopBridgeCliLaunchGuard({
|
|
50
50
|
root: recoveryRoot,
|
|
51
51
|
env: runtimeEnv,
|
|
52
|
-
cliArgs: recoveryArgs
|
|
53
|
-
|
|
54
|
-
...(recoveryTimeoutMs === undefined ? {} : { timeoutMs: recoveryTimeoutMs })
|
|
55
|
-
}, async () => {
|
|
52
|
+
cliArgs: recoveryArgs
|
|
53
|
+
}, async (sanitizedEnv) => {
|
|
56
54
|
const bin = codexBin || await findCodexBinaryImpl();
|
|
57
55
|
if (!bin) {
|
|
58
56
|
return {
|
|
@@ -67,7 +65,7 @@ export async function runCodexExec({ root, recoveryRoot = root, prompt, outputFi
|
|
|
67
65
|
}
|
|
68
66
|
return runProcessImpl(bin, args, {
|
|
69
67
|
cwd: root,
|
|
70
|
-
env: { ...
|
|
68
|
+
env: { ...sanitizedEnv, ...managedProxyEnvForChild(sanitizedEnv) },
|
|
71
69
|
onStdout,
|
|
72
70
|
onStderr,
|
|
73
71
|
timeoutMs: effectiveTimeoutMs,
|
|
@@ -77,6 +75,6 @@ export async function runCodexExec({ root, recoveryRoot = root, prompt, outputFi
|
|
|
77
75
|
});
|
|
78
76
|
});
|
|
79
77
|
return guarded.launched
|
|
80
|
-
? guarded.value
|
|
81
|
-
:
|
|
78
|
+
? { ...guarded.value, desktop_bridge_launch_guard: guarded.desktopBridgeLaunchGuard }
|
|
79
|
+
: desktopBridgeLaunchBlockedProcessResult(guarded.desktopBridgeLaunchGuard);
|
|
82
80
|
}
|
|
@@ -74,6 +74,12 @@ export async function repairCodexAppFastUi(root = process.cwd(), input = {}) {
|
|
|
74
74
|
home: path.dirname(home),
|
|
75
75
|
configPath: path.join(home, 'config.toml'),
|
|
76
76
|
codexLbEnvPath: path.join(home, 'sks-codex-lb.env'),
|
|
77
|
+
desktopBridgeStatusOptions: {
|
|
78
|
+
home: path.dirname(home),
|
|
79
|
+
env: input.env || process.env,
|
|
80
|
+
configPath: path.join(home, 'config.toml'),
|
|
81
|
+
authPath: path.join(home, 'auth.json')
|
|
82
|
+
},
|
|
77
83
|
...(input.codexLbModelCatalog ? { codexLbModelCatalog: input.codexLbModelCatalog } : {}),
|
|
78
84
|
...(input.desktopPickerEvidence ? { desktopPickerEvidence: input.desktopPickerEvidence } : {})
|
|
79
85
|
});
|
|
@@ -122,7 +128,7 @@ export async function repairCodexAppFastUi(root = process.cwd(), input = {}) {
|
|
|
122
128
|
auth_mode: after.indicators.auth_mode,
|
|
123
129
|
chat_surface: after.indicators.chat_surface,
|
|
124
130
|
chatgpt_oauth_backup_available: after.indicators.chatgpt_oauth_backup_available,
|
|
125
|
-
next_action: requiresConfirmation ? 'Run `sks doctor --fix --repair-codex-app-ui` after reviewing the repair plan.' : manual && safeAutoApply ? 'Run `sks doctor --fix` to apply the safe Codex App UI repair.' : manual ? 'Run `sks doctor --fix --repair-codex-app-ui` after reviewing the repair plan.' : chatgptOauthInactive ? 'Run `
|
|
131
|
+
next_action: requiresConfirmation ? 'Run `sks doctor --fix --repair-codex-app-ui` after reviewing the repair plan.' : manual && safeAutoApply ? 'Run `sks doctor --fix` to apply the safe Codex App UI repair.' : manual ? 'Run `sks doctor --fix --repair-codex-app-ui` after reviewing the repair plan.' : chatgptOauthInactive ? 'Run `codex login` if ChatGPT OAuth is unavailable, then run `sks bridge ensure`; Desktop Bridge provider commands do not replace ChatGPT OAuth.' : changed ? 'Restart Codex App if the selector was already hidden.' : 'No Codex App UI repair needed.',
|
|
126
132
|
blockers
|
|
127
133
|
};
|
|
128
134
|
if (input.reportPath)
|
|
@@ -173,42 +179,14 @@ function stripProjectLocalForbiddenKeys(text) {
|
|
|
173
179
|
}
|
|
174
180
|
function stripSksCausedHostOwnedLines(text) {
|
|
175
181
|
const sourceLines = String(text || '').split(/\r?\n/);
|
|
176
|
-
const preserveCodexLbSelection = hasActiveCodexLbProviderSelection(text);
|
|
177
|
-
const preserveOpenRouterSelection = hasActiveOpenRouterProviderSelection(text);
|
|
178
182
|
const stripped = stripMatchingLines(text, (line, table, _previous, _next, index) => {
|
|
179
183
|
const isLegacyFastTable = table ? FAST_UI_LEGACY_TABLES.has(table) : false;
|
|
180
184
|
if (isLegacyFastTable)
|
|
181
185
|
return true;
|
|
182
|
-
if (!table && preserveCodexLbSelection && /^\s*model_provider\s*=\s*"codex-lb"\s*(?:#.*)?$/.test(line))
|
|
183
|
-
return false;
|
|
184
|
-
if (!table && preserveOpenRouterSelection && /^\s*(?:model_provider\s*=\s*"openrouter"|model\s*=)/.test(line))
|
|
185
|
-
return false;
|
|
186
186
|
return !table && FAST_UI_TOP_LEVEL_RE.test(line) && isSksOwnedGlobalUiLock(sourceLines, index);
|
|
187
187
|
});
|
|
188
188
|
return stripped;
|
|
189
189
|
}
|
|
190
|
-
function hasActiveOpenRouterProviderSelection(text) {
|
|
191
|
-
const source = String(text || '');
|
|
192
|
-
if (!/(?:^|\n)\s*model_provider\s*=\s*"openrouter"\s*(?:#.*)?(?=\n|$)/.test(source))
|
|
193
|
-
return false;
|
|
194
|
-
const body = source.match(/(?:^|\n)\[model_providers\.openrouter\]([^\n]*(?:\n(?!\s*\[)[^\n]*)*)/)?.[1] || '';
|
|
195
|
-
return /(?:^|\n)\s*base_url\s*=\s*"https:\/\/openrouter\.ai\/api\/v1"\s*(?:#.*)?(?=\n|$)/.test(body)
|
|
196
|
-
&& /(?:^|\n)\s*wire_api\s*=\s*"responses"\s*(?:#.*)?(?=\n|$)/.test(body);
|
|
197
|
-
}
|
|
198
|
-
function hasActiveCodexLbProviderSelection(text) {
|
|
199
|
-
const source = String(text || '');
|
|
200
|
-
if (!/(?:^|\n)\s*model_provider\s*=\s*"codex-lb"\s*(?:#.*)?(?=\n|$)/.test(source))
|
|
201
|
-
return false;
|
|
202
|
-
const body = source.match(/(?:^|\n)\[model_providers\.codex-lb\]([^\n]*(?:\n(?!\s*\[)[^\n]*)*)/)?.[1] || '';
|
|
203
|
-
const providerIdentity = /(?:^|\n)\s*name\s*=\s*"(?:openai|codex-lb)"\s*(?:#.*)?(?=\n|$)/i.test(body);
|
|
204
|
-
const baseUrl = /(?:^|\n)\s*base_url\s*=\s*"https?:\/\/[^"]+"\s*(?:#.*)?(?=\n|$)/.test(body);
|
|
205
|
-
const responsesWire = /(?:^|\n)\s*wire_api\s*=\s*"responses"\s*(?:#.*)?(?=\n|$)/.test(body);
|
|
206
|
-
const cliProviderAuth = /(?:^|\n)\s*env_key\s*=\s*"CODEX_LB_API_KEY"\s*(?:#.*)?(?=\n|$)/.test(body)
|
|
207
|
-
&& /(?:^|\n)\s*requires_openai_auth\s*=\s*false\s*(?:#.*)?(?=\n|$)/.test(body);
|
|
208
|
-
const desktopCompatAuth = /(?:^|\n)\s*env_http_headers\s*=\s*\{[^}\n]*"X-Codex-LB-API-Key"\s*=\s*"CODEX_LB_API_KEY"[^}\n]*\}\s*(?:#.*)?(?=\n|$)/.test(body)
|
|
209
|
-
&& /(?:^|\n)\s*requires_openai_auth\s*=\s*true\s*(?:#.*)?(?=\n|$)/.test(body);
|
|
210
|
-
return providerIdentity && baseUrl && responsesWire && (cliProviderAuth || desktopCompatAuth);
|
|
211
|
-
}
|
|
212
190
|
function stripMatchingLines(text, shouldRemove) {
|
|
213
191
|
const lines = text.split(/\r?\n/);
|
|
214
192
|
let table = null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
2
2
|
import { runProcess } from '../fsx.js';
|
|
3
|
-
import {
|
|
3
|
+
import { inspectDesktopBridgeCliLaunchGuard, stripRetiredDirectProviderEnv } from '../codex-control/desktop-bridge-launch-guard.js';
|
|
4
4
|
export async function attemptCodexAppLaunch(input) {
|
|
5
5
|
const platform = input.platform || process.platform;
|
|
6
6
|
const timeoutMs = Math.max(1, Math.min(Number(input.timeoutMs || 3000), 3000));
|
|
@@ -46,16 +46,14 @@ export async function attemptCodexAppLaunch(input) {
|
|
|
46
46
|
blockers: launched ? [] : ['codex_app_launch_failed']
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
const env = input.env || process.env;
|
|
49
|
+
const env = stripRetiredDirectProviderEnv(input.env || process.env);
|
|
50
50
|
const execute = input.runProcessImpl || runProcess;
|
|
51
|
-
const
|
|
51
|
+
const launchGuard = await inspectDesktopBridgeCliLaunchGuard({
|
|
52
52
|
root: input.cwd,
|
|
53
53
|
env,
|
|
54
|
-
cliArgs: ['/app']
|
|
55
|
-
...(input.recoveryFetch ? { fetchImpl: input.recoveryFetch } : {}),
|
|
56
|
-
...(input.recoveryTimeoutMs === undefined ? {} : { timeoutMs: input.recoveryTimeoutMs })
|
|
54
|
+
cliArgs: ['/app']
|
|
57
55
|
});
|
|
58
|
-
if (!
|
|
56
|
+
if (!launchGuard.ok) {
|
|
59
57
|
return launchAttempt({
|
|
60
58
|
attempted: false,
|
|
61
59
|
launched: false,
|
|
@@ -63,9 +61,9 @@ export async function attemptCodexAppLaunch(input) {
|
|
|
63
61
|
mode: input.mode,
|
|
64
62
|
command_line: commandLine,
|
|
65
63
|
exit_code: null,
|
|
66
|
-
fallback_reason: '
|
|
67
|
-
blockers:
|
|
68
|
-
|
|
64
|
+
fallback_reason: 'desktop_bridge_launch_guard_blocked',
|
|
65
|
+
blockers: launchGuard.blockers,
|
|
66
|
+
desktop_bridge_launch_guard: launchGuard
|
|
69
67
|
});
|
|
70
68
|
}
|
|
71
69
|
codexBin ||= await (input.findCodexBinaryImpl || findCodexBinary)();
|
|
@@ -80,7 +78,7 @@ export async function attemptCodexAppLaunch(input) {
|
|
|
80
78
|
exit_code: null,
|
|
81
79
|
fallback_reason: 'codex_cli_missing_artifact_only_fallback',
|
|
82
80
|
blockers: ['codex_cli_missing'],
|
|
83
|
-
|
|
81
|
+
desktop_bridge_launch_guard: launchGuard
|
|
84
82
|
});
|
|
85
83
|
}
|
|
86
84
|
const result = await execute(codexBin, ['/app'], {
|
|
@@ -120,7 +118,7 @@ export async function attemptCodexAppLaunch(input) {
|
|
|
120
118
|
stderr_tail: stderr.slice(-4000),
|
|
121
119
|
fallback_reason: fallbackReason,
|
|
122
120
|
blockers: launched ? [] : [timedOut ? 'codex_app_launch_interactive_or_timeout' : 'codex_app_launch_failed'],
|
|
123
|
-
|
|
121
|
+
desktop_bridge_launch_guard: launchGuard
|
|
124
122
|
});
|
|
125
123
|
}
|
|
126
124
|
function launchAttempt(input) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { exists, runProcess, which } from '../fsx.js';
|
|
2
|
-
import {
|
|
2
|
+
import { inspectDesktopBridgeCliLaunchGuard, stripRetiredDirectProviderEnv } from '../codex-control/desktop-bridge-launch-guard.js';
|
|
3
3
|
export async function quitCodexApp(opts = {}) {
|
|
4
4
|
const env = opts.env || process.env;
|
|
5
5
|
const appName = String(opts.appName || env.SKS_CODEX_APP_NAME || 'ChatGPT');
|
|
@@ -73,7 +73,7 @@ export async function quitCodexApp(opts = {}) {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
export async function restartCodexApp(opts = {}) {
|
|
76
|
-
const env = opts.env || process.env;
|
|
76
|
+
const env = stripRetiredDirectProviderEnv(opts.env || process.env);
|
|
77
77
|
const appName = String(opts.appName || env.SKS_CODEX_APP_NAME || 'ChatGPT');
|
|
78
78
|
const bundleId = String(opts.bundleId || env.SKS_CODEX_APP_BUNDLE_ID || 'com.openai.codex');
|
|
79
79
|
if (opts.enabled === false || env.SKS_SKIP_CODEX_APP_RESTART === '1') {
|
|
@@ -96,22 +96,20 @@ export async function restartCodexApp(opts = {}) {
|
|
|
96
96
|
]
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
|
-
const
|
|
99
|
+
const launchGuard = await inspectDesktopBridgeCliLaunchGuard({
|
|
100
100
|
root: opts.root || process.cwd(),
|
|
101
101
|
env,
|
|
102
|
-
cliArgs: ['/app']
|
|
103
|
-
...(opts.recoveryFetch ? { fetchImpl: opts.recoveryFetch } : {}),
|
|
104
|
-
...(opts.recoveryTimeoutMs === undefined ? {} : { timeoutMs: opts.recoveryTimeoutMs })
|
|
102
|
+
cliArgs: ['/app']
|
|
105
103
|
});
|
|
106
|
-
if (!
|
|
104
|
+
if (!launchGuard.ok) {
|
|
107
105
|
return {
|
|
108
106
|
schema: 'sks.codex-app-restart.v1',
|
|
109
107
|
ok: false,
|
|
110
|
-
status: '
|
|
108
|
+
status: 'desktop_bridge_launch_guard_blocked',
|
|
111
109
|
app_name: appName,
|
|
112
110
|
bundle_id: bundleId,
|
|
113
|
-
blockers:
|
|
114
|
-
|
|
111
|
+
blockers: launchGuard.blockers,
|
|
112
|
+
desktop_bridge_launch_guard: launchGuard
|
|
115
113
|
};
|
|
116
114
|
}
|
|
117
115
|
const appTarget = bundleId ? `application id ${JSON.stringify(bundleId)}` : `application ${JSON.stringify(appName)}`;
|
|
@@ -145,7 +143,7 @@ export async function restartCodexApp(opts = {}) {
|
|
|
145
143
|
quit: { ok: true, code: quit.code, error: null },
|
|
146
144
|
exit_wait: { ok: false, attempts, error: 'codex_app_exit_timeout' },
|
|
147
145
|
blockers: ['codex_app_exit_timeout'],
|
|
148
|
-
|
|
146
|
+
desktop_bridge_launch_guard: launchGuard
|
|
149
147
|
};
|
|
150
148
|
}
|
|
151
149
|
await sleep(Number(opts.delayMs ?? env.SKS_CODEX_APP_RESTART_DELAY_MS ?? 150));
|
|
@@ -168,7 +166,7 @@ export async function restartCodexApp(opts = {}) {
|
|
|
168
166
|
...(quitOk ? [] : ['codex_app_quit_failed']),
|
|
169
167
|
...(openOk ? [] : ['codex_app_open_failed'])
|
|
170
168
|
],
|
|
171
|
-
|
|
169
|
+
desktop_bridge_launch_guard: launchGuard
|
|
172
170
|
};
|
|
173
171
|
}
|
|
174
172
|
function skipped(appName, reason) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export const SKS_MENUBAR_LABEL = 'com.sneakoscope.sks-menubar';
|
|
2
2
|
export const CONTROL_CENTER_DOMAIN = 'com.apple.controlcenter';
|
|
3
3
|
export const CONTROL_CENTER_PREFERRED_POSITION = 360;
|
|
4
|
-
export const SECRET_LAUNCH_ENV_KEYS = ['CODEX_LB_API_KEY', 'OPENROUTER_API_KEY'];
|
|
5
4
|
export const MENU_ITEMS = [
|
|
6
5
|
'Open SKS Control Center',
|
|
7
6
|
'Pending approvals',
|
|
@@ -22,16 +21,14 @@ export const NATIVE_SOURCE_FILES = [
|
|
|
22
21
|
'MCPServersViewController.swift',
|
|
23
22
|
'ProvidersViewController.swift',
|
|
24
23
|
'ProvidersReliability.swift',
|
|
25
|
-
'ProvidersConnectTest.swift',
|
|
26
24
|
'ProvidersRoutingTruth.swift',
|
|
27
|
-
'ProvidersFastMode.swift',
|
|
28
25
|
'ProvidersOpenRouter.swift',
|
|
29
|
-
'
|
|
30
|
-
'ProvidersMultiProvider.swift',
|
|
26
|
+
'ProvidersBridgeCatalog.swift',
|
|
31
27
|
'RemoteCodingViewController.swift',
|
|
32
28
|
'DiagnosticsViewController.swift',
|
|
33
29
|
'SettingsViewController.swift',
|
|
34
30
|
'OperationModels.swift',
|
|
31
|
+
'ProviderRouteExplanation.swift',
|
|
35
32
|
'OperationCoordinator.swift',
|
|
36
33
|
'ProcessClient.swift',
|
|
37
34
|
'ProcessExecutionState.swift',
|
|
@@ -2,6 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import { exists, nowIso, readJson, readText, runProcess, writeJsonAtomic } from '../../fsx.js';
|
|
3
3
|
import { ensureConfinedDirectory, inspectConfinedPath, removeManagedPathVerified } from '../../managed-path-safety.js';
|
|
4
4
|
const MENU_BAR_EXECUTABLE_SUFFIX = path.join('SKSMenuBar.app', 'Contents', 'MacOS', 'SKSMenuBar');
|
|
5
|
+
const MENU_BAR_PROCESS_DISCOVERY_TIMEOUT_MS = 5_000;
|
|
5
6
|
export function projectMenuBarDuplicateInstallDirs(input) {
|
|
6
7
|
const root = path.resolve(input.root);
|
|
7
8
|
const home = path.resolve(input.paths.home);
|
|
@@ -187,7 +188,7 @@ async function runningMenuBarDuplicateInstallDirs(canonicalInstallDir, env) {
|
|
|
187
188
|
...(uid === null ? [] : ['-U', String(uid)]),
|
|
188
189
|
'-f',
|
|
189
190
|
'SKSMenuBar\\.app/Contents/MacOS/SKSMenuBar'
|
|
190
|
-
], { timeoutMs:
|
|
191
|
+
], { timeoutMs: MENU_BAR_PROCESS_DISCOVERY_TIMEOUT_MS, maxOutputBytes: 32 * 1024 }).catch(() => ({ code: 1, stdout: '' }));
|
|
191
192
|
if (result.code !== 0)
|
|
192
193
|
return [];
|
|
193
194
|
const rows = String(result.stdout || '').split(/\r?\n/).filter(Boolean).map((line) => ({
|
|
@@ -208,7 +209,7 @@ async function runningMenuBarDuplicateInstallDirs(canonicalInstallDir, env) {
|
|
|
208
209
|
unresolvedPids.join(','),
|
|
209
210
|
'-o',
|
|
210
211
|
'pid=,command='
|
|
211
|
-
], { timeoutMs:
|
|
212
|
+
], { timeoutMs: MENU_BAR_PROCESS_DISCOVERY_TIMEOUT_MS, maxOutputBytes: 64 * 1024 }).catch(() => ({ code: 1, stdout: '' }));
|
|
212
213
|
if (processList.code === 0) {
|
|
213
214
|
executablePaths.push(...String(processList.stdout || '')
|
|
214
215
|
.split(/\r?\n/)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { writeJsonAtomic } from '../../../fsx.js';
|
|
2
|
+
import { MENU_ITEMS } from '../constants.js';
|
|
3
|
+
import { sksMenuBarPaths } from '../paths.js';
|
|
4
|
+
import { defaultNextActions } from '../status.js';
|
|
5
|
+
export function baseResult(paths, apply, status, ok, actions, warnings) {
|
|
6
|
+
return {
|
|
7
|
+
schema: 'sks.codex-app-sks-menubar.v1', ok, apply, status, platform: process.platform,
|
|
8
|
+
app_path: paths.app_path, executable_path: paths.executable_path,
|
|
9
|
+
launch_agent_path: paths.launch_agent_path, action_script_path: paths.action_script_path,
|
|
10
|
+
build_stamp_path: paths.build_stamp_path, config_path: paths.config_path,
|
|
11
|
+
report_path: paths.report_path, menu_items: [...MENU_ITEMS], actions,
|
|
12
|
+
tcc_automation_status: 'unknown', next_actions: defaultNextActions(), blockers: [], warnings
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export async function writeReport(reportPath, result) {
|
|
16
|
+
try {
|
|
17
|
+
await writeJsonAtomic(reportPath, result);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
result.report_write_failed = true;
|
|
21
|
+
result.warnings.push('menubar_report_write_failed');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { exists, runProcess } from '../../../fsx.js';
|
|
5
|
+
export async function resolveSksEntryForInstall(explicit, root) {
|
|
6
|
+
const packaged = fileURLToPath(new URL('../../../../bin/sks.js', import.meta.url));
|
|
7
|
+
const requested = explicit ? path.resolve(explicit) : null;
|
|
8
|
+
const candidate = requested || packaged;
|
|
9
|
+
const found = await exists(candidate);
|
|
10
|
+
const relative = path.relative(path.resolve(root), candidate);
|
|
11
|
+
return {
|
|
12
|
+
requested, resolved: found ? candidate : null, packaged, exists: found,
|
|
13
|
+
project_local: relative === '' || (Boolean(relative) && !relative.startsWith('..') && !path.isAbsolute(relative)),
|
|
14
|
+
used_previous_script: false
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export async function toolVersion(tool, args) {
|
|
18
|
+
const result = await runProcess(tool, args, { timeoutMs: 5_000, maxOutputBytes: 16 * 1024 }).catch(() => ({ code: 1, stdout: '', stderr: '' }));
|
|
19
|
+
return result.code === 0 ? String(result.stdout || result.stderr).trim().split(/\r?\n/)[0] || 'unknown' : 'unknown';
|
|
20
|
+
}
|
|
21
|
+
export function realUserHome() {
|
|
22
|
+
try {
|
|
23
|
+
return path.resolve(os.userInfo().homedir);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return path.resolve(os.homedir());
|
|
27
|
+
}
|
|
28
|
+
}
|