alpic 0.0.0-dev.f5e699d → 0.0.0-dev.f610c40

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 (191) hide show
  1. package/dist/__tests__/auth.e2e.test.d.ts +1 -0
  2. package/dist/__tests__/auth.e2e.test.js +158 -0
  3. package/dist/__tests__/auth.e2e.test.js.map +1 -0
  4. package/dist/__tests__/deploy-flags.e2e.test.d.ts +1 -0
  5. package/dist/__tests__/deploy-flags.e2e.test.js +111 -0
  6. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -0
  7. package/dist/__tests__/deploy.e2e.test.d.ts +1 -0
  8. package/dist/__tests__/deploy.e2e.test.js +168 -0
  9. package/dist/__tests__/deploy.e2e.test.js.map +1 -0
  10. package/dist/__tests__/deployment-inspect.e2e.test.d.ts +1 -0
  11. package/dist/__tests__/deployment-inspect.e2e.test.js +113 -0
  12. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -0
  13. package/dist/__tests__/deployment-list.e2e.test.d.ts +1 -0
  14. package/dist/__tests__/deployment-list.e2e.test.js +116 -0
  15. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -0
  16. package/dist/__tests__/deployment-logs.e2e.test.d.ts +1 -0
  17. package/dist/__tests__/deployment-logs.e2e.test.js +255 -0
  18. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -0
  19. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.d.ts +1 -0
  20. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +260 -0
  21. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -0
  22. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.d.ts +1 -0
  23. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +140 -0
  24. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -0
  25. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.d.ts +1 -0
  26. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +151 -0
  27. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -0
  28. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.d.ts +1 -0
  29. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +343 -0
  30. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -0
  31. package/dist/__tests__/environment-variable/environment-variable-validation.test.d.ts +1 -0
  32. package/dist/__tests__/environment-variable/environment-variable-validation.test.js +20 -0
  33. package/dist/__tests__/environment-variable/environment-variable-validation.test.js.map +1 -0
  34. package/dist/__tests__/fixtures/demo-project/index.d.ts +1 -0
  35. package/dist/__tests__/fixtures/demo-project/index.js +4 -0
  36. package/dist/__tests__/fixtures/demo-project/index.js.map +1 -0
  37. package/dist/__tests__/git-flags.e2e.test.d.ts +1 -0
  38. package/dist/__tests__/git-flags.e2e.test.js +124 -0
  39. package/dist/__tests__/git-flags.e2e.test.js.map +1 -0
  40. package/dist/__tests__/git.e2e.test.d.ts +1 -0
  41. package/dist/__tests__/git.e2e.test.js +221 -0
  42. package/dist/__tests__/git.e2e.test.js.map +1 -0
  43. package/dist/__tests__/logs.e2e.test.d.ts +1 -0
  44. package/dist/__tests__/logs.e2e.test.js +227 -0
  45. package/dist/__tests__/logs.e2e.test.js.map +1 -0
  46. package/dist/__tests__/mock-server.d.ts +38 -0
  47. package/dist/__tests__/mock-server.js +728 -0
  48. package/dist/__tests__/mock-server.js.map +1 -0
  49. package/dist/__tests__/publish.e2e.test.d.ts +1 -0
  50. package/dist/__tests__/publish.e2e.test.js +505 -0
  51. package/dist/__tests__/publish.e2e.test.js.map +1 -0
  52. package/dist/__tests__/tunnel.e2e.test.d.ts +1 -0
  53. package/dist/__tests__/tunnel.e2e.test.js +64 -0
  54. package/dist/__tests__/tunnel.e2e.test.js.map +1 -0
  55. package/dist/__tests__/utils.d.ts +72 -0
  56. package/dist/__tests__/utils.js +272 -0
  57. package/dist/__tests__/utils.js.map +1 -0
  58. package/dist/api.d.ts +3 -16
  59. package/dist/api.js +14 -61
  60. package/dist/api.js.map +1 -1
  61. package/dist/commands/deploy.d.ts +7 -4
  62. package/dist/commands/deploy.js +52 -33
  63. package/dist/commands/deploy.js.map +1 -1
  64. package/dist/commands/deployment/inspect.d.ts +11 -0
  65. package/dist/commands/deployment/inspect.js +91 -0
  66. package/dist/commands/deployment/inspect.js.map +1 -0
  67. package/dist/commands/deployment/list.d.ts +11 -0
  68. package/dist/commands/deployment/list.js +97 -0
  69. package/dist/commands/deployment/list.js.map +1 -0
  70. package/dist/commands/deployment/logs.d.ts +12 -0
  71. package/dist/commands/deployment/logs.js +50 -0
  72. package/dist/commands/deployment/logs.js.map +1 -0
  73. package/dist/commands/environment-variable/add.d.ts +14 -0
  74. package/dist/commands/environment-variable/add.js +46 -0
  75. package/dist/commands/environment-variable/add.js.map +1 -0
  76. package/dist/commands/environment-variable/list.d.ts +9 -0
  77. package/dist/commands/environment-variable/list.js +44 -0
  78. package/dist/commands/environment-variable/list.js.map +1 -0
  79. package/dist/commands/environment-variable/remove.d.ts +11 -0
  80. package/dist/commands/environment-variable/remove.js +32 -0
  81. package/dist/commands/environment-variable/remove.js.map +1 -0
  82. package/dist/commands/environment-variable/update.d.ts +13 -0
  83. package/dist/commands/environment-variable/update.js +40 -0
  84. package/dist/commands/environment-variable/update.js.map +1 -0
  85. package/dist/commands/git/connect.d.ts +10 -0
  86. package/dist/commands/git/connect.js +60 -0
  87. package/dist/commands/git/connect.js.map +1 -0
  88. package/dist/commands/git/disconnect.d.ts +9 -0
  89. package/dist/commands/git/disconnect.js +45 -0
  90. package/dist/commands/git/disconnect.js.map +1 -0
  91. package/dist/commands/git.d.ts +6 -0
  92. package/dist/commands/git.js +17 -0
  93. package/dist/commands/git.js.map +1 -0
  94. package/dist/commands/login.d.ts +6 -0
  95. package/dist/commands/login.js +34 -0
  96. package/dist/commands/login.js.map +1 -0
  97. package/dist/commands/logout.d.ts +6 -0
  98. package/dist/commands/logout.js +20 -0
  99. package/dist/commands/logout.js.map +1 -0
  100. package/dist/commands/logs.d.ts +16 -0
  101. package/dist/commands/logs.js +96 -0
  102. package/dist/commands/logs.js.map +1 -0
  103. package/dist/commands/publish.d.ts +15 -0
  104. package/dist/commands/publish.js +51 -0
  105. package/dist/commands/publish.js.map +1 -0
  106. package/dist/commands/telemetry/disable.d.ts +5 -0
  107. package/dist/commands/telemetry/disable.js +14 -0
  108. package/dist/commands/telemetry/disable.js.map +1 -0
  109. package/dist/commands/telemetry/enable.d.ts +5 -0
  110. package/dist/commands/telemetry/enable.js +13 -0
  111. package/dist/commands/telemetry/enable.js.map +1 -0
  112. package/dist/commands/telemetry/status.d.ts +5 -0
  113. package/dist/commands/telemetry/status.js +19 -0
  114. package/dist/commands/telemetry/status.js.map +1 -0
  115. package/dist/commands/tunnel.d.ts +9 -0
  116. package/dist/commands/tunnel.js +53 -0
  117. package/dist/commands/tunnel.js.map +1 -0
  118. package/dist/commands/whoami.d.ts +6 -0
  119. package/dist/commands/whoami.js +13 -0
  120. package/dist/commands/whoami.js.map +1 -0
  121. package/dist/env.d.ts +4 -0
  122. package/dist/env.js +10 -0
  123. package/dist/env.js.map +1 -0
  124. package/dist/lib/alpic-command.d.ts +6 -0
  125. package/dist/lib/alpic-command.js +27 -0
  126. package/dist/lib/alpic-command.js.map +1 -0
  127. package/dist/lib/archive.d.ts +3 -3
  128. package/dist/lib/archive.js +11 -15
  129. package/dist/lib/archive.js.map +1 -1
  130. package/dist/lib/auth/auth.d.ts +2 -0
  131. package/dist/lib/auth/auth.js +21 -0
  132. package/dist/lib/auth/auth.js.map +1 -0
  133. package/dist/lib/auth/oauth/client.d.ts +28 -0
  134. package/dist/lib/auth/oauth/client.js +110 -0
  135. package/dist/lib/auth/oauth/client.js.map +1 -0
  136. package/dist/lib/auth/oauth/constants.d.ts +2 -0
  137. package/dist/lib/auth/oauth/constants.js +3 -0
  138. package/dist/lib/auth/oauth/constants.js.map +1 -0
  139. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  140. package/dist/lib/auth/oauth/server/assets/authorize.html +195 -0
  141. package/dist/lib/auth/oauth/server/assets/callback.html +88 -0
  142. package/dist/lib/auth/oauth/server/index.d.ts +8 -0
  143. package/dist/lib/auth/oauth/server/index.js +105 -0
  144. package/dist/lib/auth/oauth/server/index.js.map +1 -0
  145. package/dist/lib/auth/whoami.d.ts +1 -0
  146. package/dist/lib/auth/whoami.js +41 -0
  147. package/dist/lib/auth/whoami.js.map +1 -0
  148. package/dist/lib/base-workflow.d.ts +10 -0
  149. package/dist/lib/base-workflow.js +22 -0
  150. package/dist/lib/base-workflow.js.map +1 -0
  151. package/dist/lib/config.d.ts +2 -2
  152. package/dist/lib/config.js +7 -7
  153. package/dist/lib/config.js.map +1 -1
  154. package/dist/lib/deployment.d.ts +83 -6
  155. package/dist/lib/deployment.js +121 -9
  156. package/dist/lib/deployment.js.map +1 -1
  157. package/dist/lib/environment-variable.d.ts +41 -0
  158. package/dist/lib/environment-variable.js +311 -0
  159. package/dist/lib/environment-variable.js.map +1 -0
  160. package/dist/lib/git.d.ts +22 -0
  161. package/dist/lib/git.js +131 -0
  162. package/dist/lib/git.js.map +1 -0
  163. package/dist/lib/global-store.d.ts +28 -0
  164. package/dist/lib/global-store.js +76 -0
  165. package/dist/lib/global-store.js.map +1 -0
  166. package/dist/lib/logs.d.ts +20 -0
  167. package/dist/lib/logs.js +86 -0
  168. package/dist/lib/logs.js.map +1 -0
  169. package/dist/lib/project.d.ts +74 -11
  170. package/dist/lib/project.js +287 -142
  171. package/dist/lib/project.js.map +1 -1
  172. package/dist/lib/publish.d.ts +22 -0
  173. package/dist/lib/publish.js +188 -0
  174. package/dist/lib/publish.js.map +1 -0
  175. package/dist/lib/table.d.ts +8 -0
  176. package/dist/lib/table.js +27 -0
  177. package/dist/lib/table.js.map +1 -0
  178. package/dist/lib/telemetry.d.ts +7 -0
  179. package/dist/lib/telemetry.js +66 -0
  180. package/dist/lib/telemetry.js.map +1 -0
  181. package/dist/lib/utils.d.ts +4 -0
  182. package/dist/lib/utils.js +45 -0
  183. package/dist/lib/utils.js.map +1 -0
  184. package/dist/lib/utils.test.d.ts +1 -0
  185. package/dist/lib/utils.test.js +27 -0
  186. package/dist/lib/utils.test.js.map +1 -0
  187. package/dist/posthog.d.ts +3 -0
  188. package/dist/posthog.js +10 -0
  189. package/dist/posthog.js.map +1 -0
  190. package/dist/types.d.ts +0 -35
  191. package/package.json +41 -13
