@gajae-code/coding-agent 0.16.7 → 0.17.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/CHANGELOG.md +180 -1
- package/dist/types/capability/fs.d.ts +37 -4
- package/dist/types/capability/index.d.ts +19 -0
- package/dist/types/capability/types.d.ts +9 -0
- package/dist/types/cli/doctor/args.d.ts +36 -0
- package/dist/types/cli/doctor/checks.d.ts +18 -0
- package/dist/types/cli/doctor/config-repairs.d.ts +38 -0
- package/dist/types/cli/doctor/context.d.ts +89 -0
- package/dist/types/cli/doctor/files.d.ts +27 -0
- package/dist/types/cli/doctor/ids.d.ts +20 -0
- package/dist/types/cli/doctor/install-repairs.d.ts +94 -0
- package/dist/types/cli/doctor/journal.d.ts +43 -0
- package/dist/types/cli/doctor/managed-link.d.ts +39 -0
- package/dist/types/cli/doctor/native-probe.d.ts +2 -0
- package/dist/types/cli/doctor/permission-repairs.d.ts +25 -0
- package/dist/types/cli/doctor/plugin-quarantine.d.ts +77 -0
- package/dist/types/cli/doctor/plugin-restore.d.ts +40 -0
- package/dist/types/cli/doctor/plugin-targets.d.ts +11 -0
- package/dist/types/cli/doctor/probe-client.d.ts +9 -0
- package/dist/types/cli/doctor/probe-types.d.ts +18 -0
- package/dist/types/cli/doctor/probe.d.ts +3 -0
- package/dist/types/cli/doctor/projection-probe.d.ts +2 -0
- package/dist/types/cli/doctor/repairs.d.ts +28 -0
- package/dist/types/cli/doctor/report.d.ts +27 -0
- package/dist/types/cli/doctor/runner.d.ts +4 -0
- package/dist/types/cli/doctor/safety.d.ts +10 -0
- package/dist/types/cli/doctor/service-repairs.d.ts +8 -0
- package/dist/types/cli/doctor/service-targets.d.ts +41 -0
- package/dist/types/cli/doctor/types.d.ts +145 -0
- package/dist/types/cli/doctor-cli.d.ts +7 -0
- package/dist/types/cli/doctor-supervisor.d.ts +121 -0
- package/dist/types/cli/doctor-worker.d.ts +29 -0
- package/dist/types/cli/install-activation.d.ts +158 -0
- package/dist/types/cli/macos-community-app.d.ts +41 -0
- package/dist/types/cli/mcp-cli.d.ts +0 -11
- package/dist/types/cli/update-cli.d.ts +41 -4
- package/dist/types/cli-main.d.ts +174 -0
- package/dist/types/cli.d.ts +1 -171
- package/dist/types/commands/doctor.d.ts +7 -0
- package/dist/types/commands/sdk.d.ts +17 -8
- package/dist/types/config/autorouting-tier-map.d.ts +19 -0
- package/dist/types/config/file-lock.d.ts +27 -3
- package/dist/types/config/model-preset-registry.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +12 -5
- package/dist/types/config/model-resolver.d.ts +16 -3
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +1 -1
- package/dist/types/coordinator-mcp/question-gate-codec.d.ts +1 -1
- package/dist/types/coordinator-mcp/session-reaper.d.ts +15 -5
- package/dist/types/cursor.d.ts +9 -9
- package/dist/types/discovery/agents-md.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +36 -7
- package/dist/types/discovery/index.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +2 -0
- package/dist/types/extensibility/extensions/loader.d.ts +22 -1
- package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +14 -1
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -1
- package/dist/types/extensibility/gjc-plugins/types.d.ts +25 -0
- package/dist/types/extensibility/plugins/manager.d.ts +33 -4
- package/dist/types/extensibility/plugins/marketplace/cache.d.ts +6 -0
- package/dist/types/extensibility/plugins/marketplace/manager.d.ts +186 -0
- package/dist/types/extensibility/plugins/marketplace/registry.d.ts +27 -0
- package/dist/types/extensibility/plugins/marketplace/source-resolver.d.ts +16 -1
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +16 -3
- package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +6 -0
- package/dist/types/gjc-runtime/launch-worktree.d.ts +53 -0
- package/dist/types/gjc-runtime/session-layout.d.ts +8 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +15 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +13 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +6 -0
- package/dist/types/main.d.ts +19 -1
- package/dist/types/modes/acp/acp-agent.d.ts +40 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/runtime-mcp/config-writer.d.ts +47 -0
- package/dist/types/runtime-mcp/policy-json-edit.d.ts +60 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +4 -0
- package/dist/types/runtime-mcp/types.d.ts +2 -2
- package/dist/types/sdk/acp/adapter.d.ts +5 -1
- package/dist/types/sdk/broker/broker.d.ts +51 -0
- package/dist/types/sdk/broker/daemon-entry.d.ts +39 -0
- package/dist/types/sdk/broker/discovery.d.ts +38 -0
- package/dist/types/sdk/broker/doctor-restart.d.ts +79 -0
- package/dist/types/sdk/broker/endpoint-authority.d.ts +7 -0
- package/dist/types/sdk/broker/ensure.d.ts +14 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +2 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +50 -0
- package/dist/types/sdk/broker/runtime.d.ts +26 -0
- package/dist/types/sdk/broker/session-index.d.ts +13 -4
- package/dist/types/sdk/broker/worktree-occupancy.d.ts +14 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +16 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +101 -6
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +16 -0
- package/dist/types/sdk/bus/daemon-startup-exclusion.d.ts +43 -0
- package/dist/types/sdk/bus/doctor-daemon-restart-client.d.ts +51 -0
- package/dist/types/sdk/bus/doctor-daemon-restart.d.ts +39 -0
- package/dist/types/sdk/bus/index.d.ts +2 -0
- package/dist/types/sdk/bus/notification-service.d.ts +3 -0
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +11 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +1 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +36 -5
- package/dist/types/sdk/cli/session-cli.d.ts +1 -0
- package/dist/types/sdk/host/session-runtime.d.ts +4 -0
- package/dist/types/sdk/host/surface-policy.d.ts +3 -1
- package/dist/types/sdk/lifecycle/service.d.ts +44 -10
- package/dist/types/sdk/prompt-deadline-lease.d.ts +6 -3
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -2
- package/dist/types/sdk/prompt-failure.d.ts +47 -0
- package/dist/types/sdk/prompt-status.d.ts +19 -0
- package/dist/types/sdk/router/session-router.d.ts +3 -4
- package/dist/types/sdk/service-artifact-paths.d.ts +16 -0
- package/dist/types/sdk/session-authority.d.ts +9 -0
- package/dist/types/sdk/session.d.ts +3 -1
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/blob-store.d.ts +1 -1
- package/dist/types/session/fallback-chain-controller.d.ts +3 -6
- package/dist/types/session/internal/managed-session-scope.d.ts +44 -0
- package/dist/types/session/primary-control-surface.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +6 -0
- package/dist/types/tools/ask.d.ts +25 -0
- package/dist/types/tools/image-gen.d.ts +0 -4
- package/dist/types/tools/skill-discovery.d.ts +7 -5
- package/dist/types/tools/ultragoal-ask-guard.d.ts +7 -4
- package/dist/types/utils/changelog.d.ts +0 -9
- package/dist/types/utils/mupdf-wasm.d.ts +1 -0
- package/package.json +9 -8
- package/scripts/compile-args.ts +8 -4
- package/src/capability/fs.ts +395 -17
- package/src/capability/index.ts +273 -10
- package/src/capability/types.ts +9 -0
- package/src/cli/customize-doctor.ts +18 -12
- package/src/cli/doctor/args.ts +236 -0
- package/src/cli/doctor/checks.ts +431 -0
- package/src/cli/doctor/config-repairs.ts +517 -0
- package/src/cli/doctor/context.ts +149 -0
- package/src/cli/doctor/files.ts +149 -0
- package/src/cli/doctor/ids.ts +115 -0
- package/src/cli/doctor/install-repairs.ts +335 -0
- package/src/cli/doctor/journal.ts +423 -0
- package/src/cli/doctor/managed-link.ts +514 -0
- package/src/cli/doctor/native-probe.ts +13 -0
- package/src/cli/doctor/permission-repairs.ts +242 -0
- package/src/cli/doctor/plugin-quarantine.ts +377 -0
- package/src/cli/doctor/plugin-restore.ts +59 -0
- package/src/cli/doctor/plugin-targets.ts +373 -0
- package/src/cli/doctor/probe-client.ts +195 -0
- package/src/cli/doctor/probe-types.ts +21 -0
- package/src/cli/doctor/probe.ts +42 -0
- package/src/cli/doctor/projection-probe.ts +249 -0
- package/src/cli/doctor/repairs.ts +1157 -0
- package/src/cli/doctor/report.ts +176 -0
- package/src/cli/doctor/runner.ts +342 -0
- package/src/cli/doctor/safety.ts +40 -0
- package/src/cli/doctor/service-repairs.ts +452 -0
- package/src/cli/doctor/service-targets.ts +274 -0
- package/src/cli/doctor/types.ts +164 -0
- package/src/cli/doctor-cli.ts +62 -0
- package/src/cli/doctor-supervisor.ts +571 -0
- package/src/cli/doctor-worker.ts +181 -0
- package/src/cli/install-activation.ts +666 -0
- package/src/cli/macos-community-app.ts +1449 -0
- package/src/cli/mcp-cli.ts +11 -21
- package/src/cli/nofile-limit.ts +5 -1
- package/src/cli/plugin-cli.ts +6 -1
- package/src/cli/update-cli.ts +362 -264
- package/src/cli-main.ts +517 -0
- package/src/cli.ts +64 -433
- package/src/commands/autoresearch.ts +11 -5
- package/src/commands/completion.ts +1 -1
- package/src/commands/doctor.ts +13 -0
- package/src/commands/sdk.ts +58 -10
- package/src/commands/ultragoal.ts +11 -5
- package/src/config/autorouting-tier-map.ts +7 -0
- package/src/config/file-lock.ts +736 -71
- package/src/config/mcp-schema.json +3 -3
- package/src/config/model-preset-registry.ts +1 -0
- package/src/config/model-registry.ts +80 -27
- package/src/config/model-resolver.ts +33 -4
- package/src/config/models-config-schema.ts +2 -0
- package/src/config/settings-schema.ts +6 -2
- package/src/coordinator-mcp/question-gate-codec.ts +1 -0
- package/src/coordinator-mcp/server.ts +534 -51
- package/src/coordinator-mcp/session-reaper.ts +64 -8
- package/src/cursor.ts +223 -53
- package/src/discovery/agents-md.ts +74 -8
- package/src/discovery/agents.ts +32 -7
- package/src/discovery/builtin.ts +184 -75
- package/src/discovery/claude-plugins.ts +85 -17
- package/src/discovery/cline.ts +38 -10
- package/src/discovery/cursor.ts +19 -6
- package/src/discovery/gemini.ts +62 -22
- package/src/discovery/github.ts +13 -3
- package/src/discovery/helpers.ts +483 -89
- package/src/discovery/index.ts +1 -0
- package/src/discovery/mcp-json.ts +36 -10
- package/src/discovery/opencode.ts +36 -19
- package/src/discovery/ssh.ts +11 -8
- package/src/discovery/windsurf.ts +12 -3
- package/src/exec/bash-executor.ts +10 -3
- package/src/exec/isolated-shell.ts +15 -2
- package/src/extensibility/extensions/loader.ts +88 -26
- package/src/extensibility/gjc-plugins/lifecycle.ts +189 -0
- package/src/extensibility/gjc-plugins/paths.ts +4 -1
- package/src/extensibility/gjc-plugins/types.ts +27 -0
- package/src/extensibility/plugins/manager.ts +200 -22
- package/src/extensibility/plugins/marketplace/cache.ts +55 -2
- package/src/extensibility/plugins/marketplace/manager.ts +1262 -162
- package/src/extensibility/plugins/marketplace/registry.ts +153 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +116 -10
- package/src/extensibility/runtime-skill-discovery.ts +61 -9
- package/src/extensibility/skill-management.ts +7 -1
- package/src/gjc-runtime/autoresearch-runtime.ts +10 -1
- package/src/gjc-runtime/launch-worktree.test.ts +248 -0
- package/src/gjc-runtime/launch-worktree.ts +275 -38
- package/src/gjc-runtime/repository-binding.ts +26 -1
- package/src/gjc-runtime/session-layout.ts +10 -0
- package/src/gjc-runtime/session-state-lock.ts +330 -23
- package/src/gjc-runtime/session-state-sidecar.ts +328 -80
- package/src/gjc-runtime/ultragoal-runtime.ts +10 -1
- package/src/harness-control-plane/session-lease.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +28 -26
- package/src/main.ts +150 -29
- package/src/memories/index.ts +24 -2
- package/src/modes/acp/acp-agent.ts +522 -68
- package/src/modes/components/agent-dashboard.ts +3 -1
- package/src/modes/components/model-selector.ts +28 -19
- package/src/modes/components/plugin-settings.ts +2 -1
- package/src/modes/controllers/selector-controller.ts +15 -9
- package/src/modes/interactive-mode.ts +21 -3
- package/src/prompts/system/system-prompt.md +5 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/move-session.md +4 -0
- package/src/prompts/tools/read.md +2 -1
- package/src/prompts/tools/skill-discovery.md +6 -5
- package/src/prompts/tools/task.md +1 -0
- package/src/runtime-mcp/config-writer.ts +228 -0
- package/src/runtime-mcp/oauth-discovery.ts +114 -14
- package/src/runtime-mcp/policy-json-edit.ts +129 -0
- package/src/runtime-mcp/startup-policy.ts +14 -0
- package/src/runtime-mcp/types.ts +2 -2
- package/src/sdk/acp/adapter.ts +27 -12
- package/src/sdk/broker/broker.ts +273 -44
- package/src/sdk/broker/daemon-entry.ts +119 -0
- package/src/sdk/broker/discovery.ts +173 -20
- package/src/sdk/broker/doctor-restart.ts +206 -0
- package/src/sdk/broker/endpoint-authority.ts +36 -0
- package/src/sdk/broker/ensure.ts +49 -14
- package/src/sdk/broker/lifecycle.ts +174 -42
- package/src/sdk/broker/process-incarnation.ts +86 -2
- package/src/sdk/broker/runtime.ts +145 -21
- package/src/sdk/broker/session-index.ts +136 -22
- package/src/sdk/broker/spawn-substrate.ts +4 -1
- package/src/sdk/broker/transport.ts +5 -0
- package/src/sdk/broker/worktree-occupancy.ts +21 -1
- package/src/sdk/bus/chat-daemon-cli.ts +63 -0
- package/src/sdk/bus/chat-daemon-control.ts +260 -64
- package/src/sdk/bus/chat-daemon-runtime.ts +141 -25
- package/src/sdk/bus/daemon-startup-exclusion.ts +119 -0
- package/src/sdk/bus/doctor-daemon-restart-client.ts +291 -0
- package/src/sdk/bus/doctor-daemon-restart.ts +92 -0
- package/src/sdk/bus/index.ts +252 -51
- package/src/sdk/bus/kind-aware-reconciliation.ts +76 -41
- package/src/sdk/bus/notification-service.ts +21 -3
- package/src/sdk/bus/reconciliation-store.ts +17 -11
- package/src/sdk/bus/telegram-daemon-cli.ts +91 -5
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +47 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +1 -1
- package/src/sdk/bus/telegram-daemon.ts +178 -13
- package/src/sdk/cli/session-cli.ts +100 -12
- package/src/sdk/host/host.ts +2 -7
- package/src/sdk/host/session-runtime.test.ts +329 -8
- package/src/sdk/host/session-runtime.ts +202 -50
- package/src/sdk/host/surface-policy.ts +8 -1
- package/src/sdk/lifecycle/service.ts +199 -22
- package/src/sdk/mcp/server.ts +1 -1
- package/src/sdk/prompt-deadline-lease.ts +12 -4
- package/src/sdk/prompt-deadline-manager.ts +5 -7
- package/src/sdk/prompt-failure.ts +148 -0
- package/src/sdk/prompt-status.ts +30 -1
- package/src/sdk/prompt-watchdog.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +18 -0
- package/src/sdk/protocol/operation-registry.ts +20 -8
- package/src/sdk/router/session-router.ts +8 -3
- package/src/sdk/service-artifact-paths.ts +26 -0
- package/src/sdk/session-authority.ts +10 -0
- package/src/sdk/session.ts +361 -194
- package/src/session/agent-session.ts +398 -93
- package/src/session/blob-store.ts +9 -9
- package/src/session/fallback-chain-controller.ts +3 -7
- package/src/session/internal/managed-session-scope.ts +445 -29
- package/src/session/internal/managed-session-storage.ts +38 -6
- package/src/session/primary-control-surface.ts +12 -0
- package/src/session/session-manager.ts +11 -3
- package/src/session/session-storage.ts +1 -1
- package/src/session-import/codex.ts +6 -1
- package/src/session-import/redact.ts +7 -0
- package/src/skill-state/workflow-mutation-guard.ts +645 -39
- package/src/slash-commands/builtin-registry.ts +7 -3
- package/src/system-prompt.ts +8 -0
- package/src/task/executor.ts +36 -3
- package/src/task/types.ts +27 -5
- package/src/tools/ask.ts +114 -34
- package/src/tools/browser/actions.ts +2 -2
- package/src/tools/browser/tab-worker.ts +11 -8
- package/src/tools/descriptors.ts +6 -1
- package/src/tools/fetch.ts +7 -2
- package/src/tools/image-gen.ts +33 -34
- package/src/tools/read.ts +78 -32
- package/src/tools/skill-discovery.ts +17 -7
- package/src/tools/tool-catalog.generated.ts +8 -8
- package/src/tools/ultragoal-ask-guard.ts +16 -26
- package/src/utils/changelog.ts +7 -1
- package/src/utils/git.ts +3 -1
- package/src/utils/markit.ts +24 -2
- package/src/utils/mupdf-wasm.ts +26 -0
- package/src/web/search/providers/openai-compatible.ts +191 -14
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export type DoctorMode = "diagnose" | "dry-run" | "fix";
|
|
2
|
+
/**
|
|
3
|
+
* `unsupported` and `not_selected` are the coverage vocabulary this process
|
|
4
|
+
* accepts across the worker/probe boundary and reports in `DoctorCoverage`; the
|
|
5
|
+
* collectors on this platform never emit them, so their consumers are deliberate
|
|
6
|
+
* validation rather than reachable branches.
|
|
7
|
+
*/
|
|
8
|
+
export type CheckExecution = "completed" | "blocked" | "timeout" | "cancelled" | "unsupported" | "not_selected";
|
|
9
|
+
export type Health = "ok" | "warning" | "error" | "unknown" | "not_applicable";
|
|
10
|
+
export type EvidenceLevel = "observed" | "not_probed";
|
|
11
|
+
export type Verdict = "healthy" | "degraded" | "unhealthy" | "inconclusive";
|
|
12
|
+
export type RepairState = "planned" | "blocked" | "not_needed" | "preparing" | "pending_activation" | "verified" | "failed" | "uncertain" | "rolled_back" | "rollback_conflict";
|
|
13
|
+
export type ReadinessFactCode = "authorization_missing" | "confirmation_required" | "candidate_unresolved" | "pin_missing" | "candidate_selection_missing" | "identity_recheck_required" | "target_resolution_incomplete" | "unsupported";
|
|
14
|
+
export type DoctorScope = "user" | "project";
|
|
15
|
+
export type DoctorRiskClass = "config-change" | "permission-change" | "install-replace" | "plugin-change" | "service-interruption" | "artifact-detach" | "network" | "external-execution";
|
|
16
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
17
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
18
|
+
readonly [key: string]: JsonValue;
|
|
19
|
+
};
|
|
20
|
+
export interface CheckEvidence {
|
|
21
|
+
readonly runtimeVersion?: string;
|
|
22
|
+
readonly platform?: string;
|
|
23
|
+
readonly arch?: string;
|
|
24
|
+
readonly channel?: string;
|
|
25
|
+
readonly schemaCoverage?: "selected_fields" | "complete";
|
|
26
|
+
readonly startupStatus?: "autoload" | "autoload-off" | "disabled";
|
|
27
|
+
readonly runtimeProbed?: boolean;
|
|
28
|
+
readonly aclCoverage?: "not_probed" | "verified";
|
|
29
|
+
readonly mode?: number;
|
|
30
|
+
readonly ownerMatches?: boolean;
|
|
31
|
+
readonly contentsRead?: boolean;
|
|
32
|
+
readonly authenticationProbed?: boolean;
|
|
33
|
+
readonly present?: boolean;
|
|
34
|
+
readonly enabled?: boolean;
|
|
35
|
+
readonly autoload?: boolean;
|
|
36
|
+
readonly hasAuth?: boolean;
|
|
37
|
+
readonly status?: string;
|
|
38
|
+
readonly sourceClass?: string;
|
|
39
|
+
/** Closed observation of a known plugin artifact; never a path or content. */
|
|
40
|
+
readonly artifactStatus?: "present" | "absent" | "unreadable";
|
|
41
|
+
readonly transport?: "stdio" | "http" | "sse" | "unknown";
|
|
42
|
+
readonly count?: number;
|
|
43
|
+
readonly warningCount?: number;
|
|
44
|
+
readonly counts?: Readonly<Record<string, number>>;
|
|
45
|
+
readonly errno?: string;
|
|
46
|
+
readonly fileKind?: string;
|
|
47
|
+
readonly schemaLocation?: string;
|
|
48
|
+
readonly version?: string;
|
|
49
|
+
readonly integrityResult?: string;
|
|
50
|
+
readonly processObservation?: JsonValue;
|
|
51
|
+
readonly generation?: string;
|
|
52
|
+
readonly occupancy?: string;
|
|
53
|
+
readonly readiness?: readonly ReadinessFactCode[];
|
|
54
|
+
readonly rootId?: string;
|
|
55
|
+
readonly safeLabel?: string;
|
|
56
|
+
readonly candidateCount?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface DoctorCheck {
|
|
59
|
+
readonly id: string;
|
|
60
|
+
readonly targetId: string;
|
|
61
|
+
readonly scope?: DoctorScope;
|
|
62
|
+
readonly execution: CheckExecution;
|
|
63
|
+
readonly health: Health;
|
|
64
|
+
readonly reasonCode?: string;
|
|
65
|
+
readonly evidenceLevel: EvidenceLevel;
|
|
66
|
+
readonly observedAt?: string;
|
|
67
|
+
readonly durationMs?: number;
|
|
68
|
+
readonly dependsOn: readonly string[];
|
|
69
|
+
readonly evidence: CheckEvidence;
|
|
70
|
+
readonly remediationIds: readonly string[];
|
|
71
|
+
}
|
|
72
|
+
export interface RepairCandidate {
|
|
73
|
+
readonly id: string;
|
|
74
|
+
readonly sourceChannel: string;
|
|
75
|
+
readonly ref?: string;
|
|
76
|
+
readonly sha256?: string;
|
|
77
|
+
readonly evidence: CheckEvidence;
|
|
78
|
+
}
|
|
79
|
+
export interface DoctorRepair {
|
|
80
|
+
readonly id: string;
|
|
81
|
+
readonly targetId: string;
|
|
82
|
+
readonly riskClasses: readonly DoctorRiskClass[];
|
|
83
|
+
readonly authorization: readonly string[];
|
|
84
|
+
readonly readiness: readonly ReadinessFactCode[];
|
|
85
|
+
readonly sourceChannel?: string;
|
|
86
|
+
readonly candidates: readonly RepairCandidate[];
|
|
87
|
+
readonly selectedCandidate?: string;
|
|
88
|
+
readonly preconditions: readonly string[];
|
|
89
|
+
readonly rollbackClass?: string;
|
|
90
|
+
readonly state: RepairState;
|
|
91
|
+
readonly reasonCode?: string;
|
|
92
|
+
readonly sideEffectStarted?: boolean;
|
|
93
|
+
readonly outcome?: {
|
|
94
|
+
readonly mutationVerified: boolean;
|
|
95
|
+
readonly desiredStartupStateAchieved?: boolean;
|
|
96
|
+
};
|
|
97
|
+
readonly beforeCheckIds: readonly string[];
|
|
98
|
+
readonly afterCheckIds: readonly string[];
|
|
99
|
+
readonly restartRequired: boolean;
|
|
100
|
+
readonly restartScope?: "none" | "new-session" | "service";
|
|
101
|
+
readonly nonrollbackableEffects: readonly string[];
|
|
102
|
+
readonly activationRecordRef?: string;
|
|
103
|
+
}
|
|
104
|
+
export interface DoctorCoverage {
|
|
105
|
+
readonly requested: number;
|
|
106
|
+
readonly expanded: number;
|
|
107
|
+
readonly attempted: number;
|
|
108
|
+
readonly completed: number;
|
|
109
|
+
readonly blocked: number;
|
|
110
|
+
readonly timedOut: number;
|
|
111
|
+
readonly unsupported: number;
|
|
112
|
+
}
|
|
113
|
+
export interface DoctorSummary {
|
|
114
|
+
readonly verdict: Verdict;
|
|
115
|
+
readonly exitCode: number;
|
|
116
|
+
}
|
|
117
|
+
export interface DoctorReport {
|
|
118
|
+
readonly schemaVersion: 1;
|
|
119
|
+
readonly command: "doctor";
|
|
120
|
+
readonly runId: string;
|
|
121
|
+
readonly mode: DoctorMode;
|
|
122
|
+
readonly generatedAt: string;
|
|
123
|
+
readonly durationMs: number;
|
|
124
|
+
readonly subject: {
|
|
125
|
+
readonly gjcVersion: string;
|
|
126
|
+
readonly platform: string;
|
|
127
|
+
readonly arch: string;
|
|
128
|
+
readonly channel: string;
|
|
129
|
+
readonly scope?: DoctorScope;
|
|
130
|
+
readonly rootIds: readonly string[];
|
|
131
|
+
};
|
|
132
|
+
readonly selection: {
|
|
133
|
+
readonly checks: readonly string[];
|
|
134
|
+
readonly repair?: string;
|
|
135
|
+
readonly targetId?: string;
|
|
136
|
+
};
|
|
137
|
+
readonly coverage: DoctorCoverage;
|
|
138
|
+
readonly summary: DoctorSummary;
|
|
139
|
+
readonly checks: readonly DoctorCheck[];
|
|
140
|
+
readonly repairs: readonly DoctorRepair[];
|
|
141
|
+
readonly limits: {
|
|
142
|
+
readonly [key: string]: JsonValue;
|
|
143
|
+
};
|
|
144
|
+
readonly invocationError?: string;
|
|
145
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute the boot-safe doctor parser and delegate collection to an owned,
|
|
3
|
+
* verified-terminated child worker (`doctor-supervisor.ts`). Diagnostics and
|
|
4
|
+
* repairs never run in this process: a `Promise.race` here cannot bound
|
|
5
|
+
* synchronous fs/native work, so only the child-process boundary can.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runDoctorCli(argv: readonly string[]): Promise<void>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor bootstrap isolation supervisor (parent side).
|
|
3
|
+
*
|
|
4
|
+
* `gjc doctor` must stay usable when the normal runtime is broken (malformed
|
|
5
|
+
* config, a faulting native addon, an unbounded filesystem stall). A
|
|
6
|
+
* `Promise.race` inside the in-process runner cannot bound synchronous or
|
|
7
|
+
* native work (fs realpath/read, native addon calls, fsync) — only an owned
|
|
8
|
+
* child-process boundary can. This module owns that boundary from the
|
|
9
|
+
* parent's side; the child worker entry (imports `./doctor/runner` and is
|
|
10
|
+
* re-entered via `cli.ts`'s `--internal-doctor-worker` admission branch) is
|
|
11
|
+
* implemented in `doctor-worker.ts`.
|
|
12
|
+
*
|
|
13
|
+
* Protocol: newline-delimited JSON over the child's stdin/stdout, each
|
|
14
|
+
* message authenticated by a random per-run token delivered only via
|
|
15
|
+
* `DOCTOR_WORKER_TOKEN_ENV` (never argv, never logged, never in the report).
|
|
16
|
+
* Token comparison is constant-time. The child's stdio is fully owned by
|
|
17
|
+
* this protocol, so the interactive confirmation prompt (default No, exact
|
|
18
|
+
* action/target/value, SIGINT- and deadline-aware) is rendered by THIS
|
|
19
|
+
* parent against the real terminal — the child never touches the TTY.
|
|
20
|
+
*
|
|
21
|
+
* "Repair admitted" is a permanent fence: it is latched synchronously the
|
|
22
|
+
* instant the `admitted` message is observed, before any further await, and
|
|
23
|
+
* is never cleared. Any abnormal ending after admission is reported as an
|
|
24
|
+
* uncertain post-effect outcome (exit 4); before admission it is "nothing
|
|
25
|
+
* started" (exit 3), and a runtime that itself was admitted-then-lost is
|
|
26
|
+
* evidenced with `worker_termination_unverified`, never a silently clean
|
|
27
|
+
* exit. SIGINT is forwarded to the child; a verified clean stop after SIGINT
|
|
28
|
+
* and before admission reports 130, never fabricated merely because a
|
|
29
|
+
* `Promise.race` resolved. No successor worker is ever spawned after an
|
|
30
|
+
* unverified termination.
|
|
31
|
+
*/
|
|
32
|
+
import type { Writable } from "node:stream";
|
|
33
|
+
import type { DoctorConfirmationResult, DoctorOptions } from "./doctor/args";
|
|
34
|
+
import type { DoctorMode, DoctorRepair, DoctorReport } from "./doctor/types";
|
|
35
|
+
/** Re-entrant argv marker for the isolated doctor worker. Wiring into `cli.ts`'s admission chain is a coordinated follow-up. */
|
|
36
|
+
export declare const DOCTOR_WORKER_ARG = "--internal-doctor-worker";
|
|
37
|
+
/** Per-spawn random token; the worker must refuse to run the protocol route without an exact match. */
|
|
38
|
+
export declare const DOCTOR_WORKER_TOKEN_ENV = "GJC_DOCTOR_WORKER_TOKEN";
|
|
39
|
+
export interface SupervisedDoctorInput {
|
|
40
|
+
/** Raw argv following `doctor` (unparsed). The worker re-derives options and re-runs full security admission itself. */
|
|
41
|
+
readonly argv: readonly string[];
|
|
42
|
+
/** Parsed options for local budget/cwd/tty decisions only; `confirmRepair`/`onRepairAdmitted` here are ignored — the parent supplies live protocol-backed equivalents. */
|
|
43
|
+
readonly options: DoctorOptions;
|
|
44
|
+
}
|
|
45
|
+
export type WorkerToSupervisorMessage = {
|
|
46
|
+
readonly type: "confirm";
|
|
47
|
+
readonly token: string;
|
|
48
|
+
readonly id: number;
|
|
49
|
+
readonly repair: DoctorRepair;
|
|
50
|
+
readonly setValue?: boolean;
|
|
51
|
+
} | {
|
|
52
|
+
readonly type: "admitted";
|
|
53
|
+
readonly token: string;
|
|
54
|
+
} | {
|
|
55
|
+
readonly type: "report";
|
|
56
|
+
readonly token: string;
|
|
57
|
+
readonly report: DoctorReport;
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: "error";
|
|
60
|
+
readonly token: string;
|
|
61
|
+
readonly code: string;
|
|
62
|
+
readonly message: string;
|
|
63
|
+
};
|
|
64
|
+
/** Distributes `Omit` over the message union so each variant keeps its own extra fields (plain `Omit<Union, K>` only keeps keys common to every member). */
|
|
65
|
+
export type WorkerToSupervisorPayload = WorkerToSupervisorMessage extends infer M ? M extends {
|
|
66
|
+
readonly token: string;
|
|
67
|
+
} ? Omit<M, "token"> : never : never;
|
|
68
|
+
export type SupervisorToWorkerMessage = {
|
|
69
|
+
readonly type: "init";
|
|
70
|
+
readonly token: string;
|
|
71
|
+
readonly argv: readonly string[];
|
|
72
|
+
readonly cwd: string;
|
|
73
|
+
readonly tty: boolean;
|
|
74
|
+
readonly runId: string;
|
|
75
|
+
readonly timeoutMs: number;
|
|
76
|
+
readonly deadlineAt: number;
|
|
77
|
+
} | {
|
|
78
|
+
readonly type: "confirm-result";
|
|
79
|
+
readonly token: string;
|
|
80
|
+
readonly id: number;
|
|
81
|
+
readonly result: DoctorConfirmationResult;
|
|
82
|
+
};
|
|
83
|
+
/** An explicit `--timeout-ms` may only shorten the action-specific ceiling, never raise it. */
|
|
84
|
+
export declare function resolveSupervisedBudgetMs(options: DoctorOptions): number;
|
|
85
|
+
/**
|
|
86
|
+
* Accept a worker `report` message only when it is both structurally complete
|
|
87
|
+
* and bound to this exact run. Returns the report on success so callers never
|
|
88
|
+
* re-narrow it, and `undefined` for every rejected shape — including a missing
|
|
89
|
+
* or malformed `selection`, which used to throw at the dereference.
|
|
90
|
+
*/
|
|
91
|
+
export declare function acceptWorkerReport(value: unknown, expected: {
|
|
92
|
+
readonly runId: string;
|
|
93
|
+
readonly mode: DoctorMode;
|
|
94
|
+
readonly repair?: string;
|
|
95
|
+
readonly targetId?: string;
|
|
96
|
+
}): DoctorReport | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Write side of the parent→worker protocol.
|
|
99
|
+
*
|
|
100
|
+
* The channel is a one-way latch: once the worker has settled (exit, close, or
|
|
101
|
+
* a pipe error) no further byte is written to its stdin. A confirmation prompt
|
|
102
|
+
* can resolve arbitrarily late — after the deadline fired, after SIGINT, after
|
|
103
|
+
* the worker crashed — and its callback would otherwise write to a closed pipe,
|
|
104
|
+
* surfacing as an EPIPE / ERR_STREAM_DESTROYED that crashes the parent. The
|
|
105
|
+
* latch check and the write happen in one synchronous step, so no stream event
|
|
106
|
+
* can interleave between them, and any residual race is contained: it becomes a
|
|
107
|
+
* worker-failure outcome instead of an exception.
|
|
108
|
+
*/
|
|
109
|
+
export interface SupervisorChannel {
|
|
110
|
+
readonly settled: boolean;
|
|
111
|
+
/** Latch the channel closed without reporting a failure (normal termination). */
|
|
112
|
+
settle(): void;
|
|
113
|
+
send(message: SupervisorToWorkerMessage): void;
|
|
114
|
+
}
|
|
115
|
+
export declare function createSupervisorChannel(stdin: Writable, onChannelClosed: () => void): SupervisorChannel;
|
|
116
|
+
/**
|
|
117
|
+
* Run doctor diagnostics/repair inside an owned, verified-terminated child.
|
|
118
|
+
* Never falls back to in-process execution and never spawns a successor
|
|
119
|
+
* worker after this attempt's child is gone.
|
|
120
|
+
*/
|
|
121
|
+
export declare function runSupervisedDoctor(input: SupervisedDoctorInput): Promise<DoctorReport>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor bootstrap isolation worker (child side).
|
|
3
|
+
*
|
|
4
|
+
* This is the ONLY module that imports the real `./doctor/runner` inside the
|
|
5
|
+
* isolated child spawned by `doctor-supervisor.ts`. Its own stdio is fully
|
|
6
|
+
* consumed by the JSON-line protocol: the parent renders the interactive
|
|
7
|
+
* confirmation prompt against the real terminal and this process forwards
|
|
8
|
+
* `confirmRepair`/`onRepairAdmitted` callback activity over the wire rather
|
|
9
|
+
* than touching `process.stdin`/TTY itself. `onRepairAdmitted` latches the
|
|
10
|
+
* "admitted" fact on the parent's side the instant the message is sent —
|
|
11
|
+
* this worker sends it synchronously before any further await, exactly once
|
|
12
|
+
* per repair attempt, and never retracts it.
|
|
13
|
+
*
|
|
14
|
+
* No raw stderr, stack trace, or uncaught exception detail ever reaches the
|
|
15
|
+
* parent: every failure path here degrades to a bounded `error` message with
|
|
16
|
+
* a fixed reason code. The parent treats worker stdout as the only channel
|
|
17
|
+
* of record and never forwards this process's own stderr into the report.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* `--internal-doctor-worker` is only a routable protocol worker when BOTH the
|
|
21
|
+
* token env var is present with a plausible shape AND stdin is not a TTY — a
|
|
22
|
+
* user's own interactive terminal can never be silently routed onto the
|
|
23
|
+
* worker's non-interactive confirmation-refusal path. Any other invocation
|
|
24
|
+
* (missing token, short/malformed token, an attached TTY) falls back to
|
|
25
|
+
* ordinary CLI usage error and never enters the protocol at all.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isRoutableDoctorWorkerInvocation(env: NodeJS.ProcessEnv, stdinIsTTY: boolean | undefined): boolean;
|
|
28
|
+
/** Runs the isolated worker's full protocol lifecycle to completion. Never spawns anything; never talks to a TTY. */
|
|
29
|
+
export declare function runDoctorWorker(): Promise<void>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared target-adjacent v1 activation record authority for `gjc update` and
|
|
3
|
+
* `gjc doctor install.restore-binary`.
|
|
4
|
+
*
|
|
5
|
+
* Every identity capture is a bounded, no-follow, post-read-revalidated
|
|
6
|
+
* snapshot, never a bare fs.readFile/fs.stat pair. Every record write is a
|
|
7
|
+
* no-replace create or an exact CAS against the caller's own previously
|
|
8
|
+
* observed record identity, never a blind fs.rename overwrite. Promoting a
|
|
9
|
+
* staged candidate onto the live target uses the native exactReplaceRetained
|
|
10
|
+
* primitive: it validates both identities before mutating anything and
|
|
11
|
+
* retires the old target to a retained backup name instead of deleting it.
|
|
12
|
+
* There is no unlink/rename-based rollback path in this module.
|
|
13
|
+
*/
|
|
14
|
+
import { type NativeExactFileIdentity } from "@gajae-code/natives";
|
|
15
|
+
export type ActivationPhase = "staged" | "published" | "verified" | "pending_activation" | "rolled_back" | "uncertain";
|
|
16
|
+
/** Serialized exact regular-file identity. BigInt fields are decimal strings so the record stays plain JSON. */
|
|
17
|
+
export interface FileIdentity {
|
|
18
|
+
readonly dev: string;
|
|
19
|
+
readonly ino: string;
|
|
20
|
+
readonly nlink: string;
|
|
21
|
+
readonly parentDev?: string;
|
|
22
|
+
readonly parentIno?: string;
|
|
23
|
+
readonly size: string;
|
|
24
|
+
readonly mtimeNs: string;
|
|
25
|
+
readonly mode: number;
|
|
26
|
+
readonly sha256: string;
|
|
27
|
+
}
|
|
28
|
+
/** Serialized directory identity. No content hash: a directory has no bytes to bind. */
|
|
29
|
+
export interface DirectoryIdentity {
|
|
30
|
+
readonly dev: string;
|
|
31
|
+
readonly ino: string;
|
|
32
|
+
readonly mode: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ActivationRecordV1 {
|
|
35
|
+
readonly schemaVersion: 1;
|
|
36
|
+
readonly kind: "gjc-install-activation";
|
|
37
|
+
readonly transactionId: string;
|
|
38
|
+
readonly targetPath: string;
|
|
39
|
+
readonly parentPath: string;
|
|
40
|
+
readonly targetIdentity?: FileIdentity;
|
|
41
|
+
readonly backupIdentity?: FileIdentity;
|
|
42
|
+
readonly parentIdentity?: DirectoryIdentity;
|
|
43
|
+
readonly baseline: {
|
|
44
|
+
readonly exists: boolean;
|
|
45
|
+
readonly digest?: string;
|
|
46
|
+
readonly version?: string;
|
|
47
|
+
};
|
|
48
|
+
readonly candidate: {
|
|
49
|
+
readonly digest: string;
|
|
50
|
+
readonly version: string;
|
|
51
|
+
readonly channel?: string;
|
|
52
|
+
readonly ref?: string;
|
|
53
|
+
readonly os?: string;
|
|
54
|
+
readonly arch?: string;
|
|
55
|
+
readonly sidecars: readonly string[];
|
|
56
|
+
};
|
|
57
|
+
readonly stagingPath: string;
|
|
58
|
+
/** Staged candidate identity captured when recorded; re-checked before promotion. */
|
|
59
|
+
readonly stagingIdentity?: FileIdentity;
|
|
60
|
+
/** Single-component name exactReplaceRetained retires the old target to, inside the target's own parent. */
|
|
61
|
+
readonly backupName: string;
|
|
62
|
+
readonly phase: ActivationPhase;
|
|
63
|
+
}
|
|
64
|
+
export type ActivationRead = {
|
|
65
|
+
readonly status: "missing";
|
|
66
|
+
} | {
|
|
67
|
+
readonly status: "valid";
|
|
68
|
+
readonly record: ActivationRecordV1;
|
|
69
|
+
readonly identity: FileIdentity;
|
|
70
|
+
} | {
|
|
71
|
+
readonly status: "malformed";
|
|
72
|
+
readonly reason: string;
|
|
73
|
+
} | {
|
|
74
|
+
readonly status: "foreign";
|
|
75
|
+
readonly reason: string;
|
|
76
|
+
};
|
|
77
|
+
/** Public snapshot API shared by callers (update-cli/doctor) to capture original target/staging identities. */
|
|
78
|
+
export declare function snapshotRegularFile(filePath: string): Promise<{
|
|
79
|
+
readonly header: Uint8Array;
|
|
80
|
+
readonly identity: FileIdentity;
|
|
81
|
+
} | undefined>;
|
|
82
|
+
export declare function snapshotDirectory(directoryPath: string): Promise<DirectoryIdentity | undefined>;
|
|
83
|
+
export declare function sameFileIdentity(a: FileIdentity, b: FileIdentity): boolean;
|
|
84
|
+
export declare function sameDirectoryIdentity(a: DirectoryIdentity | undefined, b: DirectoryIdentity | undefined): boolean;
|
|
85
|
+
export declare function toNativeIdentity(identity: FileIdentity, quarantineName?: string): NativeExactFileIdentity;
|
|
86
|
+
export declare function activationRecordPath(targetPath: string): string;
|
|
87
|
+
/** Deterministic-enough, collision-checked single-component retained backup name for one transaction. */
|
|
88
|
+
export declare function activationBackupName(targetPath: string, transactionId: string): string;
|
|
89
|
+
export declare function createActivationTransactionId(): string;
|
|
90
|
+
/** Pure builder for a fresh `staged` activation record; callers still write it via createActivationRecordFile. */
|
|
91
|
+
export declare function buildActivationRecord(input: {
|
|
92
|
+
readonly targetPath: string;
|
|
93
|
+
readonly targetIdentity?: FileIdentity;
|
|
94
|
+
readonly originalTargetAbsent?: boolean;
|
|
95
|
+
readonly parentIdentity: DirectoryIdentity;
|
|
96
|
+
readonly baselineDigest?: string;
|
|
97
|
+
readonly baselineVersion?: string;
|
|
98
|
+
readonly stagingPath: string;
|
|
99
|
+
readonly stagingIdentity: FileIdentity;
|
|
100
|
+
readonly candidate: {
|
|
101
|
+
readonly digest: string;
|
|
102
|
+
readonly version: string;
|
|
103
|
+
readonly channel?: string;
|
|
104
|
+
readonly ref?: string;
|
|
105
|
+
readonly os?: string;
|
|
106
|
+
readonly arch?: string;
|
|
107
|
+
readonly sidecars?: readonly string[];
|
|
108
|
+
};
|
|
109
|
+
readonly transactionId?: string;
|
|
110
|
+
}): ActivationRecordV1;
|
|
111
|
+
/**
|
|
112
|
+
* Read the activation record for `targetPath`, itself opened bounded/
|
|
113
|
+
* no-follow/identity-revalidated. A record that is present but fails schema
|
|
114
|
+
* or path validation is reported distinctly (`malformed`/`foreign`) and is
|
|
115
|
+
* never treated as absent, so a caller cannot silently proceed past a
|
|
116
|
+
* corrupted or substituted record.
|
|
117
|
+
*/
|
|
118
|
+
export declare function readActivationRecord(targetPath: string): Promise<ActivationRead>;
|
|
119
|
+
/**
|
|
120
|
+
* Create the activation record with a no-replace write: an existing record
|
|
121
|
+
* (foreign, malformed, or a live transaction) is never overwritten blindly.
|
|
122
|
+
*/
|
|
123
|
+
export declare function createActivationRecordFile(record: ActivationRecordV1): Promise<FileIdentity>;
|
|
124
|
+
/**
|
|
125
|
+
* Compare-and-swap the activation record: the caller must supply the exact
|
|
126
|
+
* identity of the record it last read. `exactReplacePath` performs the
|
|
127
|
+
* atomic namespace-exchange CAS; a stale or substituted record is refused
|
|
128
|
+
* rather than overwritten.
|
|
129
|
+
*/
|
|
130
|
+
export declare function updateActivationRecordFile(record: ActivationRecordV1, expectedIdentity: FileIdentity): Promise<FileIdentity>;
|
|
131
|
+
export type ReconcileStatus = "missing" | "verified" | "reconciled" | "applied_unverified" | "rolled_back" | "pending_activation" | "conflict" | "malformed" | "foreign";
|
|
132
|
+
export interface ReconcileResult {
|
|
133
|
+
readonly status: ReconcileStatus;
|
|
134
|
+
readonly record?: ActivationRecordV1;
|
|
135
|
+
readonly recordIdentity?: FileIdentity;
|
|
136
|
+
readonly reason?: string;
|
|
137
|
+
/** Present only for a pre-mutation Windows sharing violation on the destination open. */
|
|
138
|
+
readonly windowsErrorCode?: string;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Reconcile the activation record for `targetPath` against durable state.
|
|
142
|
+
*
|
|
143
|
+
* `staged`/`pending_activation` phases are promoted onto the live target via
|
|
144
|
+
* `exactReplaceRetained` only when `allowPromotion` is set and every
|
|
145
|
+
* identity (staging candidate, current target, parent) still matches what
|
|
146
|
+
* the record captured; the previous target is retired intact to the
|
|
147
|
+
* record's `backupName`, never unlinked or blind-renamed. `published`
|
|
148
|
+
* records are re-verified and advanced to `verified` once the target
|
|
149
|
+
* digest/identity matches the candidate. `verified` records are read-only
|
|
150
|
+
* re-confirmations. Anything else (target/parent drift, missing staged
|
|
151
|
+
* candidate, an already-occupied backup name, a pre-mutation Windows
|
|
152
|
+
* sharing violation) is reported as `conflict` with the exact reason and
|
|
153
|
+
* never silently promoted.
|
|
154
|
+
*/
|
|
155
|
+
export declare function reconcileActivationRecord(targetPath: string, options?: {
|
|
156
|
+
readonly allowPromotion?: boolean;
|
|
157
|
+
readonly expectedRecordIdentity?: FileIdentity;
|
|
158
|
+
}): Promise<ReconcileResult>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const COMMUNITY_APP_REPOSITORY = "devswha/gajae-code-app";
|
|
2
|
+
export declare const COMMUNITY_APP_BUNDLE_ID = "app.gajae.desktop";
|
|
3
|
+
export declare const COMMUNITY_APP_TEAM_ID = "5987KT43TJ";
|
|
4
|
+
export declare const COMMUNITY_APP_SIGNING_AUTHORITY = "Developer ID Application: sangwoo ha";
|
|
5
|
+
export declare const COMMUNITY_APP_SUPPRESS_ENV = "GJC_NO_COMMUNITY_APP";
|
|
6
|
+
interface CommandResult {
|
|
7
|
+
exitCode: number;
|
|
8
|
+
stdout: string;
|
|
9
|
+
stderr: string;
|
|
10
|
+
timedOut?: boolean;
|
|
11
|
+
reaped?: boolean;
|
|
12
|
+
helpersRetained?: boolean;
|
|
13
|
+
}
|
|
14
|
+
type CommandRunner = (argv: string[]) => Promise<CommandResult>;
|
|
15
|
+
export interface CommunityAppOfferDependencies {
|
|
16
|
+
platform?: NodeJS.Platform;
|
|
17
|
+
arch?: string;
|
|
18
|
+
env?: NodeJS.ProcessEnv;
|
|
19
|
+
homeDir?: string;
|
|
20
|
+
tempDir?: string;
|
|
21
|
+
stdinIsTTY?: boolean;
|
|
22
|
+
stdoutIsTTY?: boolean;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
fetchImpl?: (url: string, init?: RequestInit) => Promise<Response>;
|
|
25
|
+
prompt?: () => Promise<boolean>;
|
|
26
|
+
command?: CommandRunner;
|
|
27
|
+
cleanupCommand?: (argv: string[], timeoutMs: number) => Promise<CommandResult>;
|
|
28
|
+
log?: (message: string) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface CommunityAppOfferResult {
|
|
31
|
+
status: "skipped" | "installed" | "failed";
|
|
32
|
+
reason: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function offerMacosCommunityApp(deps?: CommunityAppOfferDependencies): Promise<CommunityAppOfferResult>;
|
|
35
|
+
export declare function parseCommunityAppChecksumForTest(text: string, assetName: string): string | undefined;
|
|
36
|
+
export declare function communityAppAssetMatchesArchitectureForTest(name: string, arch: "arm64" | "x64"): boolean;
|
|
37
|
+
export declare function resolveCommunityAppExecutableForTest(bundlePath: string, executable: string): Promise<string | undefined>;
|
|
38
|
+
export declare function hasExpectedCommunityAppSignatureForTest(bundlePath: string, command: CommandRunner): Promise<boolean>;
|
|
39
|
+
export declare function runCommunityAppCommandForTest(argv: string[], onDescendant?: (pid: number) => void): Promise<CommandResult>;
|
|
40
|
+
export declare function abortActiveCommunityAppCommandsForTest(): void;
|
|
41
|
+
export {};
|
|
@@ -22,16 +22,5 @@ export interface MCPCommandArgs {
|
|
|
22
22
|
}
|
|
23
23
|
export declare class MCPArgsError extends Error {
|
|
24
24
|
}
|
|
25
|
-
/** Runtime status of a stored registration for conventional autoload. */
|
|
26
|
-
type AutoloadStatus = "autoload" | "autoload-off" | "disabled";
|
|
27
|
-
/**
|
|
28
|
-
* Compute the conventional-autoload status of a stored server.
|
|
29
|
-
*
|
|
30
|
-
* - `autoload-off`: the server opted out of startup connection via `autoload: false`.
|
|
31
|
-
* - `disabled`: the server is disabled via `enabled: false` or the `disabledServers` list.
|
|
32
|
-
* - `autoload`: connected by ordinary standalone sessions at startup.
|
|
33
|
-
*/
|
|
34
|
-
export declare function computeAutoloadStatus(name: string, config: MCPServerConfig, disabledServers: ReadonlySet<string>): AutoloadStatus;
|
|
35
25
|
export declare function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig;
|
|
36
26
|
export declare function runMCPCommand(args: MCPCommandArgs): Promise<void>;
|
|
37
|
-
export {};
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update CLI command handler.
|
|
3
|
+
*
|
|
4
|
+
* Handles `gjc update` to check for and install standalone GitHub release
|
|
5
|
+
* binaries. Package-manager installs are migrated to a user binary path
|
|
6
|
+
* rather than overwritten. Source checkouts and dev-links are never replaced.
|
|
7
|
+
*/
|
|
1
8
|
import { Settings } from "../config/settings";
|
|
2
9
|
import { type UpdateChannel } from "../config/update-channel";
|
|
3
10
|
import { type NotificationProvider } from "../sdk/bus/config";
|
|
4
11
|
import type { TelemetryDetails, TelemetryEventName } from "../telemetry";
|
|
5
12
|
import { type GithubReleaseLookupOptions } from "./github-release";
|
|
13
|
+
import { type DirectoryIdentity, type FileIdentity } from "./install-activation";
|
|
14
|
+
import { offerMacosCommunityApp } from "./macos-community-app";
|
|
6
15
|
export interface UpdateCommandOptions {
|
|
7
16
|
force: boolean;
|
|
8
17
|
check: boolean;
|
|
@@ -44,6 +53,14 @@ export interface BinaryReplacementOptions {
|
|
|
44
53
|
tempPath: string;
|
|
45
54
|
backupPath: string;
|
|
46
55
|
expectedVersion: string;
|
|
56
|
+
originalTarget: FileIdentity | undefined;
|
|
57
|
+
originalParent: DirectoryIdentity;
|
|
58
|
+
candidate?: {
|
|
59
|
+
readonly channel: string;
|
|
60
|
+
readonly ref: string;
|
|
61
|
+
readonly sha256: string;
|
|
62
|
+
};
|
|
63
|
+
verifyStagedVersion?: (stagingPath: string, expectedVersion: string) => Promise<void>;
|
|
47
64
|
verifyInstalledVersion: (expectedVersion: string) => Promise<InstalledVersionVerification>;
|
|
48
65
|
}
|
|
49
66
|
/**
|
|
@@ -75,6 +92,7 @@ export declare function resolveUpdateMethodForTest(ompPath: string, bunBinDir: s
|
|
|
75
92
|
export declare function resolveNpmManagedTargetForTest(ompPath: string, platform: PathPlatform, packageExists: PackageExists): PackageManagerTarget | undefined;
|
|
76
93
|
export declare function defaultUserBinaryPath(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string;
|
|
77
94
|
export declare function isProtectedSourcePathForTest(filePath: string): boolean;
|
|
95
|
+
export declare function isProtectedSourcePathForInstall(filePath: string): boolean;
|
|
78
96
|
export declare function defaultUserBinaryPathForTest(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string;
|
|
79
97
|
/** Lookup options for the GitHub release check. */
|
|
80
98
|
export interface LatestReleaseLookupOptions extends GithubReleaseLookupOptions {
|
|
@@ -82,6 +100,10 @@ export interface LatestReleaseLookupOptions extends GithubReleaseLookupOptions {
|
|
|
82
100
|
}
|
|
83
101
|
export declare function getLatestReleaseForTest(options: LatestReleaseLookupOptions): Promise<ReleaseInfo>;
|
|
84
102
|
export declare function compareVersionsForTest(a: string, b: string): number;
|
|
103
|
+
/**
|
|
104
|
+
* Get the appropriate binary name for this platform.
|
|
105
|
+
*/
|
|
106
|
+
export declare function getBinaryNameForPlatform(platform?: NodeJS.Platform, arch?: string): string;
|
|
85
107
|
export declare function resolveGjcPathForTest(options: {
|
|
86
108
|
compiled: boolean;
|
|
87
109
|
execPath: string;
|
|
@@ -129,14 +151,23 @@ export declare function recoverWindowsUpdateJournal(journalPath: string): Promis
|
|
|
129
151
|
export declare function replaceBinaryForUpdate(options: BinaryReplacementOptions): Promise<InstalledVersionVerification>;
|
|
130
152
|
export declare function runPackageManagerUpdateForTest(options: PackageManagerUpdateOptions): Promise<InstalledVersionVerification>;
|
|
131
153
|
export declare function fsyncFileForTest(filePath: string): Promise<void>;
|
|
154
|
+
/** Production adapter used by doctor restore: official release origin, checksum manifest, and runtime smoke. */
|
|
155
|
+
export declare function fetchAndVerifyOfficialPinnedCandidate(candidate: {
|
|
156
|
+
ref: string;
|
|
157
|
+
version: string;
|
|
158
|
+
os: NodeJS.Platform;
|
|
159
|
+
arch: string;
|
|
160
|
+
sha256: string;
|
|
161
|
+
}, stagingPath: string): Promise<void>;
|
|
162
|
+
export declare function smokeTestPinnedCandidate(candidate: {
|
|
163
|
+
version: string;
|
|
164
|
+
}, stagingPath: string): Promise<void>;
|
|
132
165
|
/** Injectable steps of the binary update flow (seams for testing ordering). */
|
|
133
166
|
export interface BinaryUpdateFlow {
|
|
134
167
|
download(url: string, tempPath: string): Promise<void>;
|
|
135
168
|
fsync(filePath: string): Promise<void>;
|
|
136
169
|
replace(options: BinaryReplacementOptions): Promise<InstalledVersionVerification>;
|
|
137
170
|
verifyInstalledVersion(expectedVersion: string): Promise<InstalledVersionVerification>;
|
|
138
|
-
/** Best-effort cleanup of the temp file when the flow aborts before replace. */
|
|
139
|
-
removeTemp?(filePath: string): Promise<void>;
|
|
140
171
|
/** Called once fsync has succeeded, right before replacement begins. */
|
|
141
172
|
beforeReplace?(): void;
|
|
142
173
|
}
|
|
@@ -146,15 +177,18 @@ export interface BinaryUpdateFlow {
|
|
|
146
177
|
* before it is published (renamed into place) or exec'd for verification.
|
|
147
178
|
*
|
|
148
179
|
* If fsync fails the temp bytes are not durable, so we abort before
|
|
149
|
-
* replacement/verification and
|
|
150
|
-
* possibly-truncated binary.
|
|
180
|
+
* replacement/verification and retain the staging artifact rather than risk
|
|
181
|
+
* deleting a substituted pathname or installing a possibly-truncated binary.
|
|
151
182
|
*/
|
|
152
183
|
export declare function runBinaryUpdateFlow(targetPath: string, url: string, expectedVersion: string, flow: BinaryUpdateFlow): Promise<InstalledVersionVerification>;
|
|
184
|
+
export declare function acquireBinaryUpdateLock(targetPath: string): Promise<() => Promise<void>>;
|
|
153
185
|
export declare function assertSupportedLinuxLibcForTest(glibcVersionRuntime: string | undefined, muslLoaderPresent: boolean): void;
|
|
154
186
|
/**
|
|
155
187
|
* Run the update command.
|
|
156
188
|
*/
|
|
157
189
|
export interface UpdateCommandDependencies {
|
|
190
|
+
/** User-visible migration guidance owned by the standalone update command, not the TUI logger. */
|
|
191
|
+
writeStdout?: (text: string) => void;
|
|
158
192
|
getLatestRelease?: (options?: LatestReleaseLookupOptions) => Promise<ReleaseInfo>;
|
|
159
193
|
resolveUpdateTarget?: () => Promise<UpdateTarget>;
|
|
160
194
|
verifyMigrationTarget?: (release: ReleaseInfo, runtimePath: string) => Promise<InstalledVersionVerification>;
|
|
@@ -165,6 +199,8 @@ export interface UpdateCommandDependencies {
|
|
|
165
199
|
restartDaemon?: (settings: Settings) => Promise<void>;
|
|
166
200
|
recoverNotifications?: (settings: Settings) => Promise<void>;
|
|
167
201
|
runPostUpdateRecovery?: (runtimePath: string) => Promise<void>;
|
|
202
|
+
platform?: NodeJS.Platform;
|
|
203
|
+
offerMacosCommunityApp?: typeof offerMacosCommunityApp;
|
|
168
204
|
recordTelemetryEvent?: (event: TelemetryEventName, details: TelemetryDetails) => unknown;
|
|
169
205
|
exit?: (code: number) => never;
|
|
170
206
|
}
|
|
@@ -202,6 +238,7 @@ export declare function resolveUpdateDecision(options: {
|
|
|
202
238
|
currentVersion: string;
|
|
203
239
|
migrate?: boolean;
|
|
204
240
|
}): UpdateDecision;
|
|
241
|
+
export declare function formatVerifiedBinaryInvocation(runtimePath: string, platform: NodeJS.Platform): string;
|
|
205
242
|
export declare function runUpdateCommand(opts: UpdateCommandOptions, deps?: UpdateCommandDependencies): Promise<void>;
|
|
206
243
|
/**
|
|
207
244
|
* Print update command help.
|