sneakoscope 7.3.0 → 7.6.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 +129 -10
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/cli/codex-app-command.js +1 -1
- package/dist/cli/command-manifest-lite.js +4 -1
- package/dist/cli/command-registry.js +2 -0
- package/dist/cli/install-helpers-codex-lb-chain.js +42 -0
- package/dist/cli/install-helpers-codex-lb-config.js +114 -9
- package/dist/cli/install-helpers-install-support.js +6 -16
- package/dist/cli/install-helpers.js +788 -600
- package/dist/cli/router.js +30 -2
- package/dist/commands/codex-app.js +37 -1
- package/dist/commands/codex-lb.js +491 -300
- package/dist/config/skills-manifest.json +57 -71
- package/dist/core/align/align-route.js +127 -0
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +8 -4
- package/dist/core/codex-app/codex-app-restart.js +83 -0
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +8 -4
- package/dist/core/codex-app/desktop-routing-snapshot.js +1 -1
- package/dist/core/codex-app/menubar/constants.js +5 -0
- package/dist/core/codex-app/menubar/generation-transaction-journal.js +1 -3
- package/dist/core/codex-app/menubar/installer.js +18 -0
- package/dist/core/codex-app/multi-provider-router.js +22 -10
- package/dist/core/codex-app/openrouter-activate.js +26 -1
- package/dist/core/codex-app.js +118 -26
- package/dist/core/codex-control/codex-app-server-runtime-env.js +86 -0
- package/dist/core/codex-control/codex-app-server-v2-client.js +78 -8
- package/dist/core/codex-control/codex-task-runner.js +2 -2
- package/dist/core/codex-lb/capability-runner.js +204 -0
- package/dist/core/codex-lb/capability-types.js +1 -0
- package/dist/core/codex-lb/codex-lb-env.js +9 -13
- package/dist/core/codex-lb/codex-lb-setup.js +45 -8
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +52 -74
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
- package/dist/core/codex-lb/desktop-auth-invariant.js +185 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +34 -0
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +106 -0
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +101 -0
- package/dist/core/codex-lb/desktop-bridge/index.js +10 -0
- package/dist/core/codex-lb/desktop-bridge/launchd.js +81 -0
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +27 -0
- package/dist/core/codex-lb/desktop-bridge/security.js +274 -0
- package/dist/core/codex-lb/desktop-bridge/server.js +179 -0
- package/dist/core/codex-lb/desktop-bridge/state.js +119 -0
- package/dist/core/codex-lb/desktop-bridge/types.js +16 -0
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +151 -0
- package/dist/core/codex-lb/desktop-center-credentials.js +189 -0
- package/dist/core/codex-lb/desktop-controller.js +1410 -0
- package/dist/core/codex-lb/desktop-mode.js +32 -0
- package/dist/core/codex-lb/desktop-real-evidence.js +168 -0
- package/dist/core/codex-lb/desktop-service.js +613 -0
- package/dist/core/codex-lb/legacy-migration.js +575 -0
- package/dist/core/codex-lb/migration-receipt.js +246 -0
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +60 -0
- package/dist/core/codex-lb/probes/bridge-probe.js +75 -0
- package/dist/core/codex-lb/probes/catalog-probe.js +128 -0
- package/dist/core/codex-lb/probes/computer-use-probe.js +50 -0
- package/dist/core/codex-lb/probes/image-generation-probe.js +47 -0
- package/dist/core/codex-lb/probes/probe-evidence.js +39 -0
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +44 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +403 -0
- package/dist/core/codex-native/core-skill-manifest.js +22 -6
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -1
- package/dist/core/commands/align-command.js +220 -0
- package/dist/core/commands/image-ux-review-command.js +280 -68
- package/dist/core/commands/naruto-command.js +257 -8
- package/dist/core/commands/ppt-command.js +2 -2
- package/dist/core/commands/telegram-command.js +402 -34
- package/dist/core/commands/triwiki-command.js +11 -1
- package/dist/core/commands/triwiki-graph-command.js +160 -0
- package/dist/core/commands/wiki-command.js +100 -20
- package/dist/core/doctor/skill-legacy-surface.js +1 -3
- package/dist/core/errors/message.js +3 -0
- package/dist/core/evidence/evidence-freshness.js +14 -0
- package/dist/core/feature-fixtures.js +9 -1
- package/dist/core/feature-registry.js +5 -3
- package/dist/core/fsx.js +7 -3
- package/dist/core/hooks-runtime/codex-commit-hooks-selftest.js +82 -0
- package/dist/core/hooks-runtime/context-graph-freshness-preflight.js +113 -0
- package/dist/core/hooks-runtime/hook-context.js +15 -2
- package/dist/core/hooks-runtime/managed-skill-generation-heal.js +46 -0
- package/dist/core/hooks-runtime/naruto-terminal-finalization.js +1 -0
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +33 -89
- package/dist/core/image-ux-review/callout-extraction.js +6 -0
- package/dist/core/image-ux-review/imagegen-adapter.js +64 -23
- package/dist/core/image-ux-review/real-callout-extractor.js +1 -0
- package/dist/core/image-ux-review.js +230 -12
- package/dist/core/imagegen/codex-lb-imagegen-target.js +21 -7
- package/dist/core/imagegen/imagegen-capability.js +10 -4
- package/dist/core/imagegen/require-imagegen.js +29 -5
- package/dist/core/init/skills.js +25 -13
- package/dist/core/init.js +1 -1
- package/dist/core/install/installed-package-smoke.js +157 -4
- package/dist/core/managed-assets/managed-assets-manifest.js +2 -1
- package/dist/core/managed-path-safety.js +8 -10
- package/dist/core/mcp-config/backup.js +2 -4
- package/dist/core/mcp-config/config-reader.js +2 -4
- package/dist/core/mcp-config/scope.js +3 -5
- package/dist/core/naruto/context-graph-advisor-scope.js +242 -0
- package/dist/core/naruto/context-graph-advisor.js +0 -0
- package/dist/core/perf/release-latency-slo.js +12 -6
- package/dist/core/pipeline-internals/runtime-core.js +78 -0
- package/dist/core/pipeline-internals/runtime-gates.js +5 -2
- package/dist/core/policy/latest-version-guidance.js +113 -0
- package/dist/core/ppt.js +8 -8
- package/dist/core/preflight/parallel-preflight-engine.js +1 -1
- package/dist/core/proof/auto-finalize.js +98 -6
- package/dist/core/proof/route-proof-gate.js +12 -1
- package/dist/core/proof/route-proof-policy.js +8 -8
- package/dist/core/release/gate-manifest.js +32 -1
- package/dist/core/release/npm-stage-contract.js +21 -0
- package/dist/core/release/package-size-budget.js +2 -2
- package/dist/core/release/release-gate-contract.js +5 -0
- package/dist/core/release/release-proof-io.js +1 -3
- package/dist/core/release/release-real-contract.js +5 -4
- package/dist/core/release/release-stamp-proof.js +1 -3
- package/dist/core/release/stage-publish.js +27 -0
- package/dist/core/remote/audit-idempotency.js +50 -18
- package/dist/core/remote/codex-public-activity.js +283 -0
- package/dist/core/remote/index.js +1 -0
- package/dist/core/remote/ssh-worker-client.js +4 -1
- package/dist/core/remote/worker.js +206 -27
- package/dist/core/research/research-adversarial-review.js +1 -3
- package/dist/core/research/research-claim-synthesizer.js +1 -3
- package/dist/core/research/research-falsification-runner.js +1 -3
- package/dist/core/research/research-source-evidence.js +1 -3
- package/dist/core/responses-stream.js +65 -19
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/design-policy.js +7 -2
- package/dist/core/routes/dollar-manifest-lite.js +2 -4
- package/dist/core/routes/evidence.js +1 -1
- package/dist/core/routes.js +30 -10
- package/dist/core/safety/command-contract/contracts.js +2 -0
- package/dist/core/safety/command-contract/types.js +1 -1
- package/dist/core/search/context-graph-seeds.js +205 -0
- package/dist/core/search/context.js +0 -0
- package/dist/core/search/provider.js +2 -2
- package/dist/core/secret-redaction.js +6 -0
- package/dist/core/subagents/naruto-help-contract.js +2 -1
- package/dist/core/subagents/naruto-host-credentials.js +161 -0
- package/dist/core/subagents/official-subagent-preparation.js +4 -1
- package/dist/core/subagents/official-subagent-prompt.js +44 -2
- package/dist/core/subagents/official-subagent-runner.js +26 -8
- package/dist/core/subagents/triwiki-attention.js +135 -123
- package/dist/core/telegram/bot-api.js +85 -10
- package/dist/core/telegram/center-snapshot.js +718 -0
- package/dist/core/telegram/config.js +158 -31
- package/dist/core/telegram/hub.js +288 -33
- package/dist/core/telegram/index.js +2 -0
- package/dist/core/telegram/ingress-spool.js +419 -0
- package/dist/core/telegram/ledgers.js +188 -29
- package/dist/core/telegram/messages.js +26 -6
- package/dist/core/telegram/owner-lock.js +10 -7
- package/dist/core/telegram/runtime-projection.js +38 -3
- package/dist/core/telegram/runtime.js +298 -63
- package/dist/core/telegram/service.js +137 -8
- package/dist/core/telegram/setup.js +291 -73
- package/dist/core/text/strings.js +3 -0
- package/dist/core/triwiki/code-pack.js +12 -120
- package/dist/core/triwiki/context-graph/compiler/cache-key.js +277 -0
- package/dist/core/triwiki/context-graph/compiler/extract.js +104 -0
- package/dist/core/triwiki/context-graph/compiler/freshness.js +108 -0
- package/dist/core/triwiki/context-graph/compiler/index.js +237 -0
- package/dist/core/triwiki/context-graph/compiler/merge.js +0 -0
- package/dist/core/triwiki/context-graph/compiler/serialize.js +115 -0
- package/dist/core/triwiki/context-graph/contracts.js +236 -0
- package/dist/core/triwiki/context-graph/extractors/code/builders.js +150 -0
- package/dist/core/triwiki/context-graph/extractors/code/declarations.js +161 -0
- package/dist/core/triwiki/context-graph/extractors/code/index.js +265 -0
- package/dist/core/triwiki/context-graph/extractors/code/inventory.js +237 -0
- package/dist/core/triwiki/context-graph/extractors/code/module-graph.js +252 -0
- package/dist/core/triwiki/context-graph/extractors/code/modules.js +79 -0
- package/dist/core/triwiki/context-graph/extractors/code/references.js +184 -0
- package/dist/core/triwiki/context-graph/extractors/code/selection.js +100 -0
- package/dist/core/triwiki/context-graph/extractors/code/ts-config.js +161 -0
- package/dist/core/triwiki/context-graph/extractors/code/types.js +18 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/claims.js +289 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/index.js +54 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/proof-index.js +213 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/proofs.js +266 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/redaction.js +177 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/shared.js +0 -0
- package/dist/core/triwiki/context-graph/extractors/evidence/sources.js +154 -0
- package/dist/core/triwiki/context-graph/extractors/index.js +7 -0
- package/dist/core/triwiki/context-graph/extractors/topology/commands.js +207 -0
- package/dist/core/triwiki/context-graph/extractors/topology/gate-edges.js +201 -0
- package/dist/core/triwiki/context-graph/extractors/topology/gates.js +182 -0
- package/dist/core/triwiki/context-graph/extractors/topology/globs.js +124 -0
- package/dist/core/triwiki/context-graph/extractors/topology/index.js +92 -0
- package/dist/core/triwiki/context-graph/extractors/topology/routes.js +135 -0
- package/dist/core/triwiki/context-graph/extractors/topology/shared.js +215 -0
- package/dist/core/triwiki/context-graph/graph-index.js +143 -0
- package/dist/core/triwiki/context-graph/ids.js +0 -0
- package/dist/core/triwiki/context-graph/lint/index.js +0 -0
- package/dist/core/triwiki/context-graph/lint/rules.js +232 -0
- package/dist/core/triwiki/context-graph/lint/warnings.js +93 -0
- package/dist/core/triwiki/context-graph/paths.js +116 -0
- package/dist/core/triwiki/context-graph/profiles.js +78 -0
- package/dist/core/triwiki/context-graph/projections/anchors.js +91 -0
- package/dist/core/triwiki/context-graph/projections/attention.js +58 -0
- package/dist/core/triwiki/context-graph/projections/code-pack-workspace.js +62 -0
- package/dist/core/triwiki/context-graph/projections/code-pack.js +144 -0
- package/dist/core/triwiki/context-graph/projections/index.js +7 -0
- package/dist/core/triwiki/context-graph/projections/module-view.js +140 -0
- package/dist/core/triwiki/context-graph/projections/node-summary.js +118 -0
- package/dist/core/triwiki/context-graph/projections/pack-contract.js +6 -0
- package/dist/core/triwiki/context-graph/query/explain.js +0 -0
- package/dist/core/triwiki/context-graph/query/index.js +178 -0
- package/dist/core/triwiki/context-graph/query/load.js +116 -0
- package/dist/core/triwiki/context-graph/query/pack.js +117 -0
- package/dist/core/triwiki/context-graph/query/rank.js +142 -0
- package/dist/core/triwiki/context-graph/query/ranking-config.js +64 -0
- package/dist/core/triwiki/context-graph/query/seeds.js +241 -0
- package/dist/core/triwiki/context-graph/query/snapshot-cache.js +72 -0
- package/dist/core/triwiki/context-graph/query/traverse.js +154 -0
- package/dist/core/triwiki/context-graph/query-types.js +29 -0
- package/dist/core/triwiki/context-graph/store/compile-lock.js +21 -0
- package/dist/core/triwiki/context-graph/store/event-log.js +48 -0
- package/dist/core/triwiki/context-graph/store/fragment-cache.js +85 -0
- package/dist/core/triwiki/context-graph/store/graph-status.js +85 -0
- package/dist/core/triwiki/context-graph/store/snapshot-store.js +155 -0
- package/dist/core/triwiki/triwiki-proof-bank-index-repair.js +115 -0
- package/dist/core/triwiki/triwiki-proof-bank-index-store.js +290 -0
- package/dist/core/triwiki/triwiki-proof-bank-index.js +126 -0
- package/dist/core/triwiki/triwiki-proof-bank.js +7 -1
- package/dist/core/verification/context-graph-affected.js +271 -0
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AlertFactory.swift +11 -3
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +9 -0
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +25 -3
- package/dist/native/sks-menubar/Sources/ControlKit.swift +19 -8
- package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +1 -2
- package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +45 -17
- package/dist/native/sks-menubar/Sources/OverviewSummary.swift +162 -0
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +136 -190
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +107 -11
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +5 -1
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +16 -4
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +4 -1
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +131 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +288 -341
- package/dist/native/sks-menubar/Sources/RemoteTelegramCenterState.swift +447 -0
- package/dist/native/sks-menubar/Sources/RemoteTelegramRendering.swift +484 -0
- package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +364 -115
- package/dist/native/sks-menubar/Sources/SettingsViewController.swift +73 -12
- package/dist/native/sks-menubar/Sources/SidebarItem.swift +3 -3
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +13 -13
- package/dist/native/sks-menubar/Sources/TelegramHubSupervisor.swift +469 -0
- package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +1 -6
- package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +12 -0
- package/dist/native/sks-menubar/Tests/NativeTelegramRegressionRunner.swift +55 -0
- package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +33 -0
- package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +142 -0
- package/dist/native/sks-menubar/Tests/RemoteTelegramCenterStateTests.swift +56 -0
- package/dist/native/sks-menubar/Tests/TelegramHubSupervisorTests.swift +55 -0
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +120 -0
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +169 -0
- package/dist/scripts/codex-lb-desktop-bridge-check.js +394 -0
- package/dist/scripts/codex-lb-desktop-bridge-latency-check.js +196 -0
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +287 -0
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +123 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +81 -40
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +99 -37
- package/dist/scripts/context-graph-check.js +191 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +1 -1
- package/dist/scripts/gate-policy-audit-check.js +1 -1
- package/dist/scripts/helper-dedup-check.js +0 -2
- package/dist/scripts/installed-package-smoke-check.js +4 -1
- package/dist/scripts/latest-version-guidance-check.js +74 -0
- package/dist/scripts/release-metadata-check.js +21 -4
- package/dist/scripts/release-real-check.js +7 -0
- package/dist/scripts/ux-review-imagegen-blackbox-check.js +25 -1
- package/dist/scripts/ux-review-run-wires-imagegen-check.js +9 -1
- package/package.json +8 -3
- package/release-gates.v2.json +176 -1
- package/runtime-required-scripts.json +30 -0
- package/schemas/triwiki/context-graph.schema.json +119 -0
- package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -112
- package/dist/cli/install-helpers-codex-lb-selftest.js +0 -481
- package/dist/core/triwiki/code-index-scanner.js +0 -309
package/README.md
CHANGED
|
@@ -22,7 +22,9 @@ Proof-first orchestration for Codex CLI, ChatGPT Desktop, AI coding agents, mult
|
|
|
22
22
|
Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.
|
|
23
23
|
<!-- END SKS SEARCH VISIBILITY MARKETING -->
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
This README documents package **SKS 7.6.0** — its own identity, read from `package.json` and verified by the release gate, not advice about what to install.
|
|
26
|
+
|
|
27
|
+
Use the official latest stable SKS and Codex CLI releases. SKS stays version-agnostic: older hosts keep working where capabilities allow, while Menu Bar / Center induce updates to the latest stable build. Run `sks update-check` for what is installed and read the capability report for what is actually supported — feature availability is decided by capability probes, not by a version number printed in a document. It resolves managed SKS skills from the authoritative global install, preserves a runnable Naruto child slot when `max_threads=2`, and keeps Menu Bar repair transactional so stamped generations remain verifiable. Naruto uses stable opt-in multi-agent V2 when the host exposes it. Local code search is mode-separated (`sks search files|text|structure|symbol|context`); `context` is answered by the compiled TriWiki Context Graph with evidence paths rather than lexical guessing — see [docs/architecture/context-graph.md](docs/architecture/context-graph.md) and [docs/architecture/search-engine-target.md](docs/architecture/search-engine-target.md). See [CHANGELOG.md](CHANGELOG.md).
|
|
26
28
|
|
|
27
29
|
## What 7.0.0 Ships
|
|
28
30
|
|
|
@@ -45,8 +47,15 @@ That installs or repairs SKS, runs `sks doctor --fix`, and prepares the Codex Ap
|
|
|
45
47
|
|
|
46
48
|
For package-managed installs:
|
|
47
49
|
|
|
50
|
+
The npm lifecycle is non-mutating outside the installed package by default:
|
|
51
|
+
it restores only the package-local build stamp and prints the explicit setup
|
|
52
|
+
commands. To intentionally run the legacy bootstrap during installation, set
|
|
53
|
+
`SKS_POSTINSTALL_BOOTSTRAP=1`; `SKS_POSTINSTALL_NO_BOOTSTRAP=1` remains the
|
|
54
|
+
stronger safety override.
|
|
55
|
+
|
|
48
56
|
```sh
|
|
49
57
|
npm i -g sneakoscope
|
|
58
|
+
sks bootstrap --yes
|
|
50
59
|
sks doctor --fix
|
|
51
60
|
```
|
|
52
61
|
|
|
@@ -56,11 +65,15 @@ The SKS menu bar shows the installed Codex CLI version and latest known version.
|
|
|
56
65
|
|
|
57
66
|
### Telegram remote coding on this Mac
|
|
58
67
|
|
|
59
|
-
Open **SKS Center → Remote & Telegram**, create a
|
|
68
|
+
Open **SKS Center → Remote & Telegram**, create a bot with BotFather, send `/start` to that bot from the Telegram account you want to pair, then choose **Connect This Project…** and paste the token. SKS verifies the bot, stores the token only in macOS Keychain, pairs only that private chat/user, and registers one dedicated session bound to the current project. Choose **Start Hub**, then send ordinary text to the bot. On the first real message, the Hub creates the Codex thread and starts its first turn in the same App Server connection so the thread is durably resumable; later messages resume that exact thread and return the final response to Telegram.
|
|
69
|
+
|
|
70
|
+
Telegram runtime configuration is v2-only. A legacy v1 file cannot start the Hub; Center shows a one-time reconnect prompt, and explicit reconnect/setup atomically writes the verified bot/private-pair identity, token fingerprint, and generation contract as `sks.telegram-config.v2`.
|
|
71
|
+
|
|
72
|
+
After connection, Center exposes the registered-session selector, the real user/Codex conversation from that Telegram-bound App Server thread, and a live public activity feed for turn, tool, command, file, search, and subagent lifecycle events. **Older**, **Newer**, and **Latest** page the complete stored turn history through opaque App Server cursors. On Latest, Center checks only the bounded local journal every 2.5 seconds and reloads the heavier App Server conversation when a completed-turn revision changes or the user refreshes/navigates; an older page never jumps away while you read it. The feed intentionally excludes reasoning text, raw tool output, arguments/results, credentials, and paths outside the project, and each page/activity view keeps explicit byte and item bounds. Center also shows the ordinary-text workflow and every supported Telegram command.
|
|
60
73
|
|
|
61
74
|
The Hub runs as a user LaunchAgent and uses `caffeinate -i` while the logged-in Mac is available. The Mac still needs to remain powered on, logged in, awake, and network-connected; closing the lid or logging out can stop access. Telegram input has no arbitrary shell path, runs with approvals disabled and network access disabled inside the Codex workspace sandbox, and cannot target an unpaired chat or another project.
|
|
62
75
|
|
|
63
|
-
SKS Center is the menu bar companion: install it with `sks menubar install`, then click the SKS icon in the macOS menu bar and choose **Open SKS Control Center…**. Every GUI step above has a CLI equivalent (`sks telegram setup --bot-token-stdin`, `sks telegram hub start`, `sks telegram status`). See **[docs/telegram-and-center.md](docs/telegram-and-center.md)** for the
|
|
76
|
+
SKS Center is the menu bar companion: install it with `sks menubar install`, then click the SKS icon in the macOS menu bar and choose **Open SKS Control Center…**. Every GUI step above has a CLI equivalent (`sks telegram setup --bot-token-stdin`, `sks telegram hub start`, `sks telegram status`). The hub uses long polling, so a bot with an existing webhook must have that webhook removed before the hub can start; SKS fails closed with `telegram_webhook_conflict` and never clears it automatically. See **[docs/telegram-and-center.md](docs/telegram-and-center.md)** for the complete BotFather setup, optional command menu and privacy-mode guidance, secure token rotation, verification, and troubleshooting.
|
|
64
77
|
|
|
65
78
|
## The Front Door
|
|
66
79
|
|
|
@@ -84,10 +97,113 @@ Gates are task-profile aware: greetings and answer-only turns create no mission
|
|
|
84
97
|
|
|
85
98
|
Every installed Codex hook runs one common Naruto decision gate. The gate records `none`, `generic_naruto`, or `route_owned`: Answer, DFix, Wiki, Computer Use, Goal, and simple Git/control turns stay lightweight; ordinary non-trivial work defaults to two independent official subagents; critical work spanning at least three risk domains may use three. Research, AutoResearch, and QA-Loop retain their own exact orchestration contracts instead of receiving a second generic fan-out. Explicit `--agents N` remains authoritative.
|
|
86
99
|
|
|
87
|
-
SKS installs twenty-five narrow project custom agents, including native AppKit, toolchain, protocol, runtime-reliability, TriWiki-evidence, long-context, Computer Use, Browser/Chrome, and image-generation specialists. Delegation prompts inject at most the three roles recommended for the current goal rather than serializing the full catalog, so expanding role coverage does not serialize the full inventory into every prompt. TriWiki context is also bounded and query-aware: ordinary work receives up to four trust/hydration anchors and complex, parallel, or high-risk work receives up to six, with source hydration required before relying on lower-trust hints. In CLI Zellij mode, the right side is a live observability surface rather than a static lane reservation: one monitor plus one viewport by default (maximum three) shows official thread role/model, redacted live phase/task/file updates from rollout-compatible Codex
|
|
100
|
+
SKS installs twenty-five narrow project custom agents, including native AppKit, toolchain, protocol, runtime-reliability, TriWiki-evidence, long-context, Computer Use, Browser/Chrome, and image-generation specialists. Delegation prompts inject at most the three roles recommended for the current goal rather than serializing the full catalog, so expanding role coverage does not serialize the full inventory into every prompt. TriWiki context is also bounded and query-aware: ordinary work receives up to four trust/hydration anchors and complex, parallel, or high-risk work receives up to six, with source hydration required before relying on lower-trust hints. In CLI Zellij mode, the right side is a live observability surface rather than a static lane reservation: one monitor plus one viewport by default (maximum three) shows official thread role/model, redacted live phase/task/file updates from rollout-compatible Codex sessions on the official latest stable CLI, plus `running`, `verifying`, and trustworthy parent-verdict completion/failure states. Rollout activity is display-only and never completion proof.
|
|
88
101
|
|
|
89
102
|
Official subagent requests use `--agents`; removed scheduler, pool, backend, and model flags fail closed.
|
|
90
103
|
|
|
104
|
+
## Embedding SKS In Another Agent System
|
|
105
|
+
|
|
106
|
+
By default SKS owns the credential: it pins `model_provider="openai"` and `forced_login_method="chatgpt"`, so an operator's interactive ChatGPT session authenticates the run and it cannot drift onto another provider unnoticed.
|
|
107
|
+
|
|
108
|
+
That default is wrong for an unattended host. An orchestrator that already holds and rotates a customer's OpenAI-compatible credential — a local codex-lb endpoint, OpenRouter, any `env_key` provider block — cannot log in interactively on every node, and forcing `chatgpt` makes Codex treat an `auth_mode="apikey"` session as a hard logout and delete `auth.json`. **Host mode** hands that decision back.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
sks naruto run "task" \
|
|
112
|
+
--auth-mode=host \
|
|
113
|
+
--model-provider=codex-lb \
|
|
114
|
+
--provider-env-key=CODEX_LB_API_KEY
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
| Surface | Flag | Environment | Effect |
|
|
118
|
+
| --- | --- | --- | --- |
|
|
119
|
+
| Who authenticates | `--auth-mode=host` | `SKS_NARUTO_AUTH_MODE=host` | SKS injects neither `model_provider` nor `forced_login_method`; Codex uses your `config.toml` provider block |
|
|
120
|
+
| Which provider block | `--model-provider=<name>` | `SKS_NARUTO_MODEL_PROVIDER` | Names a `[model_providers.<name>]` block. Host mode only |
|
|
121
|
+
| Which credential variable | `--provider-env-key=<NAME>` | `SKS_NARUTO_PROVIDER_ENV_KEY` | Forwards exactly that variable to the child so the block's `env_key` resolves. Host mode only |
|
|
122
|
+
| Release the login only | `--no-forced-login-method` | `SKS_NARUTO_FORCED_LOGIN_METHOD=none` | Keeps the SKS provider, drops the forced ChatGPT login |
|
|
123
|
+
| Parent model / effort | `--parent-model`, `--parent-effort` | `SKS_NARUTO_PARENT_MODEL`, `SKS_NARUTO_PARENT_EFFORT` | Overrides the built-in parent policy |
|
|
124
|
+
| Subagent model / effort | `--subagent-model`, `--subagent-effort` | `SKS_NARUTO_SUBAGENT_MODEL`, `SKS_NARUTO_SUBAGENT_EFFORT` | Overrides the default subagent policy |
|
|
125
|
+
|
|
126
|
+
Guarantees this contract makes:
|
|
127
|
+
|
|
128
|
+
- **SKS never reads, stores, forwards to a third party, or logs your credential.** It forwards one named environment variable to the Codex child and records only that variable's *name* in receipts. Values of secret-shaped variables are redacted from captured output.
|
|
129
|
+
- **A malformed value blocks the run.** An unknown auth mode, a provider name with a space, an effort tier that is not `minimal|low|medium|high|max`, or a `--provider-env-key` that is absent from the environment all fail before mission state is written. SKS never quietly falls back to its own credential — that surprise is the failure mode this contract exists to prevent.
|
|
130
|
+
- **Mixed configurations are refused.** Naming a provider while SKS still forces a ChatGPT login would authenticate one way and bill another, so it is a blocker rather than a silent precedence rule.
|
|
131
|
+
- **The default is unchanged.** Managed mode still pins the ChatGPT login, and the real-credential smoke gate still proves it.
|
|
132
|
+
|
|
133
|
+
### Designing an adapter that wraps SKS without fighting it
|
|
134
|
+
|
|
135
|
+
The rule that keeps an adapter conflict-free: **let SKS own the mission, the evidence, and the gates; let the host own the credential, the model policy, and the workspace.** Cross that line — by patching `dist/`, writing `.sneakoscope/` yourself, or re-implementing the gate DAG — and every SKS update breaks you.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
// acas/adapters/sks.ts — one process boundary, no dist patching.
|
|
139
|
+
import { execFile } from 'node:child_process'
|
|
140
|
+
import { promisify } from 'node:util'
|
|
141
|
+
|
|
142
|
+
const run = promisify(execFile)
|
|
143
|
+
|
|
144
|
+
export interface SksMissionRequest {
|
|
145
|
+
workspace: string // host owns the checkout
|
|
146
|
+
task: string
|
|
147
|
+
agents?: number
|
|
148
|
+
tenant: {
|
|
149
|
+
providerBlock: string // [model_providers.<name>] the host wrote into config.toml
|
|
150
|
+
credentialEnvKey: string // env var the block's env_key points at
|
|
151
|
+
credential: string // held by the host; never persisted by SKS
|
|
152
|
+
parentModel?: string
|
|
153
|
+
subagentModel?: string
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function runSksMission(request: SksMissionRequest) {
|
|
158
|
+
const { stdout } = await run('sks', [
|
|
159
|
+
'naruto', 'run', request.task,
|
|
160
|
+
'--json',
|
|
161
|
+
...(request.agents ? ['--agents', String(request.agents)] : []),
|
|
162
|
+
// Host owns authentication and model policy.
|
|
163
|
+
'--auth-mode=host',
|
|
164
|
+
`--model-provider=${request.tenant.providerBlock}`,
|
|
165
|
+
`--provider-env-key=${request.tenant.credentialEnvKey}`,
|
|
166
|
+
...(request.tenant.parentModel ? [`--parent-model=${request.tenant.parentModel}`] : []),
|
|
167
|
+
...(request.tenant.subagentModel ? [`--subagent-model=${request.tenant.subagentModel}`] : [])
|
|
168
|
+
], {
|
|
169
|
+
cwd: request.workspace,
|
|
170
|
+
env: {
|
|
171
|
+
...process.env,
|
|
172
|
+
// The one variable the provider block resolves. Scope it to this call
|
|
173
|
+
// rather than exporting it process-wide.
|
|
174
|
+
[request.tenant.credentialEnvKey]: request.tenant.credential
|
|
175
|
+
},
|
|
176
|
+
maxBuffer: 64 * 1024 * 1024
|
|
177
|
+
})
|
|
178
|
+
// SKS answers with its own result schema; treat it as the source of truth for
|
|
179
|
+
// status and evidence rather than re-deriving success from stdout text.
|
|
180
|
+
return JSON.parse(stdout)
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Then read the outcome through SKS's own surfaces instead of inferring it:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
sks naruto proof --json # completion proof, blockers, evidence links
|
|
188
|
+
sks triwiki graph-status --fast --json # is the compiled graph usable right now (no git, no spawn)
|
|
189
|
+
sks search context "..." --json # evidence-backed context with reason paths
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`graph-status --fast` is the probe to poll from a host loop: it reads the stored
|
|
193
|
+
artifacts only, so it costs no subprocess, and it reports which staleness reasons
|
|
194
|
+
it could not evaluate rather than returning a `fresh` that means less than it
|
|
195
|
+
looks. Drop `--fast` when you want the full git-aware verdict.
|
|
196
|
+
|
|
197
|
+
Adapter rules that keep updates safe:
|
|
198
|
+
|
|
199
|
+
1. **One process boundary.** Shell out to the `sks` CLI with `--json`. Do not import SKS internals; they are not a published API and they move.
|
|
200
|
+
2. **Never patch `dist/`.** A local patch is overwritten by every install and is asserted against by release gates. If a behaviour you need is missing, it belongs behind a flag like the ones above.
|
|
201
|
+
3. **Host owns the workspace, SKS owns `.sneakoscope/`.** Write your own state anywhere else; treat `.sneakoscope/` as SKS-owned and read-only from outside.
|
|
202
|
+
4. **Pass credentials per invocation, not per machine.** A per-call `env` entry keeps one tenant's key out of another tenant's run.
|
|
203
|
+
5. **Let the gates fail.** A blocked mission with blockers is a correct answer. Do not retry it with safety flags off, and do not treat `--trusted-project` as a default — it is an operator decision about a reviewed checkout.
|
|
204
|
+
6. **Do not pin a version in your own docs or error strings.** Ask for the official latest stable release and read the capability report; SKS enforces this on itself with the `latest-version:guidance` gate.
|
|
205
|
+
7. **Parallelism advice is advisory.** `sks naruto` decides its own wave shape; if you plan slices yourself, check them against the graph advisory rather than assuming disjointness.
|
|
206
|
+
|
|
91
207
|
## Why Not Just An LLM Reviewer?
|
|
92
208
|
|
|
93
209
|
| Question | Oracle-style LLM review | SKS gate/review |
|
|
@@ -115,7 +231,7 @@ It shows the current quickstart flow: one-line install, `$sks-plan`, `sks review
|
|
|
115
231
|
- Project memory: `sks memory build`
|
|
116
232
|
- Codebase index/pack for LLM context: `sks wiki refresh --code`, `sks wiki validate --json` (code-pack freshness)
|
|
117
233
|
- Native capability repair: `sks doctor --fix` (imagegen/Computer Use/Browser Use), `.sneakoscope/reports/native-capability-readiness.json`
|
|
118
|
-
- codex-lb continuity: `sks codex-lb status --json` verifies the selected proxy's unauthenticated `/health` `X-App-Version`. Tool-heavy continuation requires codex-lb
|
|
234
|
+
- codex-lb continuity: `sks codex-lb status --json` verifies the selected proxy's unauthenticated `/health` `X-App-Version`. Tool-heavy continuation requires a codex-lb deployment that reports the capability; use the official latest stable release. Older or unverified deployments block setup, doctor, and launch instead of silently falling back.
|
|
119
235
|
- Agent bridge for any agent system: `sks mcp-server`, `sks agent-bridge setup`, `SKS_AGENT_MODE=1` — see [docs/AGENT-BRIDGE.md](docs/AGENT-BRIDGE.md)
|
|
120
236
|
- Release gates: `npm run release:check:affected` for ordinary change-aware verification and `npm run release:check:confidence` for the final local confidence pass.
|
|
121
237
|
- Release preparation: typecheck, one clean build, focused tests, affected/confidence gates, then `npm publish --dry-run --json --registry https://registry.npmjs.org/ --tag latest --access public`. The dry-run does not publish; authorization remains a separate maintainer workflow.
|
|
@@ -129,16 +245,19 @@ It shows the current quickstart flow: one-line install, `$sks-plan`, `sks review
|
|
|
129
245
|
- macOS optional: menu bar integration and `/usr/bin/open`
|
|
130
246
|
- The menubar icon shows and hides itself automatically as the Codex desktop app launches/quits; set `quit_with_codex: true` in `~/.codex/sks-menubar/config.json` to have the menubar fully quit with Codex instead of just hiding (default `false`).
|
|
131
247
|
- Native input dialogs (API keys, codex-lb setup) pass secrets to `sks` via `--api-key-stdin` instead of a visible Terminal window or process arguments.
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
248
|
+
- Codex Desktop always keeps its real ChatGPT OAuth identity. codex-lb setup stores a separate gateway endpoint/key and never replaces `~/.codex/auth.json`.
|
|
249
|
+
- Providers separates **Desktop Full Capability**, **CLI Provider**, and **Capability Matrix**. Desktop Full Capability keeps the built-in OpenAI provider and routes supported traffic through a loopback bridge; CLI Provider is selected only for the CLI process.
|
|
250
|
+
- Authentication and routing modes do not toggle Codex App's native model picker, Fast, image, Browser Use, Computer Use, voice, plugins/apps, or other built-in surfaces. Capability status describes evidence for the codex-lb data path, not permission to use the native feature.
|
|
251
|
+
- `sks update`, setup, repair, and routing changes preserve OAuth, user model/reasoning/Fast settings, unknown catalog fields, and unrelated provider configuration. Legacy shared-auth routing requires explicit `sks codex-lb migrate-legacy-desktop --restart-app`; without a real restart and post-restart identity check it cannot finalize a migration receipt.
|
|
252
|
+
- The remote codex-lb service remains independently hosted and operated. SKS uses only the configured URL and gateway key; it does not deploy, restart, or change credentials on that host.
|
|
253
|
+
- Full release proof blocks with `real_required_missing` until fresh trust-anchored evidence covers the real Desktop feature/lifecycle matrix and the separately hosted other-Mac runtime; fixtures and configuration cannot satisfy that boundary.
|
|
135
254
|
- Update installs always rebuild the companion with the newly installed SKS package, preventing a previous-version updater from restoring a stale menu binary.
|
|
136
255
|
- The menubar dropdown's `View Last Log` item opens the most recent background action's log file, so you don't need to keep a Terminal window open to see command output.
|
|
137
256
|
- `Manage MCP Servers…` provides a resizable native table and add/remove/enable/disable controls for global Codex MCP configuration. Secret environment values and command arguments are accepted through native dialogs/stdin but omitted from list output and logs.
|
|
138
257
|
- `sks menubar status --json` reports a `codex_sync` object with `bundle_id`, `codex_running`, and `icon_visible_expected` to show Codex-lifecycle detection state.
|
|
139
258
|
- The menu displays the installed Codex CLI version, adds an `⬆` status icon when `sks codex update-status` sees a newer release, runs the official self-updater through `Update Codex CLI Now`, and exposes `Run sks doctor --fix` as a background repair action.
|
|
140
|
-
- Fast
|
|
141
|
-
- If Codex shows `[No tool output found for custom tool call ...]`, SKS blocks reuse of that structurally ambiguous thread. Upgrade codex-lb
|
|
259
|
+
- **Codex Fast** is labeled as the official 1.5× Codex speed option, with a verified service-tier status row and direct On/Off actions. Center explains that ChatGPT-sign-in GPT-5.6/GPT-5.5 use 2.5× Standard credits and GPT-5.4 uses 2×, while API-key token pricing and API Priority processing are separate. Model selection, Codex-Spark, and reasoning effort remain independent; status failures render as unavailable with neither choice falsely selected.
|
|
260
|
+
- If Codex shows `[No tool output found for custom tool call ...]`, SKS blocks reuse of that structurally ambiguous thread. Upgrade codex-lb or run `sks codex-lb disable`, inspect possible side effects, then continue the persisted mission in a fresh Codex task. SKS never rewrites session JSONL or fabricates a successful tool output.
|
|
142
261
|
- Zellij optional but recommended for terminal worker panes
|
|
143
262
|
|
|
144
263
|
## License
|
|
@@ -37,7 +37,7 @@ function remoteControlHelp() {
|
|
|
37
37
|
return [
|
|
38
38
|
'Usage: sks codex-app remote-control [--status|--check|--dry-run|--json] [-- <codex remote-control args>]',
|
|
39
39
|
'',
|
|
40
|
-
'Starts Codex CLI
|
|
40
|
+
'Starts Codex CLI remote-control, the headless remotely controllable app-server entrypoint.',
|
|
41
41
|
'SKS only wraps the first-party command and refuses older Codex CLI versions instead of falling back to app-server internals.'
|
|
42
42
|
].join('\n');
|
|
43
43
|
}
|
|
@@ -30,7 +30,7 @@ const COMMAND_MANIFEST_LITE_BASE = [
|
|
|
30
30
|
{ name: 'git', summary: 'Inspect and enforce SKS git collaboration hygiene', maturity: 'beta' },
|
|
31
31
|
{ name: 'paths', summary: 'Inspect SKS managed paths', maturity: 'beta', readonly: true, allowedDuringActiveRoute: true, diagnostic: true },
|
|
32
32
|
{ name: 'rollback', summary: 'List or apply managed-path rollback actions', maturity: 'beta', skipMigrationGate: true, allowedDuringActiveRoute: true, diagnostic: true },
|
|
33
|
-
{ name: 'postinstall', summary: '
|
|
33
|
+
{ name: 'postinstall', summary: 'Restore package state; bootstrap only with explicit opt-in', maturity: 'stable', skipMigrationGate: true },
|
|
34
34
|
{ name: 'codex', summary: 'Check Codex CLI compatibility and vendored hook schemas', maturity: 'beta', skipMigrationGate: true },
|
|
35
35
|
{ name: 'codex-app', summary: 'Check Codex App readiness', maturity: 'beta', skipMigrationGate: true },
|
|
36
36
|
{ name: 'codex-native', summary: 'Inspect Codex Native broker and routing readiness', maturity: 'beta' },
|
|
@@ -73,6 +73,7 @@ const COMMAND_MANIFEST_LITE_BASE = [
|
|
|
73
73
|
{ name: 'versioning', summary: 'Manage release version metadata', maturity: 'stable' },
|
|
74
74
|
{ name: 'reasoning', summary: 'Show reasoning route', maturity: 'labs' },
|
|
75
75
|
{ name: 'aliases', summary: 'Show command aliases', maturity: 'stable' },
|
|
76
|
+
{ name: 'align', summary: 'Prepare or inspect the $sks-align GPT-5.6 / openai/skills modernization mission', maturity: 'beta', mutatesRouteState: true },
|
|
76
77
|
{ name: 'selftest', summary: 'Run local mock selftest', maturity: 'stable' },
|
|
77
78
|
{ name: 'goal', summary: 'Print stateless Codex native Goal controls', maturity: 'beta' },
|
|
78
79
|
{ name: 'seo-geo-optimizer', summary: 'Run unified SEO/GEO optimizer audit/plan/apply/verify plus research/strategy (--include-marketing) on the search-visibility kernel', maturity: 'beta' },
|
|
@@ -111,6 +112,7 @@ const SAFE_COMMAND_CONTRACT_LITE = {
|
|
|
111
112
|
requiredCapabilities: []
|
|
112
113
|
};
|
|
113
114
|
const COMMAND_CONTRACT_OVERRIDES_LITE = {
|
|
115
|
+
align: { latency: 'long', supportsJson: true, inputProfile: 'json-only' },
|
|
114
116
|
autoresearch: { latency: 'long' },
|
|
115
117
|
bench: { latency: 'long' },
|
|
116
118
|
check: { risk: 'R1', latency: 'long' },
|
|
@@ -201,6 +203,7 @@ export function commandInputSchema(profile) {
|
|
|
201
203
|
mission: boundedString(1, 160),
|
|
202
204
|
agents: { type: 'integer', minimum: 1 },
|
|
203
205
|
max_threads: { type: 'integer', minimum: 1 },
|
|
206
|
+
stdin: { type: 'boolean' },
|
|
204
207
|
readonly: { type: 'boolean' },
|
|
205
208
|
trusted_project: { type: 'boolean' },
|
|
206
209
|
json: { type: 'boolean' }
|
|
@@ -223,6 +223,7 @@ const COMMAND_DEFINITIONS = {
|
|
|
223
223
|
versioning: entry('stable', 'Manage release version metadata', 'dist/commands/versioning.js', directCommand(() => import('../commands/versioning.js'), 'dist/commands/versioning.js')),
|
|
224
224
|
reasoning: entry('labs', 'Show reasoning route', 'dist/core/commands/basic-cli.js', basicArgs('reasoningCommand')),
|
|
225
225
|
aliases: entry('stable', 'Show command aliases', 'dist/core/commands/basic-cli.js', basicNoArgs('aliasesCommand')),
|
|
226
|
+
align: routeStateMutator(entry('beta', 'Prepare or inspect the $sks-align GPT-5.6 / openai/skills modernization mission', 'dist/core/commands/align-command.js', subcommand(() => import('../core/commands/align-command.js'), 'alignCommand', 'dist/core/commands/align-command.js', 'prepare')), ['align-gate.json']),
|
|
226
227
|
selftest: entry('stable', 'Run local mock selftest', 'dist/core/commands/basic-cli.js', basicArgs('selftestCommand')),
|
|
227
228
|
goal: entry('beta', 'Print stateless Codex native Goal controls', 'dist/core/commands/goal-command.js', subcommand(() => import('../core/commands/goal-command.js'), 'goalCommand', 'dist/core/commands/goal-command.js')),
|
|
228
229
|
'seo-geo-optimizer': entry('beta', 'Run unified SEO/GEO optimizer audit/plan/apply/verify plus research/strategy (--include-marketing) on the search-visibility kernel', 'dist/core/commands/seo-command.js', argsCommand(() => import('../core/commands/seo-command.js'), 'seoGeoOptimizerCommand', 'dist/core/commands/seo-command.js')),
|
|
@@ -256,6 +257,7 @@ const COMMAND_DEFINITIONS = {
|
|
|
256
257
|
'agent-bridge': readOnly(entry('beta', 'Publish the agent-bridge manifest and print host registration snippets for external agent systems', 'dist/core/commands/agent-bridge-command.js', subcommand(() => import('../core/commands/agent-bridge-command.js'), 'agentBridgeCommand', 'dist/core/commands/agent-bridge-command.js', 'setup')))
|
|
257
258
|
};
|
|
258
259
|
const COMMANDS_WITH_LEGACY_CONTRACT_OVERRIDES = applyCommandContractOverrides(COMMAND_DEFINITIONS, {
|
|
260
|
+
align: { latency: 'long', supportsJson: true, inputProfile: 'json-only' },
|
|
259
261
|
autoresearch: { latency: 'long' },
|
|
260
262
|
bench: { latency: 'long' },
|
|
261
263
|
check: { risk: 'R1', latency: 'long' },
|
|
@@ -4,6 +4,7 @@ import fsp from 'node:fs/promises';
|
|
|
4
4
|
import { ensureDir, packageRoot, readText, writeTextAtomic } from '../core/fsx.js';
|
|
5
5
|
import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
|
|
6
6
|
import { codexLbBaseUrlSecurityBlocker } from '../core/codex-lb/codex-lb-env.js';
|
|
7
|
+
import { probeEvidence } from '../core/codex-lb/probes/probe-evidence.js';
|
|
7
8
|
import { CODEX_LB_CANONICAL_FAST_SERVICE_TIER, codexLbEnvPath, parseCodexLbEnvKey, redactSecretText } from './install-helpers-codex-lb-shared.js';
|
|
8
9
|
function codexLbResponsesEndpoint(baseUrl = '') {
|
|
9
10
|
const base = String(baseUrl || '').trim().replace(/\/+$/, '');
|
|
@@ -288,6 +289,47 @@ export async function checkCodexLbResponseChain(status = {}, opts = {}) {
|
|
|
288
289
|
error: redactSecretText(second.error_payload?.error?.message || second.error_payload?.response?.error?.message || second.text || 'codex-lb chained Responses request failed', [apiKey])
|
|
289
290
|
}, { endpoint, home, opts, env }), opts);
|
|
290
291
|
}
|
|
292
|
+
export async function runCodexLbTextResponsesProbe(status = {}, opts = {}) {
|
|
293
|
+
const result = await checkCodexLbResponseChain(status, opts);
|
|
294
|
+
return codexLbResponseChainCapabilityEvidence(result, {
|
|
295
|
+
checkedAt: typeof opts.nowIso === 'function' ? opts.nowIso() : new Date().toISOString()
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
export function codexLbResponseChainCapabilityEvidence(result = {}, opts = {}) {
|
|
299
|
+
const checkedAt = opts.checkedAt || new Date().toISOString();
|
|
300
|
+
if (result?.skipped === true || result?.status === 'skipped') {
|
|
301
|
+
return probeEvidence({
|
|
302
|
+
skipped: true,
|
|
303
|
+
source: 'config',
|
|
304
|
+
evidence: {
|
|
305
|
+
probe: 'text_responses',
|
|
306
|
+
status: result?.status || 'skipped',
|
|
307
|
+
reason: result?.reason || null
|
|
308
|
+
}
|
|
309
|
+
}, checkedAt);
|
|
310
|
+
}
|
|
311
|
+
const verified = result?.ok === true && result?.status === 'chain_ok';
|
|
312
|
+
const blockers = verified
|
|
313
|
+
? []
|
|
314
|
+
: [
|
|
315
|
+
...(Array.isArray(result?.blockers) ? result.blockers : []),
|
|
316
|
+
`text_responses_${String(result?.status || 'probe_failed')}`
|
|
317
|
+
];
|
|
318
|
+
return probeEvidence({
|
|
319
|
+
attempted: true,
|
|
320
|
+
verified,
|
|
321
|
+
source: 'transport',
|
|
322
|
+
blockers,
|
|
323
|
+
evidence: {
|
|
324
|
+
probe: 'text_responses',
|
|
325
|
+
status: result?.status || null,
|
|
326
|
+
cached: result?.cached === true,
|
|
327
|
+
http_status: result?.http_status || null,
|
|
328
|
+
response_chain_completed: verified,
|
|
329
|
+
service_tier: result?.service_tier_evidence || null
|
|
330
|
+
}
|
|
331
|
+
}, checkedAt);
|
|
332
|
+
}
|
|
291
333
|
async function recordCodexLbChainHealth(result, opts = {}) {
|
|
292
334
|
if (!result || result.skipped || opts.recordCircuit === false)
|
|
293
335
|
return result;
|
|
@@ -4,24 +4,129 @@ import { ensureDir, readText } from '../core/fsx.js';
|
|
|
4
4
|
import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_52_OPENROUTER_MODEL, OPENROUTER_AUTH_COMMAND, OPENROUTER_AUTH_REFRESH_INTERVAL_MS, OPENROUTER_AUTH_TIMEOUT_MS, openRouterAuthCommandArgs, OPENROUTER_DEFAULT_PROFILE_ID, RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS } from '../core/codex-app/openrouter-provider.js';
|
|
5
5
|
import { openRouterSecretPaths, resolveOpenRouterApiKey } from '../core/providers/openrouter/openrouter-secret-store.js';
|
|
6
6
|
import { reconcileRetiredSksConfigText } from '../core/auto-review.js';
|
|
7
|
-
import { removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
|
|
7
|
+
import { ensureTrailingNewline, removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
|
|
8
8
|
import { codexLbConfigPath, normalizeCodexLbBaseUrl } from './install-helpers-codex-lb-shared.js';
|
|
9
9
|
import { escapeRegExp } from '../core/text/regex.js';
|
|
10
|
-
export
|
|
11
|
-
|
|
10
|
+
export const CODEX_LB_DESKTOP_BRIDGE_MARKER = '# sks-codex-lb-managed-desktop-bridge';
|
|
11
|
+
export const CODEX_LB_DESKTOP_COMPAT_MARKER = '# sks-codex-lb-managed-desktop-compat';
|
|
12
|
+
export const CODEX_LB_MODEL_CATALOG_MARKER = '# sks-codex-lb-managed-model-catalog';
|
|
13
|
+
const LEGACY_CODEX_LB_OPENAI_ROUTING_MARKER = '# sks-codex-lb-managed-openai-base-url';
|
|
14
|
+
export function upsertCodexLbNativeDesktopConfig(text, input) {
|
|
15
|
+
let next = String(text || '');
|
|
16
|
+
const selectedProvider = topLevelTomlString(next, 'model_provider');
|
|
17
|
+
if (selectedProvider && selectedProvider !== 'openai' && selectedProvider !== 'codex-lb') {
|
|
18
|
+
throw new Error('codex_lb_user_owned_model_provider_conflict');
|
|
19
|
+
}
|
|
20
|
+
if (selectedProvider === 'codex-lb' && !topLevelHasLine(next, CODEX_LB_DESKTOP_COMPAT_MARKER)) {
|
|
21
|
+
throw new Error('codex_lb_legacy_desktop_config_requires_migration');
|
|
22
|
+
}
|
|
23
|
+
if (topLevelHasLine(next, LEGACY_CODEX_LB_OPENAI_ROUTING_MARKER)
|
|
24
|
+
&& !topLevelHasLine(next, CODEX_LB_DESKTOP_BRIDGE_MARKER)) {
|
|
25
|
+
throw new Error('codex_lb_legacy_desktop_config_requires_migration');
|
|
26
|
+
}
|
|
27
|
+
const modelCatalog = topLevelTomlString(next, 'model_catalog_json');
|
|
28
|
+
if (modelCatalog && !topLevelHasLine(next, CODEX_LB_MODEL_CATALOG_MARKER)) {
|
|
29
|
+
throw new Error('codex_lb_user_owned_model_catalog_json_conflict');
|
|
30
|
+
}
|
|
31
|
+
next = removeTopLevelTomlKeyIfValue(next, 'model_provider', 'codex-lb');
|
|
32
|
+
next = removeTopLevelLine(next, CODEX_LB_DESKTOP_COMPAT_MARKER);
|
|
33
|
+
next = removeManagedModelCatalogJson(next);
|
|
34
|
+
next = upsertManagedTopLevelTomlString(next, 'openai_base_url', input.bridgeBaseUrl, CODEX_LB_DESKTOP_BRIDGE_MARKER);
|
|
35
|
+
next = upsertTomlTable(next, 'model_providers.codex-lb', cliProviderBlock(input.remoteBaseUrl));
|
|
36
|
+
return ensureTrailingNewline(next);
|
|
37
|
+
}
|
|
38
|
+
export function upsertCodexLbCompatDesktopConfig(text, input) {
|
|
39
|
+
let next = removeManagedDesktopBridgeRouting(String(text || ''));
|
|
40
|
+
next = removeManagedModelCatalogJson(next);
|
|
41
|
+
next = upsertManagedTopLevelTomlString(next, 'model_provider', 'codex-lb', CODEX_LB_DESKTOP_COMPAT_MARKER);
|
|
42
|
+
const block = [
|
|
43
|
+
'[model_providers.codex-lb]',
|
|
44
|
+
'name = "OpenAI"',
|
|
45
|
+
`base_url = ${JSON.stringify(input.remoteBaseUrl)}`,
|
|
46
|
+
'wire_api = "responses"',
|
|
47
|
+
'requires_openai_auth = true',
|
|
48
|
+
'supports_websockets = true',
|
|
49
|
+
'env_http_headers = { "X-Codex-LB-API-Key" = "CODEX_LB_API_KEY" }'
|
|
50
|
+
].join('\n');
|
|
51
|
+
next = upsertTomlTable(next, 'model_providers.codex-lb', block);
|
|
52
|
+
return ensureTrailingNewline(next);
|
|
53
|
+
}
|
|
54
|
+
export function upsertCodexLbCliProviderConfig(text, input) {
|
|
55
|
+
let next = input.selectGlobally === true
|
|
12
56
|
? upsertTopLevelTomlString(text, 'model_provider', 'codex-lb')
|
|
13
57
|
: removeTopLevelTomlKeyIfValue(text, 'model_provider', 'codex-lb');
|
|
14
|
-
|
|
58
|
+
next = upsertTomlTable(next, 'model_providers.codex-lb', cliProviderBlock(input.remoteBaseUrl));
|
|
59
|
+
return ensureTrailingNewline(next);
|
|
60
|
+
}
|
|
61
|
+
export function removeCodexLbManagedDesktopConfig(text) {
|
|
62
|
+
let next = removeManagedDesktopBridgeRouting(String(text || ''));
|
|
63
|
+
if (topLevelHasLine(next, CODEX_LB_DESKTOP_COMPAT_MARKER)) {
|
|
64
|
+
next = removeTopLevelTomlKeyIfValue(next, 'model_provider', 'codex-lb');
|
|
65
|
+
next = removeTopLevelLine(next, CODEX_LB_DESKTOP_COMPAT_MARKER);
|
|
66
|
+
}
|
|
67
|
+
next = removeManagedModelCatalogJson(next);
|
|
68
|
+
return ensureTrailingNewline(next);
|
|
69
|
+
}
|
|
70
|
+
export function removeManagedModelCatalogJson(text) {
|
|
71
|
+
if (!topLevelHasLine(text, CODEX_LB_MODEL_CATALOG_MARKER))
|
|
72
|
+
return text;
|
|
73
|
+
const withoutKey = removeTopLevelTomlKey(text, 'model_catalog_json');
|
|
74
|
+
return removeTopLevelLine(withoutKey, CODEX_LB_MODEL_CATALOG_MARKER);
|
|
75
|
+
}
|
|
76
|
+
export function removeManagedDesktopBridgeRouting(text) {
|
|
77
|
+
const markers = [
|
|
78
|
+
CODEX_LB_DESKTOP_BRIDGE_MARKER,
|
|
79
|
+
LEGACY_CODEX_LB_OPENAI_ROUTING_MARKER
|
|
80
|
+
].filter((marker) => topLevelHasLine(text, marker));
|
|
81
|
+
if (markers.length === 0)
|
|
82
|
+
return text;
|
|
83
|
+
let next = removeTopLevelTomlKey(text, 'openai_base_url');
|
|
84
|
+
for (const marker of markers)
|
|
85
|
+
next = removeTopLevelLine(next, marker);
|
|
86
|
+
return next;
|
|
87
|
+
}
|
|
88
|
+
export function upsertCodexLbConfig(text = '', baseUrl, selectDefault = true) {
|
|
89
|
+
return upsertCodexLbCliProviderConfig(text, {
|
|
90
|
+
remoteBaseUrl: String(baseUrl || ''),
|
|
91
|
+
selectGlobally: selectDefault === true
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function cliProviderBlock(remoteBaseUrl) {
|
|
95
|
+
return [
|
|
15
96
|
'[model_providers.codex-lb]',
|
|
16
|
-
'name = "
|
|
17
|
-
`base_url =
|
|
97
|
+
'name = "codex-lb"',
|
|
98
|
+
`base_url = ${JSON.stringify(remoteBaseUrl)}`,
|
|
18
99
|
'wire_api = "responses"',
|
|
19
100
|
'env_key = "CODEX_LB_API_KEY"',
|
|
20
101
|
'supports_websockets = true',
|
|
21
|
-
'requires_openai_auth =
|
|
102
|
+
'requires_openai_auth = false'
|
|
22
103
|
].join('\n');
|
|
23
|
-
|
|
24
|
-
|
|
104
|
+
}
|
|
105
|
+
function upsertManagedTopLevelTomlString(text, key, value, marker, legacyMarkers = []) {
|
|
106
|
+
const acceptedMarkers = [marker, ...legacyMarkers];
|
|
107
|
+
const existing = topLevelTomlString(text, key);
|
|
108
|
+
const ownedMarker = acceptedMarkers.find((candidate) => topLevelHasLine(text, candidate));
|
|
109
|
+
if (existing && !ownedMarker) {
|
|
110
|
+
if (existing === value)
|
|
111
|
+
return text;
|
|
112
|
+
throw new Error(`codex_lb_user_owned_${key}_conflict`);
|
|
113
|
+
}
|
|
114
|
+
let next = text;
|
|
115
|
+
for (const candidate of acceptedMarkers)
|
|
116
|
+
next = removeTopLevelLine(next, candidate);
|
|
117
|
+
next = upsertTopLevelTomlString(next, key, value);
|
|
118
|
+
return addTopLevelMarkerBeforeKey(next, key, marker);
|
|
119
|
+
}
|
|
120
|
+
function removeTopLevelTomlKey(text, key) {
|
|
121
|
+
const lines = String(text || '').split('\n');
|
|
122
|
+
const firstTable = lines.findIndex((line) => /^\s*\[.+\]\s*$/.test(line));
|
|
123
|
+
const end = firstTable === -1 ? lines.length : firstTable;
|
|
124
|
+
const keyPattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`);
|
|
125
|
+
return lines
|
|
126
|
+
.filter((line, index) => index >= end || !keyPattern.test(line))
|
|
127
|
+
.join('\n')
|
|
128
|
+
.replace(/^\n+/, '')
|
|
129
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
25
130
|
}
|
|
26
131
|
const CODEX_LB_SHARED_OPENAI_ROUTING_MARKER = '# sks-codex-lb-managed-openai-base-url';
|
|
27
132
|
export function codexLbSharedOpenAiRoutingState(text = '', baseUrl = '') {
|
|
@@ -252,22 +252,12 @@ export async function ensureGlobalCodexSkillsDuringInstall(opts = {}) {
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
export async function ensureGlobalGetdesignSkillDuringInstall() {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const add = await runProcess(skillsBin, ['add', GETDESIGN_REFERENCE.codex_skill], {
|
|
262
|
-
timeoutMs: 30000,
|
|
263
|
-
maxOutputBytes: 64 * 1024
|
|
264
|
-
}).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
|
|
265
|
-
const out = `${add.stdout || ''}\n${add.stderr || ''}`;
|
|
266
|
-
if (add.code === 0)
|
|
267
|
-
return { status: /already|exists|present/i.test(out) ? 'present' : 'installed', command: skillsBin };
|
|
268
|
-
if (/already|exists|present/i.test(out))
|
|
269
|
-
return { status: 'present', command: skillsBin };
|
|
270
|
-
return { status: 'failed', command: skillsBin, error: out.trim() || 'skills add failed' };
|
|
255
|
+
return {
|
|
256
|
+
status: 'skipped',
|
|
257
|
+
reason: 'manual_install_only',
|
|
258
|
+
install: GETDESIGN_REFERENCE.codex_skill_install,
|
|
259
|
+
reviewed_ref: GETDESIGN_REFERENCE.codex_skill_ref
|
|
260
|
+
};
|
|
271
261
|
}
|
|
272
262
|
export async function ensureCodexImagegenDuringInstall(opts = {}) {
|
|
273
263
|
if (process.env.SKS_POSTINSTALL_SKIP_IMAGEGEN_REPAIR === '1' || opts.skip === true) {
|