alpic 0.0.0-dev.f64e113 → 0.0.0-dev.f6bb60e

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 (118) hide show
  1. package/dist/__tests__/auth.e2e.test.d.ts +1 -0
  2. package/dist/__tests__/auth.e2e.test.js +142 -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 +101 -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__/fixtures/demo-project/index.d.ts +1 -0
  11. package/dist/__tests__/fixtures/demo-project/index.js +4 -0
  12. package/dist/__tests__/fixtures/demo-project/index.js.map +1 -0
  13. package/dist/__tests__/git-flags.e2e.test.d.ts +1 -0
  14. package/dist/__tests__/git-flags.e2e.test.js +124 -0
  15. package/dist/__tests__/git-flags.e2e.test.js.map +1 -0
  16. package/dist/__tests__/git.e2e.test.d.ts +1 -0
  17. package/dist/__tests__/git.e2e.test.js +221 -0
  18. package/dist/__tests__/git.e2e.test.js.map +1 -0
  19. package/dist/__tests__/mock-server.d.ts +22 -0
  20. package/dist/__tests__/mock-server.js +493 -0
  21. package/dist/__tests__/mock-server.js.map +1 -0
  22. package/dist/__tests__/utils.d.ts +67 -0
  23. package/dist/__tests__/utils.js +243 -0
  24. package/dist/__tests__/utils.js.map +1 -0
  25. package/dist/api.d.ts +3 -0
  26. package/dist/api.js +15 -0
  27. package/dist/api.js.map +1 -0
  28. package/dist/commands/deploy.d.ts +8 -2
  29. package/dist/commands/deploy.js +83 -71
  30. package/dist/commands/deploy.js.map +1 -1
  31. package/dist/commands/git/connect.d.ts +10 -0
  32. package/dist/commands/git/connect.js +61 -0
  33. package/dist/commands/git/connect.js.map +1 -0
  34. package/dist/commands/git/disconnect.d.ts +9 -0
  35. package/dist/commands/git/disconnect.js +45 -0
  36. package/dist/commands/git/disconnect.js.map +1 -0
  37. package/dist/commands/git.d.ts +6 -0
  38. package/dist/commands/git.js +17 -0
  39. package/dist/commands/git.js.map +1 -0
  40. package/dist/commands/login.d.ts +6 -0
  41. package/dist/commands/login.js +32 -0
  42. package/dist/commands/login.js.map +1 -0
  43. package/dist/commands/logout.d.ts +6 -0
  44. package/dist/commands/logout.js +20 -0
  45. package/dist/commands/logout.js.map +1 -0
  46. package/dist/commands/telemetry/disable.d.ts +5 -0
  47. package/dist/commands/telemetry/disable.js +14 -0
  48. package/dist/commands/telemetry/disable.js.map +1 -0
  49. package/dist/commands/telemetry/enable.d.ts +5 -0
  50. package/dist/commands/telemetry/enable.js +13 -0
  51. package/dist/commands/telemetry/enable.js.map +1 -0
  52. package/dist/commands/telemetry/status.d.ts +5 -0
  53. package/dist/commands/telemetry/status.js +19 -0
  54. package/dist/commands/telemetry/status.js.map +1 -0
  55. package/dist/commands/whoami.d.ts +6 -0
  56. package/dist/commands/whoami.js +13 -0
  57. package/dist/commands/whoami.js.map +1 -0
  58. package/dist/env.d.ts +4 -0
  59. package/dist/env.js +10 -0
  60. package/dist/env.js.map +1 -0
  61. package/dist/lib/alpic-command.d.ts +6 -0
  62. package/dist/lib/alpic-command.js +27 -0
  63. package/dist/lib/alpic-command.js.map +1 -0
  64. package/dist/lib/archive.d.ts +7 -0
  65. package/dist/lib/archive.js +51 -0
  66. package/dist/lib/archive.js.map +1 -0
  67. package/dist/lib/auth/auth.d.ts +2 -0
  68. package/dist/lib/auth/auth.js +21 -0
  69. package/dist/lib/auth/auth.js.map +1 -0
  70. package/dist/lib/auth/oauth/client.d.ts +28 -0
  71. package/dist/lib/auth/oauth/client.js +110 -0
  72. package/dist/lib/auth/oauth/client.js.map +1 -0
  73. package/dist/lib/auth/oauth/constants.d.ts +2 -0
  74. package/dist/lib/auth/oauth/constants.js +3 -0
  75. package/dist/lib/auth/oauth/constants.js.map +1 -0
  76. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  77. package/dist/lib/auth/oauth/server/assets/authorize.html +195 -0
  78. package/dist/lib/auth/oauth/server/assets/callback.html +88 -0
  79. package/dist/lib/auth/oauth/server/index.d.ts +8 -0
  80. package/dist/lib/auth/oauth/server/index.js +102 -0
  81. package/dist/lib/auth/oauth/server/index.js.map +1 -0
  82. package/dist/lib/auth/whoami.d.ts +1 -0
  83. package/dist/lib/auth/whoami.js +41 -0
  84. package/dist/lib/auth/whoami.js.map +1 -0
  85. package/dist/lib/base-workflow.d.ts +10 -0
  86. package/dist/lib/base-workflow.js +22 -0
  87. package/dist/lib/base-workflow.js.map +1 -0
  88. package/dist/lib/config.d.ts +11 -0
  89. package/dist/lib/config.js +31 -0
  90. package/dist/lib/config.js.map +1 -0
  91. package/dist/lib/deployment.d.ts +20 -0
  92. package/dist/lib/deployment.js +42 -0
  93. package/dist/lib/deployment.js.map +1 -0
  94. package/dist/lib/git.d.ts +22 -0
  95. package/dist/lib/git.js +133 -0
  96. package/dist/lib/git.js.map +1 -0
  97. package/dist/lib/global-store.d.ts +28 -0
  98. package/dist/lib/global-store.js +76 -0
  99. package/dist/lib/global-store.js.map +1 -0
  100. package/dist/lib/project.d.ts +71 -0
  101. package/dist/lib/project.js +297 -0
  102. package/dist/lib/project.js.map +1 -0
  103. package/dist/lib/telemetry.d.ts +7 -0
  104. package/dist/lib/telemetry.js +66 -0
  105. package/dist/lib/telemetry.js.map +1 -0
  106. package/dist/lib/upload.d.ts +1 -0
  107. package/dist/lib/upload.js +14 -0
  108. package/dist/lib/upload.js.map +1 -0
  109. package/dist/posthog.d.ts +3 -0
  110. package/dist/posthog.js +10 -0
  111. package/dist/posthog.js.map +1 -0
  112. package/dist/types.d.ts +7 -0
  113. package/dist/types.js +2 -0
  114. package/dist/types.js.map +1 -0
  115. package/package.json +35 -11
  116. package/dist/types/api.d.ts +0 -30
  117. package/dist/types/api.js +0 -2
  118. package/dist/types/api.js.map +0 -1
