@tomflow/proflow-platform-cli 0.1.1 → 0.1.3

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +24 -3
  3. package/dist/deployment/adapter.d.ts +5 -5
  4. package/dist/deployment/descriptor.d.ts +1 -1
  5. package/dist/deployment/descriptor.js +1 -1
  6. package/dist/src/apply/apply.d.ts +2 -0
  7. package/dist/src/apply/apply.js +47 -4
  8. package/dist/src/apply/current.js +14 -0
  9. package/dist/src/apply/driver.d.ts +1 -0
  10. package/dist/src/apply/driver.js +40 -12
  11. package/dist/src/apply/execute.js +28 -0
  12. package/dist/src/binding/global-binding.d.ts +69 -0
  13. package/dist/src/binding/global-binding.js +349 -0
  14. package/dist/src/binding/production-bindings.d.ts +2 -12
  15. package/dist/src/binding/production-bindings.js +18 -4
  16. package/dist/src/cli.d.ts +13 -1
  17. package/dist/src/cli.js +661 -40
  18. package/dist/src/errors.d.ts +1 -1
  19. package/dist/src/errors.js +13 -0
  20. package/dist/src/install/environment.d.ts +2 -1
  21. package/dist/src/install/environment.js +34 -30
  22. package/dist/src/install/install.js +41 -0
  23. package/dist/src/install/package-manager.d.ts +4 -2
  24. package/dist/src/install/package-manager.js +73 -17
  25. package/dist/src/lifecycle/dispatch.js +52 -1
  26. package/dist/src/lifecycle/service-process.js +32 -2
  27. package/dist/src/persistence/guards.js +1 -0
  28. package/dist/src/planner/check.js +12 -1
  29. package/dist/src/planner/plan.d.ts +1 -0
  30. package/dist/src/planner/plan.js +14 -26
  31. package/dist/src/preflight/config.d.ts +1 -0
  32. package/dist/src/preflight/config.js +43 -0
  33. package/dist/src/preflight/preflight.d.ts +2 -0
  34. package/dist/src/preflight/preflight.js +18 -2
  35. package/dist/src/preflight/requirements.d.ts +2 -2
  36. package/dist/src/preflight/requirements.js +16 -9
  37. package/dist/src/registry/npm-registry.d.ts +1 -1
  38. package/dist/src/registry/npm-registry.js +2 -1
  39. package/dist/src/security/lock.js +40 -2
  40. package/package.json +4 -4
  41. package/proflow.module.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @tomflow/proflow-platform-cli
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Real-1 final remediation and black-box release closure
8
+
9
+ ## 0.1.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Close the Real-1 global Platform control-plane contract across every published ProFlow package. Platform CLI now owns one durable global Workspace binding with canonical identity, cross-process operation locking, cwd/`--workspace` install targeting, cross-directory instance commands, whole-instance uninstall/rebind, and deterministic npm/yarn/pnpm Workspace package-manager selection. Every package-owned install entry, including newly generated Module Template packages, delegates to the Shell-global `platform` command and fails closed when that global CLI is unavailable; Deployment Conformance and the formal test plans mechanically enforce the same rule across all 24 packages.
14
+
3
15
  ## 0.1.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -8,10 +8,20 @@ Business Fact Owner: none
8
8
 
9
9
  ## Purpose
10
10
 
11
- The single platform-level deterministic Deployment planner/executor. It understands only the Module Contract and public lifecycle/verification contracts; it does not import other domains' business internals.
11
+ The single platform-level deterministic Deployment planner/executor and v1 global `platform` control plane. It understands only the Module Contract and public lifecycle/verification contracts; it does not import other domains' business internals. The global CLI binary is distinct from the single bound Platform Instance.
12
12
 
13
13
  For the v1 Custom GPT carrier it may plan/verify Web-only setup, role-scoped Action auth/schema, File Bridge/Code Interpreter/Web Search requirements, `x-openai-isConsequential:false` + Always Allow target configuration, Chrome/runtime prerequisites and current verification freshness. It never creates/guesses Task `workerRef/c-id`, never uses exact ChatGPT model id as READY truth, and never accepts System Observer assessment as Deployment READY truth.
14
14
 
15
+ ## Global CLI bootstrap
16
+
17
+ The v1 `platform` command is a Shell-global control plane. A straightforward bootstrap is:
18
+
19
+ ```text
20
+ npm install --global @tomflow/proflow-platform-cli
21
+ ```
22
+
23
+ This choice installs the global CLI only. It does **not** force the managed Workspace to use npm: a bound Workspace may independently use `npm`, `yarn`, or `pnpm`, selected from its own package-manager facts.
24
+
15
25
  ## Commands
