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
|
@@ -74,6 +74,7 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
74
74
|
private let scopePopup = NSPopUpButton()
|
|
75
75
|
private var rows: [McpRow] = []
|
|
76
76
|
private var mutating = false
|
|
77
|
+
private var refreshGeneration = 0
|
|
77
78
|
private var editor: McpEditorSheet?
|
|
78
79
|
private lazy var addButton = actionButton("Add…", #selector(addServer))
|
|
79
80
|
private lazy var editButton = actionButton("Edit…", #selector(editServer))
|
|
@@ -93,10 +94,17 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
93
94
|
required init?(coder: NSCoder) { nil }
|
|
94
95
|
|
|
95
96
|
override func loadView() {
|
|
96
|
-
for (id, title, width) in [
|
|
97
|
-
|
|
97
|
+
for (id, title, width, minimum) in [
|
|
98
|
+
("state", "State", 90.0, 72.0),
|
|
99
|
+
("name", "Name", 150.0, 110.0),
|
|
100
|
+
("transport", "Transport", 110.0, 86.0),
|
|
101
|
+
("configuration", "Configuration", 230.0, 150.0)
|
|
102
|
+
] {
|
|
103
|
+
let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(id))
|
|
104
|
+
column.title = title; column.width = width; column.minWidth = minimum
|
|
98
105
|
table.addTableColumn(column)
|
|
99
106
|
}
|
|
107
|
+
table.columnAutoresizingStyle = .lastColumnOnlyAutoresizingStyle
|
|
100
108
|
table.dataSource = self; table.delegate = self; table.usesAlternatingRowBackgroundColors = true
|
|
101
109
|
table.allowsMultipleSelection = false; table.setAccessibilityLabel("Effective MCP servers")
|
|
102
110
|
let scroll = NSScrollView(); scroll.documentView = table; scroll.hasVerticalScroller = true; scroll.hasHorizontalScroller = true
|
|
@@ -107,18 +115,24 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
107
115
|
scopeRow.orientation = .horizontal; scopeRow.spacing = 8
|
|
108
116
|
// Destructive Remove sits apart from routine edit actions; connection
|
|
109
117
|
// and maintenance actions live on their own labeled row.
|
|
110
|
-
let primary = ControlKit.actionRow([addButton, editButton, duplicateButton
|
|
118
|
+
let primary = ControlKit.actionRow([addButton, editButton, duplicateButton])
|
|
119
|
+
let stateActions = ControlKit.actionRow([toggleButton], trailing: [removeButton])
|
|
111
120
|
let manageLabel = NSTextField(labelWithString: "Manage"); manageLabel.textColor = .secondaryLabelColor
|
|
112
121
|
let connectLabel = NSTextField(labelWithString: "Connection"); connectLabel.textColor = .secondaryLabelColor
|
|
113
122
|
for label in [manageLabel, connectLabel] { label.font = NSFont.systemFont(ofSize: 11, weight: .medium) }
|
|
114
|
-
let secondary =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
let secondary = ControlKit.actionRow([testButton, oauthButton, legacySecretButton])
|
|
124
|
+
let maintenance = ControlKit.actionRow([backupsButton, refreshButton])
|
|
125
|
+
let inventoryCard = NativeView.card(
|
|
126
|
+
title: "Server inventory",
|
|
127
|
+
subtitle: "Select one row before using edit, connection, authentication, or removal actions.",
|
|
128
|
+
views: [scroll, status, manageLabel, primary, stateActions, connectLabel, secondary, maintenance]
|
|
129
|
+
)
|
|
130
|
+
view = NativeView.page([
|
|
131
|
+
ControlKit.header("MCP Servers", "Inspect global, trusted-project, or effective configuration. Effective and plugin entries are read-only until an exact writable scope is selected. New authentication uses OAuth or environment-variable names only."),
|
|
132
|
+
scopeRow,
|
|
133
|
+
inventoryCard
|
|
120
134
|
])
|
|
121
|
-
updateButtons()
|
|
135
|
+
updateButtons()
|
|
122
136
|
}
|
|
123
137
|
|
|
124
138
|
func numberOfRows(in tableView: NSTableView) -> Int { rows.count }
|
|
@@ -143,9 +157,14 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
143
157
|
@objc private func scopeChanged() { refresh() }
|
|
144
158
|
|
|
145
159
|
@objc private func refresh() {
|
|
146
|
-
|
|
160
|
+
guard !mutating else { return }
|
|
161
|
+
refreshGeneration += 1
|
|
162
|
+
let requestGeneration = refreshGeneration
|
|
163
|
+
let scope = selectedScope()
|
|
164
|
+
status.stringValue = "Loading \(scope) MCP configuration…"
|
|
165
|
+
refreshButton.isEnabled = false
|
|
147
166
|
processClient.run(["mcp", "config", "list", "--scope", scope] + scopeContext(scope, mutation: false) + ["--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
148
|
-
guard let self = self else { return }
|
|
167
|
+
guard let self = self, self.refreshGeneration == requestGeneration else { return }
|
|
149
168
|
guard let json = self.json(result.output), let servers = json["servers"] as? [[String: Any]] else {
|
|
150
169
|
self.rows = []; self.table.reloadData(); self.status.stringValue = "MCP inventory unavailable. No configuration was changed."
|
|
151
170
|
self.updateButtons(); return
|
|
@@ -155,7 +174,9 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
155
174
|
let enabled = json["enabled_count"] as? Int ?? self.rows.filter(\.enabled).count
|
|
156
175
|
let failed = json["failed_count"] as? Int ?? 0
|
|
157
176
|
let warnings = (json["warnings"] as? [String] ?? []).filter { !$0.hasPrefix("public_error:") }
|
|
158
|
-
self.status.stringValue =
|
|
177
|
+
self.status.stringValue = self.rows.isEmpty
|
|
178
|
+
? "No MCP servers are configured in the \(scope) scope."
|
|
179
|
+
: "\(self.rows.count) servers · \(enabled) enabled · \(failed) need attention" + (warnings.isEmpty ? "" : " · \(warnings.count) advisory")
|
|
159
180
|
self.updateButtons()
|
|
160
181
|
}
|
|
161
182
|
}
|
|
@@ -296,6 +317,7 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
296
317
|
|
|
297
318
|
private func mutate(_ args: [String], stdin: String? = nil) {
|
|
298
319
|
guard !mutating, let operation = operations.begin(kind: "mcp-config", mutationGroup: "mcp", summary: "MCP configuration change") else { status.stringValue = "An update or MCP mutation is already running."; return }
|
|
320
|
+
refreshGeneration += 1
|
|
299
321
|
mutating = true; updateButtons(); _ = operations.update(operation, state: .running, stage: "apply", progress: nil, summary: "Applying scoped MCP change")
|
|
300
322
|
processClient.run(args, stdin: stdin, timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
301
323
|
guard let self = self else { return }
|
|
@@ -326,6 +348,11 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
326
348
|
private func actionButton(_ title: String, _ action: Selector) -> NSButton { NativeView.button(title, target: self, action: action) }
|
|
327
349
|
private func updateButtons() {
|
|
328
350
|
let row = selected()?.row; let writable = selectedWritableRow() != nil
|
|
351
|
+
toggleButton.title = row?.enabled == true ? "Disable Selected" : "Enable Selected"
|
|
352
|
+
removeButton.title = "Remove Selected"
|
|
353
|
+
testButton.title = "Test Selected"
|
|
354
|
+
oauthButton.title = row?.authenticated == true ? "Sign Out OAuth" : "Sign In with OAuth"
|
|
355
|
+
legacySecretButton.title = "Review Legacy Secret…"
|
|
329
356
|
addButton.isEnabled = !mutating; refreshButton.isEnabled = !mutating; scopePopup.isEnabled = !mutating
|
|
330
357
|
for button in [editButton, duplicateButton, toggleButton, removeButton] { button.isEnabled = !mutating && writable }
|
|
331
358
|
testButton.isEnabled = !mutating && row != nil && row?.managedBy != "plugin"
|
|
@@ -391,12 +418,13 @@ private final class McpEditorSheet: NSObject {
|
|
|
391
418
|
pair("Default approval mode", approval), pair("Environment", remote), pair("Requirement", required)
|
|
392
419
|
])
|
|
393
420
|
grid.rowSpacing = 6; grid.columnSpacing = 12; grid.column(at: 0).xPlacement = .trailing; grid.column(at: 1).xPlacement = .fill
|
|
394
|
-
grid.column(at: 1).width =
|
|
421
|
+
grid.column(at: 1).width = 300
|
|
395
422
|
let cancel = NSButton(title: "Cancel", target: self, action: #selector(cancelSheet)); let buttons = NSStackView(views: [cancel, apply])
|
|
396
423
|
buttons.orientation = .horizontal; buttons.spacing = 8
|
|
397
|
-
let stack = NativeView.
|
|
398
|
-
|
|
399
|
-
|
|
424
|
+
let stack = NativeView.page([NativeView.detail("Connection values are used only for the selected transport. Edit fields may be left blank to preserve existing connection data."), grid, review, buttons])
|
|
425
|
+
let scroll = NativeView.scrollable(stack)
|
|
426
|
+
panel.contentView = NSView(); panel.contentView?.addSubview(scroll)
|
|
427
|
+
NSLayoutConstraint.activate([scroll.leadingAnchor.constraint(equalTo: panel.contentView!.leadingAnchor), scroll.trailingAnchor.constraint(equalTo: panel.contentView!.trailingAnchor), scroll.topAnchor.constraint(equalTo: panel.contentView!.topAnchor), scroll.bottomAnchor.constraint(equalTo: panel.contentView!.bottomAnchor)])
|
|
400
428
|
}
|
|
401
429
|
|
|
402
430
|
@objc private func transportChanged() { let local = transport.indexOfSelectedItem == 0; command.isEnabled = local; args.isEditable = local; cwd.isEnabled = local; env.isEditable = local; remote.isEnabled = local; url.isEnabled = !local; bearer.isEnabled = !local; reviewed = nil; apply.title = "Review" }
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
enum OverviewSummary {
|
|
4
|
+
static func render(
|
|
5
|
+
update: [String: Any]?,
|
|
6
|
+
mcp: [String: Any]?,
|
|
7
|
+
telegram: [String: Any]?,
|
|
8
|
+
menuBarBuild: String,
|
|
9
|
+
codexRunning: Bool?,
|
|
10
|
+
operationSummary: String
|
|
11
|
+
) -> String {
|
|
12
|
+
let codexAppState = codexRunning.map { $0 ? "Running" : "Not running" } ?? "Not configured"
|
|
13
|
+
var lines: [String] = []
|
|
14
|
+
let update = validatedUpdate(update)
|
|
15
|
+
let mcp = validatedMCP(mcp)
|
|
16
|
+
let telegram = validatedTelegram(telegram)
|
|
17
|
+
|
|
18
|
+
if let update = update {
|
|
19
|
+
let sks = update["sks"] as? [String: Any]
|
|
20
|
+
let codex = update["codex_cli"] as? [String: Any]
|
|
21
|
+
let menu = update["menubar"] as? [String: Any]
|
|
22
|
+
lines.append("SKS install: \(versionSummary(sks))")
|
|
23
|
+
lines.append("Codex CLI: \(versionSummary(codex)) · Codex app: \(codexAppState)")
|
|
24
|
+
if let inducement = codexUpdateInducement(codex) {
|
|
25
|
+
lines.append(inducement)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var menuParts = ["running build \(menuBarBuild)"]
|
|
29
|
+
if let expected = menu?["expected_version"] as? String { menuParts.append("expected \(expected)") }
|
|
30
|
+
if let installed = menu?["installed_version"] as? String, installed != menuBarBuild {
|
|
31
|
+
menuParts.append("snapshot installed \(installed)")
|
|
32
|
+
}
|
|
33
|
+
if let rebuildRequired = menu?["rebuild_required"] as? Bool {
|
|
34
|
+
menuParts.append(rebuildRequired ? "rebuild required" : "current")
|
|
35
|
+
} else {
|
|
36
|
+
menuParts.append("rebuild state unknown")
|
|
37
|
+
}
|
|
38
|
+
menuParts.append("signature \(verificationState(menu?["signature_ok"]))")
|
|
39
|
+
menuParts.append("resources \(verificationState(menu?["resources_ok"]))")
|
|
40
|
+
lines.append("Menu Bar: \(menuParts.joined(separator: " · "))")
|
|
41
|
+
|
|
42
|
+
let source = snapshotSource(update["source"] as? String)
|
|
43
|
+
var updateParts = [integer(update["update_count"]).map { "\($0) pending" } ?? "pending count unknown", "\(source) snapshot"]
|
|
44
|
+
if let error = diagnosticNotice(update["public_error"] as? String, update: update) {
|
|
45
|
+
updateParts.append("notice: \(error)")
|
|
46
|
+
} else if let warnings = update["warnings"] as? [String], !warnings.isEmpty {
|
|
47
|
+
updateParts.append("\(warnings.count) warning\(warnings.count == 1 ? "" : "s")")
|
|
48
|
+
}
|
|
49
|
+
lines.append("Updates: \(updateParts.joined(separator: " · "))")
|
|
50
|
+
} else {
|
|
51
|
+
lines.append("SKS install: unavailable")
|
|
52
|
+
lines.append("Codex CLI: unavailable · Codex app: \(codexAppState)")
|
|
53
|
+
lines.append("Menu Bar: running build \(menuBarBuild) · update status unavailable")
|
|
54
|
+
lines.append("Updates: unavailable")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if let mcp = mcp,
|
|
58
|
+
let enabled = integer(mcp["enabled_count"]),
|
|
59
|
+
let failed = integer(mcp["failed_count"]) {
|
|
60
|
+
lines.append("MCP: \(enabled) enabled · \(failed) failed")
|
|
61
|
+
} else {
|
|
62
|
+
lines.append("MCP: unavailable")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if let telegram = telegram {
|
|
66
|
+
let owner = telegram["owner"] as? [String: Any]
|
|
67
|
+
let configured = telegram["configured"] as? Bool
|
|
68
|
+
let hubState = owner != nil ? "Running" : configured == true ? "Stopped" : configured == false ? "Not configured" : "Unknown"
|
|
69
|
+
let machines = integer(telegram["machine_count"]).map { "\($0) registered Macs" } ?? "registered Macs unknown"
|
|
70
|
+
let targets = integer(telegram["target_count"]).map { "\($0) configured targets" } ?? "configured targets unknown"
|
|
71
|
+
let issues = ((telegram["config_issues"] as? [String]) ?? []).count
|
|
72
|
+
+ ((telegram["remote_config_issues"] as? [String]) ?? []).count
|
|
73
|
+
var fleet = "Remote fleet: \(machines) · \(targets)"
|
|
74
|
+
if issues > 0 { fleet += " · \(issues) issue\(issues == 1 ? "" : "s")" }
|
|
75
|
+
lines.append("Telegram Hub: \(hubState) · \(fleet)")
|
|
76
|
+
} else {
|
|
77
|
+
lines.append("Telegram Hub: unavailable · Remote fleet: unavailable")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
lines.append("Last operation: \(operationSummary) · Logs and snapshots use mode 0600")
|
|
81
|
+
return lines.joined(separator: "\n")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private static func validatedUpdate(_ value: [String: Any]?) -> [String: Any]? {
|
|
85
|
+
guard value?["schema"] as? String == "sks.update-status.v3",
|
|
86
|
+
value?["source"] is String,
|
|
87
|
+
integer(value?["update_count"]) != nil,
|
|
88
|
+
let sks = value?["sks"] as? [String: Any],
|
|
89
|
+
let codex = value?["codex_cli"] as? [String: Any],
|
|
90
|
+
let menu = value?["menubar"] as? [String: Any],
|
|
91
|
+
sks["update_available"] is Bool,
|
|
92
|
+
codex["update_available"] is Bool,
|
|
93
|
+
menu["expected_version"] is String,
|
|
94
|
+
menu["rebuild_required"] is Bool else { return nil }
|
|
95
|
+
return value
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private static func validatedMCP(_ value: [String: Any]?) -> [String: Any]? {
|
|
99
|
+
guard value?["schema"] as? String == "sks.mcp-inventory.v2",
|
|
100
|
+
integer(value?["enabled_count"]) != nil,
|
|
101
|
+
integer(value?["failed_count"]) != nil else { return nil }
|
|
102
|
+
return value
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private static func validatedTelegram(_ value: [String: Any]?) -> [String: Any]? {
|
|
106
|
+
guard value?["schema"] as? String == "sks.telegram-status.v1",
|
|
107
|
+
value?["configured"] is Bool,
|
|
108
|
+
integer(value?["machine_count"]) != nil,
|
|
109
|
+
integer(value?["target_count"]) != nil,
|
|
110
|
+
value?["config_issues"] is [String],
|
|
111
|
+
value?["remote_config_issues"] is [String] else { return nil }
|
|
112
|
+
return value
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private static func versionSummary(_ value: [String: Any]?) -> String {
|
|
116
|
+
guard let current = nonEmpty(value?["current"] as? String) else { return "not detected" }
|
|
117
|
+
guard let latest = nonEmpty(value?["latest"] as? String) else { return current }
|
|
118
|
+
if value?["update_available"] as? Bool == true, latest != current { return "\(current) → \(latest) available" }
|
|
119
|
+
if latest == current { return "\(current) (current)" }
|
|
120
|
+
return "\(current) · registry last seen \(latest)"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private static func codexUpdateInducement(_ value: [String: Any]?) -> String? {
|
|
124
|
+
guard value?["update_available"] as? Bool == true else { return nil }
|
|
125
|
+
let current = nonEmpty(value?["current"] as? String) ?? "installed"
|
|
126
|
+
let latest = nonEmpty(value?["latest"] as? String) ?? "preferred latest"
|
|
127
|
+
return "Action: update Codex CLI (\(current) → \(latest)) from Updates, or choose Update Codex CLI Now in the menu bar."
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private static func verificationState(_ value: Any?) -> String {
|
|
131
|
+
guard let value = value as? Bool else { return "unknown" }
|
|
132
|
+
return value ? "verified" : "needs attention"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private static func snapshotSource(_ value: String?) -> String {
|
|
136
|
+
guard let value = nonEmpty(value) else { return "unknown" }
|
|
137
|
+
return value.replacingOccurrences(of: "_", with: " ")
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private static func diagnosticNotice(_ value: String?, update: [String: Any]) -> String? {
|
|
141
|
+
guard let value = nonEmpty(value) else { return nil }
|
|
142
|
+
let versions = [
|
|
143
|
+
(update["sks"] as? [String: Any])?["current"] as? String,
|
|
144
|
+
(update["sks"] as? [String: Any])?["latest"] as? String,
|
|
145
|
+
(update["codex_cli"] as? [String: Any])?["current"] as? String,
|
|
146
|
+
(update["codex_cli"] as? [String: Any])?["latest"] as? String
|
|
147
|
+
].compactMap { $0 }
|
|
148
|
+
if versions.contains(value) { return nil }
|
|
149
|
+
if value.range(of: #"^v?\d+(?:\.\d+){1,3}(?:[-+][A-Za-z0-9.-]+)?$"#, options: .regularExpression) != nil { return nil }
|
|
150
|
+
return value
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private static func integer(_ value: Any?) -> Int? {
|
|
154
|
+
if let value = value as? Int { return value }
|
|
155
|
+
return (value as? NSNumber)?.intValue
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private static func nonEmpty(_ value: String?) -> String? {
|
|
159
|
+
guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else { return nil }
|
|
160
|
+
return value
|
|
161
|
+
}
|
|
162
|
+
}
|