primitive-admin 1.0.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 (38) hide show
  1. package/README.md +495 -0
  2. package/dist/bin/primitive.js +72 -0
  3. package/dist/bin/primitive.js.map +1 -0
  4. package/dist/src/commands/admins.js +268 -0
  5. package/dist/src/commands/admins.js.map +1 -0
  6. package/dist/src/commands/analytics.js +195 -0
  7. package/dist/src/commands/analytics.js.map +1 -0
  8. package/dist/src/commands/apps.js +238 -0
  9. package/dist/src/commands/apps.js.map +1 -0
  10. package/dist/src/commands/auth.js +178 -0
  11. package/dist/src/commands/auth.js.map +1 -0
  12. package/dist/src/commands/catalog.js +460 -0
  13. package/dist/src/commands/catalog.js.map +1 -0
  14. package/dist/src/commands/integrations.js +438 -0
  15. package/dist/src/commands/integrations.js.map +1 -0
  16. package/dist/src/commands/prompts.js +999 -0
  17. package/dist/src/commands/prompts.js.map +1 -0
  18. package/dist/src/commands/sync.js +598 -0
  19. package/dist/src/commands/sync.js.map +1 -0
  20. package/dist/src/commands/users.js +293 -0
  21. package/dist/src/commands/users.js.map +1 -0
  22. package/dist/src/commands/waitlist.js +176 -0
  23. package/dist/src/commands/waitlist.js.map +1 -0
  24. package/dist/src/commands/workflows.js +876 -0
  25. package/dist/src/commands/workflows.js.map +1 -0
  26. package/dist/src/lib/api-client.js +522 -0
  27. package/dist/src/lib/api-client.js.map +1 -0
  28. package/dist/src/lib/auth-flow.js +306 -0
  29. package/dist/src/lib/auth-flow.js.map +1 -0
  30. package/dist/src/lib/config.js +90 -0
  31. package/dist/src/lib/config.js.map +1 -0
  32. package/dist/src/lib/fetch.js +43 -0
  33. package/dist/src/lib/fetch.js.map +1 -0
  34. package/dist/src/lib/output.js +143 -0
  35. package/dist/src/lib/output.js.map +1 -0
  36. package/dist/src/types/index.js +2 -0
  37. package/dist/src/types/index.js.map +1 -0
  38. package/package.json +47 -0