16
26
 
17
27
  ```
@@ -20,8 +30,8 @@ platform modules [module|package]
20
30
  platform docs [module|package] [documentId]
21
31
  platform preflight [module]
22
32
  platform preflight --intent install
23
- platform install [package]
24
- platform uninstall <module|package>
33
+ platform install [package] [--workspace <path>]
34
+ platform uninstall [module|package]
25
35
  platform upgrade [module|package]
26
36
  platform plan --intent install|configure|upgrade|uninstall|repair [options]
27
37
  platform apply <planRef>
@@ -35,3 +45,14 @@ platform manifest [module]
35
45
  ```
36
46
 
37
47
  `install` / `upgrade` / `uninstall` are AI-friendly high-level commands that reuse the same frozen Plan -> Apply engine. `search` reads the npm Registry installable world; `modules` reads the current Workspace managed world; `docs` mechanically aggregates package-owned Descriptor, npm `bin/exports`, and declared documentation without maintaining a second package-knowledge catalog. Package mutation is real Workspace package-manager mutation and is never satisfied by the historical no-op driver seam.
48
+
49
+
50
+ ## v1 global workspace semantics
51
+
52
+ - The `platform` binary is installed globally and can be invoked from any shell directory.
53
+ - At most one ProFlow Workspace may be bound globally at a time.
54
+ - `platform install` targets the current working directory by default; `platform install --workspace <path>` explicitly selects the requested Workspace for Agent/automation use.
55
+ - Requested Workspace paths are canonicalized before binding comparison. A second distinct Workspace is rejected with `WORKSPACE_ALREADY_BOUND` until the current Platform Instance is uninstalled.
56
+ - `status/start/stop/restart/modules/docs/verify/doctor/upgrade/uninstall` resolve the durable global binding rather than the caller's cwd. `platform status` exposes the bound Workspace path.
57
+ - `platform uninstall` without a module/package removes the current Platform Instance and clears its binding; it does not uninstall the global CLI package.
58
+ - Workspace package mutation is package-manager agnostic for v1: `npm`, `yarn`, and `pnpm` are supported. The CLI installation manager and the bound Workspace manager are independent facts.
@@ -5,7 +5,7 @@ export declare const behaviorAdapter: {
5
5
  ok: boolean;
6
6
  status: "SUCCEEDED";
7
7
  moduleRef: "platform-cli";
8
- moduleVersion: "0.1.1";
8
+ moduleVersion: "0.1.3";
9
9
  data?: {} | null;
10
10
  };
11
11
  observedEffects: never[];
@@ -16,7 +16,7 @@ export declare const behaviorAdapter: {
16
16
  ok: boolean;
17
17
  status: "SUCCEEDED";
18
18
  moduleRef: "platform-cli";
19
- moduleVersion: "0.1.1";
19
+ moduleVersion: "0.1.3";
20
20
  data?: {} | null;
21
21
  };
22
22
  observedEffects: never[];
@@ -27,7 +27,7 @@ export declare const behaviorAdapter: {
27
27
  ok: boolean;
28
28
  status: "SUCCEEDED";
29
29
  moduleRef: "platform-cli";
30
- moduleVersion: "0.1.1";
30
+ moduleVersion: "0.1.3";
31
31
  data?: {} | null;
32
32
  };
33
33
  observedEffects: never[];
@@ -38,7 +38,7 @@ export declare const behaviorAdapter: {
38
38
  ok: boolean;
39
39
  status: "SUCCEEDED";
40
40
  moduleRef: "platform-cli";
41
- moduleVersion: "0.1.1";
41
+ moduleVersion: "0.1.3";
42
42
  data?: {} | null;
43
43
  };
44
44
  observedEffects: never[];
@@ -49,7 +49,7 @@ export declare const behaviorAdapter: {
49
49
  ok: boolean;
50
50
  status: "SUCCEEDED";
51
51
  moduleRef: "platform-cli";
52
- moduleVersion: "0.1.1";
52
+ moduleVersion: "0.1.3";
53
53
  data?: {} | null;
54
54
  };
55
55
  observedEffects: never[];
