@moretea-labs/forge 1.6.0 → 1.7.1
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/AGENTS.md +4 -0
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +4 -0
- package/README.md +2 -2
- package/README.zh-CN.md +1 -1
- package/SKILL.md +2 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/hooks/hook-input.sh +11 -8
- package/assets/hooks/lib/session-state.sh +10 -7
- package/assets/hooks/lib/workflow-state.sh +13 -177
- package/assets/hooks/post-tool-observer.sh +8 -2
- package/assets/hooks/prompt-guard.sh +5 -81
- package/assets/hooks/session-start-context.sh +56 -1
- package/assets/partials/05-workflow.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +2 -0
- package/assets/partials-agents/03-orchestration.partial.md +1 -1
- package/assets/plugin-registry.v1.json +3 -3
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/harness-overview.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/contract.template.md +2 -7
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +17 -0
- package/assets/templates/helpers/check-task-workflow.sh +4 -4
- package/assets/templates/helpers/contract-worktree.sh +1 -21
- package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
- package/assets/templates/helpers/inspect-project-state.ts +8 -6
- package/assets/templates/helpers/migrate-project-template.sh +22 -45
- package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
- package/assets/templates/helpers/new-plan.sh +1 -1
- package/assets/templates/helpers/plan-to-todo.sh +12 -37
- package/assets/templates/helpers/ship-worktrees.sh +2 -29
- package/assets/templates/helpers/verify-contract.sh +1 -111
- package/assets/templates/helpers/verify-sprint.sh +3 -180
- package/assets/templates/helpers/workflow-contract.ts +5 -1
- package/assets/templates/plan.template.md +1 -1
- package/assets/templates/review.template.md +9 -34
- package/assets/workflow-contract.v1.json +10 -19
- package/docs/README.md +10 -10
- package/docs/architecture/CURRENT.md +178 -0
- package/docs/architecture/EVOLUTION.md +42 -0
- package/docs/architecture/current/README.md +4 -156
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
- package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
- package/docs/architecture/history/README.md +7 -0
- package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
- package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
- package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
- package/docs/architecture/history.md +3 -34
- package/docs/architecture/index.md +15 -98
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
- package/docs/architecture/versions/1.6.md +38 -0
- package/docs/architecture/versions/1.7.md +41 -0
- package/docs/forge-chatgpt-browser-engine.md +2 -2
- package/docs/forge-chatgpt-mcp-setup.md +4 -28
- package/docs/forge-chatgpt-supervised-automation.md +3 -3
- package/docs/forge-github-issue-launcher.md +1 -1
- package/docs/forge-plugin-management.md +1 -1
- package/docs/forge-runtime-self-healing-loop.md +1 -1
- package/docs/operations/controller-browser-plugin.md +26 -6
- package/docs/operations/controller-performance-and-502.md +143 -0
- package/docs/operations/controller-reliability-runbook.md +1 -1
- package/docs/operations/features.md +2 -2
- package/docs/operations/github-repository.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +5 -3
- package/docs/wiki/Architecture.md +6 -6
- package/docs/wiki/Implementation.md +2 -2
- package/docs/wiki/Integrations.md +2 -2
- package/docs/wiki/Work-Lifecycle.md +1 -1
- package/package.json +33 -11
- package/scripts/activate-source-baseline.ts +17 -13
- package/scripts/architecture-event.ts +2 -820
- package/scripts/architecture-queue.sh +2 -645
- package/scripts/archive-architecture-request.sh +2 -242
- package/scripts/archive-workflow.sh +1 -291
- package/scripts/benchmark-background-check-overlap.ts +228 -0
- package/scripts/benchmark-mcp-host.sh +117 -0
- package/scripts/benchmark-mcp-transport.ts +170 -0
- package/scripts/benchmark-quality-harness.ts +146 -0
- package/scripts/benchmark-route-session-concurrency.ts +207 -6
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
- package/scripts/benchmark-typescript-navigation.ts +186 -0
- package/scripts/benchmark-work-efficiency.ts +334 -0
- package/scripts/capability-config.ts +2 -392
- package/scripts/capability-resolver.ts +2 -503
- package/scripts/capture-plan.sh +1 -332
- package/scripts/check-agent-tooling.sh +2 -1558
- package/scripts/check-architecture-sync.sh +2 -371
- package/scripts/check-brain-manifest.sh +2 -253
- package/scripts/check-context-files.sh +2 -47
- package/scripts/check-deploy-sql-order.sh +2 -115
- package/scripts/check-mcp-compatibility.ts +14 -0
- package/scripts/check-runtime-architecture.mjs +349 -79
- package/scripts/check-skill-version.ts +3 -191
- package/scripts/check-source-duplication.mjs +61 -0
- package/scripts/check-stable-baseline.ts +92 -0
- package/scripts/check-task-sync.sh +2 -63
- package/scripts/check-task-workflow.sh +2 -1000
- package/scripts/codex-handoff-resume.sh +2 -267
- package/scripts/context-contract-sync.sh +2 -514
- package/scripts/contract-run.ts +2 -463
- package/scripts/contract-worktree.sh +1 -722
- package/scripts/ensure-task-workflow.sh +1 -1225
- package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
- package/scripts/inspect-project-state.ts +4 -279
- package/scripts/install-standalone-recovery.ts +24 -0
- package/scripts/lib/project-init-lib.sh +22 -46
- package/scripts/lib/run-forge-helper.sh +19 -0
- package/scripts/lib/run-forge-helper.ts +26 -0
- package/scripts/migrate-project-template.sh +1 -1189
- package/scripts/migrate-workflow-docs.ts +4 -412
- package/scripts/new-plan.sh +1 -180
- package/scripts/new-spec.sh +1 -47
- package/scripts/new-sprint.sh +1 -46
- package/scripts/plan-to-todo.sh +1 -796
- package/scripts/prepare-codex-handoff.sh +2 -201
- package/scripts/prepare-handoff.sh +1 -78
- package/scripts/refresh-current-status.sh +2 -467
- package/scripts/run-governed-gate.ts +5 -1
- package/scripts/select-agent-context-blocks.sh +2 -64
- package/scripts/ship-worktrees.sh +1 -558
- package/scripts/smoke-ios-physical-device.ts +4 -2
- package/scripts/smoke-runtime-recovery.ts +1 -35
- package/scripts/smoke-schedule-engine.ts +1 -20
- package/scripts/sprint-backlog.sh +1 -834
- package/scripts/stage-runtime-release.ts +2 -1
- package/scripts/summarize-failures.sh +2 -123
- package/scripts/switch-plan.sh +1 -150
- package/scripts/sync-brain-docs.sh +2 -379
- package/scripts/sync-generated-authority.mjs +175 -0
- package/scripts/verify-contract.sh +2 -703
- package/scripts/verify-forge-runtime.sh +0 -1
- package/scripts/verify-sprint.sh +1 -677
- package/scripts/workflow-contract.ts +4 -205
- package/scripts/workstream-sync.sh +2 -261
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/commands/init-hook.ts +3 -3
- package/src/cli/commands/mcp.ts +9 -5
- package/src/cli/commands/plugin.ts +12 -3
- package/src/cli/commands/recovery.ts +25 -3
- package/src/cli/commands/runtime.ts +55 -3
- package/src/cli/commands/security.ts +12 -1
- package/src/cli/commands/setup-profile.ts +31 -21
- package/src/cli/controller/check-runner.ts +113 -5
- package/src/cli/controller/composite-result.ts +1 -1
- package/src/cli/controller/context/focus.ts +51 -0
- package/src/cli/controller/context/instruction-context.ts +114 -0
- package/src/cli/controller/context/known-paths.ts +76 -0
- package/src/cli/controller/context/query-planning.ts +110 -0
- package/src/cli/controller/context/rule-resolution.ts +532 -0
- package/src/cli/controller/context/source-materializer.ts +278 -0
- package/src/cli/controller/context/structural.ts +16 -0
- package/src/cli/controller/context/types.ts +286 -0
- package/src/cli/controller/context-pack.ts +828 -487
- package/src/cli/controller/launch-agents.ts +77 -2
- package/src/cli/controller/operational-plan.ts +2 -2
- package/src/cli/controller/work-mode.ts +6 -4
- package/src/cli/editing/edit-session.ts +60 -7
- package/src/cli/github/contracts.ts +16 -0
- package/src/cli/github/github.ts +135 -16
- package/src/cli/github/session.ts +2 -1
- package/src/cli/installer/managed-entries.ts +15 -1
- package/src/cli/local-bridge/console-automations.ts +54 -78
- package/src/cli/local-bridge/console-view-models.ts +1 -35
- package/src/cli/local-bridge/facade-api.ts +37 -264
- package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
- package/src/cli/local-bridge/frontend/src/styles.css +1 -1
- package/src/cli/local-bridge/frontend/src/types.ts +5 -8
- package/src/cli/local-bridge/job-store.ts +1 -490
- package/src/cli/local-bridge/server.ts +2 -515
- package/src/cli/local-bridge/ui-dist/app.css +1 -1
- package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
- package/src/cli/mcp/auth.ts +5 -5
- package/src/cli/mcp/instructions.ts +3 -2
- package/src/cli/mcp/legacy-tool-service.ts +10 -222
- package/src/cli/mcp/multi-repository.ts +16 -5
- package/src/cli/mcp/oauth.ts +175 -26
- package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
- package/src/cli/mcp/repository-tools.ts +282 -146
- package/src/cli/mcp/server.ts +586 -116
- package/src/cli/mcp/tool-capability-cache.ts +1 -1
- package/src/cli/mcp/tool-contract.ts +14 -0
- package/src/cli/mcp/toolset-selection.ts +1 -1
- package/src/cli/mcp/toolset.ts +44 -7
- package/src/cli/mcp/transports/http.ts +124 -14
- package/src/cli/mcp/transports/session-registry.ts +43 -5
- package/src/cli/mcp/types.ts +3 -3
- package/src/cli/repositories/command-classifier.ts +103 -21
- package/src/cli/repositories/command-executor.ts +78 -526
- package/src/cli/repositories/command-process.ts +108 -0
- package/src/cli/repositories/command-scope.ts +99 -41
- package/src/cli/repositories/controller-home.ts +7 -8
- package/src/cli/repositories/git-command-executor.ts +2 -0
- package/src/cli/repositories/locks.ts +53 -16
- package/src/cli/repositories/repository-snapshot.ts +124 -0
- package/src/cli/repositories/selected-path-actions.ts +17 -9
- package/src/cli/repositories/structured-git.ts +118 -6
- package/src/cli/repository/inspector.ts +563 -65
- package/src/cli/repository/session-cache.ts +58 -17
- package/src/cli/v81-entry.ts +1 -4
- package/src/effects/fs-transaction.ts +85 -17
- package/src/runtime/context/codegraph-read-provider.ts +233 -2
- package/src/runtime/context/codegraph-sidecar.cjs +74 -40
- package/src/runtime/context/generic-lsp-provider.ts +355 -0
- package/src/runtime/context/lsp-client.ts +283 -0
- package/src/runtime/context/semantic-navigation-contract.ts +61 -0
- package/src/runtime/context/semantic-navigation.ts +223 -0
- package/src/runtime/context/swift-navigation.ts +565 -0
- package/src/runtime/context/typescript-navigation.ts +226 -0
- package/src/runtime/control-plane/dispatch-priority.ts +28 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +48 -16
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
- package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
- package/src/runtime/control-plane/execution/session-store.ts +18 -0
- package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
- package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
- package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
- package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
- package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
- package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
- package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
- package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +22 -18
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +156 -11
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
- package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
- package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +90 -9
- package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
- package/src/runtime/control-plane/facade/controller-round-relay.ts +1118 -0
- package/src/runtime/control-plane/facade/controller-session-store.ts +302 -12
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +17 -1
- package/src/runtime/control-plane/facade/goal-workloop.ts +928 -190
- package/src/runtime/control-plane/facade/index.ts +3 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +275 -42
- package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
- package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
- package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
- package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
- package/src/runtime/control-plane/facade/types.ts +90 -10
- package/src/runtime/control-plane/facade/work-contract-store.ts +157 -261
- package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
- package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
- package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
- package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +152 -0
- package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +278 -543
- package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
- package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
- package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
- package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
- package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +63 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +365 -117
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +89 -0
- package/src/runtime/control-plane/launcher/thin-launcher.ts +244 -11
- package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
- package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
- package/src/runtime/control-plane/release-retention.ts +62 -2
- package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
- package/src/runtime/control-plane/routing/route-policy.ts +24 -21
- package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
- package/src/runtime/control-plane/runtime-status-client.ts +0 -2
- package/src/runtime/diagnostics/mcp-timing.ts +13 -0
- package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
- package/src/runtime/diagnostics/performance.ts +24 -1
- package/src/runtime/evidence/event-ledger.ts +1 -1
- package/src/runtime/evidence/process-check-execution.ts +18 -0
- package/src/runtime/execution/jobs/child-reference.ts +6 -2
- package/src/runtime/execution/jobs/store.ts +58 -4
- package/src/runtime/execution/jobs/types.ts +1 -1
- package/src/runtime/execution/managed-workspace.ts +203 -1
- package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
- package/src/runtime/execution/process-runtime/check-result.ts +88 -0
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
- package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +367 -40
- package/src/runtime/execution/process-runtime/gc.ts +38 -6
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +1201 -0
- package/src/runtime/execution/process-runtime/persisted-check.ts +51 -5
- package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
- package/src/runtime/execution/process-runtime/runtime.ts +53 -3
- package/src/runtime/execution/process-runtime/store.ts +1 -0
- package/src/runtime/execution/process-runtime/types.ts +4 -12
- package/src/runtime/execution/thin-harness/async-process.ts +12 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
- package/src/runtime/execution/work-activity.ts +21 -0
- package/src/runtime/execution/workers/executor.ts +18 -61
- package/src/runtime/gateway/mcp/execution-tools.ts +35 -1852
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
- package/src/runtime/gateway/mcp/process-tools.ts +83 -37
- package/src/runtime/gateway/mcp/router.ts +186 -84
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +565 -0
- package/src/runtime/gateway/mcp/runtime-tools.ts +2378 -1947
- package/src/runtime/plugins/app-store-connect-adapter.ts +216 -47
- package/src/runtime/plugins/browser-adapter.ts +2662 -829
- package/src/runtime/plugins/browser-automation-service.ts +10 -0
- package/src/runtime/plugins/browser-handoff-host.ts +2 -25
- package/src/runtime/plugins/browser-handoff.ts +110 -5
- package/src/runtime/plugins/browser-macos-bridge.ts +701 -63
- package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
- package/src/runtime/plugins/browser-native-session-service.ts +222 -0
- package/src/runtime/plugins/browser-node-bridge.ts +6 -34
- package/src/runtime/plugins/browser-provider-registry.ts +109 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +154 -0
- package/src/runtime/plugins/browser-runtime.ts +193 -0
- package/src/runtime/plugins/browser-session-authority.ts +332 -0
- package/src/runtime/plugins/browser-session-store.ts +121 -0
- package/src/runtime/plugins/browser-session-types.ts +98 -0
- package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +10 -4
- package/src/runtime/plugins/external-adapter.ts +358 -3
- package/src/runtime/plugins/external-unix-socket.ts +7 -1
- package/src/runtime/plugins/first-party-registry.ts +2 -0
- package/src/runtime/plugins/github-adapter.ts +125 -0
- package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
- package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
- package/src/runtime/plugins/ios-adapter.ts +106 -16
- package/src/runtime/plugins/ios-agent-device.ts +234 -64
- package/src/runtime/plugins/ios-physical-device.ts +1143 -392
- package/src/runtime/plugins/lightweight-action.ts +153 -0
- package/src/runtime/plugins/local-system-adapter.ts +123 -6
- package/src/runtime/plugins/macos-capability-broker.ts +47 -9
- package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
- package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
- package/src/runtime/plugins/resend-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +330 -33
- package/src/runtime/plugins/types.ts +38 -3
- package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
- package/src/runtime/projections/git-status-sampler.ts +16 -16
- package/src/runtime/projections/materialized-view.ts +28 -10
- package/src/runtime/recovery/maintenance-executor.ts +426 -25
- package/src/runtime/root/mcp-transport.ts +180 -10
- package/src/runtime/root/package-connector-service.ts +230 -10
- package/src/runtime/root/package-runtime-release.ts +143 -17
- package/src/runtime/root/package-runtime-service.ts +461 -22
- package/src/runtime/root/release-manifest.ts +144 -18
- package/src/runtime/root/release-materialize.ts +125 -32
- package/src/runtime/root/release-store.ts +48 -11
- package/src/runtime/root/runtime.ts +23 -5
- package/src/runtime/root/service.ts +100 -29
- package/src/runtime/root/types.ts +12 -0
- package/src/runtime/safe-tooling/ios-development.ts +321 -63
- package/src/runtime/shared/trusted-executable.ts +62 -0
- package/src/runtime/shared/trusted-node-executable.ts +48 -0
- package/src/runtime/standalone-recovery/core.ts +1079 -240
- package/src/runtime/standalone-recovery/entry.ts +100 -24
- package/src/runtime/standalone-recovery/installer.ts +20 -4
- package/src/runtime/standalone-recovery/service-labels.ts +2 -0
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
- package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
- package/src/runtime/workflow/schedules/engine.ts +364 -202
- package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
- package/src/runtime/workflow/schedules/settlement.ts +64 -17
- package/src/runtime/workflow/schedules/store.ts +209 -19
- package/src/runtime/workflow/schedules/types.ts +2 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
- package/src/testing/test-governance.ts +8 -40
- package/assets/reference-configs/heartbeat-triage.md +0 -57
- package/assets/templates/helpers/harness-trace-grade.sh +0 -150
- package/assets/templates/helpers/heartbeat-triage.sh +0 -361
- package/assets/templates/helpers/maintenance-triage.sh +0 -167
- package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
- package/docs/architecture/current/architecture-invariants.md +0 -331
- package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
- package/docs/architecture/current/codegraph-context-provider.md +0 -238
- package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
- package/docs/architecture/current/controller-repository-decoupling.md +0 -148
- package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
- package/docs/architecture/current/entity-model.md +0 -612
- package/docs/architecture/current/external-plugin-governance.md +0 -396
- package/docs/architecture/current/failure-recovery.md +0 -447
- package/docs/architecture/current/governance.md +0 -213
- package/docs/architecture/current/human-interaction-plane.md +0 -87
- package/docs/architecture/current/implementation-status.md +0 -128
- package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
- package/docs/architecture/current/legacy-governance.md +0 -58
- package/docs/architecture/current/local-workspace-target-grants.md +0 -70
- package/docs/architecture/current/migration-roadmap.md +0 -105
- package/docs/architecture/current/multi-repository-execution.md +0 -371
- package/docs/architecture/current/operations-runbook.md +0 -45
- package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
- package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
- package/docs/architecture/current/repository-access-modes.md +0 -102
- package/docs/architecture/current/route-policy.md +0 -15
- package/docs/architecture/current/route-session-concurrency.md +0 -85
- package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
- package/docs/architecture/current/runtime-directory-map.md +0 -49
- package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
- package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
- package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
- package/docs/architecture/current/system-overview.md +0 -169
- package/docs/architecture/current/target-requirements-traceability.md +0 -202
- package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
- package/docs/architecture/current/thin-harness-v1.md +0 -321
- package/docs/architecture/current/verification-and-release-gates.md +0 -391
- package/docs/forge-autonomous-goal-loop.md +0 -9
- package/docs/forge-provider-configuration.md +0 -7
- package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
- package/docs/operations/gmail-assistant-routines.md +0 -186
- package/docs/operations/personal-assistant-operator-guide.md +0 -61
- package/docs/operations/provider-configuration.md +0 -31
- package/scripts/harness-trace-grade.sh +0 -150
- package/scripts/heartbeat-triage.sh +0 -361
- package/scripts/maintenance-triage.sh +0 -167
- package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
- package/src/cli/repositories/goal-registry.ts +0 -239
- package/src/runtime/assistant/action-proposals.ts +0 -279
- package/src/runtime/assistant/intent.ts +0 -395
- package/src/runtime/assistant/model-provider.ts +0 -460
- package/src/runtime/assistant/openapi.ts +0 -223
- package/src/runtime/assistant/policy.ts +0 -89
- package/src/runtime/assistant/readiness.ts +0 -258
- package/src/runtime/assistant/routine-runtime.ts +0 -477
- package/src/runtime/assistant/schedule-binding.ts +0 -171
- package/src/runtime/assistant/standing-grants.ts +0 -375
- package/src/runtime/assistant/store.ts +0 -243
- package/src/runtime/assistant/types.ts +0 -135
- package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
- package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
- package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
- package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
- package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
- package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
- package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
- package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
- package/src/runtime/control-plane/goal-loop/index.ts +0 -13
- package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
- package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
- package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
- package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
- package/src/runtime/control-plane/goal-loop/types.ts +0 -378
- package/src/runtime/control-plane/startup-recovery.ts +0 -198
- package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
- package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
- package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
- package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
- package/src/runtime/workflow/findings/store.ts +0 -204
- package/src/runtime/workflow/findings/types.ts +0 -58
- package/src/runtime/workflow/portfolio/engine.ts +0 -20
- package/src/runtime/workflow/portfolio/store.ts +0 -185
- package/src/runtime/workflow/portfolio/types.ts +0 -29
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
persistControllerAccessMode,
|
|
11
11
|
resolveControllerAccessState,
|
|
12
12
|
} from '../mcp/access-mode';
|
|
13
|
-
import { listControllerChecks
|
|
13
|
+
import { listControllerChecks } from '../controller/check-runner';
|
|
14
14
|
import { createMcpToolContext, type MultiRepositoryMcpToolContext } from '../mcp/multi-repository';
|
|
15
15
|
import { readSchedulerHealthSnapshot } from '../../runtime/control-plane/global-scheduler/scheduler';
|
|
16
16
|
import { observeRuntimeStatus } from '../../runtime/root/status';
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
buildFacadeResult,
|
|
28
28
|
buildSyncOperationDigest,
|
|
29
29
|
classifyUserFacingError,
|
|
30
|
-
classifyVerificationOutcome,
|
|
31
30
|
continueGoalWorkloop,
|
|
32
31
|
delegateToCodexCerebellum,
|
|
33
32
|
dismissHandoffItem,
|
|
@@ -44,7 +43,6 @@ import {
|
|
|
44
43
|
stopGoalWorkloop,
|
|
45
44
|
summarizeHandoffItem,
|
|
46
45
|
summarizeWorkContract,
|
|
47
|
-
verifyGoalWorkloop,
|
|
48
46
|
type ExecutionModeSelectionInput,
|
|
49
47
|
type FacadeResult,
|
|
50
48
|
type HandoffItem,
|
|
@@ -80,7 +78,6 @@ import type {
|
|
|
80
78
|
CommandCenterViewModel,
|
|
81
79
|
ConnectorFreshnessViewModel,
|
|
82
80
|
ConsoleErrorViewModel,
|
|
83
|
-
GoalLoopStatusViewModel,
|
|
84
81
|
HandoffCardViewModel,
|
|
85
82
|
ModePreviewViewModel,
|
|
86
83
|
PlainStatusTone,
|
|
@@ -94,35 +91,8 @@ import type {
|
|
|
94
91
|
VerificationViewModel,
|
|
95
92
|
WorkSummaryViewModel,
|
|
96
93
|
} from './console-view-models';
|
|
97
|
-
import {
|
|
98
|
-
buildAutomationSettingsView,
|
|
99
|
-
executorRoutePreviewWithConfig,
|
|
100
|
-
executorRoutingConfigGet,
|
|
101
|
-
executorRoutingConfigReset,
|
|
102
|
-
executorRoutingConfigUpdate,
|
|
103
|
-
goalLoopPolicyGet,
|
|
104
|
-
goalLoopPolicyUpdate,
|
|
105
|
-
goalStatus as goalLoopStatusSnapshot,
|
|
106
|
-
localToolDisable,
|
|
107
|
-
localToolEnable,
|
|
108
|
-
localToolHealthCheck,
|
|
109
|
-
localToolList,
|
|
110
|
-
localToolConfigGet,
|
|
111
|
-
localToolConfigUpdate,
|
|
112
|
-
providerApiSettingsGet,
|
|
113
|
-
providerApiSettingsUpdate,
|
|
114
|
-
providerConfigGet,
|
|
115
|
-
providerConfigUpdate,
|
|
116
|
-
providerCredentialsStatus,
|
|
117
|
-
providerDisable,
|
|
118
|
-
providerEnable,
|
|
119
|
-
providerHealthCheck,
|
|
120
|
-
providerPriorityUpdate,
|
|
121
|
-
providerResetDefaults,
|
|
122
|
-
type ConfigFacadeContext,
|
|
123
|
-
type GoalLoopContext,
|
|
124
|
-
} from '../../runtime/control-plane/goal-loop';
|
|
125
94
|
import { listActiveOccurrences, listSchedules } from '../../runtime/workflow/schedules/store';
|
|
95
|
+
import { executeWorkVerification } from '../../runtime/control-plane/execution/work-verification-service';
|
|
126
96
|
|
|
127
97
|
export type ConsoleFacadeContext = {
|
|
128
98
|
controllerHome: string;
|
|
@@ -995,7 +965,6 @@ export async function buildCommandCenter(
|
|
|
995
965
|
const handoffs = listHandoffItems({ ...store(ctx), status: 'pending', limit: 20 }).map(mapHandoffCard);
|
|
996
966
|
const plugins = listConsolePlugins(ctx);
|
|
997
967
|
const pluginSummary = buildPluginSummary(plugins);
|
|
998
|
-
const goalLoop = buildGoalLoopStatusView(ctx);
|
|
999
968
|
const access = controllerAccessStateView(ctx);
|
|
1000
969
|
const banner = readiness.connectorFreshness?.severity === 'warning' || readiness.connectorFreshness?.severity === 'error'
|
|
1001
970
|
? readiness.connectorFreshness.summary
|
|
@@ -1014,7 +983,6 @@ export async function buildCommandCenter(
|
|
|
1014
983
|
currentWork: activeWork[0],
|
|
1015
984
|
recentWork: allRecent,
|
|
1016
985
|
handoffs,
|
|
1017
|
-
goalLoop,
|
|
1018
986
|
pluginSummary,
|
|
1019
987
|
plugins,
|
|
1020
988
|
modePreviewDefault: plainMode('direct_control'),
|
|
@@ -1031,192 +999,6 @@ export async function buildCommandCenter(
|
|
|
1031
999
|
};
|
|
1032
1000
|
}
|
|
1033
1001
|
|
|
1034
|
-
function configCtx(ctx: ConsoleFacadeContext): ConfigFacadeContext {
|
|
1035
|
-
return { controllerHome: ctx.controllerHome };
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
export function buildGoalLoopStatusView(ctx: ConsoleFacadeContext): GoalLoopStatusViewModel {
|
|
1039
|
-
const goalCtx: GoalLoopContext = {
|
|
1040
|
-
goalStore: store(ctx),
|
|
1041
|
-
packetStore: store(ctx),
|
|
1042
|
-
repoId: ctx.repository.repoId,
|
|
1043
|
-
configLocation: { controllerHome: ctx.controllerHome },
|
|
1044
|
-
providerEnv: { configLocation: { controllerHome: ctx.controllerHome } },
|
|
1045
|
-
};
|
|
1046
|
-
const snapshot = goalLoopStatusSnapshot(goalCtx) as {
|
|
1047
|
-
activeGoals?: Array<Record<string, unknown>>;
|
|
1048
|
-
activeCount?: number;
|
|
1049
|
-
invokableProviders?: string[];
|
|
1050
|
-
handoffOnlyProviders?: string[];
|
|
1051
|
-
providers?: Array<Record<string, unknown>>;
|
|
1052
|
-
};
|
|
1053
|
-
let automationSummary: string | undefined;
|
|
1054
|
-
let liveEffective: boolean | undefined;
|
|
1055
|
-
try {
|
|
1056
|
-
const settings = buildAutomationSettingsView(configCtx(ctx));
|
|
1057
|
-
automationSummary = settings.overview.plainLanguageSummary;
|
|
1058
|
-
liveEffective = settings.overview.liveModelProvidersEffective;
|
|
1059
|
-
} catch {
|
|
1060
|
-
automationSummary = undefined;
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
const goals = (snapshot.activeGoals ?? []).map((goal) => {
|
|
1064
|
-
const stage = String(goal.stage ?? '');
|
|
1065
|
-
const providerSelected = typeof goal.providerSelected === 'string' ? goal.providerSelected : undefined;
|
|
1066
|
-
const waitingReason = typeof goal.waitingReason === 'string' ? goal.waitingReason : undefined;
|
|
1067
|
-
const nextSafeAction = typeof goal.nextSafeAction === 'string' ? goal.nextSafeAction : undefined;
|
|
1068
|
-
const handoffPacketAvailable = goal.handoffPacketAvailable === true;
|
|
1069
|
-
return {
|
|
1070
|
-
title: String(goal.title ?? ''),
|
|
1071
|
-
stage,
|
|
1072
|
-
currentStep: String(goal.currentStep ?? ''),
|
|
1073
|
-
providerSelected,
|
|
1074
|
-
waitingReason,
|
|
1075
|
-
nextSafeAction,
|
|
1076
|
-
handoffPacketAvailable,
|
|
1077
|
-
approvalRequired: Boolean(waitingReason) || stage === 'waiting_for_user',
|
|
1078
|
-
whyThisProvider: providerSelected
|
|
1079
|
-
? `Last selected provider: ${providerSelected}`
|
|
1080
|
-
: 'No provider selected yet',
|
|
1081
|
-
whatHappensNext: nextSafeAction
|
|
1082
|
-
?? (handoffPacketAvailable
|
|
1083
|
-
? 'Open handoff packet or configure a direct provider'
|
|
1084
|
-
: 'Wait for next daemon tick or open Automation Settings'),
|
|
1085
|
-
whatIsBlocked: waitingReason
|
|
1086
|
-
?? (stage === 'handoff_ready'
|
|
1087
|
-
? 'Waiting for handoff supervisor (ChatGPT is not auto-invokable)'
|
|
1088
|
-
: undefined),
|
|
1089
|
-
};
|
|
1090
|
-
});
|
|
1091
|
-
return {
|
|
1092
|
-
activeCount: snapshot.activeCount ?? goals.length,
|
|
1093
|
-
goals,
|
|
1094
|
-
invokableProviders: snapshot.invokableProviders ?? [],
|
|
1095
|
-
handoffOnlyProviders: snapshot.handoffOnlyProviders ?? [],
|
|
1096
|
-
providerHealth: (snapshot.providers ?? []).map((provider) => ({
|
|
1097
|
-
providerId: String(provider.providerId ?? ''),
|
|
1098
|
-
status: String(provider.status ?? ''),
|
|
1099
|
-
directDispatchAllowed: provider.directDispatchAllowed === true,
|
|
1100
|
-
handoffOnly: provider.handoffOnly === true,
|
|
1101
|
-
summary: String(provider.summary ?? ''),
|
|
1102
|
-
})),
|
|
1103
|
-
automationSummary,
|
|
1104
|
-
liveModelProvidersEffective: liveEffective,
|
|
1105
|
-
settingsPathHint: 'Model & Tool Providers',
|
|
1106
|
-
nextTickHint: 'Daemon ticks active goals about every 5 seconds when the controller is running.',
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
export function getAutomationSettings(ctx: ConsoleFacadeContext) {
|
|
1111
|
-
return buildAutomationSettingsView(configCtx(ctx));
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
export function consoleProviderConfigGet(ctx: ConsoleFacadeContext) {
|
|
1115
|
-
return providerConfigGet(configCtx(ctx));
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
export function consoleProviderConfigUpdate(ctx: ConsoleFacadeContext, body: Record<string, unknown>) {
|
|
1119
|
-
return providerConfigUpdate(configCtx(ctx), body as unknown as Parameters<typeof providerConfigUpdate>[1]);
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
export function consoleProviderEnable(ctx: ConsoleFacadeContext, providerId: string) {
|
|
1123
|
-
return providerEnable(configCtx(ctx), providerId);
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
export function consoleProviderDisable(ctx: ConsoleFacadeContext, providerId: string) {
|
|
1127
|
-
return providerDisable(configCtx(ctx), providerId);
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
export function consoleProviderPriority(ctx: ConsoleFacadeContext, providerId: string, direction: 'up' | 'down' | number) {
|
|
1131
|
-
return providerPriorityUpdate(configCtx(ctx), providerId, direction);
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
export function consoleProviderHealth(ctx: ConsoleFacadeContext, providerId?: string) {
|
|
1135
|
-
return providerHealthCheck(configCtx(ctx), providerId);
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
export function consoleProviderCredentials(ctx: ConsoleFacadeContext) {
|
|
1139
|
-
return providerCredentialsStatus(configCtx(ctx));
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
export function consoleProviderReset(ctx: ConsoleFacadeContext) {
|
|
1143
|
-
return providerResetDefaults(configCtx(ctx));
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
export function consoleProviderApiSettingsGet(ctx: ConsoleFacadeContext, providerId: string) {
|
|
1147
|
-
return providerApiSettingsGet(configCtx(ctx), providerId);
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
export function consoleProviderApiSettingsUpdate(
|
|
1151
|
-
ctx: ConsoleFacadeContext,
|
|
1152
|
-
providerId: string,
|
|
1153
|
-
body: Record<string, unknown>,
|
|
1154
|
-
) {
|
|
1155
|
-
return providerApiSettingsUpdate(configCtx(ctx), providerId, {
|
|
1156
|
-
baseUrl: typeof body.baseUrl === 'string' ? body.baseUrl : typeof body.base_url === 'string' ? body.base_url : undefined,
|
|
1157
|
-
model: typeof body.model === 'string' ? body.model : undefined,
|
|
1158
|
-
apiKey: typeof body.apiKey === 'string'
|
|
1159
|
-
? body.apiKey
|
|
1160
|
-
: typeof body.api_key === 'string'
|
|
1161
|
-
? body.api_key
|
|
1162
|
-
: undefined,
|
|
1163
|
-
clearApiKey: body.clearApiKey === true || body.clear_api_key === true,
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
export function consoleLocalToolList(ctx: ConsoleFacadeContext) {
|
|
1168
|
-
return localToolList(configCtx(ctx));
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
export function consoleLocalToolEnable(ctx: ConsoleFacadeContext, toolId: string) {
|
|
1172
|
-
return localToolEnable(configCtx(ctx), toolId);
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
export function consoleLocalToolDisable(ctx: ConsoleFacadeContext, toolId: string) {
|
|
1176
|
-
return localToolDisable(configCtx(ctx), toolId);
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
export function consoleLocalToolHealth(ctx: ConsoleFacadeContext, toolId?: string) {
|
|
1180
|
-
return localToolHealthCheck(configCtx(ctx), toolId);
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
export function consoleLocalToolConfigGet(ctx: ConsoleFacadeContext) {
|
|
1184
|
-
return localToolConfigGet(configCtx(ctx));
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
export function consoleLocalToolConfigUpdate(ctx: ConsoleFacadeContext, body: Record<string, unknown>) {
|
|
1188
|
-
return localToolConfigUpdate(configCtx(ctx), body as unknown as Parameters<typeof localToolConfigUpdate>[1]);
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
export function consoleRoutingGet(ctx: ConsoleFacadeContext) {
|
|
1192
|
-
return executorRoutingConfigGet(configCtx(ctx));
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
export function consoleRoutingUpdate(ctx: ConsoleFacadeContext, body: Record<string, unknown>) {
|
|
1196
|
-
return executorRoutingConfigUpdate(configCtx(ctx), body as unknown as Parameters<typeof executorRoutingConfigUpdate>[1]);
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
export function consoleRoutingReset(ctx: ConsoleFacadeContext) {
|
|
1200
|
-
return executorRoutingConfigReset(configCtx(ctx));
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
export function consoleRoutePreview(ctx: ConsoleFacadeContext, body: Record<string, unknown> = {}) {
|
|
1204
|
-
return executorRoutePreviewWithConfig(configCtx(ctx), {
|
|
1205
|
-
taskIntent: typeof body.taskIntent === 'string' ? body.taskIntent as never : typeof body.task_intent === 'string' ? body.task_intent as never : undefined,
|
|
1206
|
-
risk: typeof body.risk === 'string' ? body.risk as never : undefined,
|
|
1207
|
-
objective: typeof body.objective === 'string' ? body.objective : undefined,
|
|
1208
|
-
externalWrite: body.externalWrite === true || body.external_write === true,
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
export function consoleGoalLoopPolicyGet(ctx: ConsoleFacadeContext) {
|
|
1213
|
-
return goalLoopPolicyGet(configCtx(ctx));
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
export function consoleGoalLoopPolicyUpdate(ctx: ConsoleFacadeContext, body: Record<string, unknown>) {
|
|
1217
|
-
return goalLoopPolicyUpdate(configCtx(ctx), body as unknown as Parameters<typeof goalLoopPolicyUpdate>[1]);
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
1002
|
export function getConsoleAccessPolicy(ctx: ConsoleFacadeContext) {
|
|
1221
1003
|
const policy = readRepositoryAccessPolicy(ctx.controllerHome, ctx.repository.repoId);
|
|
1222
1004
|
return {
|
|
@@ -1259,6 +1041,9 @@ export function startConsoleWork(
|
|
|
1259
1041
|
requiresApproval?: boolean;
|
|
1260
1042
|
destructive?: boolean;
|
|
1261
1043
|
accessMode?: AccessMode;
|
|
1044
|
+
workspaceMode?: 'current' | 'isolated' | 'auto';
|
|
1045
|
+
requireWorktree?: boolean;
|
|
1046
|
+
directMainProhibited?: boolean;
|
|
1262
1047
|
approvalConfirmed?: boolean;
|
|
1263
1048
|
forceMode?: 'direct_control' | 'goal_workloop' | 'handoff_only';
|
|
1264
1049
|
checkIds?: string[];
|
|
@@ -1278,7 +1063,17 @@ export function startConsoleWork(
|
|
|
1278
1063
|
allowedPaths: input.allowedPaths,
|
|
1279
1064
|
forbiddenPaths: input.forbiddenPaths,
|
|
1280
1065
|
checks: input.checkIds,
|
|
1281
|
-
constraints: input.accessMode
|
|
1066
|
+
constraints: input.accessMode !== undefined
|
|
1067
|
+
|| input.workspaceMode !== undefined
|
|
1068
|
+
|| input.requireWorktree !== undefined
|
|
1069
|
+
|| input.directMainProhibited !== undefined
|
|
1070
|
+
? {
|
|
1071
|
+
...(input.accessMode !== undefined ? { accessMode: input.accessMode } : {}),
|
|
1072
|
+
...(input.workspaceMode !== undefined ? { workspaceMode: input.workspaceMode } : {}),
|
|
1073
|
+
...(input.requireWorktree !== undefined ? { requireWorktree: input.requireWorktree } : {}),
|
|
1074
|
+
...(input.directMainProhibited !== undefined ? { directMainProhibited: input.directMainProhibited } : {}),
|
|
1075
|
+
}
|
|
1076
|
+
: undefined,
|
|
1282
1077
|
modeInput: {
|
|
1283
1078
|
objective: input.objective,
|
|
1284
1079
|
expectedFiles: input.expectedFiles,
|
|
@@ -1309,51 +1104,24 @@ export function continueConsoleWork(ctx: ConsoleFacadeContext, workId: string, n
|
|
|
1309
1104
|
);
|
|
1310
1105
|
}
|
|
1311
1106
|
|
|
1312
|
-
export function verifyConsoleWork(
|
|
1107
|
+
export async function verifyConsoleWork(
|
|
1313
1108
|
ctx: ConsoleFacadeContext,
|
|
1314
1109
|
input: { workId: string; checkId?: string; simulate?: boolean; checkFailed?: boolean; infrastructureFailed?: boolean },
|
|
1315
|
-
): FacadeResult {
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
return verifyGoalWorkloop(workloopCtx, {
|
|
1331
|
-
workId: input.workId,
|
|
1332
|
-
checkId: classified.normalizedCheckId ?? requested,
|
|
1333
|
-
checkFailed: input.checkFailed === true,
|
|
1334
|
-
infrastructureFailed: input.infrastructureFailed === true,
|
|
1335
|
-
});
|
|
1336
|
-
}
|
|
1337
|
-
try {
|
|
1338
|
-
const executed = runControllerCheck(ctx.repository.canonicalRoot, classified.normalizedCheckId!);
|
|
1339
|
-
return verifyGoalWorkloop(workloopCtx, {
|
|
1340
|
-
workId: input.workId,
|
|
1341
|
-
checkId: classified.normalizedCheckId!,
|
|
1342
|
-
infrastructureFailed: executed.timedOut === true,
|
|
1343
|
-
checkFailed: !executed.ok && !executed.timedOut,
|
|
1344
|
-
});
|
|
1345
|
-
} catch (error) {
|
|
1346
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1347
|
-
const facade = verifyGoalWorkloop(workloopCtx, {
|
|
1348
|
-
workId: input.workId,
|
|
1349
|
-
checkId: classified.normalizedCheckId ?? requested,
|
|
1350
|
-
infrastructureFailed: true,
|
|
1351
|
-
});
|
|
1352
|
-
return {
|
|
1353
|
-
...facade,
|
|
1354
|
-
warnings: [...facade.warnings, `环境执行检查失败:${message.slice(0, 160)}`],
|
|
1355
|
-
};
|
|
1356
|
-
}
|
|
1110
|
+
): Promise<FacadeResult> {
|
|
1111
|
+
const verification = await executeWorkVerification({
|
|
1112
|
+
controllerHome: ctx.controllerHome,
|
|
1113
|
+
repository: ctx.repository,
|
|
1114
|
+
workId: input.workId,
|
|
1115
|
+
checkId: input.checkId,
|
|
1116
|
+
interactiveWaitMs: 0,
|
|
1117
|
+
simulate: input.simulate
|
|
1118
|
+
? {
|
|
1119
|
+
checkFailed: input.checkFailed === true,
|
|
1120
|
+
infrastructureFailed: input.infrastructureFailed === true,
|
|
1121
|
+
}
|
|
1122
|
+
: undefined,
|
|
1123
|
+
});
|
|
1124
|
+
return verification.facade;
|
|
1357
1125
|
}
|
|
1358
1126
|
|
|
1359
1127
|
export function finalizeConsoleWork(ctx: ConsoleFacadeContext, workId: string): FacadeResult {
|
|
@@ -1493,6 +1261,11 @@ export function approveConsoleHandoff(ctx: ConsoleFacadeContext, handoffId: stri
|
|
|
1493
1261
|
requiresApproval: payload.requiresApproval === true,
|
|
1494
1262
|
destructive: payload.destructive === true,
|
|
1495
1263
|
accessMode: isAccessMode(payload.accessMode) ? payload.accessMode : undefined,
|
|
1264
|
+
workspaceMode: payload.workspaceMode === 'current' || payload.workspaceMode === 'isolated' || payload.workspaceMode === 'auto'
|
|
1265
|
+
? payload.workspaceMode
|
|
1266
|
+
: undefined,
|
|
1267
|
+
requireWorktree: typeof payload.requireWorktree === 'boolean' ? payload.requireWorktree : undefined,
|
|
1268
|
+
directMainProhibited: typeof payload.directMainProhibited === 'boolean' ? payload.directMainProhibited : undefined,
|
|
1496
1269
|
approvalConfirmed: true,
|
|
1497
1270
|
forceMode: 'goal_workloop',
|
|
1498
1271
|
checkIds: strings(payload.checkIds),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import{useCallback,useEffect,useState}from'react';import'./design/tokens.css';import'./styles.css';import type{AutomationView,ConsoleData,
|
|
2
|
-
async function loadData():Promise<ConsoleData>{const[commandCenter,work,workPortfolio,automations,
|
|
1
|
+
import{useCallback,useEffect,useState}from'react';import'./design/tokens.css';import'./styles.css';import type{AutomationView,ConsoleData,RouteId}from'./types';import{api}from'./lib/api';import{routeFromHash}from'./lib/routes';import{AppShell}from'./shell/AppShell';import{OverviewView}from'./features/overview/OverviewView';import{AutomationsView}from'./features/automations/AutomationsView';import{WorkView}from'./features/work/WorkView';import{CapabilitiesView}from'./features/capabilities/CapabilitiesView';import{RepositoriesView}from'./features/repositories/RepositoriesView';import{SystemView}from'./features/system/SystemView';
|
|
2
|
+
async function loadData():Promise<ConsoleData>{const[commandCenter,work,workPortfolio,automations,connector]=await Promise.all([api.commandCenter(),api.work(),api.workPortfolio(),api.automations(),api.connector().catch(()=>undefined)]);return{commandCenter,work,workPortfolio,automations,connector,generatedAt:new Date().toISOString()}}
|
|
3
3
|
export default function App(){const[route,setRoute]=useState<RouteId>(routeFromHash());const[data,setData]=useState<ConsoleData>();const[busy,setBusy]=useState(false);const[error,setError]=useState('');
|
|
4
4
|
const refresh=useCallback(async()=>{setBusy(true);setError('');try{setData(await loadData())}catch(e){setError(e instanceof Error?e.message:String(e))}finally{setBusy(false)}},[]);
|
|
5
5
|
useEffect(()=>{void refresh();const onHash=()=>setRoute(routeFromHash());addEventListener('hashchange',onHash);return()=>removeEventListener('hashchange',onHash)},[refresh]);
|
|
6
6
|
const mutate=useCallback(async(fn:()=>Promise<unknown>)=>{setBusy(true);try{await fn();setData(await loadData())}catch(e){setError(e instanceof Error?e.message:String(e))}finally{setBusy(false)}},[]);
|
|
7
7
|
if(!data)return <div className="boot-state"><span className="brand-mark">F</span><strong>{error?'Forge console unavailable':'Loading Forge…'}</strong>{error&&<><p>{error}</p><button className="button" onClick={()=>void refresh()}>Retry</button></>}</div>;
|
|
8
8
|
const common={data,busy,onRefresh:()=>void refresh()};let view;
|
|
9
|
-
switch(route){case'automations':view=<AutomationsView {...common} onAction={(a:AutomationView,action:'run'|'pause'|'resume')=>mutate(()=>api.automationAction(a.source,a.repoId,a.id,action))}/>;break;case'work':view=<WorkView {...common}/>;break;case'capabilities':view=<CapabilitiesView {...common}/>;break;case'repositories':view=<RepositoriesView {...common} onRegister={(p,n)=>mutate(()=>api.registerRepository(p,n))} onRemove={id=>mutate(()=>api.removeRepository(id))}/>;break;case'
|
|
9
|
+
switch(route){case'automations':view=<AutomationsView {...common} onAction={(a:AutomationView,action:'run'|'pause'|'resume')=>mutate(()=>api.automationAction(a.source,a.repoId,a.id,action))}/>;break;case'work':view=<WorkView {...common}/>;break;case'capabilities':view=<CapabilitiesView {...common}/>;break;case'repositories':view=<RepositoriesView {...common} onRegister={(p,n)=>mutate(()=>api.registerRepository(p,n))} onRemove={id=>mutate(()=>api.removeRepository(id))}/>;break;case'system':view=<SystemView {...common}/>;break;default:view=<OverviewView {...common}/>}
|
|
10
10
|
return <AppShell route={route}>{error&&<div className="global-error"><strong>Last action failed</strong><span>{error}</span><button onClick={()=>setError('')}>×</button></div>}{view}</AppShell>}
|
|
@@ -7,12 +7,13 @@ import { StatusText } from '../../components/StatusText';
|
|
|
7
7
|
import { Button } from '../../components/Button';
|
|
8
8
|
import { formatDate, compact } from '../../lib/format';
|
|
9
9
|
|
|
10
|
-
type Filter = 'enabled' | 'paused' | 'attention' | 'all';
|
|
10
|
+
type Filter = 'enabled' | 'paused' | 'attention' | 'completed' | 'all';
|
|
11
11
|
|
|
12
12
|
function statusLabel(status: AutomationView['status']): string {
|
|
13
13
|
if (status === 'enabled') return '运行中';
|
|
14
14
|
if (status === 'paused') return '已暂停';
|
|
15
15
|
if (status === 'attention') return '需要处理';
|
|
16
|
+
if (status === 'completed') return '已完成';
|
|
16
17
|
return '已停用';
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -20,6 +21,7 @@ function statusTone(status: AutomationView['status']): string {
|
|
|
20
21
|
if (status === 'enabled') return 'success';
|
|
21
22
|
if (status === 'attention') return 'danger';
|
|
22
23
|
if (status === 'paused') return 'warning';
|
|
24
|
+
if (status === 'completed') return 'success';
|
|
23
25
|
return 'neutral';
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -50,10 +52,16 @@ function executionDetails(automation: AutomationView): Array<[string, string]> {
|
|
|
50
52
|
if (!automation.agentModel) return [];
|
|
51
53
|
return [
|
|
52
54
|
['执行模型', `${automation.agentModel} · ${reasoningLabel(automation.reasoningLevel)}推理`],
|
|
53
|
-
['
|
|
55
|
+
['标签页策略', tabPolicyLabel(automation.tabPolicy)],
|
|
54
56
|
];
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
function nextRunLabel(value?: string, completed = false): string {
|
|
60
|
+
if (completed) return '不会再次触发';
|
|
61
|
+
if (!value) return '等待下一次计划';
|
|
62
|
+
return Number.isFinite(Date.parse(value)) ? formatDate(value) : value;
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
function historyTone(tone: AutomationHistoryView['tone']): string {
|
|
58
66
|
if (tone === 'green') return 'success';
|
|
59
67
|
if (tone === 'amber') return 'warning';
|
|
@@ -90,24 +98,25 @@ export function AutomationsView({ data, busy, onRefresh, onAction }: {
|
|
|
90
98
|
const observation = selected ? observationLabel(selected.observationStatus) : undefined;
|
|
91
99
|
|
|
92
100
|
return <>
|
|
93
|
-
<CommandBar eyebrow="AUTOMATION" title="
|
|
101
|
+
<CommandBar eyebrow="AUTOMATION" title="自动任务" description="查看哪些任务正在运行、何时再次执行、是否需要处理,以及最近实际发生了什么。" refreshedAt={data.automations.generatedAt} busy={busy} onRefresh={onRefresh} />
|
|
94
102
|
<div className="toolbar automation-toolbar">
|
|
95
103
|
<Segmented value={filter} onChange={setFilter} items={[
|
|
96
104
|
{ id: 'enabled', label: '运行中', count: all.filter((item) => item.status === 'enabled').length },
|
|
97
105
|
{ id: 'paused', label: '已暂停', count: all.filter((item) => item.status === 'paused' || item.status === 'disabled').length },
|
|
98
106
|
{ id: 'attention', label: '需要处理', count: all.filter((item) => item.status === 'attention').length },
|
|
107
|
+
{ id: 'completed', label: '已完成', count: all.filter((item) => item.status === 'completed').length },
|
|
99
108
|
{ id: 'all', label: '全部', count: all.length },
|
|
100
109
|
]} />
|
|
101
110
|
</div>
|
|
102
111
|
<div className="split-workspace automation-layout">
|
|
103
112
|
<div className="table-wrap">
|
|
104
113
|
<table className="data-table automation-table">
|
|
105
|
-
<thead><tr><th
|
|
114
|
+
<thead><tr><th>自动任务</th><th>触发</th><th>行为</th><th>状态</th><th>最近结果</th></tr></thead>
|
|
106
115
|
<tbody>{list.map((automation) => <tr key={key(automation)} className={selected && key(selected) === key(automation) ? 'selected' : ''} onClick={() => setSelectedKey(key(automation))}>
|
|
107
116
|
<td><strong>{automation.name}</strong><small>{automation.repositoryName} · {automation.modeLabel}</small></td>
|
|
108
117
|
<td><span>{automation.schedule}</span><small>{automation.timezone ?? '本地时区'}</small></td>
|
|
109
118
|
<td><span>{automation.delivery ?? '本地执行'}</span>{automation.targetLabel && <small>{automation.targetLabel}</small>}</td>
|
|
110
|
-
<td><StatusText label={statusLabel(automation.status)} tone={statusTone(automation.status)} />{automation.live !== undefined && <small>{automation.live ? '
|
|
119
|
+
<td><StatusText label={statusLabel(automation.status)} tone={statusTone(automation.status)} />{automation.live !== undefined && <small>{automation.live ? '实际执行' : '仅预演'}</small>}</td>
|
|
111
120
|
<td><span>{compact(automation.lastResult, 26) || '—'}</span><small>{formatDate(automation.lastRunAt)}</small></td>
|
|
112
121
|
</tr>)}</tbody>
|
|
113
122
|
</table>
|
|
@@ -116,25 +125,26 @@ export function AutomationsView({ data, busy, onRefresh, onAction }: {
|
|
|
116
125
|
<DetailPane title={selected?.name} subtitle={selected?.summary} empty="选择一个 Automation 查看配置与执行历史">
|
|
117
126
|
{selected && <>
|
|
118
127
|
<div className="automation-detail-status">
|
|
119
|
-
<div><span className="eyebrow"
|
|
128
|
+
<div><span className="eyebrow">当前状态</span><StatusText label={statusLabel(selected.status)} tone={statusTone(selected.status)} /></div>
|
|
120
129
|
<div className="automation-result"><strong>{selected.lastResult ?? '尚未执行'}</strong><small>{formatDate(selected.observationAt ?? selected.lastRunAt)}</small></div>
|
|
121
130
|
</div>
|
|
122
131
|
<DefinitionList items={[
|
|
123
132
|
['类型', selected.modeLabel],
|
|
124
133
|
['触发计划', `${selected.schedule}${selected.timezone ? ` · ${selected.timezone}` : ''}`],
|
|
125
134
|
['触发后的行为', selected.delivery ?? '本地执行'],
|
|
135
|
+
['下次执行', nextRunLabel(selected.nextRunHint, selected.status === 'completed')],
|
|
126
136
|
['观察目标', selected.targetLabel ?? '—'],
|
|
127
137
|
['观察状态', observation ?? '—'],
|
|
128
|
-
['
|
|
129
|
-
['
|
|
138
|
+
['关联工作', selected.boundWorkObjective ? compact(selected.boundWorkObjective, 96) : selected.boundWorkId ?? '—'],
|
|
139
|
+
['执行方式', selected.live === undefined ? '—' : selected.live ? '实际执行' : '仅预演'],
|
|
130
140
|
...executionDetails(selected),
|
|
131
|
-
['运行策略', selected.policySummary ?? '—'],
|
|
132
141
|
]} />
|
|
133
|
-
{selected.
|
|
134
|
-
|
|
135
|
-
<div className="
|
|
142
|
+
{selected.attentionMessage && <div className="detail-callout danger"><strong>需要处理</strong><p>{selected.attentionMessage}</p></div>}
|
|
143
|
+
{!selected.attentionMessage && selected.pausedReason && <div className={`detail-callout ${selected.status === 'completed' ? 'success' : 'warning'}`}><strong>{selected.status === 'completed' ? '任务已完成' : '暂停原因'}</strong><p>{selected.pausedReason}</p></div>}
|
|
144
|
+
<div className="detail-button-row">{selected.actions.map((action) => <Button key={action} disabled={busy} className={action === 'pause' ? 'danger-text' : ''} onClick={() => void onAction(selected, action)}>{action === 'run' ? '立即运行' : action === 'pause' ? '暂停任务' : '恢复任务'}</Button>)}</div>
|
|
145
|
+
<div className="automation-section-head"><div><span className="eyebrow">执行记录</span><h3>最近执行</h3></div><span>{selected.history.length} 条</span></div>
|
|
136
146
|
<History items={selected.history} />
|
|
137
|
-
<details className="advanced automation-advanced"><summary>技术信息</summary><pre>{JSON.stringify({ scheduleId: selected.source === 'schedule' ? selected.id : undefined, workId: selected.boundWorkId, source: selected.source, next: selected.nextRunHint, failureCount: selected.failureCount }, null, 2)}</pre></details>
|
|
147
|
+
<details className="advanced automation-advanced"><summary>技术信息</summary><pre>{JSON.stringify({ scheduleId: selected.source === 'schedule' ? selected.id : undefined, workId: selected.boundWorkId, source: selected.source, next: selected.nextRunHint, failureCount: selected.failureCount, policy: selected.policySummary }, null, 2)}</pre></details>
|
|
138
148
|
<p className="detail-note">这里只展示配置、状态与执行摘要;邮件正文、浏览器 Cookie、登录凭据和 continuation prompt 不会复制到控制台。</p>
|
|
139
149
|
</>}
|
|
140
150
|
</DetailPane>
|
|
@@ -1,4 +1,37 @@
|
|
|
1
|
-
import{useMemo,useState}from'react';
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import{useMemo,useState}from'react';
|
|
2
|
+
import type{ConsoleData,PluginView}from'../../types';
|
|
3
|
+
import{CommandBar}from'../../shell/CommandBar';
|
|
4
|
+
import{Segmented}from'../../components/Segmented';
|
|
5
|
+
import{DetailPane,DefinitionList}from'../../components/DetailPane';
|
|
6
|
+
import{StatusText}from'../../components/StatusText';
|
|
7
|
+
import{compact,pretty}from'../../lib/format';
|
|
8
|
+
|
|
9
|
+
type Filter='all'|'extensions'|'services'|'execution';
|
|
10
|
+
|
|
11
|
+
function category(plugin:PluginView):Exclude<Filter,'all'>{
|
|
12
|
+
const text=`${plugin.name} ${plugin.provider} ${(plugin.capabilityLabels??[]).join(' ')}`.toLowerCase();
|
|
13
|
+
if(/gmail|calendar|github|google task|notion/.test(text))return'services';
|
|
14
|
+
if(/browser|desktop|ios|repository|codegraph|local/.test(text))return'execution';
|
|
15
|
+
return'extensions';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function CapabilitiesView({data,busy,onRefresh}:{data:ConsoleData;busy:boolean;onRefresh:()=>void}){
|
|
19
|
+
const plugins=data.commandCenter.plugins??[];
|
|
20
|
+
const[filter,setFilter]=useState<Filter>('all');
|
|
21
|
+
const[selectedId,setSelectedId]=useState<string>();
|
|
22
|
+
const filtered=useMemo(()=>plugins.filter(plugin=>filter==='all'||category(plugin)===filter),[plugins,filter]);
|
|
23
|
+
const selected=filtered.find(plugin=>plugin.id===selectedId)??filtered[0];
|
|
24
|
+
return <>
|
|
25
|
+
<CommandBar eyebrow="CAPABILITY CATALOG" title="Capabilities" description="从“Forge 能做什么”查看扩展、服务与执行能力,而不是浏览 MCP tool 清单。" refreshedAt={data.generatedAt} busy={busy} onRefresh={onRefresh}/>
|
|
26
|
+
<div className="toolbar"><Segmented value={filter} onChange={setFilter} items={[
|
|
27
|
+
{id:'all',label:'All',count:plugins.length},
|
|
28
|
+
{id:'extensions',label:'Extensions',count:plugins.filter(plugin=>category(plugin)==='extensions').length},
|
|
29
|
+
{id:'services',label:'Services',count:plugins.filter(plugin=>category(plugin)==='services').length},
|
|
30
|
+
{id:'execution',label:'Execution',count:plugins.filter(plugin=>category(plugin)==='execution').length},
|
|
31
|
+
]}/></div>
|
|
32
|
+
<div className="split-workspace">
|
|
33
|
+
<div className="scan-list">{filtered.map(plugin=><button key={plugin.id} className={`scan-row ${selected?.id===plugin.id?'selected':''}`} onClick={()=>setSelectedId(plugin.id)}><div className="scan-main"><span className="row-eyebrow">{category(plugin).toUpperCase()}</span><strong>{plugin.name}</strong><p>{compact(plugin.description,100)}</p></div><StatusText label={plugin.statusLabel??plugin.status??'Unknown'} tone={plugin.status??plugin.tone}/></button>)}</div>
|
|
34
|
+
<DetailPane title={selected?.name} subtitle={selected?.description}>{selected&&<><DefinitionList items={[["Status",<StatusText label={selected.statusLabel??selected.status??'Unknown'} tone={selected.status??selected.tone}/>],["Provider",selected.provider??'—'],["Health",selected.healthLabel??'—'],["Lifecycle",selected.lifecycleLabel??'—']]}/>{selected.nextStep&&<div className="detail-callout warning"><strong>Next step</strong><p>{selected.nextStep}</p></div>}{(selected.capabilityLabels??[]).length>0&&<div className="capability-lines">{selected.capabilityLabels!.map(label=><span key={label}>{label}</span>)}</div>}{(selected.warnings??[]).map(warning=><div className="detail-callout warning" key={warning}>{warning}</div>)}<details className="advanced"><summary>Advanced · actions & protocol</summary><pre>{pretty({actions:selected.actions,advanced:selected.advanced})}</pre></details></>}</DetailPane>
|
|
35
|
+
</div>
|
|
36
|
+
</>;
|
|
37
|
+
}
|
|
@@ -88,7 +88,7 @@ export function OverviewView({ data, busy, onRefresh }: { data: ConsoleData; bus
|
|
|
88
88
|
key: 'automations',
|
|
89
89
|
source: 'Automations',
|
|
90
90
|
title: `${automations.needsAttention} automation${automations.needsAttention === 1 ? '' : 's'} need attention`,
|
|
91
|
-
summary: 'Inspect configured
|
|
91
|
+
summary: 'Inspect configured schedules.',
|
|
92
92
|
statusLabel: 'Inspect',
|
|
93
93
|
tone: 'warning',
|
|
94
94
|
href: '#/automations',
|
|
@@ -117,10 +117,12 @@ export function OverviewView({ data, busy, onRefresh }: { data: ConsoleData; bus
|
|
|
117
117
|
? `${portfolio.summary.open} open · ${portfolio.summary.needsAttention} need attention`
|
|
118
118
|
: `${portfolio.summary.open} open · no attention needed`;
|
|
119
119
|
const automationSummary = automations.needsAttention
|
|
120
|
-
? `${automations.enabled}
|
|
120
|
+
? `${automations.enabled} 个运行中 · ${automations.needsAttention} 个需要处理`
|
|
121
121
|
: automations.paused
|
|
122
|
-
? `${automations.enabled}
|
|
123
|
-
:
|
|
122
|
+
? `${automations.enabled} 个运行中 · ${automations.paused} 个已暂停`
|
|
123
|
+
: (automations.completed ?? 0) > 0
|
|
124
|
+
? `${automations.enabled} 个运行中 · ${automations.completed} 个已完成`
|
|
125
|
+
: `${automations.enabled} 个运行中 · 状态正常`;
|
|
124
126
|
const capabilitySummary = (plugins.needsAttention ?? 0) > 0
|
|
125
127
|
? `${plugins.ready ?? 0} / ${capabilityTotal} ready · ${plugins.needsAttention} need attention`
|
|
126
128
|
: `${plugins.ready ?? 0} / ${capabilityTotal} ready`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AutomationsResponse, CommandCenterView, Dict, WorkPortfolioResponse, WorkResponse } from '../types';
|
|
2
2
|
export class ApiError extends Error { constructor(message:string, readonly status:number, readonly payload:unknown){super(message);} }
|
|
3
3
|
const CONSOLE_REQUEST_TIMEOUT_MS=15_000;
|
|
4
4
|
export async function requestJson<T>(path:string,init:RequestInit={}):Promise<T>{
|
|
@@ -22,14 +22,9 @@ export const api={
|
|
|
22
22
|
work:()=>requestJson<WorkResponse>('/api/console/requirements'),
|
|
23
23
|
workPortfolio:()=>requestJson<WorkPortfolioResponse>('/api/console/work-portfolio'),
|
|
24
24
|
automations:()=>requestJson<AutomationsResponse>('/api/console/automations'),
|
|
25
|
-
automationSettings:()=>requestJson<AutomationSettingsView>('/api/console/automation-settings'),
|
|
26
25
|
connector:()=>requestJson<Dict>('/api/console/connector/status'),
|
|
27
26
|
advanced:()=>requestJson<Dict>('/api/console/advanced'),
|
|
28
27
|
automationAction:(source:string,repoId:string,id:string,action:string)=>requestJson<Dict>(`/api/console/automations/${encodeURIComponent(source)}/${encodeURIComponent(repoId)}/${encodeURIComponent(id)}/${encodeURIComponent(action)}`,{method:'POST',body:'{}'}),
|
|
29
|
-
providerAction:(id:string,action:'enable'|'disable')=>requestJson<Dict>(`/api/console/providers/${encodeURIComponent(id)}/${action}`,{method:'POST',body:'{}'}),
|
|
30
|
-
providerHealth:(id:string)=>requestJson<Dict>('/api/console/providers/health',{method:'POST',body:JSON.stringify({providerId:id})}),
|
|
31
|
-
localToolAction:(id:string,action:'enable'|'disable')=>requestJson<Dict>(`/api/console/local-tools/${encodeURIComponent(id)}/${action}`,{method:'POST',body:'{}'}),
|
|
32
|
-
localToolHealth:(id:string)=>requestJson<Dict>('/api/console/local-tools/health',{method:'POST',body:JSON.stringify({toolId:id})}),
|
|
33
28
|
registerRepository:(path:string,displayName?:string)=>requestJson<Dict>('/api/repositories/register',{method:'POST',body:JSON.stringify({path,displayName})}),
|
|
34
29
|
removeRepository:(id:string)=>requestJson<Dict>(`/api/repositories/${encodeURIComponent(id)}/remove`,{method:'POST',body:'{}'}),
|
|
35
30
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RouteId } from '../types';
|
|
2
2
|
export const routes:{id:RouteId;label:string;group:'daily'|'manage'|'system'}[]=[
|
|
3
3
|
{id:'overview',label:'Overview',group:'daily'}, {id:'automations',label:'Automations',group:'daily'}, {id:'work',label:'Work',group:'daily'},
|
|
4
|
-
{id:'capabilities',label:'Capabilities',group:'manage'}, {id:'repositories',label:'Repositories',group:'manage'},
|
|
4
|
+
{id:'capabilities',label:'Capabilities',group:'manage'}, {id:'repositories',label:'Repositories',group:'manage'},
|
|
5
5
|
{id:'system',label:'System',group:'system'},
|
|
6
6
|
];
|
|
7
7
|
export function routeFromHash():RouteId{const id=location.hash.replace(/^#\/?/,'').split('/')[0] as RouteId;return routes.some(r=>r.id===id)?id:'overview';}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type{ComponentType,SVGProps}from'react';import type{RouteId}from'../types';import{routes}from'../lib/routes';import{AutomationIcon,CapabilityIcon,OverviewIcon,RepoIcon,
|
|
2
|
-
const icons:Record<RouteId,ComponentType<SVGProps<SVGSVGElement>>>={overview:OverviewIcon,automations:AutomationIcon,work:WorkIcon,capabilities:CapabilityIcon,repositories:RepoIcon,
|
|
1
|
+
import type{ComponentType,SVGProps}from'react';import type{RouteId}from'../types';import{routes}from'../lib/routes';import{AutomationIcon,CapabilityIcon,OverviewIcon,RepoIcon,SystemIcon,WorkIcon}from'../design/icons';
|
|
2
|
+
const icons:Record<RouteId,ComponentType<SVGProps<SVGSVGElement>>>={overview:OverviewIcon,automations:AutomationIcon,work:WorkIcon,capabilities:CapabilityIcon,repositories:RepoIcon,system:SystemIcon};
|
|
3
3
|
const groupLabels={daily:'Workspace',manage:'Configure',system:'System'} as const;
|
|
4
4
|
export function Sidebar({route}:{route:RouteId}){let last='';return <aside className="sidebar"><div className="brand"><span className="brand-mark">F</span><div><strong>Forge</strong><small>Utility Console</small></div></div><nav>{routes.map(item=>{const Icon=icons[item.id];const first=item.group!==last;last=item.group;return <div key={item.id} className={first?'nav-group-start':'nav-item'}>{first&&<div className="nav-group-label">{groupLabels[item.group]}</div>}<a href={`#/${item.id}`} className={route===item.id?'active':''}><Icon/><span>{item.label}</span></a></div>})}</nav><div className="sidebar-foot"><span className="pulse-dot"/><span><strong>Runtime connected</strong><small>ChatGPT remains the primary workspace</small></span></div></aside>}
|