@@ -0,0 +1,243 @@
1
+ import pty from "node-pty";
2
+ import { execFileSync } from "node:child_process";
3
+ import { randomUUID } from "node:crypto";
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+ import { cp, mkdtemp, readFile } from "node:fs/promises";
6
+ import { tmpdir } from "node:os";
7
+ import { dirname, join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { expect } from "vitest";
10
+ const __testDirname = dirname(fileURLToPath(import.meta.url));
11
+ export async function cliSession(cmd, args, options, fn = async () => { }) {
12
+ const { cwd, env, cols = 100, rows = 30, timeoutMs = 8000 } = options;
13
+ const mergedEnv = {
14
+ ...process.env,
15
+ NO_COLOR: "1",
16
+ // Resolve @alpic-ai/api to TypeScript source via the "development" export condition,
17
+ // so e2e tests run without building the api package first.
18
+ NODE_OPTIONS: [process.env.NODE_OPTIONS, "--conditions=development"].filter(Boolean).join(" "),
19
+ NODE_TLS_REJECT_UNAUTHORIZED: "0",
20
+ ...Object.fromEntries(Object.entries(env ?? {}).filter(([, v]) => v !== undefined)),
21
+ };
22
+ for (const [k, v] of Object.entries(mergedEnv)) {
23
+ if (typeof v !== "string") {
24
+ console.error("[pty] bad env entry:", k, v, typeof v);
25
+ throw new Error(`env value for ${k} is not a string`);
26
+ }
27
+ }
28
+ const term = pty.spawn(cmd, args, {
29
+ cwd,
30
+ env: mergedEnv,
31
+ name: "xterm-256color",
32
+ cols,
33
+ rows,
34
+ });
35
+ let buf = "";
36
+ const append = (data) => {
37
+ buf += data;
38
+ };
39
+ term.onData(append);
40
+ let exitCode = null;
41
+ const exitPromise = new Promise((resolve) => {
42
+ term.onExit((e) => {
43
+ exitCode = e.exitCode ?? null;
44
+ resolve();
45
+ });
46
+ });
47
+ const controller = {
48
+ expect: (pattern, opts) => waitFor(() => matches(buf, pattern), opts?.timeoutMs ?? timeoutMs, () => buf, pattern),
49
+ send: async (line) => {
50
+ term.write(line + "\r");
51
+ },
52
+ write: (data) => term.write(data),
53
+ output: () => buf,
54
+ clear: () => {
55
+ buf = "";
56
+ },
57
+ stop: () => {
58
+ try {
59
+ term.kill();
60
+ }
61
+ catch {
62
+ // ignore
63
+ }
64
+ },
65
+ };
66
+ try {
67
+ await fn(controller);
68
+ }
69
+ finally {
70
+ await Promise.race([exitPromise, sleep(1500)]);
71
+ controller.stop();
72
+ await Promise.race([exitPromise, sleep(200)]);
73
+ }
74
+ return { exitCode, output: buf };
75
+ }
76
+ function matches(text, pattern) {
77
+ if (typeof pattern === "string")
78
+ return text.includes(pattern);
79
+ return pattern.test(text);
80
+ }
81
+ async function waitFor(predicate, timeoutMs, getOutput, pattern) {
82
+ const start = Date.now();
83
+ while (true) {
84
+ if (predicate())
85
+ return;
86
+ if (Date.now() - start > timeoutMs) {
87
+ const out = getOutput();
88
+ throw new Error(`Timed out after ${timeoutMs}ms waiting for: ${patternToString(pattern)}\n\n` +
89
+ `--- current output ---\n${out}\n--- end output ---\n`);
90
+ }
91
+ await sleep(20);
92
+ }
93
+ }
94
+ function patternToString(p) {
95
+ return typeof p === "string" ? JSON.stringify(p) : `/${p.source}/${p.flags}`;
96
+ }
97
+ function sleep(ms) {
98
+ return new Promise((r) => setTimeout(r, ms));
99
+ }
100
+ export function buildMockProject(params) {
101
+ const { projectId, teamId, projectName, environmentId, environmentName, sourceRepository = null, sourceBranch = null, } = params;
102
+ const mcpServerUrl = `https://mcp-${projectId}.alpic.ai`;
103
+ return {
104
+ id: projectId,
105
+ name: projectName,
106
+ teamId,
107
+ environments: [
108
+ {
109
+ id: environmentId,
110
+ name: environmentName,
111
+ sourceBranch,
112
+ mcpServerUrl,
113
+ createdAt: new Date(),
114
+ projectId,
115
+ latestDeployment: null,
116
+ },
117
+ ],
118
+ productionEnvironment: {
119
+ id: environmentId,
120
+ name: environmentName,
121
+ mcpServerUrl,
122
+ domains: [],
123
+ latestDeployment: null,
124
+ },
125
+ sourceRepository,
126
+ runtime: "node24",
127
+ transport: null,
128
+ rootDirectory: null,
129
+ buildCommand: null,
130
+ buildOutputDir: null,
131
+ installCommand: null,
132
+ startCommand: null,
133
+ createdAt: new Date(),
134
+ };
135
+ }
136
+ export async function setupTestDirectory(options = {}) {
137
+ const { initGit = false } = options;
138
+ const uniqueId = randomUUID();
139
+ const cwd = await mkdtemp(join(tmpdir(), `alpic-cli-e2e-${uniqueId}-`));
140
+ const fixturePath = join(__testDirname, "fixtures", "demo-project");
141
+ await cp(fixturePath, cwd, { recursive: true });
142
+ if (initGit) {
143
+ runGit(["init"], cwd);
144
+ runGit(["remote", "add", "origin", "git@github.com:acme/frontend.git"], cwd);
145
+ runGit(["remote", "add", "upstream", "https://github.com/acme/backend.git"], cwd);
146
+ }
147
+ const binPath = join(process.cwd(), "bin", "dev.js");
148
+ return { cwd, binPath };
149
+ }
150
+ export function createConfigFile(cwd, projectId, teamId, projectName, environmentId, environmentName) {
151
+ const configDir = join(cwd, ".alpic");
152
+ mkdirSync(configDir, { recursive: true });
153
+ const configPath = join(configDir, "project.json");
154
+ writeFileSync(configPath, JSON.stringify({
155
+ projectId,
156
+ teamId,
157
+ projectName,
158
+ environmentId,
159
+ environmentName,
160
+ }));
161
+ }
162
+ export function runGit(args, cwd) {
163
+ execFileSync("git", args, {
164
+ cwd,
165
+ stdio: ["ignore", "pipe", "pipe"],
166
+ });
167
+ }
168
+ export function expectSuccessfulApiCall(call, customAssertions) {
169
+ expect(call).toBeDefined();
170
+ expect(call?.responseStatus).toBe(200);
171
+ if (customAssertions && call) {
172
+ customAssertions(call);
173
+ }
174
+ }
175
+ /**
176
+ * Create OAuth credentials in a temp config dir and return env for CLI subprocess.
177
+ * Use this to run commands with OAuth auth (no ALPIC_API_KEY).
178
+ * Caller must pass serverUrl so userinfo can be pointed at the mock server.
179
+ */
180
+ export function createOAuthEnv(cwd, serverUrl) {
181
+ const alpicConfigDir = join(cwd, ".config", "alpic");
182
+ mkdirSync(alpicConfigDir, { recursive: true });
183
+ const credentialsPath = join(alpicConfigDir, "credentials.json");
184
+ const expiresAt = Math.floor(Date.now() / 1000) + 3600; // seconds
185
+ writeFileSync(credentialsPath, JSON.stringify({
186
+ access_token: "test-oauth-token",
187
+ refresh_token: "test-refresh-token",
188
+ expires_at: expiresAt,
189
+ sub: "test-sub",
190
+ }), "utf-8");
191
+ return {
192
+ ALPIC_GLOBAL_CONFIG_DIR: alpicConfigDir,
193
+ ALPIC_COGNITO_URL: serverUrl,
194
+ ALPIC_API_BASE_URL: serverUrl,
195
+ };
196
+ }
197
+ export async function verifyConfigFile(cwd, output, expected) {
198
+ const cfgPath = join(cwd, ".alpic", "project.json");
199
+ const cfg = await readFile(cfgPath, "utf8");
200
+ const config = JSON.parse(cfg);
201
+ expect(config.projectName).toBe(expected.projectName);
202
+ if (expected.projectId !== undefined) {
203
+ expect(config.projectId).toBe(expected.projectId);
204
+ }
205
+ else {
206
+ expect(config.projectId).toBeDefined();
207
+ }
208
+ if (expected.teamId !== undefined) {
209
+ expect(config.teamId).toBe(expected.teamId);
210
+ }
211
+ else {
212
+ expect(config.teamId).toBeDefined();
213
+ }
214
+ if (expected.environmentId !== undefined) {
215
+ expect(config.environmentId).toBe(expected.environmentId);
216
+ }
217
+ else {
218
+ expect(config.environmentId).toBeDefined();
219
+ }
220
+ if (expected.environmentName !== undefined) {
221
+ expect(config.environmentName).toBe(expected.environmentName);
222
+ }
223
+ else {
224
+ expect(config.environmentName).toBeDefined();
225
+ }
226
+ expect(output).toMatch(/Deployment completed|Deployment summary/);
227
+ }
228
+ export async function verifyDeploymentFlow(cli, mockServer) {
229
+ await cli.expect(/Collected \d+ file/);
230
+ await cli.expect("Upload complete");
231
+ const uploadCall = mockServer.getLastCall("POST", "/v1/deployments/upload");
232
+ expectSuccessfulApiCall(uploadCall);
233
+ await cli.expect("Deployment started");
234
+ const deployCall = mockServer.getLastCall("POST", /\/v1\/environments\/.*\/deploy/);
235
+ expectSuccessfulApiCall(deployCall);
236
+ await cli.expect("View deployment details:");
237
+ await cli.expect("Deployment summary:");
238
+ const deploymentStatusCalls = mockServer.getCalls("GET", /\/v1\/deployments\/.*/);
239
+ expect(deploymentStatusCalls.length).toBeGreaterThan(0);
240
+ const envCall = mockServer.getLastCall("GET", /\/v1\/environments\/.*/);
241
+ expectSuccessfulApiCall(envCall);
242
+ }
243
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/__tests__/utils.ts"],"names":[],"mappings":"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"}
package/dist/api.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { ContractRouterClient } from "@orpc/contract";
2
+ import { contract } from "@alpic-ai/api";
3
+ export declare const api: ContractRouterClient<typeof contract>;
package/dist/api.js ADDED
@@ -0,0 +1,15 @@
1
+ import { createORPCClient } from "@orpc/client";
2
+ import { ResponseValidationPlugin } from "@orpc/contract/plugins";
3
+ import { OpenAPILink } from "@orpc/openapi-client/fetch";
4
+ import { contract } from "@alpic-ai/api";
5
+ import { env } from "./env.js";
6
+ import { getApiToken } from "./lib/auth/auth.js";
7
+ const link = new OpenAPILink(contract, {
8
+ url: env.ALPIC_API_BASE_URL,
9
+ headers: async () => {
10
+ return getApiToken().then((token) => (token ? { Authorization: `Bearer ${token}` } : {}));
11
+ },
12
+ plugins: [new ResponseValidationPlugin(contract)],
13
+ });
14
+ export const api = createORPCClient(link);
15
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE;IACrC,GAAG,EAAE,GAAG,CAAC,kBAAkB;IAC3B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,OAAO,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,CAAC,IAAI,wBAAwB,CAAC,QAAQ,CAAC,CAAC;CAClD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,GAAG,GAA0C,gBAAgB,CAAC,IAAI,CAAC,CAAC"}
@@ -1,6 +1,12 @@
1
- import { Command } from "@oclif/core";
2
- export declare class Deploy extends Command {
1
+ import { AlpicCommand } from "../lib/alpic-command.js";
2
+ export declare class Deploy extends AlpicCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ static flags: {
6
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ runtime: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ "root-dir": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ "project-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
5
11
  run(): Promise<void>;
6
12
  }
@@ -1,89 +1,101 @@
1
1
  import * as p from "@clack/prompts";
2
- import { Command } from "@oclif/core";
3
- import { execSync } from "node:child_process";
4
- import { mkdtempSync, readFileSync, rmSync } from "node:fs";
5
- import { tmpdir } from "node:os";
6
- import { join } from "node:path";
7
- import { create as tarCreate } from "tar";
8
- const API_BASE_URL = "http://localhost:3000";
9
- export class Deploy extends Command {
2
+ import { Flags } from "@oclif/core";
3
+ import chalk from "chalk";
4
+ import { readFileSync, rmSync } from "node:fs";
5
+ import { api } from "../api.js";
6
+ import { AlpicCommand } from "../lib/alpic-command.js";
7
+ import { createTarArchive, getFilesToPack } from "../lib/archive.js";
8
+ import { deployAndWait, formatElapsed } from "../lib/deployment.js";
9
+ import { ProjectWorkflow } from "../lib/project.js";
10
+ import { uploadToPresignedUrl } from "../lib/upload.js";
11
+ const RUNTIMES = ["node24", "node22", "python3.14", "python3.13"];
12
+ export class Deploy extends AlpicCommand {
10
13
  static description = "Deploy a project to Alpic";
11
- static examples = ["<%= config.bin %> deploy"];
14
+ static examples = [
15
+ "<%= config.bin %> deploy",
16
+ "<%= config.bin %> deploy --yes --project-name my-app --runtime node24",
17
+ ];
18
+ static flags = {
19
+ yes: Flags.boolean({
20
+ char: "y",
21
+ description: "Skip all confirmation prompts",
22
+ required: false,
23
+ }),
24
+ runtime: Flags.string({
25
+ description: "New project runtime (node24, node22, python3.14, python3.13)",
26
+ required: false,
27
+ options: RUNTIMES,
28
+ }),
29
+ "root-dir": Flags.string({
30
+ description: "New project root directory (useful for monorepos)",
31
+ required: false,
32
+ }),
33
+ "project-name": Flags.string({
34
+ description: "New project name",
35
+ required: false,
36
+ }),
37
+ };
12
38
  async run() {
13
- await this.parse(Deploy);
39
+ const { flags } = await this.parse(Deploy);
40
+ const projectFlags = {
41
+ yes: flags.yes,
42
+ projectName: flags["project-name"],
43
+ runtime: flags.runtime,
44
+ rootDir: flags["root-dir"],
45
+ };
14
46
  p.intro("Deploying to Alpic");
15
- const apiKey = process.env.ALPIC_API_KEY;
16
- if (!apiKey) {
17
- p.cancel("ALPIC_API_KEY environment variable is required");
18
- this.exit(1);
47
+ await this.ensureAuthenticated();
48
+ const workflow = new ProjectWorkflow(projectFlags);
49
+ const config = await workflow.resolveProjectForDeploy();
50
+ if (!config) {
51
+ p.cancel("Deploy cancelled");
19
52
  return;
20
53
  }
21
54
  const spinner = p.spinner();
55
+ let tmpDir;
22
56
  try {
23
57
  spinner.start("Collecting source files...");
24
- const filesOutput = execSync("git ls-files -z --cached --others --exclude-standard", {
25
- encoding: "utf8",
26
- maxBuffer: 10 * 1024 * 1024,
27
- });
28
- const files = filesOutput.split("\0").filter(Boolean);
29
- if (files.length === 0) {
30
- spinner.stop("No files to deploy");
31
- p.cancel("No tracked or untracked files found. Ensure you are in a git repository with files to deploy.");
32
- this.exit(1);
33
- return;
34
- }
58
+ const files = getFilesToPack();
35
59
  spinner.stop(`Collected ${files.length} file${files.length === 1 ? "" : "s"}`);
36
- spinner.start("Creating archive...");
37
- const tmpDir = mkdtempSync(join(tmpdir(), "alpic-deploy-"));
38
- const archivePath = join(tmpDir, "source.tar.gz");
39
- await tarCreate({
40
- gzip: true,
41
- file: archivePath,
42
- cwd: process.cwd(),
43
- }, files);
44
- spinner.stop("Archive created");
45
- spinner.start("Getting upload URL...");
46
- const uploadRes = await fetch(`${API_BASE_URL}/v1/deployments/upload`, {
47
- method: "POST",
48
- headers: {
49
- "Content-Type": "application/json",
50
- Authorization: `Bearer ${apiKey}`,
51
- },
52
- });
53
- if (!uploadRes.ok) {
54
- const errBody = await uploadRes.text();
55
- spinner.stop("Failed to get upload URL");
56
- p.cancel(`API request failed: ${uploadRes.status} ${uploadRes.statusText} - ${errBody}`);
57
- this.exit(1);
58
- return;
59
- }
60
- const { uploadUrl, objectKey } = (await uploadRes.json());
61
- spinner.stop("Upload URL received");
60
+ const result = await createTarArchive(files);
61
+ tmpDir = result.tmpDir;
62
+ const archivePath = result.archivePath;
63
+ const { uploadUrl, token } = await api.deployments.uploadArtifact.v1();
62
64
  spinner.start("Uploading source...");
63
- const archiveBuffer = readFileSync(archivePath);
64
- rmSync(tmpDir, { recursive: true });
65
- const putRes = await fetch(uploadUrl, {
66
- method: "PUT",
67
- headers: {
68
- "Content-Type": "application/gzip",
69
- "Content-Length": String(archiveBuffer.byteLength),
70
- },
71
- body: archiveBuffer,
65
+ const buffer = readFileSync(archivePath);
66
+ await uploadToPresignedUrl(uploadUrl, buffer);
67
+ spinner.stop("Upload complete");
68
+ spinner.start("Triggering deployment...");
69
+ const deployStartedAt = Date.now();
70
+ const initialDeployment = await api.environments.deploy.v1({ environmentId: config.environmentId, token });
71
+ spinner.stop("Deployment started");
72
+ const { deployment, elapsedMs } = await deployAndWait({
73
+ initial: initialDeployment,
74
+ startedAt: deployStartedAt,
72
75
  });
73
- if (!putRes.ok) {
74
- spinner.stop("Upload failed");
75
- p.cancel(`Upload failed: ${putRes.status} ${putRes.statusText}`);
76
- this.exit(1);
77
- return;
76
+ const elapsedStr = formatElapsed(elapsedMs);
77
+ if (deployment.status !== "deployed") {
78
+ throw new Error("Deployment failed");
78
79
  }
79
- spinner.stop("Upload complete");
80
- p.outro("Source code uploaded successfully.");
81
- p.note(objectKey, "Artifact key (use this when triggering a deployment)");
80
+ const environment = await api.environments.get.v1({ environmentId: config.environmentId });
81
+ const urls = environment.mcpServerUrl ? [environment.mcpServerUrl] : environment.domains;
82
+ p.box([...urls.map((url) => chalk.bold(`🔗 ${url}`)), "", `Completed in ${elapsedStr}`].join("\n"), "Deployment summary:", {
83
+ contentAlign: "center",
84
+ titleAlign: "center",
85
+ width: "auto",
86
+ rounded: true,
87
+ contentPadding: 3,
88
+ });
82
89
  }
83
90
  catch (error) {
84
- spinner.stop("Deploy failed");
85
- p.cancel(`Error: ${error instanceof Error ? error.message : String(error)}`);
86
- this.exit(1);
91
+ spinner.stop();
92
+ const message = error instanceof Error ? error.message : String(error);
93
+ p.cancel(`Error: ${message}`);
94
+ }
95
+ finally {
96
+ if (tmpDir) {
97
+ rmSync(tmpDir, { recursive: true, force: true });
98
+ }
87
99
  }
88
100
  }
89
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { AlpicCommand } from "../../lib/alpic-command.js";
2
+ export default class GitConnect extends AlpicCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ "remote-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,61 @@
1
+ import * as p from "@clack/prompts";
2
+ import { Flags } from "@oclif/core";
3
+ import chalk from "chalk";
4
+ import { api } from "../../api.js";
5
+ import { AlpicCommand } from "../../lib/alpic-command.js";
6
+ import { config } from "../../lib/config.js";
7
+ import { GitWorkflow, confirmLinkAnotherIfAlreadyConnected, isGitRepository, listGithubRemotes, showGitSetupInstructions, } from "../../lib/git.js";
8
+ export default class GitConnect extends AlpicCommand {
9
+ static description = "Connect a linked Alpic project to a git remote source";
10
+ static examples = [
11
+ "<%= config.bin %> git connect",
12
+ "<%= config.bin %> git connect --yes",
13
+ "<%= config.bin %> git connect --remote-name origin",
14
+ ];
15
+ static flags = {
16
+ yes: Flags.boolean({
17
+ char: "y",
18
+ description: "Automatically select the remote when only one is available",
19
+ default: false,
20
+ }),
21
+ "remote-name": Flags.string({
22
+ description: "Name of the remote to connect",
23
+ }),
24
+ };
25
+ async run() {
26
+ const { flags } = await this.parse(GitConnect);
27
+ p.intro("Connecting git repository to Alpic");
28
+ await this.ensureAuthenticated();
29
+ const linkedConfig = config.load();
30
+ if (!linkedConfig) {
31
+ throw new Error("This directory is not linked to an Alpic project. Link it first using `alpic deploy`.");
32
+ }
33
+ if (!isGitRepository()) {
34
+ p.log.message("This directory is not a git repository.");
35
+ showGitSetupInstructions();
36
+ return;
37
+ }
38
+ const remotes = listGithubRemotes();
39
+ if (remotes.length === 0) {
40
+ p.log.message("This git repository has no remotes configured.");
41
+ showGitSetupInstructions();
42
+ return;
43
+ }
44
+ const project = await api.projects.get.v1({ projectId: linkedConfig.projectId });
45
+ if (!(await confirmLinkAnotherIfAlreadyConnected(project))) {
46
+ return;
47
+ }
48
+ const workflow = new GitWorkflow({ yes: flags.yes, remoteName: flags["remote-name"] });
49
+ const selectedSourceRepository = await workflow.selectRemoteSourceRepository(remotes);
50
+ if (selectedSourceRepository === null) {
51
+ throw new Error("No remote source repository selected.");
52
+ }
53
+ await api.projects.update.v1({
54
+ projectId: linkedConfig.projectId,
55
+ sourceRepository: selectedSourceRepository,
56
+ });
57
+ p.log.info("To automatically trigger deployments on every push,\nmake sure to install the Alpic GitHub App on this repository.");
58
+ p.outro(`✅ Connected ${chalk.bold(selectedSourceRepository)} to project ${chalk.bold(project.name)}.`);
59
+ }
60
+ }
61
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/commands/git/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { AlpicCommand } from "../../lib/alpic-command.js";
2
+ export default class GitDisconnect extends AlpicCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,45 @@
1
+ import * as p from "@clack/prompts";
2
+ import { Flags } from "@oclif/core";
3
+ import chalk from "chalk";
4
+ import { api } from "../../api.js";
5
+ import { AlpicCommand } from "../../lib/alpic-command.js";
6
+ import { config } from "../../lib/config.js";
7
+ import { GitWorkflow } from "../../lib/git.js";
8
+ export default class GitDisconnect extends AlpicCommand {
9
+ static description = "Disconnect a linked Alpic project from its git remote source";
10
+ static examples = ["<%= config.bin %> git disconnect", "<%= config.bin %> git disconnect --yes"];
11
+ static flags = {
12
+ yes: Flags.boolean({
13
+ char: "y",
14
+ description: "Skip the confirmation prompt",
15
+ default: false,
16
+ }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(GitDisconnect);
20
+ p.intro("Disconnecting git repository from Alpic");
21
+ await this.ensureAuthenticated();
22
+ const linkedConfig = config.load();
23
+ if (!linkedConfig) {
24
+ p.cancel("This directory is not linked to an Alpic project. Link it first using `alpic deploy`.");
25
+ return;
26
+ }
27
+ const project = await api.projects.get.v1({ projectId: linkedConfig.projectId });
28
+ if (!project.sourceRepository) {
29
+ p.cancel(`Project "${project.name}" is not connected to any repository.`);
30
+ return;
31
+ }
32
+ const workflow = new GitWorkflow({ yes: flags.yes });
33
+ const confirmed = await workflow.confirmDisconnect(project.sourceRepository, project.name);
34
+ if (!confirmed) {
35
+ p.cancel("Git disconnect cancelled");
36
+ return;
37
+ }
38
+ await api.projects.update.v1({
39
+ projectId: linkedConfig.projectId,
40
+ sourceRepository: null,
41
+ });
42
+ p.outro(`✅ Disconnected ${chalk.bold(project.sourceRepository)} from project ${chalk.bold(project.name)}.`);
43
+ }
44
+ }
45
+ //# sourceMappingURL=disconnect.js.map