@@ -3,7 +3,7 @@ export declare const descriptor: {
3
3
  readonly contractVersion: "1.0.0";
4
4
  readonly moduleRef: "platform-cli";
5
5
  readonly packageName: "@tomflow/proflow-platform-cli";
6
- readonly moduleVersion: "0.1.1";
6
+ readonly moduleVersion: "0.1.3";
7
7
  readonly kind: "cli";
8
8
  readonly templateVersion: "1.0.0";
9
9
  readonly platformCompatibility: ">=1.0.0 <2.0.0";
@@ -3,7 +3,7 @@ export const descriptor = {
3
3
  contractVersion: "1.0.0",
4
4
  moduleRef: "platform-cli",
5
5
  packageName: "@tomflow/proflow-platform-cli",
6
- moduleVersion: "0.1.1",
6
+ moduleVersion: "0.1.3",
7
7
  kind: "cli",
8
8
  templateVersion: "1.0.0",
9
9
  platformCompatibility: ">=1.0.0 <2.0.0",
@@ -12,6 +12,8 @@ export interface ApplyContext {
12
12
  current: PlanInput;
13
13
  driver: PackageManagerDriver;
14
14
  observer?: RealityObserver;
15
+ /** Rebuilds installed descriptors/bindings after a package mutation. */
16
+ refreshCatalog?: () => Promise<ModuleCatalog>;
15
17
  }
16
18
  /**
17
19
  * Applies a frozen deployment plan deterministically. Every step is re-checked
@@ -1,7 +1,7 @@
1
1
  import { PlatformError } from "../errors.js";
2
2
  import { ensureLayout } from "../paths.js";
3
3
  import { emptyDeploymentState, loadDeploymentState, loadPlan, saveDeploymentState, } from "../persistence/index.js";
4
- import { checkPlanStale, evaluateStepCheck, } from "../planner/index.js";
4
+ import { checkPlanStale, ExecuteStrategy, evaluateStepCheck, } from "../planner/index.js";
5
5
  import { acquireWorkspaceLock } from "../security/index.js";
6
6
  import { executeStep } from "./execute.js";
7
7
  import { createRealityObserver } from "./reality.js";
@@ -21,10 +21,11 @@ function failureMessage(error) {
21
21
  */
22
22
  export async function applyPlan(context) {
23
23
  const driver = context.driver;
24
- const observer = context.observer ??
24
+ let catalog = context.catalog;
25
+ let observer = context.observer ??
25
26
  createRealityObserver({
26
27
  paths: context.paths,
27
- catalog: context.catalog,
28
+ catalog,
28
29
  driver,
29
30
  });
30
31
  await ensureLayout(context.paths);
@@ -105,7 +106,7 @@ export async function applyPlan(context) {
105
106
  }
106
107
  let outcome;
107
108
  try {
108
- outcome = await executeStep({ paths: context.paths, catalog: context.catalog, driver }, step, plan);
109
+ outcome = await executeStep({ paths: context.paths, catalog, driver }, step, plan);
109
110
  }
110
111
  catch (error) {
111
112
  stepResults.push({
@@ -125,6 +126,20 @@ export async function applyPlan(context) {
125
126
  }
126
127
  switch (outcome.kind) {
127
128
  case "SUCCEEDED": {
129
+ if (step.executeStrategy === ExecuteStrategy.lifecycleUninstall) {
130
+ // A lifecycle uninstall is owned by the module adapter. Its typed
131
+ // SUCCEEDED result is the authoritative teardown confirmation. An
132
+ // idempotent uninstall can legitimately leave status UNBOUND/UNKNOWN,
133
+ // so a second status probe must not reinterpret that successful
134
+ // teardown as a failed lifecycle:stopped postcondition.
135
+ stepResults.push({
136
+ stepRef: step.stepRef,
137
+ moduleRef: step.moduleRef,
138
+ status: "EXECUTED",
139
+ message: `${step.moduleRef} owner confirmed lifecycle uninstall`,
140
+ });
141
+ break;
142
+ }
128
143
  // Postcondition re-check: only a genuinely successful mutation is
129
144
  // confirmed; an effect that cannot be confirmed stops the apply
130
145
  // rather than blindly repeating it.
@@ -168,6 +183,34 @@ export async function applyPlan(context) {
168
183
  status: "EXECUTED",
169
184
  message: post.reason,
170
185
  });
186
+ if (step.kind === "package" && context.refreshCatalog !== undefined) {
187
+ try {
188
+ catalog = await context.refreshCatalog();
189
+ if (context.observer === undefined) {
190
+ observer = createRealityObserver({
191
+ paths: context.paths,
192
+ catalog,
193
+ driver,
194
+ });
195
+ }
196
+ }
197
+ catch (error) {
198
+ stepResults.push({
199
+ stepRef: step.stepRef,
200
+ moduleRef: step.moduleRef,
201
+ status: "FAILED",
202
+ message: `post-package catalog refresh failed: ${failureMessage(error)}`,
203
+ });
204
+ state.updatedAt = nowIso();
205
+ await saveDeploymentState(context.paths, state);
206
+ return {
207
+ planRef: plan.planRef,
208
+ outcome: "FAILED",
209
+ stepResults,
210
+ completedAt: nowIso(),
211
+ };
212
+ }
213
+ }
171
214
  break;
172
215
  }
173
216
  case "ACTION_REQUIRED": {
@@ -65,6 +65,20 @@ export async function rebuildCurrentAssumptions(catalog, plan) {
65
65
  facts: diagnosis.facts,
66
66
  };
67
67
  }
68
+ if (plan.intent === "uninstall") {
69
+ // A persisted uninstall plan does not store uninstallScope. Recover the only
70
+ // legal scope from its module set for the staleness re-plan: any core module
71
+ // can only have entered the plan through whole-instance uninstall.
72
+ const uninstallScope = plan.resolvedModules.some((module) => module.installClass === "core")
73
+ ? "platform-instance"
74
+ : "module";
75
+ return {
76
+ intent: plan.intent,
77
+ modules,
78
+ targets: plan.moduleTargets,
79
+ uninstallScope,
80
+ };
81
+ }
68
82
  return {
69
83
  intent: plan.intent,
70
84
  modules,
@@ -20,4 +20,5 @@ export declare function workspaceResidentDriver(): PackageManagerDriver;
20
20
  export declare function createWorkspacePackageManagerDriver(options: {
21
21
  workspaceRoot: string;
22
22
  runner?: PackageCommandRunner;
23
+ executableAvailable?: (command: string) => boolean;
23
24
  }): PackageManagerDriver;
@@ -1,7 +1,7 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { PlatformError } from "../errors.js";
4
- import { readWorkspacePackageManagerSelection, systemPackageCommandRunner, } from "../install/package-manager.js";
4
+ import { findExecutable, readWorkspacePackageManagerSelection, systemPackageCommandRunner, } from "../install/package-manager.js";
5
5
  import { atomicWrite } from "../paths.js";
6
6
  /**
7
7
  * Monorepo/test seam retained for source-resident planning. Production CLI must
@@ -20,26 +20,27 @@ export function workspaceResidentDriver() {
20
20
  }
21
21
  export function createWorkspacePackageManagerDriver(options) {
22
22
  const runner = options.runner ?? systemPackageCommandRunner();
23
+ const executableAvailable = options.executableAvailable ?? findExecutable;
23
24
  return {
24
25
  observeInstalledVersion: (module) => observeInstalledVersion(options.workspaceRoot, module.packageName),
25
26
  install: async (module) => {
26
27
  await ensureWorkspacePackageJson(options.workspaceRoot);
27
- const manager = await requirePackageManager(options.workspaceRoot);
28
+ const manager = await requirePackageManager(options.workspaceRoot, executableAvailable);
28
29
  await mutatePackage(runner, manager, options.workspaceRoot, "install", `${module.packageName}@${module.moduleVersion}`);
29
30
  },
30
31
  upgrade: async (module) => {
31
32
  await ensureWorkspacePackageJson(options.workspaceRoot);
32
- const manager = await requirePackageManager(options.workspaceRoot);
33
+ const manager = await requirePackageManager(options.workspaceRoot, executableAvailable);
33
34
  await mutatePackage(runner, manager, options.workspaceRoot, "upgrade", `${module.packageName}@${module.moduleVersion}`);
34
35
  },
35
36
  remove: async (module) => {
36
- const manager = await requirePackageManager(options.workspaceRoot);
37
+ const manager = await requirePackageManager(options.workspaceRoot, executableAvailable);
37
38
  await mutatePackage(runner, manager, options.workspaceRoot, "remove", module.packageName);
38
39
  },
39
40
  };
40
41
  }
41
42
  async function mutatePackage(runner, manager, workspaceRoot, operation, packageSpec) {
42
- const args = packageManagerArgs(manager.name, operation, packageSpec);
43
+ const args = await packageManagerArgs(runner, manager, workspaceRoot, operation, packageSpec);
43
44
  try {
44
45
  await runner.run(manager.name, args, workspaceRoot);
45
46
  }
@@ -47,20 +48,47 @@ async function mutatePackage(runner, manager, workspaceRoot, operation, packageS
47
48
  throw new PlatformError(operation === "upgrade" ? "UPGRADE_FAILED" : "APPLY_FAILED", `${manager.name} ${operation} failed for ${packageSpec}: ${errorMessage(error)}`);
48
49
  }
49
50
  }
50
- function packageManagerArgs(manager, operation, packageSpec) {
51
- if (manager === "pnpm") {
51
+ async function packageManagerArgs(runner, manager, workspaceRoot, operation, packageSpec) {
52
+ if (manager.name === "pnpm") {
52
53
  return operation === "remove"
53
54
  ? ["remove", "--ignore-scripts", packageSpec]
54
55
  : ["add", "--save-exact", "--ignore-scripts", packageSpec];
55
56
  }
57
+ if (manager.name === "npm") {
58
+ return operation === "remove"
59
+ ? ["uninstall", "--ignore-scripts", packageSpec]
60
+ : ["install", "--save-exact", "--ignore-scripts", packageSpec];
61
+ }
62
+ const major = await yarnMajorVersion(runner, manager, workspaceRoot);
63
+ if (major <= 1) {
64
+ return operation === "remove"
65
+ ? ["remove", "--ignore-scripts", packageSpec]
66
+ : ["add", "--exact", "--ignore-scripts", packageSpec];
67
+ }
56
68
  return operation === "remove"
57
- ? ["uninstall", "--ignore-scripts", packageSpec]
58
- : ["install", "--save-exact", "--ignore-scripts", packageSpec];
69
+ ? ["remove", "--mode=skip-build", packageSpec]
70
+ : ["add", "--exact", "--mode=skip-build", packageSpec];
71
+ }
72
+ async function yarnMajorVersion(runner, manager, workspaceRoot) {
73
+ const declaredVersion = declaredPackageManagerVersion(manager.declared);
74
+ const value = declaredVersion ??
75
+ (await runner.run("yarn", ["--version"], workspaceRoot)).trim();
76
+ const major = Number.parseInt(value.split(".")[0] ?? "", 10);
77
+ if (!Number.isInteger(major) || major < 1) {
78
+ throw new PlatformError("PACKAGE_MANAGER_UNAVAILABLE", `cannot determine a supported Yarn major version from ${value || "<empty>"}`);
79
+ }
80
+ return major;
81
+ }
82
+ function declaredPackageManagerVersion(declared) {
83
+ if (declared === undefined)
84
+ return undefined;
85
+ const separator = declared.lastIndexOf("@");
86
+ return separator > 0 ? declared.slice(separator + 1) : undefined;
59
87
  }
60
- async function requirePackageManager(workspaceRoot) {
88
+ async function requirePackageManager(workspaceRoot, executableAvailable) {
61
89
  const manager = await readWorkspacePackageManagerSelection(workspaceRoot);
62
- if (manager === undefined) {
63
- throw new PlatformError("APPLY_FAILED", "workspace packageManager is not supported; expected npm or pnpm");
90
+ if (!executableAvailable(manager.name)) {
91
+ throw new PlatformError("PACKAGE_MANAGER_UNAVAILABLE", `workspace package manager ${manager.name} is not available on PATH`);
64
92
  }
65
93
  return manager;
66
94
  }
@@ -6,6 +6,29 @@ import { cleanupRemovableFilesystemEffects } from "./cleanup.js";
6
6
  function moduleOf(plan, step) {
7
7
  return plan.resolvedModules.find((module) => module.moduleRef === step.moduleRef);
8
8
  }
9
+ function moduleSourceForMaterialization(module) {
10
+ if (module.source.type === "registry") {
11
+ throw new PlatformError("APPLY_FAILED", `registry bootstrap target ${module.packageName} has no local config materializer`);
12
+ }
13
+ return {
14
+ type: module.source.type,
15
+ packageName: module.packageName,
16
+ ...(module.source.path === undefined ? {} : { path: module.source.path }),
17
+ };
18
+ }
19
+ async function materializeModuleOwnedConfig(deps, module, config) {
20
+ const namespace = await deps.catalog.loadAdapter(moduleSourceForMaterialization(module));
21
+ if (typeof namespace !== "object" || namespace === null)
22
+ return;
23
+ const materializer = Reflect.get(namespace, "materializeProductionConfig");
24
+ if (typeof materializer !== "function")
25
+ return;
26
+ await materializer({
27
+ moduleRef: module.moduleRef,
28
+ config: config.values,
29
+ workspaceRoot: deps.paths.root,
30
+ });
31
+ }
9
32
  function configForStep(plan, step, module) {
10
33
  const target = plan.moduleTargets.find((entry) => entry.moduleRef === step.moduleRef);
11
34
  if (target?.config === undefined)
@@ -98,6 +121,11 @@ export async function executeStep(deps, step, plan) {
98
121
  if (config === undefined) {
99
122
  throw new PlatformError("APPLY_FAILED", `module ${step.moduleRef} has no config target to materialize`);
100
123
  }
124
+ // The Platform-owned public config is authoritative apply reality. Do not
125
+ // commit it until the module-owned materializer has accepted the target;
126
+ // otherwise a failed materializer can leave a false-satisfied config step
127
+ // that a same-plan resume would incorrectly SKIP.
128
+ await materializeModuleOwnedConfig(deps, module, config);
101
129
  await materializeConfig(deps.paths, config);
102
130
  return { kind: "SUCCEEDED" };
103
131
  }
@@ -0,0 +1,69 @@
1
+ export declare const GLOBAL_BINDING_CONTRACT: "deployment.global-binding.v1";
2
+ export declare const WORKSPACE_INSTANCE_CONTRACT: "deployment.workspace-instance.v1";
3
+ export type GlobalBindingState = "INSTALLING" | "INSTALLED" | "UNINSTALLING" | "BROKEN";
4
+ export interface GlobalWorkspaceBinding {
5
+ contract: typeof GLOBAL_BINDING_CONTRACT;
6
+ state: GlobalBindingState;
7
+ workspacePath: string;
8
+ workspaceRealPath: string;
9
+ workspaceInstanceId: string;
10
+ createdAt: string;
11
+ updatedAt: string;
12
+ failure?: {
13
+ code: string;
14
+ message: string;
15
+ };
16
+ }
17
+ export interface WorkspaceInstanceMarker {
18
+ contract: typeof WORKSPACE_INSTANCE_CONTRACT;
19
+ workspaceInstanceId: string;
20
+ workspaceRealPath: string;
21
+ createdAt: string;
22
+ }
23
+ export interface GlobalPlatformPaths {
24
+ root: string;
25
+ bindingJson: string;
26
+ bindingLock: string;
27
+ operationLock: string;
28
+ }
29
+ export interface BoundWorkspaceObservation {
30
+ binding: GlobalWorkspaceBinding;
31
+ workspaceExists: boolean;
32
+ }
33
+ export interface GlobalBindingLockHandle {
34
+ release(): Promise<void>;
35
+ }
36
+ export declare function globalPlatformPaths(globalRoot?: string): GlobalPlatformPaths;
37
+ export declare function canonicalizeWorkspace(workspace: string): Promise<{
38
+ workspacePath: string;
39
+ workspaceRealPath: string;
40
+ }>;
41
+ export declare function loadGlobalBinding(globalRoot?: string): Promise<GlobalWorkspaceBinding | undefined>;
42
+ export declare function observeBoundWorkspace(globalRoot?: string): Promise<BoundWorkspaceObservation | undefined>;
43
+ export declare function requireBoundWorkspace(globalRoot?: string): Promise<GlobalWorkspaceBinding>;
44
+ export declare function claimWorkspaceBinding(options: {
45
+ workspace: string;
46
+ globalRoot?: string | undefined;
47
+ }): Promise<{
48
+ binding: GlobalWorkspaceBinding;
49
+ alreadyBound: boolean;
50
+ }>;
51
+ export declare function updateGlobalBindingState(options: {
52
+ workspaceInstanceId: string;
53
+ state: GlobalBindingState;
54
+ globalRoot?: string | undefined;
55
+ failure?: {
56
+ code: string;
57
+ message: string;
58
+ };
59
+ }): Promise<GlobalWorkspaceBinding>;
60
+ export declare function clearGlobalBinding(options: {
61
+ workspaceInstanceId: string;
62
+ globalRoot?: string | undefined;
63
+ removeWorkspaceMarker?: boolean;
64
+ }): Promise<void>;
65
+ export declare function forgetMissingWorkspaceBinding(options: {
66
+ globalRoot?: string | undefined;
67
+ }): Promise<GlobalWorkspaceBinding>;
68
+ export declare function acquireGlobalBindingLock(paths: GlobalPlatformPaths): Promise<GlobalBindingLockHandle>;
69
+ export declare function acquireGlobalOperationLock(globalRoot?: string): Promise<GlobalBindingLockHandle>;