@@ -0,0 +1,86 @@
1
+ import chalk from "chalk";
2
+ import { api } from "../api.js";
3
+ const LOG_TYPE_COLORS = {
4
+ ERROR: chalk.red,
5
+ WARNING: chalk.yellow,
6
+ DEBUG: chalk.gray,
7
+ INFO: chalk.white,
8
+ START: chalk.dim,
9
+ END: chalk.dim,
10
+ };
11
+ const LOG_TYPE_LABELS = {
12
+ START: "START",
13
+ END: "END",
14
+ INFO: "INFO",
15
+ ERROR: "ERROR",
16
+ WARNING: "WARN",
17
+ DEBUG: "DEBUG",
18
+ };
19
+ const LOG_LEVEL_WIDTH = 5;
20
+ export function formatLogTimestamp(timestamp, noColor) {
21
+ if (!timestamp)
22
+ return "";
23
+ const formatted = timestamp.toISOString().replace("T", " ").slice(0, 23);
24
+ return noColor ? formatted : chalk.gray(formatted);
25
+ }
26
+ export function printLog(log, { noColor = false } = {}) {
27
+ const colorize = noColor ? (s) => s : (LOG_TYPE_COLORS[log.type] ?? chalk.white);
28
+ const ts = formatLogTimestamp(log.timestamp, noColor);
29
+ const shortRequestId = log.requestId.split("-")[0] ?? log.requestId;
30
+ const levelPrefix = `${LOG_TYPE_LABELS[log.type].padEnd(LOG_LEVEL_WIDTH, " ")} `;
31
+ let message;
32
+ if (log.type === "START") {
33
+ const methodPrefix = log.method ? `method: ${log.method}, ` : "";
34
+ const startMessage = `--- MCP REQUEST START --- (${methodPrefix}requestId: ${shortRequestId})`;
35
+ message = noColor ? startMessage : chalk.dim(startMessage);
36
+ process.stdout.write(`${ts} ${levelPrefix}${message}\n`);
37
+ return;
38
+ }
39
+ else if (log.type === "END") {
40
+ const durationSuffix = log.durationInMs !== undefined ? ` (duration: ${log.durationInMs}ms)` : "";
41
+ const endMessage = `--- MCP REQUEST END -----${durationSuffix}`;
42
+ message = noColor ? endMessage : chalk.dim(endMessage);
43
+ process.stdout.write(`${ts} ${levelPrefix}${message}\n`);
44
+ return;
45
+ }
46
+ else {
47
+ message = colorize(log.content ?? "");
48
+ }
49
+ process.stdout.write(`${ts} ${levelPrefix}${message}\n`);
50
+ }
51
+ export async function followEnvironmentLogs({ environmentId, limit, level, search, nextToken, initialLogs = [], pollIntervalMs = 3_000, onLog, }) {
52
+ const lastInitialLog = initialLogs.at(-1);
53
+ let lastTimestamp = lastInitialLog === undefined
54
+ ? new Date().toISOString()
55
+ : new Date(lastInitialLog.timestamp.getTime() + 1).toISOString();
56
+ let cursor = nextToken ?? null;
57
+ while (true) {
58
+ const options = {
59
+ environmentId,
60
+ since: lastTimestamp,
61
+ limit,
62
+ level,
63
+ search,
64
+ nextToken: cursor ?? undefined,
65
+ };
66
+ const response = await api.environments.getLogs.v1(options);
67
+ for (const log of response.logs) {
68
+ onLog(log);
69
+ lastTimestamp = new Date(log.timestamp.getTime() + 1).toISOString();
70
+ }
71
+ cursor = response.nextToken;
72
+ if (cursor === null) {
73
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
74
+ }
75
+ }
76
+ }
77
+ export function parseLevel(values) {
78
+ return values.map((value) => {
79
+ const normalized = value.toUpperCase();
80
+ if (!["INFO", "ERROR", "WARNING", "DEBUG"].includes(normalized)) {
81
+ throw new Error(`Invalid log level: "${value}". Valid values: info, error, warning, debug`);
82
+ }
83
+ return normalized;
84
+ });
85
+ }
86
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/lib/logs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAiBhC,MAAM,eAAe,GAA0C;IAC7D,KAAK,EAAE,KAAK,CAAC,GAAG;IAChB,OAAO,EAAE,KAAK,CAAC,MAAM;IACrB,KAAK,EAAE,KAAK,CAAC,IAAI;IACjB,IAAI,EAAE,KAAK,CAAC,KAAK;IACjB,KAAK,EAAE,KAAK,CAAC,GAAG;IAChB,GAAG,EAAE,KAAK,CAAC,GAAG;CACf,CAAC;AACF,MAAM,eAAe,GAA4C;IAC/D,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,OAAO;CACf,CAAC;AACF,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,UAAU,kBAAkB,CAAC,SAA2B,EAAE,OAAgB;IAC9E,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAoB,EAAE,EAAE,OAAO,GAAG,KAAK,KAA4B,EAAE;IAC5F,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACzF,MAAM,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC;IACpE,MAAM,WAAW,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,CAAC,IAAI,CAAC;IAElF,IAAI,OAAe,CAAC;IACpB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,YAAY,GAAG,8BAA8B,YAAY,cAAc,cAAc,GAAG,CAAC;QAC/F,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,WAAW,GAAG,OAAO,IAAI,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;SAAM,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClG,MAAM,UAAU,GAAG,4BAA4B,cAAc,EAAE,CAAC;QAChE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,WAAW,GAAG,OAAO,IAAI,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,WAAW,GAAG,OAAO,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC1C,aAAa,EACb,KAAK,EACL,KAAK,EACL,MAAM,EACN,SAAS,EACT,WAAW,GAAG,EAAE,EAChB,cAAc,GAAG,KAAK,EACtB,KAAK,GACuB;IAC5B,MAAM,cAAc,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,aAAa,GACf,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC1B,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACrE,IAAI,MAAM,GAAG,SAAS,IAAI,IAAI,CAAC;IAE/B,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG;YACd,aAAa;YACb,KAAK,EAAE,aAAa;YACpB,KAAK;YACL,KAAK;YACL,MAAM;YACN,SAAS,EAAE,MAAM,IAAI,SAAS;SAC/B,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAE5D,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,KAAK,CAAC,GAAG,CAAC,CAAC;YACX,aAAa,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACtE,CAAC;QAED,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC;QAE5B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAgB;IACzC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,8CAA8C,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,UAAsB,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,11 +1,74 @@
1
- import type { ApiEnvironment, ApiProject, ProjectConfig } from "../types.js";
2
- export declare function resolveDeployDir(raw: string | undefined): string;
3
- export declare function confirmDeployWithExistingConfig(existingConfig: ProjectConfig): Promise<boolean>;
4
- export declare function selectEnvironmentFromList(environments: ApiEnvironment[]): Promise<ApiEnvironment | null>;
5
- export declare function confirmDeployWithoutConfig(deployDir: string): Promise<boolean>;
6
- export declare function confirmLinkExisting(): Promise<boolean>;
7
- export declare function confirmLinkToAnotherProject(): Promise<boolean>;
8
- export declare function selectProjectFromList(projects: ApiProject[]): Promise<ApiProject | null>;
9
- export declare function resolveProjectForDeploy(deployDir: string): Promise<(ProjectConfig & {
10
- environmentId: string;
11
- }) | null>;
1
+ import type { RouterOutput, Runtime } from "@alpic-ai/api";
2
+ import type { ProjectConfig } from "../types.js";
3
+ import { BaseWorkflow } from "./base-workflow.js";
4
+ export type ProjectFlags = {
5
+ "non-interactive"?: boolean;
6
+ projectName?: string;
7
+ runtime?: Runtime;
8
+ rootDir?: string;
9
+ };
10
+ export declare const resolveProjectId: (flags: {
11
+ "project-id"?: string;
12
+ }) => string;
13
+ export declare class ProjectWorkflow extends BaseWorkflow<ProjectFlags> {
14
+ selectEnvironmentFromList(environments: RouterOutput["projects"]["get"]["v1"]["environments"]): Promise<(typeof environments)[number] | null>;
15
+ selectProjectFromList(projects: RouterOutput["projects"]["list"]["v1"]): Promise<{
16
+ id: string;
17
+ name: string;
18
+ teamId: string;
19
+ sourceRepository: string | null;
20
+ runtime: "python3.13" | "python3.14" | "node22" | "node24";
21
+ transport: "stdio" | "sse" | "streamablehttp" | null;
22
+ rootDirectory: string | null;
23
+ buildCommand: string | null;
24
+ buildOutputDir: string | null;
25
+ installCommand: string | null;
26
+ startCommand: string | null;
27
+ createdAt: Date;
28
+ productionEnvironment: {
29
+ id: string;
30
+ name: string;
31
+ mcpServerUrl: string;
32
+ domains: {
33
+ domain: string;
34
+ status: "ongoing" | "deployed" | "failed";
35
+ createdAt: Date;
36
+ }[];
37
+ latestDeployment: {
38
+ id: string;
39
+ status: "ongoing" | "deployed" | "failed" | "canceled";
40
+ sourceCommitId: string | null;
41
+ sourceCommitMessage: string | null;
42
+ completedAt: Date | null;
43
+ } | null;
44
+ } | null;
45
+ environments: {
46
+ id: string;
47
+ name: string;
48
+ sourceBranch: string | null;
49
+ mcpServerUrl: string;
50
+ createdAt: Date;
51
+ projectId: string;
52
+ latestDeployment: {
53
+ id: string;
54
+ status: "ongoing" | "deployed" | "failed" | "canceled";
55
+ sourceCommitId: string | null;
56
+ sourceCommitMessage: string | null;
57
+ completedAt: Date | null;
58
+ } | null;
59
+ }[];
60
+ } | null>;
61
+ promptRootDirectory(): Promise<string | null>;
62
+ private directoryExists;
63
+ private detectRuntime;
64
+ confirmDeployWithExistingConfig(existingConfig: ProjectConfig): Promise<boolean | null>;
65
+ confirmDeployDirectory(): Promise<boolean>;
66
+ confirmLinkExisting(): Promise<boolean>;
67
+ confirmLinkToAnotherProject(): Promise<boolean>;
68
+ resolveProjectForDeploy(): Promise<(ProjectConfig & {
69
+ environmentId: string;
70
+ }) | null>;
71
+ private resolveEnvironmentForProject;
72
+ private runCreateProjectFlow;
73
+ private runLinkingFlow;
74
+ }
@@ -1,161 +1,306 @@
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { resolve } from "node:path";
1
3
  import * as p from "@clack/prompts";