@@ -0,0 +1,306 @@
1
+ import { createServer } from "http";
2
+ import open from "open";
3
+ import { saveCredentials } from "./config.js";
4
+ import { fetchWithTLS } from "./fetch.js";
5
+ import { error, info } from "./output.js";
6
+ const DEFAULT_CALLBACK_PORT = 9876;
7
+ export async function browserLogin(serverUrl) {
8
+ return new Promise((resolve) => {
9
+ const port = DEFAULT_CALLBACK_PORT;
10
+ let server = null;
11
+ let timeoutId = null;
12
+ const sockets = new Set();
13
+ const cleanup = () => {
14
+ if (timeoutId) {
15
+ clearTimeout(timeoutId);
16
+ timeoutId = null;
17
+ }
18
+ // Destroy all tracked sockets to ensure connections are fully closed
19
+ for (const socket of sockets) {
20
+ socket.destroy();
21
+ }
22
+ sockets.clear();
23
+ if (server) {
24
+ server.close();
25
+ server = null;
26
+ }
27
+ };
28
+ // Create local server to receive OAuth callback
29
+ server = createServer(async (req, res) => {
30
+ const url = new URL(req.url || "/", `http://localhost:${port}`);
31
+ if (url.pathname === "/callback") {
32
+ const code = url.searchParams.get("code");
33
+ const errorParam = url.searchParams.get("error");
34
+ if (errorParam) {
35
+ res.writeHead(200, { "Content-Type": "text/html", "Connection": "close" });
36
+ res.end(getErrorHtml(errorParam));
37
+ cleanup();
38
+ resolve({ success: false, error: errorParam });
39
+ return;
40
+ }
41
+ if (!code) {
42
+ res.writeHead(200, { "Content-Type": "text/html", "Connection": "close" });
43
+ res.end(getErrorHtml("No authorization code received"));
44
+ cleanup();
45
+ resolve({ success: false, error: "No authorization code received" });
46
+ return;
47
+ }
48
+ // Exchange CLI auth code for tokens via dedicated endpoint
49
+ try {
50
+ const tokenResponse = await fetchWithTLS(`${serverUrl}/admin/api/cli/token-exchange`, {
51
+ method: "POST",
52
+ headers: {
53
+ "Content-Type": "application/json",
54
+ },
55
+ body: JSON.stringify({ code }),
56
+ });
57
+ if (!tokenResponse.ok) {
58
+ const errorData = await tokenResponse.text();
59
+ let errorMessage = "Token exchange failed";
60
+ try {
61
+ const parsed = JSON.parse(errorData);
62
+ errorMessage = parsed.error || parsed.message || errorMessage;
63
+ }
64
+ catch {
65
+ // Use default message
66
+ }
67
+ res.writeHead(200, { "Content-Type": "text/html", "Connection": "close" });
68
+ res.end(getErrorHtml(errorMessage));
69
+ cleanup();
70
+ resolve({ success: false, error: errorMessage });
71
+ return;
72
+ }
73
+ const tokenData = await tokenResponse.json();
74
+ const credentials = {
75
+ serverUrl,
76
+ accessToken: tokenData.accessToken,
77
+ refreshToken: tokenData.refreshToken || "",
78
+ expiresAt: tokenData.expiresAt || new Date(Date.now() + 3600 * 1000).toISOString(),
79
+ adminId: tokenData.adminId || "",
80
+ email: tokenData.email || "",
81
+ role: tokenData.role || "admin",
82
+ name: tokenData.name,
83
+ globalAdminAppId: tokenData.globalAdminAppId,
84
+ };
85
+ saveCredentials(credentials);
86
+ res.writeHead(200, { "Content-Type": "text/html", "Connection": "close" });
87
+ res.end(getSuccessHtml(credentials.email));
88
+ cleanup();
89
+ resolve({ success: true, credentials });
90
+ }
91
+ catch (err) {
92
+ res.writeHead(200, { "Content-Type": "text/html", "Connection": "close" });
93
+ res.end(getErrorHtml(err.message || "Token exchange failed"));
94
+ cleanup();
95
+ resolve({ success: false, error: err.message || "Token exchange failed" });
96
+ }
97
+ return;
98
+ }
99
+ // For any other path, just return a simple message
100
+ res.writeHead(200, { "Content-Type": "text/plain", "Connection": "close" });
101
+ res.end("Waiting for OAuth callback...");
102
+ });
103
+ // Track connections so we can destroy them on cleanup
104
+ server.on("connection", (socket) => {
105
+ sockets.add(socket);
106
+ socket.on("close", () => {
107
+ sockets.delete(socket);
108
+ });
109
+ });
110
+ server.on("error", (err) => {
111
+ if (err.code === "EADDRINUSE") {
112
+ error(`Port ${port} is already in use. Please close any other bao-admin login processes.`);
113
+ }
114
+ else {
115
+ error(`Failed to start local server: ${err.message}`);
116
+ }
117
+ cleanup();
118
+ resolve({ success: false, error: err.message });
119
+ });
120
+ server.listen(port, async () => {
121
+ info(`Starting OAuth flow...`);
122
+ info(`Listening on port ${port} for callback...`);
123
+ // Build the OAuth initiation URL
124
+ const oauthUrl = `${serverUrl}/admin/api/oauth-cli?redirect_port=${port}`;
125
+ try {
126
+ // Open the browser (don't wait for it to close)
127
+ const childProcess = await open(oauthUrl, { wait: false });
128
+ // Detach the child process so it doesn't keep Node.js running
129
+ childProcess.unref();
130
+ info(`Browser opened. Please complete authentication.`);
131
+ info(`If the browser didn't open, visit: ${oauthUrl}`);
132
+ }
133
+ catch (err) {
134
+ error(`Could not open browser automatically.`);
135
+ info(`Please visit: ${oauthUrl}`);
136
+ }
137
+ });
138
+ // Timeout after 5 minutes
139
+ timeoutId = setTimeout(() => {
140
+ if (server) {
141
+ error(`Login timed out after 5 minutes.`);
142
+ cleanup();
143
+ resolve({ success: false, error: "Login timeout" });
144
+ }
145
+ }, 5 * 60 * 1000);
146
+ });
147
+ }
148
+ function parseJwt(token) {
149
+ try {
150
+ const parts = token.split(".");
151
+ if (parts.length !== 3)
152
+ return {};
153
+ const payload = parts[1];
154
+ const decoded = Buffer.from(payload, "base64url").toString("utf-8");
155
+ return JSON.parse(decoded);
156
+ }
157
+ catch {
158
+ return {};
159
+ }
160
+ }
161
+ function getSuccessHtml(email) {
162
+ return `
163
+ <!DOCTYPE html>
164
+ <html>
165
+ <head>
166
+ <title>Login Successful</title>
167
+ <style>
168
+ body {
169
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
170
+ display: flex;
171
+ justify-content: center;
172
+ align-items: center;
173
+ min-height: 100vh;
174
+ margin: 0;
175
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
176
+ }
177
+ .card {
178
+ background: white;
179
+ border-radius: 12px;
180
+ padding: 48px;
181
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
182
+ text-align: center;
183
+ max-width: 400px;
184
+ }
185
+ .success-icon {
186
+ width: 80px;
187
+ height: 80px;
188
+ background: #10B981;
189
+ border-radius: 50%;
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: center;
193
+ margin: 0 auto 24px;
194
+ }
195
+ .success-icon svg {
196
+ width: 40px;
197
+ height: 40px;
198
+ fill: white;
199
+ }
200
+ h1 {
201
+ color: #1F2937;
202
+ margin: 0 0 12px;
203
+ font-size: 24px;
204
+ }
205
+ p {
206
+ color: #6B7280;
207
+ margin: 0;
208
+ font-size: 16px;
209
+ }
210
+ .email {
211
+ color: #4F46E5;
212
+ font-weight: 500;
213
+ }
214
+ .close-note {
215
+ margin-top: 24px;
216
+ font-size: 14px;
217
+ color: #9CA3AF;
218
+ }
219
+ </style>
220
+ </head>
221
+ <body>
222
+ <div class="card">
223
+ <div class="success-icon">
224
+ <svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
225
+ </div>
226
+ <h1>Login Successful!</h1>
227
+ <p>You're now logged in as <span class="email">${email}</span></p>
228
+ <p class="close-note">You can close this window and return to the terminal.</p>
229
+ </div>
230
+ </body>
231
+ </html>
232
+ `;
233
+ }
234
+ function getErrorHtml(errorMessage) {
235
+ return `
236
+ <!DOCTYPE html>
237
+ <html>
238
+ <head>
239
+ <title>Login Failed</title>
240
+ <style>
241
+ body {
242
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
243
+ display: flex;
244
+ justify-content: center;
245
+ align-items: center;
246
+ min-height: 100vh;
247
+ margin: 0;
248
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
249
+ }
250
+ .card {
251
+ background: white;
252
+ border-radius: 12px;
253
+ padding: 48px;
254
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
255
+ text-align: center;
256
+ max-width: 400px;
257
+ }
258
+ .error-icon {
259
+ width: 80px;
260
+ height: 80px;
261
+ background: #EF4444;
262
+ border-radius: 50%;
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ margin: 0 auto 24px;
267
+ }
268
+ .error-icon svg {
269
+ width: 40px;
270
+ height: 40px;
271
+ fill: white;
272
+ }
273
+ h1 {
274
+ color: #1F2937;
275
+ margin: 0 0 12px;
276
+ font-size: 24px;
277
+ }
278
+ p {
279
+ color: #6B7280;
280
+ margin: 0;
281
+ font-size: 16px;
282
+ }
283
+ .error-message {
284
+ color: #EF4444;
285
+ background: #FEF2F2;
286
+ padding: 12px;
287
+ border-radius: 8px;
288
+ margin-top: 16px;
289
+ font-size: 14px;
290
+ }
291
+ </style>
292
+ </head>
293
+ <body>
294
+ <div class="card">
295
+ <div class="error-icon">
296
+ <svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
297
+ </div>
298
+ <h1>Login Failed</h1>
299
+ <p>There was a problem completing authentication.</p>
300
+ <div class="error-message">${errorMessage}</div>
301
+ </div>
302
+ </body>
303
+ </html>
304
+ `;
305
+ }
306
+ //# sourceMappingURL=auth-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-flow.js","sourceRoot":"","sources":["../../../src/lib/auth-flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ // Allow override via environment variable for testing
5
+ const CONFIG_DIR = process.env.PRIMITIVE_CONFIG_DIR || join(homedir(), ".primitive");
6
+ const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
7
+ function ensureConfigDir() {
8
+ if (!existsSync(CONFIG_DIR)) {
9
+ mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
10
+ }
11
+ }
12
+ export function loadCredentials() {
13
+ try {
14
+ if (!existsSync(CREDENTIALS_FILE)) {
15
+ return null;
16
+ }
17
+ const data = readFileSync(CREDENTIALS_FILE, "utf-8");
18
+ return JSON.parse(data);
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ export function saveCredentials(credentials) {
25
+ ensureConfigDir();
26
+ writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), {
27
+ mode: 0o600,
28
+ });
29
+ // Ensure file permissions are secure
30
+ chmodSync(CREDENTIALS_FILE, 0o600);
31
+ }
32
+ export function clearCredentials() {
33
+ try {
34
+ if (existsSync(CREDENTIALS_FILE)) {
35
+ writeFileSync(CREDENTIALS_FILE, "", { mode: 0o600 });
36
+ // Actually remove the file
37
+ const { unlinkSync } = require("fs");
38
+ unlinkSync(CREDENTIALS_FILE);
39
+ }
40
+ }
41
+ catch {
42
+ // Ignore errors
43
+ }
44
+ }
45
+ export function isTokenExpired(credentials) {
46
+ if (!credentials.expiresAt)
47
+ return true;
48
+ const expiresAt = new Date(credentials.expiresAt).getTime();
49
+ const now = Date.now();
50
+ // Consider expired if less than 60 seconds remaining
51
+ return expiresAt - now < 60 * 1000;
52
+ }
53
+ export function isTokenExpiringSoon(credentials) {
54
+ if (!credentials.expiresAt)
55
+ return true;
56
+ const expiresAt = new Date(credentials.expiresAt).getTime();
57
+ const now = Date.now();
58
+ // Consider expiring soon if less than 5 minutes remaining
59
+ return expiresAt - now < 5 * 60 * 1000;
60
+ }
61
+ export function setCurrentApp(appId, appName) {
62
+ const credentials = loadCredentials();
63
+ if (!credentials) {
64
+ throw new Error("Not logged in. Run 'primitive login' first.");
65
+ }
66
+ credentials.currentAppId = appId;
67
+ credentials.currentAppName = appName;
68
+ saveCredentials(credentials);
69
+ }
70
+ export function clearCurrentApp() {
71
+ const credentials = loadCredentials();
72
+ if (!credentials) {
73
+ return;
74
+ }
75
+ delete credentials.currentAppId;
76
+ delete credentials.currentAppName;
77
+ saveCredentials(credentials);
78
+ }
79
+ export function getCurrentAppId() {
80
+ const credentials = loadCredentials();
81
+ return credentials?.currentAppId;
82
+ }
83
+ export function getServerUrl() {
84
+ const credentials = loadCredentials();
85
+ if (!credentials?.serverUrl) {
86
+ throw new Error("Not logged in. Run 'primitive login' first.");
87
+ }
88
+ return credentials.serverUrl;
89
+ }
90
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import https from "https";
2
+ /**
3
+ * Custom fetch that accepts self-signed certificates for localhost.
4
+ * Used for local development with HTTPS.
5
+ */
6
+ export async function fetchWithTLS(url, options = {}) {
7
+ const urlObj = new URL(url);
8
+ // For localhost HTTPS, use a custom agent that accepts self-signed certs
9
+ if (urlObj.protocol === "https:" && (urlObj.hostname === "localhost" || urlObj.hostname === "127.0.0.1")) {
10
+ return new Promise((resolve, reject) => {
11
+ const postData = options.body || "";
12
+ const req = https.request({
13
+ hostname: urlObj.hostname,
14
+ port: urlObj.port || 443,
15
+ path: urlObj.pathname + urlObj.search,
16
+ method: options.method || "GET",
17
+ headers: options.headers,
18
+ rejectUnauthorized: false, // Accept self-signed certs
19
+ }, (res) => {
20
+ let data = "";
21
+ res.on("data", (chunk) => { data += chunk; });
22
+ res.on("end", () => {
23
+ resolve({
24
+ ok: res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300,
25
+ status: res.statusCode || 0,
26
+ statusText: res.statusMessage || "",
27
+ text: async () => data,
28
+ json: async () => JSON.parse(data),
29
+ headers: new Headers(res.headers),
30
+ });
31
+ });
32
+ });
33
+ req.on("error", reject);
34
+ if (postData) {
35
+ req.write(postData);
36
+ }
37
+ req.end();
38
+ });
39
+ }
40
+ // For non-localhost or HTTP, use standard fetch
41
+ return fetch(url, options);
42
+ }
43
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/lib/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,UAAuB,EAAE;IACvE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5B,yEAAyE;IACzE,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC,EAAE,CAAC;QACzG,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAc,IAAI,EAAE,CAAC;YAE9C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;gBACxB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,GAAG;gBACxB,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM;gBACrC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;gBAC/B,OAAO,EAAE,OAAO,CAAC,OAAiC;gBAClD,kBAAkB,EAAE,KAAK,EAAE,2BAA2B;aACvD,EAAE,CAAC,GAAG,EAAE,EAAE;gBACT,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACjB,OAAO,CAAC;wBACN,EAAE,EAAE,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG;wBACjF,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;wBAC3B,UAAU,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;wBACnC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;wBACtB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;wBAClC,OAAO,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,OAAiC,CAAC;qBAChD,CAAC,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACxB,IAAI,QAAQ,EAAE,CAAC;gBACb,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACtB,CAAC;YACD,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gDAAgD;IAChD,OAAO,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,143 @@
1
+ import chalk from "chalk";
2
+ export function formatTable(data, columns) {
3
+ if (data.length === 0) {
4
+ return chalk.dim("No results found.");
5
+ }
6
+ // Calculate column widths
7
+ const widths = columns.map((col) => {
8
+ const headerWidth = col.header.length;
9
+ const maxDataWidth = Math.max(...data.map((row) => {
10
+ const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? "");
11
+ return value.length;
12
+ }));
13
+ return col.width ?? Math.max(headerWidth, maxDataWidth);
14
+ });
15
+ // Format header
16
+ const header = columns
17
+ .map((col, i) => {
18
+ const text = col.header;
19
+ return padString(text, widths[i], col.align ?? "left");
20
+ })
21
+ .join(" ");
22
+ // Format separator
23
+ const separator = widths.map((w) => "-".repeat(w)).join(" ");
24
+ // Format rows
25
+ const rows = data.map((row) => columns
26
+ .map((col, i) => {
27
+ const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? "");
28
+ return padString(value, widths[i], col.align ?? "left");
29
+ })
30
+ .join(" "));
31
+ return [chalk.bold(header), chalk.dim(separator), ...rows].join("\n");
32
+ }
33
+ function padString(str, width, align) {
34
+ const stripped = stripAnsi(str);
35
+ const padding = Math.max(0, width - stripped.length);
36
+ if (align === "right") {
37
+ return " ".repeat(padding) + str;
38
+ }
39
+ else if (align === "center") {
40
+ const left = Math.floor(padding / 2);
41
+ const right = padding - left;
42
+ return " ".repeat(left) + str + " ".repeat(right);
43
+ }
44
+ return str + " ".repeat(padding);
45
+ }
46
+ function stripAnsi(str) {
47
+ // Simple ANSI escape code stripper
48
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
49
+ }
50
+ export function success(message) {
51
+ console.log(chalk.green("✓") + " " + message);
52
+ }
53
+ export function error(message) {
54
+ console.error(chalk.red("✗") + " " + message);
55
+ }
56
+ export function warn(message) {
57
+ console.log(chalk.yellow("!") + " " + message);
58
+ }
59
+ export function info(message) {
60
+ console.log(chalk.blue("i") + " " + message);
61
+ }
62
+ export function dim(message) {
63
+ console.log(chalk.dim(message));
64
+ }
65
+ export function heading(message) {
66
+ console.log(chalk.bold.underline(message));
67
+ }
68
+ export function json(data) {
69
+ console.log(JSON.stringify(data, null, 2));
70
+ }
71
+ export function formatDate(date) {
72
+ if (!date)
73
+ return chalk.dim("-");
74
+ const d = new Date(date);
75
+ return d.toISOString().replace("T", " ").slice(0, 19);
76
+ }
77
+ export function formatStatus(status) {
78
+ if (!status)
79
+ return "-";
80
+ switch (status.toLowerCase()) {
81
+ case "active":
82
+ return chalk.green(status);
83
+ case "draft":
84
+ return chalk.yellow(status);
85
+ case "archived":
86
+ case "deprecated":
87
+ return chalk.dim(status);
88
+ case "completed":
89
+ return chalk.green(status);
90
+ case "running":
91
+ case "pending":
92
+ return chalk.blue(status);
93
+ case "failed":
94
+ return chalk.red(status);
95
+ default:
96
+ return status;
97
+ }
98
+ }
99
+ export function formatId(id) {
100
+ // Truncate long IDs for display
101
+ if (id.length > 26) {
102
+ return id.slice(0, 26);
103
+ }
104
+ return id;
105
+ }
106
+ export function formatBoolean(value) {
107
+ if (value === true)
108
+ return chalk.green("yes");
109
+ if (value === false)
110
+ return chalk.dim("no");
111
+ return chalk.dim("-");
112
+ }
113
+ export function formatNumber(value) {
114
+ if (value === undefined || value === null)
115
+ return chalk.dim("-");
116
+ return value.toLocaleString();
117
+ }
118
+ export function formatDuration(ms) {
119
+ if (ms === undefined || ms === null)
120
+ return chalk.dim("-");
121
+ if (ms < 1000)
122
+ return `${ms}ms`;
123
+ if (ms < 60000)
124
+ return `${(ms / 1000).toFixed(1)}s`;
125
+ return `${(ms / 60000).toFixed(1)}m`;
126
+ }
127
+ export function formatPercent(value) {
128
+ if (value === undefined || value === null)
129
+ return chalk.dim("-");
130
+ return `${(value * 100).toFixed(1)}%`;
131
+ }
132
+ export function keyValue(label, value) {
133
+ const formattedValue = value === null || value === undefined
134
+ ? chalk.dim("-")
135
+ : typeof value === "boolean"
136
+ ? formatBoolean(value)
137
+ : String(value);
138
+ console.log(`${chalk.dim(label + ":")} ${formattedValue}`);
139
+ }
140
+ export function divider() {
141
+ console.log(chalk.dim("-".repeat(60)));
142
+ }
143
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/lib/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "primitive-admin",
3
+ "version": "1.0.0",
4
+ "description": "CLI for administering Primitive applications",
5
+ "type": "module",
6
+ "bin": {
7
+ "primitive": "./dist/bin/primitive.js"
8
+ },
9
+ "files": [
10
+ "dist/",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "typecheck": "tsc --noEmit",
16
+ "prepublishOnly": "pnpm run build",
17
+ "test": "vitest run --config vitest.config.ts",
18
+ "test:unit": "vitest run --config vitest.config.ts tests/unit",
19
+ "test:integration": "vitest run --config vitest.config.ts tests/integration"
20
+ },
21
+ "keywords": [
22
+ "primitive",
23
+ "cli",
24
+ "admin"
25
+ ],
26
+ "author": "Primitive LLC",
27
+ "license": "UNLICENSED",
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "dependencies": {
32
+ "@iarna/toml": "^2.2.5",
33
+ "@inquirer/prompts": "^7.5.0",
34
+ "@inquirer/search": "^4.1.0",
35
+ "chalk": "^5.3.0",
36
+ "commander": "^12.1.0",
37
+ "inquirer": "^9.2.12",
38
+ "open": "^10.0.3"
39
+ },
40
+ "devDependencies": {
41
+ "@types/inquirer": "^9.0.9",
42
+ "@types/node": "^20.17.6",
43
+ "tsx": "^4.20.3",
44
+ "typescript": "^5.7.2",
45
+ "vitest": "^1.6.1"
46
+ }
47
+ }