@slock-ai/computer 0.0.33 → 0.0.35

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/index.js CHANGED
@@ -29724,7 +29724,7 @@ var ComputerAttachClient = class {
29724
29724
  };
29725
29725
  }
29726
29726
  if (res.status === 401) return { status: "error", code: "session_invalid" };
29727
- if (res.status === 403) return { status: "not_authorized" };
29727
+ if (res.status === 403) return code === "requires_admin" ? { status: "requires_admin" } : { status: "not_authorized" };
29728
29728
  if (res.status === 404) {
29729
29729
  if (code === "not_authorized" || code === "server_not_found") return { status: "server_not_found" };
29730
29730
  if (!code || code === "computer_attach_disabled") return { status: "disabled" };
@@ -29768,7 +29768,7 @@ var ComputerAttachClient = class {
29768
29768
  if (res.status === 409 && code === "legacy_machine_key_migrated") {
29769
29769
  return { status: "legacy_machine_key_migrated" };
29770
29770
  }
29771
- if (res.status === 403) return { status: "not_authorized" };
29771
+ if (res.status === 403) return code === "requires_admin" ? { status: "requires_admin" } : { status: "not_authorized" };
29772
29772
  if (res.status === 404) return { status: "disabled" };
29773
29773
  if (!code) return { status: "unexpected_response", httpStatus: res.status };
29774
29774
  return { status: "error", code };
@@ -29813,7 +29813,7 @@ var ComputerAttachClient = class {
29813
29813
  if (res.status === 409 && code === "legacy_machine_key_migrated") {
29814
29814
  return { status: "legacy_machine_key_migrated" };
29815
29815
  }
29816
- if (res.status === 403) return { status: "not_authorized" };
29816
+ if (res.status === 403) return code === "requires_admin" ? { status: "requires_admin" } : { status: "not_authorized" };
29817
29817
  if (res.status === 404) return { status: "disabled" };
29818
29818
  if (!code) return { status: "unexpected_response", httpStatus: res.status };
29819
29819
  return { status: "error", code };
@@ -30381,6 +30381,12 @@ async function attach(input, options = {}) {
30381
30381
  "Not authorized to attach to that server. Check the server slug and that you're a member."
30382
30382
  );
30383
30383
  }
30384
+ if (attached.status === "requires_admin") {
30385
+ throw new ComputerServiceError(
30386
+ "ATTACH_REQUIRES_ADMIN",
30387
+ "Attaching a Computer requires the admin or owner role on this server. You are a member, but only admins/owners can attach \u2014 ask a server admin to attach this Computer or to grant you the admin role."
30388
+ );
30389
+ }
30384
30390
  if (attached.status === "server_not_found") {
30385
30391
  throw new ComputerServiceError(
30386
30392
  "ATTACH_SERVER_NOT_FOUND",
@@ -30827,6 +30833,13 @@ async function completeAdoptionExchange(input, options) {
30827
30833
  "Not authorized to adopt this machine on this server. Check that you are a current member."
30828
30834
  );
30829
30835
  }
30836
+ if (result.status === "requires_admin") {
30837
+ await appendAdoptionFailureLog(slockHome, log, startedAt, "requires_admin");
30838
+ throw new ComputerServiceError(
30839
+ "ADOPT_REQUIRES_ADMIN",
30840
+ "Adopting a legacy machine into a Computer requires the admin or owner role on this server. You are a member, but holding the legacy machine key is not enough \u2014 ask a server admin to adopt it or to grant you the admin role."
30841
+ );
30842
+ }
30830
30843
  if (result.status === "unexpected_response") {
30831
30844
  await appendAdoptionFailureLog(
30832
30845
  slockHome,
@@ -48,6 +48,30 @@ type LegacyMachineRosterResult = {
48
48
  status: "error";
49
49
  code: string;
50
50
  };
51
+ /** A server the user belongs to. `role` mirrors the server-side
52
+ * `server_members.role` enum (`owner | admin | member`). */
53
+ interface UserServerEntry {
54
+ id: string;
55
+ name: string;
56
+ slug: string;
57
+ role: "owner" | "admin" | "member";
58
+ }
59
+ type UserServersResult = {
60
+ status: "success";
61
+ servers: UserServerEntry[];
62
+ } | {
63
+ status: "auth_required";
64
+ } | {
65
+ status: "error";
66
+ code: string;
67
+ };
68
+ declare class ServersClient {
69
+ private readonly baseUrl;
70
+ private readonly accessToken;
71
+ constructor(baseUrl: string, accessToken: string);
72
+ private url;
73
+ list(): Promise<UserServersResult>;
74
+ }
51
75
  declare class LegacyMachinesClient {
52
76
  private readonly baseUrl;
53
77
  private readonly accessToken;
@@ -652,4 +676,4 @@ interface UpgradeLogEntryErr {
652
676
  */
653
677
  declare function assertUpgradeLogEntry(entry: UpgradeLogEntry): void;
654
678
 
655
- export { type ComputerStatusReport, type ConnectService, type ConnectServiceOptions, type DaemonState, IPC_ERROR_CODES, type IpcErrorCode, type LegacyMachineCandidate, type LegacyMachineRosterClient, type LegacyMachineRosterEntry, type LegacyMachineRosterResult, LegacyMachinesClient, type ListRunnersResult, MIGRATION_DETECTION_KINDS, MIGRATION_FRESH_TRIGGERS, type ManualPathValidation, type MigrationDetection, type MigrationDetectionKind, type MigrationFreshTrigger, type PickerSelection, RUNNER_STATE_VALUES, type RequestMethodMap, type RequestOptions, type ResetRunnerResult, type ResetServiceResult, type RunnerListItem as RunnerInfo, type RunnerListPerServer, type RunnerState, type RunnerStatusResult, SERVICE_STATE_VALUES, STATE_READER_ERROR_CODES, type ServerHealth, type ServerStatusRow, type ServiceClient, ServiceClientError, type ServiceEvent, type ServiceState, type ServiceStatusResult, StateReaderError, type StateReaderErrorCode, UPGRADE_ERROR_CODES, type UpgradeBundle, type UpgradeErrorCode, type UpgradeLogEntry, type UpgradeLogEntryErr, type UpgradeLogEntryOk, type UpgradeStartResult, type UpgradeTrigger, assertUpgradeLogEntry, detectLegacyMigration, isIpcErrorCode, isMigrationDetectionKind, isRunnerState, isServiceState, listRunners, pickMigrationCandidateFromInput, readRunnerStatus, readServiceStatus, validateManualMigratePath };
679
+ export { type ComputerStatusReport, type ConnectService, type ConnectServiceOptions, type DaemonState, IPC_ERROR_CODES, type IpcErrorCode, type LegacyMachineCandidate, type LegacyMachineRosterClient, type LegacyMachineRosterEntry, type LegacyMachineRosterResult, LegacyMachinesClient, type ListRunnersResult, MIGRATION_DETECTION_KINDS, MIGRATION_FRESH_TRIGGERS, type ManualPathValidation, type MigrationDetection, type MigrationDetectionKind, type MigrationFreshTrigger, type PickerSelection, RUNNER_STATE_VALUES, type RequestMethodMap, type RequestOptions, type ResetRunnerResult, type ResetServiceResult, type RunnerListItem as RunnerInfo, type RunnerListPerServer, type RunnerState, type RunnerStatusResult, SERVICE_STATE_VALUES, STATE_READER_ERROR_CODES, type ServerHealth, type ServerStatusRow, ServersClient, type ServiceClient, ServiceClientError, type ServiceEvent, type ServiceState, type ServiceStatusResult, StateReaderError, type StateReaderErrorCode, UPGRADE_ERROR_CODES, type UpgradeBundle, type UpgradeErrorCode, type UpgradeLogEntry, type UpgradeLogEntryErr, type UpgradeLogEntryOk, type UpgradeStartResult, type UpgradeTrigger, type UserServerEntry, type UserServersResult, assertUpgradeLogEntry, detectLegacyMigration, isIpcErrorCode, isMigrationDetectionKind, isRunnerState, isServiceState, listRunners, pickMigrationCandidateFromInput, readRunnerStatus, readServiceStatus, validateManualMigratePath };
package/dist/lib/index.js CHANGED
@@ -189,6 +189,50 @@ async function firstReadableOwner(paths) {
189
189
 
190
190
  // src/apiClient.ts
191
191
  import { fetch } from "undici";
192
+ var ServersClient = class {
193
+ constructor(baseUrl, accessToken) {
194
+ this.baseUrl = baseUrl;
195
+ this.accessToken = accessToken;
196
+ }
197
+ url(p) {
198
+ return new URL(p, this.baseUrl).toString();
199
+ }
200
+ async list() {
201
+ let res;
202
+ try {
203
+ res = await fetch(this.url("/api/servers/"), {
204
+ method: "GET",
205
+ headers: { Authorization: `Bearer ${this.accessToken}` }
206
+ });
207
+ } catch {
208
+ return { status: "error", code: "request_failed" };
209
+ }
210
+ if (res.status === 401) return { status: "auth_required" };
211
+ const body = await res.json().catch(() => null);
212
+ if (res.status === 200 && Array.isArray(body)) {
213
+ const servers = body.map((raw) => {
214
+ if (!raw || typeof raw !== "object") return null;
215
+ const e = raw;
216
+ if (typeof e.id !== "string" || typeof e.slug !== "string" || typeof e.role !== "string") {
217
+ return null;
218
+ }
219
+ if (e.role !== "owner" && e.role !== "admin" && e.role !== "member") {
220
+ return null;
221
+ }
222
+ return {
223
+ id: e.id,
224
+ name: typeof e.name === "string" ? e.name : e.slug,
225
+ slug: e.slug,
226
+ role: e.role
227
+ };
228
+ }).filter((entry) => entry !== null);
229
+ return { status: "success", servers };
230
+ }
231
+ const errBody = body;
232
+ const code = errBody && typeof errBody.code === "string" ? errBody.code : `http_${res.status}`;
233
+ return { status: "error", code };
234
+ }
235
+ };
192
236
  var LegacyMachinesClient = class {
193
237
  constructor(baseUrl, accessToken) {
194
238
  this.baseUrl = baseUrl;
@@ -796,6 +840,7 @@ export {
796
840
  RUNNER_STATE_VALUES,
797
841
  SERVICE_STATE_VALUES,
798
842
  STATE_READER_ERROR_CODES,
843
+ ServersClient,
799
844
  ServiceClientError,
800
845
  StateReaderError,
801
846
  UPGRADE_ERROR_CODES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slock-ai/computer",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "description": "Slock Computer — standalone human/local-machine control-plane CLI (login + attach). Distinct from the agent-facing @slock-ai/cli.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -28,7 +28,7 @@
28
28
  "commander": "^12.1.0",
29
29
  "proper-lockfile": "^4.1.2",
30
30
  "undici": "^7.24.7",
31
- "@slock-ai/daemon": "0.57.2"
31
+ "@slock-ai/daemon": "0.57.5"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^25.5.0",