2
4
  import chalk from "chalk";
3
- import { existsSync, statSync } from "node:fs";
4
- import { resolve } from "node:path";
5
5
  import { api } from "../api.js";
6
+ import { BaseWorkflow } from "./base-workflow.js";
6
7
  import { config } from "./config.js";
7
- export function resolveDeployDir(raw) {
8
- const dir = resolve((raw ?? "").trim() || process.cwd());
9
- if (!existsSync(dir)) {
10
- throw new Error(`Path does not exist: ${dir}`);
8
+ export const resolveProjectId = (flags) => {
9
+ if (flags["project-id"]) {
10
+ return flags["project-id"];
11
11
  }
12
- if (!statSync(dir).isDirectory()) {
13
- throw new Error(`Path is not a directory: ${dir}`);
12
+ const projectId = config.load()?.projectId;
13
+ if (projectId !== undefined) {
14
+ p.log.info(`Using project id from .alpic config: ${chalk.bold(projectId)}`);
15
+ return projectId;
14
16
  }
15
- return dir;
16
- }
17
- export async function confirmDeployWithExistingConfig(existingConfig) {
18
- const envLabel = existingConfig.environmentName ? ` to environment "${existingConfig.environmentName}"` : "";
19
- const confirm = await p.confirm({
20
- message: chalk.bold(`Deploy project "${existingConfig.projectName}"${envLabel}?`),
21
- initialValue: true,
22
- });
23
- if (p.isCancel(confirm))
24
- return false;
25
- return confirm === true;
26
- }
27
- export async function selectEnvironmentFromList(environments) {
28
- if (environments.length === 0) {
29
- return null;
17
+ throw new Error("No project specified. Use --project-id <projectId> or run from a linked directory.");
18
+ };
19
+ export class ProjectWorkflow extends BaseWorkflow {
20
+ async selectEnvironmentFromList(environments) {
21
+ if (environments.length === 0) {
22
+ return null;
23
+ }
24
+ const choice = await p.select({
25
+ message: chalk.bold("Choose an environment to deploy to"),
26
+ options: environments.map((env) => ({
27
+ value: env.id,
28
+ label: env.sourceBranch ? `${env.name} (${env.sourceBranch})` : env.name,
29
+ })),
30
+ });
31
+ if (p.isCancel(choice))
32
+ return null;
33
+ const environment = environments.find((e) => e.id === choice);
34
+ return environment ?? null;
30
35
  }
31
- const choice = await p.select({
32
- message: chalk.bold("Choose an environment to deploy to"),
33
- options: environments.map((env) => ({
34
- value: env.id,
35
- label: `${env.name} (${env.sourceBranch})`,
36
- })),
37
- });
38
- if (p.isCancel(choice))
39
- return null;
40
- const environment = environments.find((e) => e.id === choice);
41
- return environment ?? null;
42
- }
43
- export async function confirmDeployWithoutConfig(deployDir) {
44
- const confirm = await p.confirm({
45
- message: chalk.bold(`Deploy the directory? `) + chalk.cyan(deployDir),
46
- initialValue: true,
47
- });
48
- if (p.isCancel(confirm))
49
- return false;
50
- return confirm === true;
51
- }
52
- export async function confirmLinkExisting() {
53
- const link = await p.confirm({
54
- message: chalk.bold("Link to existing project?"),
55
- initialValue: true,
56
- });
57
- if (p.isCancel(link))
58
- return false;
59
- return link === true;
60
- }
61
- export async function confirmLinkToAnotherProject() {
62
- const link = await p.confirm({
63
- message: chalk.bold("Link to another project?"),
64
- initialValue: true,
65
- });
66
- if (p.isCancel(link))
67
- return false;
68
- return link === true;
69
- }
70
- export async function selectProjectFromList(projects) {
71
- if (projects.length === 0) {
72
- return null;
36
+ async selectProjectFromList(projects) {
37
+ if (projects.length === 0) {
38
+ return null;
39
+ }
40
+ const choice = await p.select({
41
+ message: chalk.bold("Choose a project"),
42
+ options: projects.map((proj) => ({ value: proj.id, label: proj.name })),
43
+ });
44
+ if (p.isCancel(choice))
45
+ return null;
46
+ const project = projects.find((proj) => proj.id === choice);
47
+ return project ?? null;
73
48
  }
74
- const choice = await p.select({
75
- message: chalk.bold("Choose a project"),
76
- options: projects.map((proj) => ({ value: proj.id, label: proj.name })),
77
- });
78
- if (p.isCancel(choice))
79
- return null;
80
- const project = projects.find((proj) => proj.id === choice);
81
- return project ?? null;
82
- }
83
- async function resolveEnvironmentForProject(projectId) {
84
- const project = await api.getProject(projectId);
85
- const environments = project.environments ?? [];
86
- if (environments.length === 0) {
87
- throw new Error("No environments found for this project.");
49
+ async promptRootDirectory() {
50
+ if (this.isNonInteractive()) {
51
+ if (this.flags.rootDir) {
52
+ const trimmed = this.flags.rootDir.trim();
53
+ if (trimmed === "" || trimmed === ".")
54
+ return null;
55
+ if (!this.directoryExists(trimmed)) {
56
+ throw new Error(`Directory does not exist: ${resolve(trimmed)}`);
57
+ }
58
+ return trimmed;
59
+ }
60
+ return null;
61
+ }
62
+ while (true) {
63
+ const rootDir = await p.text({
64
+ message: chalk.bold("Root directory"),
65
+ placeholder: ".",
66
+ initialValue: ".",
67
+ validate: (value) => {
68
+ if (value != null && value.length > 512)
69
+ return "Path must be at most 512 characters.";
70
+ return undefined;
71
+ },
72
+ });
73
+ if (p.isCancel(rootDir))
74
+ return null;
75
+ const trimmed = rootDir.trim();
76
+ if (trimmed === "" || trimmed === ".")
77
+ return null;
78
+ if (!this.directoryExists(trimmed)) {
79
+ p.log.error(`Directory does not exist: ${trimmed}`);
80
+ continue;
81
+ }
82
+ return trimmed;
83
+ }
88
84
  }
89
- const environment = await selectEnvironmentFromList(environments);
90
- if (!environment)
85
+ directoryExists(dir) {
86
+ return existsSync(dir) && statSync(dir).isDirectory();
87
+ }
88
+ detectRuntime() {
89
+ const has = (file) => existsSync(file);
90
+ const read = (file) => {
91
+ try {
92
+ return readFileSync(file, "utf8");
93
+ }
94
+ catch {
95
+ return "";
96
+ }
97
+ };
98
+ if (has("pyproject.toml") || has("requirements.txt") || has("setup.py") || has(".python-version")) {
99
+ return "python3.13";
100
+ }
101
+ if (has("package.json")) {
102
+ const nvmrc = has(".nvmrc") ? (read(".nvmrc").trim().split(/\s/)[0] ?? "") : "";
103
+ const major = nvmrc.replace(/^v/i, "").match(/^(\d+)/)?.[1];
104
+ if (major === "22")
105
+ return "node22";
106
+ return "node24";
107
+ }
91
108
  return null;
92
- return { environmentId: environment.id, environmentName: environment.name };
93
- }
94
- export async function resolveProjectForDeploy(deployDir) {
95
- const existingConfig = config.load(deployDir);
96
- if (existingConfig) {
97
- const confirm = await confirmDeployWithExistingConfig(existingConfig);
98
- if (!confirm) {
99
- const linkAnother = await confirmLinkToAnotherProject();
100
- if (!linkAnother)
109
+ }
110
+ async confirmDeployWithExistingConfig(existingConfig) {
111
+ const envLabel = existingConfig.environmentName ? ` to environment "${existingConfig.environmentName}"` : "";
112
+ const confirmed = await this.confirm({
113
+ message: chalk.bold(`Deploy project "${existingConfig.projectName}"${envLabel}?`),
114
+ initialValue: true,
115
+ });
116
+ if (p.isCancel(confirmed))
117
+ return null;
118
+ return confirmed === true;
119
+ }
120
+ async confirmDeployDirectory() {
121
+ const confirmed = await this.confirm({
122
+ message: chalk.bold(`Deploy the directory? `) + chalk.cyan(process.cwd()),
123
+ initialValue: true,
124
+ });
125
+ if (p.isCancel(confirmed))
126
+ return false;
127
+ return confirmed === true;
128
+ }
129
+ async confirmLinkExisting() {
130
+ const link = await this.confirm({
131
+ message: chalk.bold("Link to existing project?"),
132
+ initialValue: true,
133
+ }, false);
134
+ if (p.isCancel(link))
135
+ return false;
136
+ return link === true;
137
+ }
138
+ async confirmLinkToAnotherProject() {
139
+ const link = await this.confirm({
140
+ message: chalk.bold("Link to another project?"),
141
+ initialValue: true,
142
+ }, false);
143
+ if (p.isCancel(link))
144
+ return false;
145
+ return link === true;
146
+ }
147
+ async resolveProjectForDeploy() {
148
+ const ok = await this.confirmDeployDirectory();
149
+ if (!ok)
150
+ return null;
151
+ const existingConfig = config.load();
152
+ if (existingConfig) {
153
+ let confirmed;
154
+ while (true) {
155
+ confirmed = await this.confirmDeployWithExistingConfig(existingConfig);
156
+ if (confirmed === null)
157
+ return null;
158
+ if (confirmed)
159
+ break;
160
+ const linkAnother = await this.confirmLinkToAnotherProject();
161
+ if (p.isCancel(linkAnother))
162
+ return null;
163
+ if (linkAnother) {
164
+ const linkExisting = await this.confirmLinkExisting();
165
+ if (!linkExisting) {
166
+ return this.runCreateProjectFlow();
167
+ }
168
+ return this.runLinkingFlow();
169
+ }
170
+ }
171
+ if (existingConfig.environmentId) {
172
+ return {
173
+ projectId: existingConfig.projectId,
174
+ teamId: existingConfig.teamId,
175
+ projectName: existingConfig.projectName,
176
+ environmentId: existingConfig.environmentId,
177
+ environmentName: existingConfig.environmentName,
178
+ };
179
+ }
180
+ const env = await this.resolveEnvironmentForProject(existingConfig.projectId);
181
+ if (!env)
101
182
  return null;
102
- return runLinkingFlow(deployDir);
103
- }
104
- if (existingConfig.environmentId) {
105
- return {
106
- projectId: existingConfig.projectId,
107
- teamId: existingConfig.teamId,
108
- projectName: existingConfig.projectName,
109
- environmentId: existingConfig.environmentId,
110
- environmentName: existingConfig.environmentName,
183
+ const updatedConfig = {
184
+ ...existingConfig,
185
+ environmentId: env.environmentId,
186
+ environmentName: env.environmentName,
111
187
  };
188
+ config.save(updatedConfig);
189
+ p.note(`Environment "${env.environmentName}" will be used for future deploys.`, undefined, {
190
+ format: (line) => line,
191
+ });
192
+ return updatedConfig;
112
193
  }
113
- const env = await resolveEnvironmentForProject(existingConfig.projectId);
114
- if (!env)
115
- return null;
116
- const updatedConfig = {
117
- ...existingConfig,
118
- environmentId: env.environmentId,
119
- environmentName: env.environmentName,
120
- };
121
- config.save(updatedConfig, deployDir);
122
- p.note(`Environment "${env.environmentName}" will be used for future deploys.`);
123
- return updatedConfig;
194
+ const linkExisting = await this.confirmLinkExisting();
195
+ if (!linkExisting) {
196
+ return this.runCreateProjectFlow();
197
+ }
198
+ return this.runLinkingFlow();
124
199
  }
125
- const ok = await confirmDeployWithoutConfig(deployDir);
126
- if (!ok)
127
- return null;
128
- const linkExisting = await confirmLinkExisting();
129
- if (!linkExisting) {
130
- p.note("Creating a new project is not implemented yet.", "Not yet implemented");
131
- return null;
200
+ async resolveEnvironmentForProject(projectId) {
201
+ const project = await api.projects.get.v1({ projectId });
202
+ const environments = project.environments ?? [];
203
+ if (environments.length === 0) {
204
+ throw new Error("No environments found for this project.");
205
+ }
206
+ const environment = await this.selectEnvironmentFromList(environments);
207
+ if (!environment)
208
+ return null;
209
+ return { environmentId: environment.id, environmentName: environment.name };
132
210
  }
133
- return runLinkingFlow(deployDir);
134
- }
135
- async function runLinkingFlow(deployDir) {
136
- const projects = await api.listProjects();
137
- if (projects.length === 0) {
138
- throw new Error("No projects found. Create a project in the Alpic dashboard first.");
211
+ async runCreateProjectFlow() {
212
+ if (this.isNonInteractive() && !this.flags.projectName) {
213
+ throw new Error("--project-name is required when using --non-interactive");
214
+ }
215
+ const name = this.flags.projectName ??
216
+ (await p.text({
217
+ message: chalk.bold("Project name"),
218
+ placeholder: "my-app",
219
+ validate: (value) => {
220
+ if (!value?.trim())
221
+ return "Project name is required.";
222
+ if (value.length > 100)
223
+ return "Project name must be at most 100 characters.";
224
+ return undefined;
225
+ },
226
+ }));
227
+ if (p.isCancel(name)) {
228
+ throw new Error("Project name is required.");
229
+ }
230
+ const detectedRuntime = this.detectRuntime();
231
+ const defaultRuntime = detectedRuntime ?? "node24";
232
+ const runtime = this.isNonInteractive()
233
+ ? (this.flags.runtime ?? defaultRuntime)
234
+ : await p.select({
235
+ message: chalk.bold("Runtime"),
236
+ options: [
237
+ { value: "node24", label: "Node.js 24" },
238
+ { value: "node22", label: "Node.js 22" },
239
+ { value: "python3.14", label: "Python 3.14" },
240
+ { value: "python3.13", label: "Python 3.13" },
241
+ ],
242
+ initialValue: defaultRuntime,
243
+ });
244
+ if (p.isCancel(runtime)) {
245
+ throw new Error("Runtime is required.");
246
+ }
247
+ const rootDirectory = await this.promptRootDirectory();
248
+ const spin = p.spinner();
249
+ spin.start("Creating project...");
250
+ try {
251
+ const projectInput = {
252
+ name,
253
+ runtime,
254
+ };
255
+ projectInput.rootDirectory = rootDirectory ?? undefined;
256
+ const created = await api.projects.create.v1(projectInput);
257
+ spin.stop("Project created.");
258
+ const productionEnv = created.productionEnvironment;
259
+ if (!productionEnv) {
260
+ throw new Error("Project was created but has no Production environment.");
261
+ }
262
+ const newConfig = {
263
+ projectId: created.id,
264
+ teamId: created.teamId,
265
+ projectName: created.name,
266
+ environmentId: productionEnv.id,
267
+ environmentName: productionEnv.name,
268
+ };
269
+ config.save(newConfig);
270
+ return newConfig;
271
+ }
272
+ catch (error) {
273
+ spin.stop();
274
+ throw error;
275
+ }
139
276
  }
140
- const project = await selectProjectFromList(projects);
141
- if (!project)
142
- return null;
143
- const environments = project.environments ?? [];
144
- if (environments.length === 0) {
145
- throw new Error("No environments found for this project.");
277
+ async runLinkingFlow() {
278
+ const projects = await api.projects.list.v1();
279
+ if (projects.length === 0) {
280
+ throw new Error("No projects found. Create a project in the Alpic dashboard first.");
281
+ }
282
+ const project = await this.selectProjectFromList(projects);
283
+ if (!project)
284
+ return null;
285
+ const environments = project.environments ?? [];
286
+ if (environments.length === 0) {
287
+ throw new Error("No environments found for this project.");
288
+ }
289
+ const environment = await this.selectEnvironmentFromList(environments);
290
+ if (!environment)
291
+ return null;
292
+ const newConfig = {
293
+ projectId: project.id,
294
+ teamId: project.teamId,
295
+ projectName: project.name,
296
+ environmentId: environment.id,
297
+ environmentName: environment.name,
298
+ };
299
+ config.save(newConfig);
300
+ p.note(`Linked to project "${project.name}", environment "${environment.name}".`, undefined, {
301
+ format: (line) => line,
302
+ });
303
+ return newConfig;
146
304
  }
147
- const environment = await selectEnvironmentFromList(environments);
148
- if (!environment)
149
- return null;
150
- const newConfig = {
151
- projectId: project.id,
152
- teamId: project.teamId,
153
- projectName: project.name,
154
- environmentId: environment.id,
155
- environmentName: environment.name,
156
- };
157
- config.save(newConfig, deployDir);
158
- p.note(`Linked to project "${project.name}", environment "${environment.name}".`);
159
- return newConfig;
160
305
  }
161
306
  //# sourceMappingURL=project.js.map