@hasna/machines 0.0.18 → 0.0.20

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/dist/consumer.js CHANGED
@@ -4212,6 +4212,7 @@ var machineSchema = exports_external.object({
4212
4212
  workspacePath: exports_external.string(),
4213
4213
  bunPath: exports_external.string().optional(),
4214
4214
  tags: exports_external.array(exports_external.string()).optional(),
4215
+ metadata: exports_external.record(exports_external.unknown()).optional(),
4215
4216
  packages: exports_external.array(packageSchema).optional(),
4216
4217
  apps: exports_external.array(appSchema).optional(),
4217
4218
  files: exports_external.array(fileSchema).optional()
@@ -4310,6 +4311,40 @@ function getPackageVersion() {
4310
4311
  // src/topology.ts
4311
4312
  var MACHINES_CONSUMER_CONTRACT_VERSION = 1;
4312
4313
  var MACHINES_PACKAGE_NAME = "@hasna/machines";
4314
+ var MACHINES_CONSUMER_ENTRYPOINT = "@hasna/machines/consumer";
4315
+ var MACHINES_CONSUMER_CAPABILITIES = {
4316
+ topology: true,
4317
+ compatibility: true,
4318
+ route_resolution: true,
4319
+ cli_json_fallback: true,
4320
+ workspace_path_mapping: true
4321
+ };
4322
+ var MACHINES_CONSUMER_CONTRACT = {
4323
+ schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
4324
+ package_name: MACHINES_PACKAGE_NAME,
4325
+ entrypoint: MACHINES_CONSUMER_ENTRYPOINT,
4326
+ capabilities: MACHINES_CONSUMER_CAPABILITIES,
4327
+ envelopes: ["topology", "route", "workspace", "compatibility"],
4328
+ stable_exports: [
4329
+ "MACHINES_CONSUMER_CONTRACT",
4330
+ "MACHINES_CONSUMER_CONTRACT_VERSION",
4331
+ "MACHINES_CONSUMER_CAPABILITIES",
4332
+ "MACHINES_PACKAGE_NAME",
4333
+ "discoverMachineTopology",
4334
+ "getLocalMachineTopology",
4335
+ "resolveMachineRoute",
4336
+ "resolveMachineWorkspace",
4337
+ "checkMachineCompatibility",
4338
+ "resolveMachineCommand",
4339
+ "runMachineCommand",
4340
+ "buildSshCommand",
4341
+ "resolveSshTarget",
4342
+ "getPackageVersion"
4343
+ ]
4344
+ };
4345
+ function getMachinesConsumerCapabilities() {
4346
+ return { ...MACHINES_CONSUMER_CAPABILITIES };
4347
+ }
4313
4348
  function normalizePlatform2(value = platform2()) {
4314
4349
  const normalized = value.toLowerCase();
4315
4350
  if (normalized === "darwin" || normalized === "macos")
@@ -4510,12 +4545,7 @@ function discoverMachineTopology(options = {}) {
4510
4545
  name: MACHINES_PACKAGE_NAME,
4511
4546
  version: getPackageVersion()
4512
4547
  },
4513
- capabilities: {
4514
- topology: true,
4515
- compatibility: true,
4516
- route_resolution: true,
4517
- cli_json_fallback: true
4518
- },
4548
+ capabilities: getMachinesConsumerCapabilities(),
4519
4549
  generated_at: now.toISOString(),
4520
4550
  local_machine_id: localMachineId,
4521
4551
  local_hostname: hostname3(),
@@ -4639,6 +4669,215 @@ function resolveMachineRoute(machineId, options = {}) {
4639
4669
  warnings
4640
4670
  };
4641
4671
  }
4672
+ function isRecord(value) {
4673
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4674
+ }
4675
+ function metadataString(metadata, keys) {
4676
+ for (const key of keys) {
4677
+ const value = metadata[key];
4678
+ if (typeof value === "string" && value.trim())
4679
+ return value.trim();
4680
+ }
4681
+ return null;
4682
+ }
4683
+ function metadataBoolean(metadata, keys) {
4684
+ for (const key of keys) {
4685
+ const value = metadata[key];
4686
+ if (typeof value === "boolean")
4687
+ return value;
4688
+ }
4689
+ return null;
4690
+ }
4691
+ function metadataStringArray(metadata, keys) {
4692
+ for (const key of keys) {
4693
+ const value = metadata[key];
4694
+ if (Array.isArray(value))
4695
+ return value.filter((entry) => typeof entry === "string");
4696
+ }
4697
+ return [];
4698
+ }
4699
+ function readMappedPath(input) {
4700
+ for (const containerName of input.containers) {
4701
+ const container = input.metadata[containerName];
4702
+ if (!isRecord(container))
4703
+ continue;
4704
+ for (const key of input.keys) {
4705
+ const value = container[key];
4706
+ if (typeof value === "string" && value.trim())
4707
+ return value.trim();
4708
+ if (isRecord(value)) {
4709
+ const path = metadataString(value, ["path", "root", "workspacePath", "workspace_path"]);
4710
+ if (path)
4711
+ return path;
4712
+ }
4713
+ }
4714
+ }
4715
+ return null;
4716
+ }
4717
+ function trimTrailingSlash(value) {
4718
+ return value.replace(/\/+$/, "");
4719
+ }
4720
+ function joinPath(left, right) {
4721
+ return `${trimTrailingSlash(left)}/${right.replace(/^\/+/, "")}`;
4722
+ }
4723
+ function inferRepoRoot(workspaceRoot, repoName) {
4724
+ if (!workspaceRoot || !repoName)
4725
+ return null;
4726
+ const root = trimTrailingSlash(workspaceRoot);
4727
+ if (root.endsWith(`/${repoName}`) || root === repoName)
4728
+ return root;
4729
+ if (root.endsWith("/workspace") || root.endsWith("/Workspace")) {
4730
+ return joinPath(root, `hasna/opensource/${repoName}`);
4731
+ }
4732
+ return joinPath(root, repoName);
4733
+ }
4734
+ function projectPathFromMetadata(metadata, projectId, repoName) {
4735
+ const keys = [projectId, repoName].filter((value) => Boolean(value));
4736
+ return readMappedPath({
4737
+ metadata,
4738
+ containers: ["workspace_paths", "workspacePaths", "repo_paths", "repoPaths", "project_paths", "projectPaths", "projects"],
4739
+ keys
4740
+ });
4741
+ }
4742
+ function openFilesPathFromMetadata(metadata, projectId, repoName) {
4743
+ const direct = metadataString(metadata, ["open_files_root", "openFilesRoot", "open_files_path", "openFilesPath"]);
4744
+ if (direct)
4745
+ return direct;
4746
+ const keys = [projectId, repoName, "open-files", "open_files", "default"].filter((value) => Boolean(value));
4747
+ return readMappedPath({
4748
+ metadata,
4749
+ containers: ["open_files_roots", "openFilesRoots", "open_files_paths", "openFilesPaths"],
4750
+ keys
4751
+ });
4752
+ }
4753
+ function trustStatus(machine) {
4754
+ if (!machine)
4755
+ return "unknown";
4756
+ const explicit = metadataString(machine.metadata, ["trust_status", "trustStatus"]);
4757
+ if (explicit === "trusted" || explicit === "untrusted" || explicit === "unknown")
4758
+ return explicit;
4759
+ const trusted = metadataBoolean(machine.metadata, ["trusted", "syncTrusted", "sync_trusted"]);
4760
+ if (trusted === true)
4761
+ return "trusted";
4762
+ if (trusted === false)
4763
+ return "untrusted";
4764
+ if (machine.route_hints.some((hint) => hint.kind === "local"))
4765
+ return "trusted";
4766
+ if (machine.tags.includes("trusted"))
4767
+ return "trusted";
4768
+ return "unknown";
4769
+ }
4770
+ function authStatus(machine) {
4771
+ if (!machine)
4772
+ return "unknown";
4773
+ const explicit = metadataString(machine.metadata, ["auth_status", "authStatus"]);
4774
+ if (explicit === "authenticated" || explicit === "unauthenticated" || explicit === "unknown")
4775
+ return explicit;
4776
+ const authenticated = metadataBoolean(machine.metadata, ["authenticated", "sshAuthorized", "ssh_authorized"]);
4777
+ if (authenticated === true)
4778
+ return "authenticated";
4779
+ if (authenticated === false)
4780
+ return "unauthenticated";
4781
+ if (machine.route_hints.some((hint) => hint.kind === "local"))
4782
+ return "authenticated";
4783
+ return "unknown";
4784
+ }
4785
+ function primaryMachine(machine, projectId, primaryMachineId) {
4786
+ if (!machine)
4787
+ return false;
4788
+ if (primaryMachineId)
4789
+ return machine.machine_id === primaryMachineId;
4790
+ if (metadataBoolean(machine.metadata, ["primary", "primary_machine", "primaryMachine"]) === true)
4791
+ return true;
4792
+ const primaryProjects = metadataStringArray(machine.metadata, ["primary_projects", "primaryProjects"]);
4793
+ if (primaryProjects.includes(projectId))
4794
+ return true;
4795
+ return machine.tags.includes("primary");
4796
+ }
4797
+ function metadataKeysForDiagnostics(metadata) {
4798
+ return Object.keys(metadata).filter((key) => !/(secret|token|key|password|credential)/i.test(key)).sort();
4799
+ }
4800
+ function resolveMachineWorkspace(options) {
4801
+ const topology = options.topology ?? discoverMachineTopology(options);
4802
+ const warnings = [...topology.warnings];
4803
+ const { machine, matchedBy } = findRouteMachine(topology, options.machineId);
4804
+ const generatedAt = (options.now ?? new Date).toISOString();
4805
+ const repoName = options.repoName ?? options.projectId;
4806
+ const openFilesRepoName = options.openFilesRepoName ?? "open-files";
4807
+ if (!machine) {
4808
+ warnings.push(`machine_not_found:${options.machineId}`);
4809
+ return {
4810
+ schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
4811
+ package: topology.package,
4812
+ ok: false,
4813
+ requested_machine_id: options.machineId,
4814
+ machine_id: null,
4815
+ generated_at: generatedAt,
4816
+ project: { project_id: options.projectId, repo_name: repoName, canonical: Boolean(options.projectId) },
4817
+ machine: { current: false, primary: false, trust_status: "unknown", auth_status: "unknown" },
4818
+ paths: {
4819
+ workspace_root: { path: null, source: "unresolved" },
4820
+ project_root: { path: null, source: "unresolved" },
4821
+ open_files_root: { path: null, source: "unresolved" }
4822
+ },
4823
+ evidence: {
4824
+ topology: true,
4825
+ matched_by: matchedBy,
4826
+ manifest_declared: null,
4827
+ metadata_keys: []
4828
+ },
4829
+ warnings
4830
+ };
4831
+ }
4832
+ const metadata = machine.metadata;
4833
+ const workspaceRootPath = options.workspaceRoot ?? machine.workspace_path;
4834
+ const workspaceRootSource = options.workspaceRoot ? "argument" : machine.workspace_path ? "manifest" : "unresolved";
4835
+ const metadataProjectRoot = projectPathFromMetadata(metadata, options.projectId, repoName);
4836
+ const inferredProjectRoot = inferRepoRoot(workspaceRootPath, repoName);
4837
+ const projectRootPath = options.projectRoot ?? metadataProjectRoot ?? inferredProjectRoot;
4838
+ const projectRootSource = options.projectRoot ? "argument" : metadataProjectRoot ? "manifest_metadata" : inferredProjectRoot ? "inferred" : "unresolved";
4839
+ const metadataOpenFilesRoot = openFilesPathFromMetadata(metadata, options.projectId, openFilesRepoName);
4840
+ const inferredOpenFilesRoot = inferRepoRoot(workspaceRootPath, openFilesRepoName);
4841
+ const openFilesRootPath = options.openFilesRoot ?? metadataOpenFilesRoot ?? inferredOpenFilesRoot;
4842
+ const openFilesRootSource = options.openFilesRoot ? "argument" : metadataOpenFilesRoot ? "manifest_metadata" : inferredOpenFilesRoot ? "inferred" : "unresolved";
4843
+ if (projectRootSource === "inferred")
4844
+ warnings.push(`project_root_inferred:${options.projectId}`);
4845
+ if (openFilesRootSource === "inferred")
4846
+ warnings.push(`open_files_root_inferred:${options.projectId}`);
4847
+ if (!projectRootPath)
4848
+ warnings.push(`project_root_unresolved:${options.projectId}`);
4849
+ return {
4850
+ schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
4851
+ package: topology.package,
4852
+ ok: Boolean(projectRootPath),
4853
+ requested_machine_id: options.machineId,
4854
+ machine_id: machine.machine_id,
4855
+ generated_at: generatedAt,
4856
+ project: {
4857
+ project_id: options.projectId,
4858
+ repo_name: repoName,
4859
+ canonical: Boolean(options.projectId && repoName)
4860
+ },
4861
+ machine: {
4862
+ current: machine.machine_id === topology.local_machine_id,
4863
+ primary: primaryMachine(machine, options.projectId, options.primaryMachineId),
4864
+ trust_status: trustStatus(machine),
4865
+ auth_status: authStatus(machine)
4866
+ },
4867
+ paths: {
4868
+ workspace_root: { path: workspaceRootPath, source: workspaceRootSource },
4869
+ project_root: { path: projectRootPath, source: projectRootSource },
4870
+ open_files_root: { path: openFilesRootPath, source: openFilesRootSource }
4871
+ },
4872
+ evidence: {
4873
+ topology: true,
4874
+ matched_by: matchedBy,
4875
+ manifest_declared: machine.manifest_declared,
4876
+ metadata_keys: metadataKeysForDiagnostics(metadata)
4877
+ },
4878
+ warnings
4879
+ };
4880
+ }
4642
4881
  function getLocalMachineTopology(options = {}) {
4643
4882
  const topology = discoverMachineTopology(options);
4644
4883
  return topology.machines.find((machine) => machine.machine_id === topology.local_machine_id) ?? {
@@ -4957,12 +5196,7 @@ function checkMachineCompatibility(options = {}) {
4957
5196
  name: MACHINES_PACKAGE_NAME,
4958
5197
  version: getPackageVersion()
4959
5198
  },
4960
- capabilities: {
4961
- topology: true,
4962
- compatibility: true,
4963
- route_resolution: true,
4964
- cli_json_fallback: true
4965
- },
5199
+ capabilities: getMachinesConsumerCapabilities(),
4966
5200
  ok: summary.fail === 0,
4967
5201
  machine_id: machineId,
4968
5202
  source: checks[0]?.source ?? "local",
@@ -4974,13 +5208,18 @@ function checkMachineCompatibility(options = {}) {
4974
5208
  export {
4975
5209
  runMachineCommand,
4976
5210
  resolveSshTarget,
5211
+ resolveMachineWorkspace,
4977
5212
  resolveMachineRoute,
4978
5213
  resolveMachineCommand,
4979
5214
  getPackageVersion,
5215
+ getMachinesConsumerCapabilities,
4980
5216
  getLocalMachineTopology,
4981
5217
  discoverMachineTopology,
4982
5218
  checkMachineCompatibility,
4983
5219
  buildSshCommand,
4984
5220
  MACHINES_PACKAGE_NAME,
4985
- MACHINES_CONSUMER_CONTRACT_VERSION
5221
+ MACHINES_CONSUMER_ENTRYPOINT,
5222
+ MACHINES_CONSUMER_CONTRACT_VERSION,
5223
+ MACHINES_CONSUMER_CONTRACT,
5224
+ MACHINES_CONSUMER_CAPABILITIES
4986
5225
  };