@semilayer/cli 1.1.0

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 (73) hide show
  1. package/dist/auth-config-3MWVCUTJ.js +117 -0
  2. package/dist/auth-config-3MWVCUTJ.js.map +1 -0
  3. package/dist/billing-OY5GJP5X.js +265 -0
  4. package/dist/billing-OY5GJP5X.js.map +1 -0
  5. package/dist/bin.d.ts +2 -0
  6. package/dist/bin.js +49 -0
  7. package/dist/bin.js.map +1 -0
  8. package/dist/chunk-7TA63VHV.js +38 -0
  9. package/dist/chunk-7TA63VHV.js.map +1 -0
  10. package/dist/chunk-ALA4X7UU.js +19 -0
  11. package/dist/chunk-ALA4X7UU.js.map +1 -0
  12. package/dist/chunk-NIDLPHWY.js +53 -0
  13. package/dist/chunk-NIDLPHWY.js.map +1 -0
  14. package/dist/chunk-QMF7LD67.js +39 -0
  15. package/dist/chunk-QMF7LD67.js.map +1 -0
  16. package/dist/chunk-QXIVJY7K.js +56 -0
  17. package/dist/chunk-QXIVJY7K.js.map +1 -0
  18. package/dist/chunk-T3UROBMA.js +169 -0
  19. package/dist/chunk-T3UROBMA.js.map +1 -0
  20. package/dist/chunk-WZYOSGN3.js +88 -0
  21. package/dist/chunk-WZYOSGN3.js.map +1 -0
  22. package/dist/config-DACYO7JC.js +103 -0
  23. package/dist/config-DACYO7JC.js.map +1 -0
  24. package/dist/dev-R3AZSONQ.js +57 -0
  25. package/dist/dev-R3AZSONQ.js.map +1 -0
  26. package/dist/envs-RNZQ3OQP.js +105 -0
  27. package/dist/envs-RNZQ3OQP.js.map +1 -0
  28. package/dist/export-YRFR3JH2.js +81 -0
  29. package/dist/export-YRFR3JH2.js.map +1 -0
  30. package/dist/generate-QUETX3TN.js +41 -0
  31. package/dist/generate-QUETX3TN.js.map +1 -0
  32. package/dist/index.d.ts +43 -0
  33. package/dist/index.js +34 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/init-TWJAGUN3.js +187 -0
  36. package/dist/init-TWJAGUN3.js.map +1 -0
  37. package/dist/keys-JBKCYKJU.js +111 -0
  38. package/dist/keys-JBKCYKJU.js.map +1 -0
  39. package/dist/lenses-VZSDFH3D.js +51 -0
  40. package/dist/lenses-VZSDFH3D.js.map +1 -0
  41. package/dist/login-BZ6ZPFHC.js +119 -0
  42. package/dist/login-BZ6ZPFHC.js.map +1 -0
  43. package/dist/logout-VMPRV62T.js +38 -0
  44. package/dist/logout-VMPRV62T.js.map +1 -0
  45. package/dist/members-DVE5FDLZ.js +110 -0
  46. package/dist/members-DVE5FDLZ.js.map +1 -0
  47. package/dist/observe-W346RZBX.js +149 -0
  48. package/dist/observe-W346RZBX.js.map +1 -0
  49. package/dist/orgs-YA3TVA3T.js +67 -0
  50. package/dist/orgs-YA3TVA3T.js.map +1 -0
  51. package/dist/pause-GQ6PKBUA.js +50 -0
  52. package/dist/pause-GQ6PKBUA.js.map +1 -0
  53. package/dist/projects-DMA2AXH3.js +107 -0
  54. package/dist/projects-DMA2AXH3.js.map +1 -0
  55. package/dist/push-3ZK3W2AC.js +145 -0
  56. package/dist/push-3ZK3W2AC.js.map +1 -0
  57. package/dist/resume-KVRPLXZZ.js +50 -0
  58. package/dist/resume-KVRPLXZZ.js.map +1 -0
  59. package/dist/run-IR5B4AE3.js +375 -0
  60. package/dist/run-IR5B4AE3.js.map +1 -0
  61. package/dist/sources-S52HUWRK.js +170 -0
  62. package/dist/sources-S52HUWRK.js.map +1 -0
  63. package/dist/status-AUECH6RX.js +130 -0
  64. package/dist/status-AUECH6RX.js.map +1 -0
  65. package/dist/stream-V7RGHTPR.js +344 -0
  66. package/dist/stream-V7RGHTPR.js.map +1 -0
  67. package/dist/sync-NRTC3WX4.js +68 -0
  68. package/dist/sync-NRTC3WX4.js.map +1 -0
  69. package/dist/whoami-EQGW6V5D.js +50 -0
  70. package/dist/whoami-EQGW6V5D.js.map +1 -0
  71. package/dist/wizard-QLAR33T2.js +306 -0
  72. package/dist/wizard-QLAR33T2.js.map +1 -0
  73. package/package.json +40 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadContext
4
+ } from "./chunk-QMF7LD67.js";
5
+ import {
6
+ saveCredentials
7
+ } from "./chunk-7TA63VHV.js";
8
+ import {
9
+ error,
10
+ info,
11
+ success
12
+ } from "./chunk-WZYOSGN3.js";
13
+
14
+ // src/commands/login.ts
15
+ import { defineCommand } from "citty";
16
+
17
+ // src/lib/server.ts
18
+ import { createServer } from "http";
19
+ import { URL } from "url";
20
+ function startCallbackServer(port, timeoutMs = 6e4) {
21
+ let resolve;
22
+ let reject;
23
+ const promise = new Promise((res, rej) => {
24
+ resolve = res;
25
+ reject = rej;
26
+ });
27
+ const server = createServer((req, res) => {
28
+ const url = new URL(req.url ?? "/", `http://localhost:${port}`);
29
+ if (url.pathname === "/callback") {
30
+ const accessToken = url.searchParams.get("access_token");
31
+ const refreshToken = url.searchParams.get("refresh_token");
32
+ if (accessToken && refreshToken) {
33
+ res.writeHead(200, { "Content-Type": "text/html" });
34
+ res.end(
35
+ "<html><body><h2>Logged in! You can close this tab.</h2></body></html>"
36
+ );
37
+ resolve({ accessToken, refreshToken });
38
+ } else {
39
+ res.writeHead(400, { "Content-Type": "text/html" });
40
+ res.end("<html><body><h2>Login failed \u2014 missing tokens.</h2></body></html>");
41
+ reject(new Error("Callback missing access_token or refresh_token"));
42
+ }
43
+ } else {
44
+ res.writeHead(404);
45
+ res.end();
46
+ }
47
+ });
48
+ const timeout = setTimeout(() => {
49
+ server.close();
50
+ reject(new Error("Login timed out. Try again."));
51
+ }, timeoutMs);
52
+ promise.finally(() => {
53
+ clearTimeout(timeout);
54
+ server.close();
55
+ });
56
+ server.listen(port, "127.0.0.1");
57
+ return { promise, server };
58
+ }
59
+ async function findAvailablePort() {
60
+ const { createServer: createNet } = await import("net");
61
+ for (let port = 9876; port <= 9899; port++) {
62
+ const available = await new Promise((resolve) => {
63
+ const srv = createNet();
64
+ srv.once("error", () => resolve(false));
65
+ srv.listen(port, "127.0.0.1", () => {
66
+ srv.close(() => resolve(true));
67
+ });
68
+ });
69
+ if (available) return port;
70
+ }
71
+ throw new Error("No available port found in range 9876-9899");
72
+ }
73
+
74
+ // src/commands/login.ts
75
+ var login_default = defineCommand({
76
+ meta: { name: "login", description: "Authenticate with the SemiLayer service" },
77
+ args: {
78
+ "service-url": {
79
+ type: "string",
80
+ description: "Service API URL"
81
+ }
82
+ },
83
+ async run({ args }) {
84
+ const ctx = await loadContext();
85
+ const serviceUrl = args["service-url"] || ctx?.serviceUrl || "https://api.semilayer.com";
86
+ const port = await findAvailablePort();
87
+ const redirectUri = `http://localhost:${port}/callback`;
88
+ const loginUrl = `${serviceUrl}/auth/login?app=cli&redirect=${encodeURIComponent(redirectUri)}`;
89
+ info(`Opening browser for login...`);
90
+ info(`If it doesn't open, visit: ${loginUrl}`);
91
+ const { exec } = await import("child_process");
92
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? 'start ""' : "xdg-open";
93
+ exec(`${cmd} "${loginUrl}"`);
94
+ const { promise } = startCallbackServer(port);
95
+ try {
96
+ const { accessToken, refreshToken } = await promise;
97
+ const payload = JSON.parse(
98
+ Buffer.from(accessToken.split(".")[1], "base64url").toString()
99
+ );
100
+ const email = payload.email ?? "unknown";
101
+ const expiresAt = new Date(payload.exp * 1e3).toISOString();
102
+ await saveCredentials({
103
+ accessToken,
104
+ refreshToken,
105
+ expiresAt,
106
+ email,
107
+ serviceUrl
108
+ });
109
+ success(`Logged in as ${email}`);
110
+ } catch (err) {
111
+ error(err.message);
112
+ process.exitCode = 1;
113
+ }
114
+ }
115
+ });
116
+ export {
117
+ login_default as default
118
+ };
119
+ //# sourceMappingURL=login-BZ6ZPFHC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/login.ts","../src/lib/server.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport { findAvailablePort, startCallbackServer } from '../lib/server.js'\nimport { saveCredentials } from '../lib/credentials.js'\nimport { loadContext } from '../lib/context.js'\nimport { success, error, info } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'login', description: 'Authenticate with the SemiLayer service' },\n args: {\n 'service-url': {\n type: 'string',\n description: 'Service API URL',\n },\n },\n async run({ args }) {\n const ctx = await loadContext()\n const serviceUrl =\n args['service-url'] || ctx?.serviceUrl || 'https://api.semilayer.com'\n\n const port = await findAvailablePort()\n const redirectUri = `http://localhost:${port}/callback`\n\n const loginUrl = `${serviceUrl}/auth/login?app=cli&redirect=${encodeURIComponent(redirectUri)}`\n\n info(`Opening browser for login...`)\n info(`If it doesn't open, visit: ${loginUrl}`)\n\n // Open browser\n const { exec } = await import('node:child_process')\n const cmd =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start \"\"'\n : 'xdg-open'\n exec(`${cmd} \"${loginUrl}\"`)\n\n // Wait for callback\n const { promise } = startCallbackServer(port)\n\n try {\n const { accessToken, refreshToken } = await promise\n\n // Decode JWT to get email and expiry\n const payload = JSON.parse(\n Buffer.from(accessToken.split('.')[1]!, 'base64url').toString(),\n )\n const email = payload.email ?? 'unknown'\n const expiresAt = new Date(payload.exp * 1000).toISOString()\n\n await saveCredentials({\n accessToken,\n refreshToken,\n expiresAt,\n email,\n serviceUrl,\n })\n\n success(`Logged in as ${email}`)\n } catch (err) {\n error((err as Error).message)\n process.exitCode = 1\n }\n },\n})\n","import { createServer, type Server } from 'node:http'\nimport { URL } from 'node:url'\n\nexport interface CallbackResult {\n accessToken: string\n refreshToken: string\n}\n\n/**\n * Start a temporary localhost HTTP server that waits for the OIDC callback.\n * Returns the tokens from the query params, then shuts down.\n */\nexport function startCallbackServer(\n port: number,\n timeoutMs = 60_000,\n): { promise: Promise<CallbackResult>; server: Server } {\n let resolve: (result: CallbackResult) => void\n let reject: (err: Error) => void\n\n const promise = new Promise<CallbackResult>((res, rej) => {\n resolve = res\n reject = rej\n })\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost:${port}`)\n\n if (url.pathname === '/callback') {\n const accessToken = url.searchParams.get('access_token')\n const refreshToken = url.searchParams.get('refresh_token')\n\n if (accessToken && refreshToken) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(\n '<html><body><h2>Logged in! You can close this tab.</h2></body></html>',\n )\n resolve!({ accessToken, refreshToken })\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html' })\n res.end('<html><body><h2>Login failed — missing tokens.</h2></body></html>')\n reject!(new Error('Callback missing access_token or refresh_token'))\n }\n } else {\n res.writeHead(404)\n res.end()\n }\n })\n\n const timeout = setTimeout(() => {\n server.close()\n reject!(new Error('Login timed out. Try again.'))\n }, timeoutMs)\n\n // Clean up timeout when resolved\n promise.finally(() => {\n clearTimeout(timeout)\n server.close()\n })\n\n server.listen(port, '127.0.0.1')\n\n return { promise, server }\n}\n\n/** Find an available port in the 9876-9899 range */\nexport async function findAvailablePort(): Promise<number> {\n const { createServer: createNet } = await import('node:net')\n for (let port = 9876; port <= 9899; port++) {\n const available = await new Promise<boolean>((resolve) => {\n const srv = createNet()\n srv.once('error', () => resolve(false))\n srv.listen(port, '127.0.0.1', () => {\n srv.close(() => resolve(true))\n })\n })\n if (available) return port\n }\n throw new Error('No available port found in range 9876-9899')\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;;;ACA9B,SAAS,oBAAiC;AAC1C,SAAS,WAAW;AAWb,SAAS,oBACd,MACA,YAAY,KAC0C;AACtD,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAwB,CAAC,KAAK,QAAQ;AACxD,cAAU;AACV,aAAS;AAAA,EACX,CAAC;AAED,QAAM,SAAS,aAAa,CAAC,KAAK,QAAQ;AACxC,UAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,oBAAoB,IAAI,EAAE;AAE9D,QAAI,IAAI,aAAa,aAAa;AAChC,YAAM,cAAc,IAAI,aAAa,IAAI,cAAc;AACvD,YAAM,eAAe,IAAI,aAAa,IAAI,eAAe;AAEzD,UAAI,eAAe,cAAc;AAC/B,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI;AAAA,UACF;AAAA,QACF;AACA,gBAAS,EAAE,aAAa,aAAa,CAAC;AAAA,MACxC,OAAO;AACL,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI,IAAI,wEAAmE;AAC3E,eAAQ,IAAI,MAAM,gDAAgD,CAAC;AAAA,MACrE;AAAA,IACF,OAAO;AACL,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI;AAAA,IACV;AAAA,EACF,CAAC;AAED,QAAM,UAAU,WAAW,MAAM;AAC/B,WAAO,MAAM;AACb,WAAQ,IAAI,MAAM,6BAA6B,CAAC;AAAA,EAClD,GAAG,SAAS;AAGZ,UAAQ,QAAQ,MAAM;AACpB,iBAAa,OAAO;AACpB,WAAO,MAAM;AAAA,EACf,CAAC;AAED,SAAO,OAAO,MAAM,WAAW;AAE/B,SAAO,EAAE,SAAS,OAAO;AAC3B;AAGA,eAAsB,oBAAqC;AACzD,QAAM,EAAE,cAAc,UAAU,IAAI,MAAM,OAAO,KAAU;AAC3D,WAAS,OAAO,MAAM,QAAQ,MAAM,QAAQ;AAC1C,UAAM,YAAY,MAAM,IAAI,QAAiB,CAAC,YAAY;AACxD,YAAM,MAAM,UAAU;AACtB,UAAI,KAAK,SAAS,MAAM,QAAQ,KAAK,CAAC;AACtC,UAAI,OAAO,MAAM,aAAa,MAAM;AAClC,YAAI,MAAM,MAAM,QAAQ,IAAI,CAAC;AAAA,MAC/B,CAAC;AAAA,IACH,CAAC;AACD,QAAI,UAAW,QAAO;AAAA,EACxB;AACA,QAAM,IAAI,MAAM,4CAA4C;AAC9D;;;ADxEA,IAAO,gBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,SAAS,aAAa,0CAA0C;AAAA,EAC9E,MAAM;AAAA,IACJ,eAAe;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,MAAM,MAAM,YAAY;AAC9B,UAAM,aACJ,KAAK,aAAa,KAAK,KAAK,cAAc;AAE5C,UAAM,OAAO,MAAM,kBAAkB;AACrC,UAAM,cAAc,oBAAoB,IAAI;AAE5C,UAAM,WAAW,GAAG,UAAU,gCAAgC,mBAAmB,WAAW,CAAC;AAE7F,SAAK,8BAA8B;AACnC,SAAK,8BAA8B,QAAQ,EAAE;AAG7C,UAAM,EAAE,KAAK,IAAI,MAAM,OAAO,eAAoB;AAClD,UAAM,MACJ,QAAQ,aAAa,WACjB,SACA,QAAQ,aAAa,UACnB,aACA;AACR,SAAK,GAAG,GAAG,KAAK,QAAQ,GAAG;AAG3B,UAAM,EAAE,QAAQ,IAAI,oBAAoB,IAAI;AAE5C,QAAI;AACF,YAAM,EAAE,aAAa,aAAa,IAAI,MAAM;AAG5C,YAAM,UAAU,KAAK;AAAA,QACnB,OAAO,KAAK,YAAY,MAAM,GAAG,EAAE,CAAC,GAAI,WAAW,EAAE,SAAS;AAAA,MAChE;AACA,YAAM,QAAQ,QAAQ,SAAS;AAC/B,YAAM,YAAY,IAAI,KAAK,QAAQ,MAAM,GAAI,EAAE,YAAY;AAE3D,YAAM,gBAAgB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,cAAQ,gBAAgB,KAAK,EAAE;AAAA,IACjC,SAAS,KAAK;AACZ,YAAO,IAAc,OAAO;AAC5B,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ clearCredentials,
4
+ loadCredentials
5
+ } from "./chunk-7TA63VHV.js";
6
+ import {
7
+ info,
8
+ success
9
+ } from "./chunk-WZYOSGN3.js";
10
+
11
+ // src/commands/logout.ts
12
+ import { defineCommand } from "citty";
13
+ var logout_default = defineCommand({
14
+ meta: { name: "logout", description: "Log out and clear local credentials" },
15
+ async run() {
16
+ const creds = await loadCredentials();
17
+ if (!creds) {
18
+ info("Already logged out.");
19
+ return;
20
+ }
21
+ try {
22
+ await fetch(`${creds.serviceUrl}/auth/logout`, {
23
+ method: "POST",
24
+ headers: {
25
+ Authorization: `Bearer ${creds.refreshToken}`,
26
+ "Content-Type": "application/json"
27
+ }
28
+ });
29
+ } catch {
30
+ }
31
+ await clearCredentials();
32
+ success("Logged out.");
33
+ }
34
+ });
35
+ export {
36
+ logout_default as default
37
+ };
38
+ //# sourceMappingURL=logout-VMPRV62T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/logout.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport { loadCredentials, clearCredentials } from '../lib/credentials.js'\nimport { success, info } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'logout', description: 'Log out and clear local credentials' },\n async run() {\n const creds = await loadCredentials()\n\n if (!creds) {\n info('Already logged out.')\n return\n }\n\n // Revoke refresh token on the server (best-effort)\n try {\n await fetch(`${creds.serviceUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${creds.refreshToken}`,\n 'Content-Type': 'application/json',\n },\n })\n } catch {\n // Server unreachable — still clear local creds\n }\n\n await clearCredentials()\n success('Logged out.')\n },\n})\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,qBAAqB;AAI9B,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,sCAAsC;AAAA,EAC3E,MAAM,MAAM;AACV,UAAM,QAAQ,MAAM,gBAAgB;AAEpC,QAAI,CAAC,OAAO;AACV,WAAK,qBAAqB;AAC1B;AAAA,IACF;AAGA,QAAI;AACF,YAAM,MAAM,GAAG,MAAM,UAAU,gBAAgB;AAAA,QAC7C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU,MAAM,YAAY;AAAA,UAC3C,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,UAAM,iBAAiB;AACvB,YAAQ,aAAa;AAAA,EACvB;AACF,CAAC;","names":[]}
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ orgPath
4
+ } from "./chunk-ALA4X7UU.js";
5
+ import {
6
+ loadContext
7
+ } from "./chunk-QMF7LD67.js";
8
+ import {
9
+ confirm
10
+ } from "./chunk-QXIVJY7K.js";
11
+ import {
12
+ createApiClient
13
+ } from "./chunk-T3UROBMA.js";
14
+ import "./chunk-7TA63VHV.js";
15
+ import {
16
+ bold,
17
+ error,
18
+ newline,
19
+ success,
20
+ table
21
+ } from "./chunk-WZYOSGN3.js";
22
+
23
+ // src/commands/members.ts
24
+ import { defineCommand } from "citty";
25
+ var members_default = defineCommand({
26
+ meta: { name: "members", description: "Manage organization members" },
27
+ subCommands: {
28
+ list: defineCommand({
29
+ meta: { name: "list", description: "List members in the current organization" },
30
+ async run() {
31
+ const ctx = await loadContext();
32
+ if (!ctx) {
33
+ error("No .semilayerrc found. Run `semilayer init` first.");
34
+ process.exitCode = 1;
35
+ return;
36
+ }
37
+ const api = await createApiClient();
38
+ const { members } = await api.get(`${orgPath(ctx)}/members`);
39
+ if (members.length === 0) {
40
+ newline();
41
+ bold("No members found.");
42
+ return;
43
+ }
44
+ table(
45
+ ["Email", "Role"],
46
+ members.map((m) => [m.email, m.role])
47
+ );
48
+ }
49
+ }),
50
+ invite: defineCommand({
51
+ meta: { name: "invite", description: "Invite a member to the organization" },
52
+ args: {
53
+ email: { type: "string", description: "Email address to invite", required: true },
54
+ role: { type: "string", description: "Role to assign", default: "developer" }
55
+ },
56
+ async run({ args }) {
57
+ const ctx = await loadContext();
58
+ if (!ctx) {
59
+ error("No .semilayerrc found. Run `semilayer init` first.");
60
+ process.exitCode = 1;
61
+ return;
62
+ }
63
+ const api = await createApiClient();
64
+ await api.post(`${orgPath(ctx)}/members`, { email: args.email, role: args.role });
65
+ success(`Invitation sent to ${args.email} as ${args.role}.`);
66
+ }
67
+ }),
68
+ update: defineCommand({
69
+ meta: { name: "update", description: "Update a member's role" },
70
+ args: {
71
+ "member-id": { type: "string", description: "Member ID", required: true },
72
+ role: { type: "string", description: "New role", required: true }
73
+ },
74
+ async run({ args }) {
75
+ const ctx = await loadContext();
76
+ if (!ctx) {
77
+ error("No .semilayerrc found. Run `semilayer init` first.");
78
+ process.exitCode = 1;
79
+ return;
80
+ }
81
+ const api = await createApiClient();
82
+ await api.patch(`${orgPath(ctx)}/members/${args["member-id"]}`, { role: args.role });
83
+ success(`Member role updated to ${args.role}.`);
84
+ }
85
+ }),
86
+ remove: defineCommand({
87
+ meta: { name: "remove", description: "Remove a member from the organization" },
88
+ args: {
89
+ "member-id": { type: "string", description: "Member ID", required: true }
90
+ },
91
+ async run({ args }) {
92
+ const ctx = await loadContext();
93
+ if (!ctx) {
94
+ error("No .semilayerrc found. Run `semilayer init` first.");
95
+ process.exitCode = 1;
96
+ return;
97
+ }
98
+ const ok = await confirm(`Remove member ${args["member-id"]}? This cannot be undone.`);
99
+ if (!ok) return;
100
+ const api = await createApiClient();
101
+ await api.del(`${orgPath(ctx)}/members/${args["member-id"]}`);
102
+ success("Member removed.");
103
+ }
104
+ })
105
+ }
106
+ });
107
+ export {
108
+ members_default as default
109
+ };
110
+ //# sourceMappingURL=members-DVE5FDLZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/members.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Member } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { loadContext } from '../lib/context.js'\nimport { orgPath } from '../lib/env-path.js'\nimport { success, error, bold, table, newline } from '../lib/output.js'\nimport { confirm } from '../lib/prompt.js'\n\nexport default defineCommand({\n meta: { name: 'members', description: 'Manage organization members' },\n subCommands: {\n list: defineCommand({\n meta: { name: 'list', description: 'List members in the current organization' },\n async run() {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const api = await createApiClient()\n const { members } = await api.get<{ members: Member[] }>(`${orgPath(ctx)}/members`)\n if (members.length === 0) {\n newline()\n bold('No members found.')\n return\n }\n table(\n ['Email', 'Role'],\n members.map((m) => [m.email, m.role]),\n )\n },\n }),\n\n invite: defineCommand({\n meta: { name: 'invite', description: 'Invite a member to the organization' },\n args: {\n email: { type: 'string', description: 'Email address to invite', required: true },\n role: { type: 'string', description: 'Role to assign', default: 'developer' },\n },\n async run({ args }) {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const api = await createApiClient()\n await api.post(`${orgPath(ctx)}/members`, { email: args.email, role: args.role })\n success(`Invitation sent to ${args.email} as ${args.role}.`)\n },\n }),\n\n update: defineCommand({\n meta: { name: 'update', description: \"Update a member's role\" },\n args: {\n 'member-id': { type: 'string', description: 'Member ID', required: true },\n role: { type: 'string', description: 'New role', required: true },\n },\n async run({ args }) {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const api = await createApiClient()\n await api.patch(`${orgPath(ctx)}/members/${args['member-id']}`, { role: args.role })\n success(`Member role updated to ${args.role}.`)\n },\n }),\n\n remove: defineCommand({\n meta: { name: 'remove', description: 'Remove a member from the organization' },\n args: {\n 'member-id': { type: 'string', description: 'Member ID', required: true },\n },\n async run({ args }) {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const ok = await confirm(`Remove member ${args['member-id']}? This cannot be undone.`)\n if (!ok) return\n const api = await createApiClient()\n await api.del(`${orgPath(ctx)}/members/${args['member-id']}`)\n success('Member removed.')\n },\n }),\n },\n})\n"],"mappings":"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","names":[]}
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadContext
4
+ } from "./chunk-QMF7LD67.js";
5
+ import {
6
+ bold,
7
+ dim,
8
+ error,
9
+ info,
10
+ label,
11
+ newline
12
+ } from "./chunk-WZYOSGN3.js";
13
+
14
+ // src/commands/observe.ts
15
+ import { defineCommand } from "citty";
16
+ import {
17
+ BeamClient,
18
+ BeamStreamError,
19
+ BeamStreamRateLimitError,
20
+ BeamStreamClosedError
21
+ } from "@semilayer/client";
22
+ function isApiKey(value) {
23
+ return value.startsWith("sk_") || value.startsWith("pk_") || value.startsWith("ik_");
24
+ }
25
+ var observe_default = defineCommand({
26
+ meta: {
27
+ name: "observe",
28
+ description: "Observe a single record live \u2014 first yield is the current state, subsequent yields are deltas"
29
+ },
30
+ args: {
31
+ lens: {
32
+ type: "positional",
33
+ description: "Lens name",
34
+ required: true
35
+ },
36
+ "record-id": {
37
+ type: "positional",
38
+ description: "Record id to observe",
39
+ required: true
40
+ },
41
+ "api-key": {
42
+ type: "string",
43
+ description: "API key (sk_* or pk_*)",
44
+ required: true
45
+ },
46
+ "user-token": {
47
+ type: "string",
48
+ description: "End-user JWT (passed through as ?userToken for row-level access rules)"
49
+ },
50
+ output: {
51
+ type: "string",
52
+ description: "Output format: ndjson | pretty (default: auto \u2014 ndjson when piping)",
53
+ alias: "o"
54
+ }
55
+ },
56
+ async run({ args }) {
57
+ try {
58
+ if (!args["api-key"]) {
59
+ throw new Error("observe requires --api-key (sk_* or pk_*)");
60
+ }
61
+ if (!isApiKey(args["api-key"])) {
62
+ throw new Error("--api-key must be an API key (sk_* or pk_*)");
63
+ }
64
+ if (args["api-key"].startsWith("ik_")) {
65
+ throw new Error("Ingest keys (ik_*) cannot open stream connections");
66
+ }
67
+ const ctx = await loadContext();
68
+ const baseUrl = ctx?.serviceUrl ?? "https://api.semilayer.com";
69
+ const client = new BeamClient({
70
+ baseUrl,
71
+ apiKey: args["api-key"],
72
+ userToken: args["user-token"]
73
+ });
74
+ const mode = process.stdout.isTTY && args.output !== "ndjson" ? "pretty" : "ndjson";
75
+ if (mode === "pretty") {
76
+ newline();
77
+ label("Observe", `${bold(args.lens)} \u2192 ${dim(args["record-id"])}`);
78
+ info(dim("Waiting for current state + deltas\u2026 (Ctrl-C to stop)"));
79
+ newline();
80
+ }
81
+ const iter = client.observe(args.lens, args["record-id"]);
82
+ let version = 0;
83
+ const reader = iter[Symbol.asyncIterator]();
84
+ const onSigint = () => {
85
+ if (reader.return) void reader.return(void 0);
86
+ };
87
+ process.on("SIGINT", onSigint);
88
+ try {
89
+ while (true) {
90
+ const { value, done } = await reader.next();
91
+ if (done) break;
92
+ version += 1;
93
+ if (mode === "ndjson") {
94
+ console.log(JSON.stringify(value));
95
+ } else {
96
+ const tag = version === 1 ? dim("current") : dim(`delta ${version - 1}`);
97
+ console.log(`${dim(`[v${version}]`)} ${tag} ${JSON.stringify(value)}`);
98
+ }
99
+ }
100
+ } finally {
101
+ process.off("SIGINT", onSigint);
102
+ }
103
+ if (mode === "pretty") {
104
+ newline();
105
+ info(dim(`${version} version${version === 1 ? "" : "s"} seen`));
106
+ }
107
+ } catch (err) {
108
+ handleStreamError(err, args.lens);
109
+ }
110
+ }
111
+ });
112
+ function handleStreamError(err, lens) {
113
+ if (err instanceof BeamStreamRateLimitError) {
114
+ error(`Rate limited: ${err.detail}`);
115
+ info(dim("Back off and retry. Paid plans have much higher limits."));
116
+ process.exitCode = 1;
117
+ return;
118
+ }
119
+ if (err instanceof BeamStreamClosedError) {
120
+ if (err.closeCode === 4290) {
121
+ error("Concurrent connection limit reached for your org.");
122
+ } else if (err.closeCode === 4291) {
123
+ error("Hourly rows-streamed quota exhausted.");
124
+ } else if (err.closeCode === 4401) {
125
+ error("Auth failed on the stream upgrade.");
126
+ } else if (err.closeCode === 4403) {
127
+ error(`Live tail is disabled for lens '${lens}'.`);
128
+ } else {
129
+ error(`Stream closed: ${err.closeCode} ${err.reason}`);
130
+ }
131
+ process.exitCode = 1;
132
+ return;
133
+ }
134
+ if (err instanceof BeamStreamError) {
135
+ if (err.code === "not_found") {
136
+ error(`Record not found: ${err.detail}`);
137
+ } else {
138
+ error(`Stream error (${err.code}): ${err.detail}`);
139
+ }
140
+ process.exitCode = 1;
141
+ return;
142
+ }
143
+ error(err.message);
144
+ process.exitCode = 1;
145
+ }
146
+ export {
147
+ observe_default as default
148
+ };
149
+ //# sourceMappingURL=observe-W346RZBX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/observe.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport {\n BeamClient,\n BeamStreamError,\n BeamStreamRateLimitError,\n BeamStreamClosedError,\n} from '@semilayer/client'\nimport { loadContext } from '../lib/context.js'\nimport { error, info, dim, bold, newline, label } from '../lib/output.js'\n\nfunction isApiKey(value: string): boolean {\n return value.startsWith('sk_') || value.startsWith('pk_') || value.startsWith('ik_')\n}\n\nexport default defineCommand({\n meta: {\n name: 'observe',\n description:\n 'Observe a single record live — first yield is the current state, subsequent yields are deltas',\n },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n 'record-id': {\n type: 'positional',\n description: 'Record id to observe',\n required: true,\n },\n 'api-key': {\n type: 'string',\n description: 'API key (sk_* or pk_*)',\n required: true,\n },\n 'user-token': {\n type: 'string',\n description: 'End-user JWT (passed through as ?userToken for row-level access rules)',\n },\n output: {\n type: 'string',\n description: 'Output format: ndjson | pretty (default: auto — ndjson when piping)',\n alias: 'o',\n },\n },\n async run({ args }) {\n try {\n if (!args['api-key']) {\n throw new Error('observe requires --api-key (sk_* or pk_*)')\n }\n if (!isApiKey(args['api-key'])) {\n throw new Error('--api-key must be an API key (sk_* or pk_*)')\n }\n if (args['api-key'].startsWith('ik_')) {\n throw new Error('Ingest keys (ik_*) cannot open stream connections')\n }\n\n const ctx = await loadContext()\n const baseUrl = ctx?.serviceUrl ?? 'https://api.semilayer.com'\n const client = new BeamClient({\n baseUrl,\n apiKey: args['api-key'],\n userToken: args['user-token'],\n })\n\n const mode = process.stdout.isTTY && args.output !== 'ndjson' ? 'pretty' : 'ndjson'\n\n if (mode === 'pretty') {\n newline()\n label('Observe', `${bold(args.lens)} → ${dim(args['record-id'])}`)\n info(dim('Waiting for current state + deltas… (Ctrl-C to stop)'))\n newline()\n }\n\n const iter = client.observe(args.lens, args['record-id'])\n let version = 0\n const reader = iter[Symbol.asyncIterator]()\n const onSigint = () => {\n if (reader.return) void reader.return(undefined as never)\n }\n process.on('SIGINT', onSigint)\n\n try {\n while (true) {\n const { value, done } = await reader.next()\n if (done) break\n version += 1\n if (mode === 'ndjson') {\n console.log(JSON.stringify(value))\n } else {\n const tag = version === 1 ? dim('current') : dim(`delta ${version - 1}`)\n console.log(`${dim(`[v${version}]`)} ${tag} ${JSON.stringify(value)}`)\n }\n }\n } finally {\n process.off('SIGINT', onSigint)\n }\n\n if (mode === 'pretty') {\n newline()\n info(dim(`${version} version${version === 1 ? '' : 's'} seen`))\n }\n } catch (err) {\n handleStreamError(err, args.lens)\n }\n },\n})\n\nfunction handleStreamError(err: unknown, lens: string): void {\n if (err instanceof BeamStreamRateLimitError) {\n error(`Rate limited: ${err.detail}`)\n info(dim('Back off and retry. Paid plans have much higher limits.'))\n process.exitCode = 1\n return\n }\n if (err instanceof BeamStreamClosedError) {\n if (err.closeCode === 4290) {\n error('Concurrent connection limit reached for your org.')\n } else if (err.closeCode === 4291) {\n error('Hourly rows-streamed quota exhausted.')\n } else if (err.closeCode === 4401) {\n error('Auth failed on the stream upgrade.')\n } else if (err.closeCode === 4403) {\n error(`Live tail is disabled for lens '${lens}'.`)\n } else {\n error(`Stream closed: ${err.closeCode} ${err.reason}`)\n }\n process.exitCode = 1\n return\n }\n if (err instanceof BeamStreamError) {\n if (err.code === 'not_found') {\n error(`Record not found: ${err.detail}`)\n } else {\n error(`Stream error (${err.code}): ${err.detail}`)\n }\n process.exitCode = 1\n return\n }\n error((err as Error).message)\n process.exitCode = 1\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ confirm
4
+ } from "./chunk-QXIVJY7K.js";
5
+ import {
6
+ createApiClient
7
+ } from "./chunk-T3UROBMA.js";
8
+ import "./chunk-7TA63VHV.js";
9
+ import {
10
+ bold,
11
+ newline,
12
+ success,
13
+ table
14
+ } from "./chunk-WZYOSGN3.js";
15
+
16
+ // src/commands/orgs.ts
17
+ import { defineCommand } from "citty";
18
+ var orgs_default = defineCommand({
19
+ meta: { name: "orgs", description: "Manage organizations" },
20
+ subCommands: {
21
+ list: defineCommand({
22
+ meta: { name: "list", description: "List all organizations" },
23
+ async run() {
24
+ const api = await createApiClient();
25
+ const { orgs } = await api.get("/v1/orgs/");
26
+ if (orgs.length === 0) {
27
+ newline();
28
+ bold("No organizations found.");
29
+ return;
30
+ }
31
+ table(
32
+ ["Slug", "Name"],
33
+ orgs.map((o) => [o.slug, o.name])
34
+ );
35
+ }
36
+ }),
37
+ create: defineCommand({
38
+ meta: { name: "create", description: "Create a new organization" },
39
+ args: {
40
+ name: { type: "string", description: "Organization name", required: true },
41
+ slug: { type: "string", description: "Organization slug", required: true }
42
+ },
43
+ async run({ args }) {
44
+ const api = await createApiClient();
45
+ await api.post("/v1/orgs/", { name: args.name, slug: args.slug });
46
+ success(`Organization "${args.name}" (${args.slug}) created.`);
47
+ }
48
+ }),
49
+ delete: defineCommand({
50
+ meta: { name: "delete", description: "Delete an organization" },
51
+ args: {
52
+ org: { type: "string", description: "Organization slug to delete", required: true }
53
+ },
54
+ async run({ args }) {
55
+ const ok = await confirm(`Delete organization "${args.org}"? This cannot be undone.`);
56
+ if (!ok) return;
57
+ const api = await createApiClient();
58
+ await api.del(`/v1/orgs/${args.org}`);
59
+ success(`Organization "${args.org}" deleted.`);
60
+ }
61
+ })
62
+ }
63
+ });
64
+ export {
65
+ orgs_default as default
66
+ };
67
+ //# sourceMappingURL=orgs-YA3TVA3T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/orgs.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Org } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { success, bold, table, newline } from '../lib/output.js'\nimport { confirm } from '../lib/prompt.js'\n\nexport default defineCommand({\n meta: { name: 'orgs', description: 'Manage organizations' },\n subCommands: {\n list: defineCommand({\n meta: { name: 'list', description: 'List all organizations' },\n async run() {\n const api = await createApiClient()\n const { orgs } = await api.get<{ orgs: Org[] }>('/v1/orgs/')\n if (orgs.length === 0) {\n newline()\n bold('No organizations found.')\n return\n }\n table(\n ['Slug', 'Name'],\n orgs.map((o) => [o.slug, o.name]),\n )\n },\n }),\n\n create: defineCommand({\n meta: { name: 'create', description: 'Create a new organization' },\n args: {\n name: { type: 'string', description: 'Organization name', required: true },\n slug: { type: 'string', description: 'Organization slug', required: true },\n },\n async run({ args }) {\n const api = await createApiClient()\n await api.post('/v1/orgs/', { name: args.name, slug: args.slug })\n success(`Organization \"${args.name}\" (${args.slug}) created.`)\n },\n }),\n\n delete: defineCommand({\n meta: { name: 'delete', description: 'Delete an organization' },\n args: {\n org: { type: 'string', description: 'Organization slug to delete', required: true },\n },\n async run({ args }) {\n const ok = await confirm(`Delete organization \"${args.org}\"? This cannot be undone.`)\n if (!ok) return\n const api = await createApiClient()\n await api.del(`/v1/orgs/${args.org}`)\n success(`Organization \"${args.org}\" deleted.`)\n },\n }),\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAM9B,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,QAAQ,aAAa,uBAAuB;AAAA,EAC1D,aAAa;AAAA,IACX,MAAM,cAAc;AAAA,MAClB,MAAM,EAAE,MAAM,QAAQ,aAAa,yBAAyB;AAAA,MAC5D,MAAM,MAAM;AACV,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAqB,WAAW;AAC3D,YAAI,KAAK,WAAW,GAAG;AACrB,kBAAQ;AACR,eAAK,yBAAyB;AAC9B;AAAA,QACF;AACA;AAAA,UACE,CAAC,QAAQ,MAAM;AAAA,UACf,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,QAAQ,cAAc;AAAA,MACpB,MAAM,EAAE,MAAM,UAAU,aAAa,4BAA4B;AAAA,MACjE,MAAM;AAAA,QACJ,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,UAAU,KAAK;AAAA,QACzE,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,UAAU,KAAK;AAAA,MAC3E;AAAA,MACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,IAAI,KAAK,aAAa,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC;AAChE,gBAAQ,iBAAiB,KAAK,IAAI,MAAM,KAAK,IAAI,YAAY;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,IAED,QAAQ,cAAc;AAAA,MACpB,MAAM,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,MAC9D,MAAM;AAAA,QACJ,KAAK,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,MACpF;AAAA,MACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,cAAM,KAAK,MAAM,QAAQ,wBAAwB,KAAK,GAAG,2BAA2B;AACpF,YAAI,CAAC,GAAI;AACT,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,IAAI,IAAI,YAAY,KAAK,GAAG,EAAE;AACpC,gBAAQ,iBAAiB,KAAK,GAAG,YAAY;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;","names":[]}
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ envPath
4
+ } from "./chunk-ALA4X7UU.js";
5
+ import {
6
+ loadContext
7
+ } from "./chunk-QMF7LD67.js";
8
+ import {
9
+ createApiClient
10
+ } from "./chunk-T3UROBMA.js";
11
+ import "./chunk-7TA63VHV.js";
12
+ import {
13
+ error,
14
+ success
15
+ } from "./chunk-WZYOSGN3.js";
16
+
17
+ // src/commands/pause.ts
18
+ import { defineCommand } from "citty";
19
+ var pause_default = defineCommand({
20
+ meta: { name: "pause", description: "Pause ingestion for a lens" },
21
+ args: {
22
+ lens: {
23
+ type: "positional",
24
+ description: "Lens name",
25
+ required: true
26
+ }
27
+ },
28
+ async run({ args }) {
29
+ const ctx = await loadContext();
30
+ if (!ctx) {
31
+ error("No .semilayerrc found. Run `semilayer init` first.");
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ const api = await createApiClient();
36
+ const { lenses } = await api.get(`${envPath(ctx)}/lenses`);
37
+ const lens = lenses.find((l) => l.name === args.lens);
38
+ if (!lens) {
39
+ error(`Lens "${args.lens}" not found`);
40
+ process.exitCode = 1;
41
+ return;
42
+ }
43
+ await api.post(`${envPath(ctx)}/lenses/${lens.id}/pause`);
44
+ success(`Lens "${args.lens}" paused.`);
45
+ }
46
+ });
47
+ export {
48
+ pause_default as default
49
+ };
50
+ //# sourceMappingURL=pause-GQ6PKBUA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/pause.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Lens } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { loadContext } from '../lib/context.js'\nimport { envPath } from '../lib/env-path.js'\nimport { success, error } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'pause', description: 'Pause ingestion for a lens' },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n },\n async run({ args }) {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const api = await createApiClient()\n const { lenses } = await api.get<{ lenses: Lens[] }>(`${envPath(ctx)}/lenses`)\n const lens = lenses.find((l) => l.name === args.lens)\n if (!lens) {\n error(`Lens \"${args.lens}\" not found`)\n process.exitCode = 1\n return\n }\n await api.post(`${envPath(ctx)}/lenses/${lens.id}/pause`)\n success(`Lens \"${args.lens}\" paused.`)\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAO9B,IAAO,gBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,SAAS,aAAa,6BAA6B;AAAA,EACjE,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,MAAM,MAAM,YAAY;AAC9B,QAAI,CAAC,KAAK;AACR,YAAM,oDAAoD;AAC1D,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM,MAAM,MAAM,gBAAgB;AAClC,UAAM,EAAE,OAAO,IAAI,MAAM,IAAI,IAAwB,GAAG,QAAQ,GAAG,CAAC,SAAS;AAC7E,UAAM,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACpD,QAAI,CAAC,MAAM;AACT,YAAM,SAAS,KAAK,IAAI,aAAa;AACrC,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM,IAAI,KAAK,GAAG,QAAQ,GAAG,CAAC,WAAW,KAAK,EAAE,QAAQ;AACxD,YAAQ,SAAS,KAAK,IAAI,WAAW;AAAA,EACvC;AACF,CAAC;","names":[]}