@percher/core 0.4.13 → 0.4.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/deploy-repo.d.ts +28 -0
- package/dist/commands/deploy-repo.d.ts.map +1 -0
- package/dist/commands/deploy-repo.js +265 -0
- package/dist/commands/deploy-repo.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -32
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts +37 -5
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +39 -6
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/publish-from-repo.d.ts +22 -0
- package/dist/commands/publish-from-repo.d.ts.map +1 -0
- package/dist/commands/publish-from-repo.js +236 -0
- package/dist/commands/publish-from-repo.js.map +1 -0
- package/dist/commands/publish-inline.d.ts +32 -0
- package/dist/commands/publish-inline.d.ts.map +1 -0
- package/dist/commands/publish-inline.js +339 -0
- package/dist/commands/publish-inline.js.map +1 -0
- package/dist/commands/publish.d.ts +63 -0
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +34 -4
- package/dist/commands/publish.js.map +1 -1
- package/dist/detect.d.ts +19 -0
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +128 -39
- package/dist/detect.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/static-docker.d.ts.map +1 -1
- package/dist/static-docker.js +2 -1
- package/dist/static-docker.js.map +1 -1
- package/dist/tarball.d.ts +39 -1
- package/dist/tarball.d.ts.map +1 -1
- package/dist/tarball.js +92 -16
- package/dist/tarball.js.map +1 -1
- package/dist/templates.d.ts +6 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +8 -0
- package/dist/templates.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Context } from "../context.js";
|
|
3
|
+
import type { PublishResult } from "./publish.js";
|
|
4
|
+
export declare const deployRepoInputSchema: z.ZodObject<{
|
|
5
|
+
app: z.ZodString;
|
|
6
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
7
|
+
note: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type DeployRepoInput = z.infer<typeof deployRepoInputSchema>;
|
|
10
|
+
/**
|
|
11
|
+
* Hosted MCP deploy command (plan §0a "Hosted deploy" / Phase 5) — deploy
|
|
12
|
+
* the LATEST commit of an app's connected GitHub/Forgejo repo. This is the
|
|
13
|
+
* hosted "deploy my app" path: a filesystem-free agent has no `cwd` and
|
|
14
|
+
* cannot upload local files, so `app` is REQUIRED (no percher.toml fallback)
|
|
15
|
+
* and the source is always the connected repo's tracked-branch HEAD.
|
|
16
|
+
*
|
|
17
|
+
* Wraps the API's POST /apps/:appRef/deploys/from-latest-commit (which
|
|
18
|
+
* reuses the connect/webhook clone+package+enqueue machinery) and polls to
|
|
19
|
+
* terminal status. Returns the same PublishResult shape as `redeploy` so
|
|
20
|
+
* CLI/MCP consumers reuse rendering + recovery logic, including the
|
|
21
|
+
* `wait_deploy` hand-off so an agent can chain `percher_wait_for_deploy`.
|
|
22
|
+
*
|
|
23
|
+
* NO_CONNECTED_REPO surfaces as an actionable error: the app must have a
|
|
24
|
+
* connected repo before this path works, which the agent should relay to
|
|
25
|
+
* the user (connect a repo first).
|
|
26
|
+
*/
|
|
27
|
+
export declare function deployRepo(ctx: Context, input: DeployRepoInput): Promise<PublishResult>;
|
|
28
|
+
//# sourceMappingURL=deploy-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-repo.d.ts","sourceRoot":"","sources":["../../src/commands/deploy-repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,WAAW,CAAC;AAG7D,eAAO,MAAM,qBAAqB;;;;iBAIhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAoO7F"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { PercherApiError } from "@percher/client";
|
|
2
|
+
import { TIMEOUTS } from "@percher/shared/timeouts";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { pollDeployment } from "../poll-deployment.js";
|
|
5
|
+
import { RECOVERY_NEEDS_LOGIN, RECOVERY_NONE, recoveryAsk, recoveryFixConfig } from "../recovery.js";
|
|
6
|
+
import { classifyDeploymentFailure } from "./publish-failure.js";
|
|
7
|
+
export const deployRepoInputSchema = z.object({
|
|
8
|
+
app: z.string().describe("App name or id (required — hosted has no cwd)."),
|
|
9
|
+
branch: z.string().optional().describe("Branch to deploy. Defaults to the app's tracked branch."),
|
|
10
|
+
note: z.string().optional().describe("Optional note recorded against the deploy."),
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Hosted MCP deploy command (plan §0a "Hosted deploy" / Phase 5) — deploy
|
|
14
|
+
* the LATEST commit of an app's connected GitHub/Forgejo repo. This is the
|
|
15
|
+
* hosted "deploy my app" path: a filesystem-free agent has no `cwd` and
|
|
16
|
+
* cannot upload local files, so `app` is REQUIRED (no percher.toml fallback)
|
|
17
|
+
* and the source is always the connected repo's tracked-branch HEAD.
|
|
18
|
+
*
|
|
19
|
+
* Wraps the API's POST /apps/:appRef/deploys/from-latest-commit (which
|
|
20
|
+
* reuses the connect/webhook clone+package+enqueue machinery) and polls to
|
|
21
|
+
* terminal status. Returns the same PublishResult shape as `redeploy` so
|
|
22
|
+
* CLI/MCP consumers reuse rendering + recovery logic, including the
|
|
23
|
+
* `wait_deploy` hand-off so an agent can chain `percher_wait_for_deploy`.
|
|
24
|
+
*
|
|
25
|
+
* NO_CONNECTED_REPO surfaces as an actionable error: the app must have a
|
|
26
|
+
* connected repo before this path works, which the agent should relay to
|
|
27
|
+
* the user (connect a repo first).
|
|
28
|
+
*/
|
|
29
|
+
export async function deployRepo(ctx, input) {
|
|
30
|
+
const t0 = Date.now();
|
|
31
|
+
const appName = input.app;
|
|
32
|
+
let app;
|
|
33
|
+
try {
|
|
34
|
+
app = await ctx.client.apps.get(appName);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof PercherApiError) {
|
|
38
|
+
// Mirror redeploy: only 404 is a "wrong app name" signal. 401 is
|
|
39
|
+
// auth; anything else is a real error worth bubbling so the caller
|
|
40
|
+
// sees the actual API failure rather than a misleading "not found".
|
|
41
|
+
if (err.status === 401) {
|
|
42
|
+
return {
|
|
43
|
+
status: "needs_login",
|
|
44
|
+
fileCount: 0,
|
|
45
|
+
bytes: 0,
|
|
46
|
+
recovery: RECOVERY_NEEDS_LOGIN,
|
|
47
|
+
summary: "Not logged in — run `bunx percher login` first.",
|
|
48
|
+
configPath: "",
|
|
49
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (err.status === 404) {
|
|
53
|
+
return failureResult({
|
|
54
|
+
title: "App not found",
|
|
55
|
+
explanation: `Could not resolve app "${appName}".`,
|
|
56
|
+
suggestion: "Check the app name with `bunx percher whoami` or your dashboard.",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
ctx.status(`Deploying latest commit for ${app.name}...`);
|
|
63
|
+
let initial;
|
|
64
|
+
try {
|
|
65
|
+
initial = await ctx.client.apps.deployLatestCommit(app.id, {
|
|
66
|
+
...(input.branch ? { branch: input.branch } : {}),
|
|
67
|
+
...(input.note ? { note: input.note } : {}),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if (err instanceof PercherApiError) {
|
|
72
|
+
if (err.code === "NO_CONNECTED_REPO") {
|
|
73
|
+
// The marquee precondition: there's nothing to deploy from. This
|
|
74
|
+
// is not retryable as-is — the user must connect a repo first, so
|
|
75
|
+
// route it through fix_config (an actionable, agent-relayable
|
|
76
|
+
// problem) rather than a blind retry.
|
|
77
|
+
return {
|
|
78
|
+
status: "failed",
|
|
79
|
+
app,
|
|
80
|
+
fileCount: 0,
|
|
81
|
+
bytes: 0,
|
|
82
|
+
error: {
|
|
83
|
+
title: "No connected repo",
|
|
84
|
+
explanation: err.message,
|
|
85
|
+
suggestion: "Connect a GitHub or Forgejo repo to this app first (e.g. `percher github connect <repoUrl>`), then deploy again.",
|
|
86
|
+
},
|
|
87
|
+
recovery: recoveryFixConfig({
|
|
88
|
+
problems: [
|
|
89
|
+
{
|
|
90
|
+
file: "percher.toml",
|
|
91
|
+
message: "This app has no connected GitHub or Forgejo repo. Connect one (e.g. `percher github connect <repoUrl>`) before deploying its latest commit.",
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
reasonCode: "config_invalid",
|
|
95
|
+
}),
|
|
96
|
+
summary: `${app.name} has no connected repo — connect one before deploying.`,
|
|
97
|
+
configPath: "",
|
|
98
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
switch (err.code) {
|
|
102
|
+
case "REPO_DEPLOY_RATE_LIMITED": {
|
|
103
|
+
// Per-app repo-deploy cap (deploy-from-repo.ts). Surface as an
|
|
104
|
+
// ask_user so the agent waits/asks rather than hammering the
|
|
105
|
+
// server-side clone loop.
|
|
106
|
+
const extra = err.extra ?? {};
|
|
107
|
+
const retryAfterSec = extra.retryAfterSec ?? 60;
|
|
108
|
+
return {
|
|
109
|
+
status: "failed",
|
|
110
|
+
app,
|
|
111
|
+
fileCount: 0,
|
|
112
|
+
bytes: 0,
|
|
113
|
+
error: {
|
|
114
|
+
title: "Repo deploy rate limit reached",
|
|
115
|
+
explanation: err.message,
|
|
116
|
+
suggestion: `Wait ${retryAfterSec}s and try again — this is a short-window per-app limit.`,
|
|
117
|
+
},
|
|
118
|
+
recovery: recoveryAsk({
|
|
119
|
+
prompt: `Repo-deploy rate limit reached on ${app.name}. Wait ${retryAfterSec}s and try again.`,
|
|
120
|
+
options: ["wait before retrying"],
|
|
121
|
+
reasonCode: "infra_transient",
|
|
122
|
+
retryable: true,
|
|
123
|
+
}),
|
|
124
|
+
summary: `Repo-deploy rate limit hit on ${app.name}. Retry in ${retryAfterSec}s.`,
|
|
125
|
+
configPath: "",
|
|
126
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
case "ACCOUNT_SUSPENDED":
|
|
130
|
+
case "APP_SUSPENDED":
|
|
131
|
+
case "EMAIL_NOT_VERIFIED":
|
|
132
|
+
case "INVALID_REPO_URL":
|
|
133
|
+
case "DNS_DRIFT":
|
|
134
|
+
case "CLONE_FAILED":
|
|
135
|
+
case "CLONE_TIMEOUT":
|
|
136
|
+
return failureResult({
|
|
137
|
+
title: err.message,
|
|
138
|
+
explanation: err.message,
|
|
139
|
+
suggestion: "See the suggestion in the API error response. Re-run once the underlying issue is resolved.",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
// Poll the new deployment to terminal status. Same poll budget +
|
|
146
|
+
// heartbeat pattern as redeploy (sourced from the shared timeout
|
|
147
|
+
// contract), just without an upload step to wait through.
|
|
148
|
+
const buildStart = Date.now();
|
|
149
|
+
const timeoutMs = TIMEOUTS.clientPublishPoll;
|
|
150
|
+
let lastStatus;
|
|
151
|
+
let nextHeartbeatMs = 15_000;
|
|
152
|
+
let deployment = initial;
|
|
153
|
+
let timedOut = null;
|
|
154
|
+
try {
|
|
155
|
+
deployment = await pollDeployment({
|
|
156
|
+
ctx,
|
|
157
|
+
appId: app.id,
|
|
158
|
+
initial,
|
|
159
|
+
intervalMs: 2000,
|
|
160
|
+
timeoutMs,
|
|
161
|
+
appName: app.name,
|
|
162
|
+
onTick: (d) => {
|
|
163
|
+
const elapsedMs = Date.now() - buildStart;
|
|
164
|
+
if (d.status !== lastStatus) {
|
|
165
|
+
ctx.status(`${d.status}...`);
|
|
166
|
+
lastStatus = d.status;
|
|
167
|
+
nextHeartbeatMs = elapsedMs + 15_000;
|
|
168
|
+
}
|
|
169
|
+
else if (elapsedMs >= nextHeartbeatMs) {
|
|
170
|
+
ctx.status(`${d.status}... (${Math.round(elapsedMs / 1000)}s elapsed)`);
|
|
171
|
+
nextHeartbeatMs = elapsedMs + 15_000;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
onTimeout: (d) => {
|
|
175
|
+
timedOut = { deployment: d };
|
|
176
|
+
throw new (class PollTimeoutSentinel extends Error {
|
|
177
|
+
})("__poll_timeout__");
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
if (!timedOut) {
|
|
183
|
+
return failureResult({
|
|
184
|
+
title: "Deploy did not complete",
|
|
185
|
+
explanation: err instanceof Error
|
|
186
|
+
? err.message
|
|
187
|
+
: "The deploy stopped responding before reaching a terminal state.",
|
|
188
|
+
suggestion: `Inspect with \`bunx percher deploys inspect ${initial.id}\`.`,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (timedOut) {
|
|
193
|
+
const stuck = timedOut.deployment;
|
|
194
|
+
return failureResult({
|
|
195
|
+
title: "Deploy timed out",
|
|
196
|
+
explanation: "The deploy did not complete within 5 minutes.",
|
|
197
|
+
suggestion: `Inspect with \`bunx percher deploys inspect ${stuck.id}\`.`,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const totalSeconds = (Date.now() - t0) / 1000;
|
|
201
|
+
const url = deployment.previewUrl ?? deployment.url ?? app.url;
|
|
202
|
+
if (deployment.status === "failed") {
|
|
203
|
+
// Route through the same classifier publish + wait use so failed
|
|
204
|
+
// repo-deploys get the same structured-code rendering.
|
|
205
|
+
const { error, recovery, summary } = await classifyDeploymentFailure({
|
|
206
|
+
ctx,
|
|
207
|
+
app,
|
|
208
|
+
deployment,
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
status: "failed",
|
|
212
|
+
app,
|
|
213
|
+
deployment,
|
|
214
|
+
fileCount: 0,
|
|
215
|
+
bytes: 0,
|
|
216
|
+
error,
|
|
217
|
+
recovery,
|
|
218
|
+
summary,
|
|
219
|
+
configPath: "",
|
|
220
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// Detect a cache hit so the summary tells the user "cached, Ns" when the
|
|
224
|
+
// build skipped. Best-effort; left undefined on fetch failure.
|
|
225
|
+
let cacheHit;
|
|
226
|
+
try {
|
|
227
|
+
const { events } = await ctx.client.apps.getDeployEvents(app.id, deployment.id);
|
|
228
|
+
cacheHit = events.some((e) => e.stage === "build" && e.status === "ok" && e.subStage === "cache_hit");
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
/* leave undefined */
|
|
232
|
+
}
|
|
233
|
+
ctx.status(`Live at ${url} (${totalSeconds.toFixed(0)}s)`);
|
|
234
|
+
const cacheTag = cacheHit ? "cached, " : "";
|
|
235
|
+
return {
|
|
236
|
+
status: "live",
|
|
237
|
+
app,
|
|
238
|
+
deployment,
|
|
239
|
+
url,
|
|
240
|
+
timing: { totalSeconds, packageMs: 0, uploadMs: 0, buildMs: Date.now() - buildStart },
|
|
241
|
+
fileCount: 0,
|
|
242
|
+
bytes: 0,
|
|
243
|
+
cacheHit,
|
|
244
|
+
recovery: RECOVERY_NONE,
|
|
245
|
+
summary: `${app.name} deployed (${cacheTag}${totalSeconds.toFixed(0)}s) → ${url}`,
|
|
246
|
+
configPath: "",
|
|
247
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function failureResult(error) {
|
|
251
|
+
return {
|
|
252
|
+
status: "failed",
|
|
253
|
+
fileCount: 0,
|
|
254
|
+
bytes: 0,
|
|
255
|
+
error,
|
|
256
|
+
recovery: recoveryAsk({
|
|
257
|
+
prompt: `${error.title}: ${error.explanation} ${error.suggestion}`.trim(),
|
|
258
|
+
reasonCode: "unknown",
|
|
259
|
+
}),
|
|
260
|
+
summary: error.title,
|
|
261
|
+
configPath: "",
|
|
262
|
+
bundle: { fileCount: 0, bytes: 0 },
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=deploy-repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-repo.js","sourceRoot":"","sources":["../../src/commands/deploy-repo.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,aAAa,EAAa,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,aAAa,EAAa,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAEL,KAAK,iBAAiB,EAGvB,MAAM,WAAW,CAAC;AAInB;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAU1D;AAaD,eAAO,MAAM,eAAe;;;;;;;;;;iBAU1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAQD,wBAAsB,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAiGnF"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
3
|
import { generateName, serialize } from "@percher/toml";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { detectFramework, refineBunRuntime } from "../detect.js";
|
|
5
|
+
import { configFromDetection, detectFramework, refineBunRuntime, } from "../detect.js";
|
|
6
6
|
import { PercherCoreError } from "../errors.js";
|
|
7
7
|
import { renderStaticFrameworkCaddyfile, renderStaticFrameworkDockerfile } from "../static-docker.js";
|
|
8
8
|
/**
|
|
@@ -38,21 +38,6 @@ export function isSuspiciousAutoName(name) {
|
|
|
38
38
|
function detectInteractive() {
|
|
39
39
|
return process.stdin?.isTTY === true && process.stdout?.isTTY === true;
|
|
40
40
|
}
|
|
41
|
-
function buildDataConfig(mode) {
|
|
42
|
-
if (mode === "convex") {
|
|
43
|
-
return {
|
|
44
|
-
mode: "convex",
|
|
45
|
-
convex: { deployment_url: "https://your-project.convex.cloud" },
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
if (mode === "supabase") {
|
|
49
|
-
return {
|
|
50
|
-
mode: "supabase",
|
|
51
|
-
supabase: { url: "https://your-project.supabase.co" },
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return { mode: mode };
|
|
55
|
-
}
|
|
56
41
|
export const initInputSchema = z.object({
|
|
57
42
|
force: z.boolean().optional(),
|
|
58
43
|
name: z.string().optional(),
|
|
@@ -111,22 +96,7 @@ export async function init(ctx, input = {}) {
|
|
|
111
96
|
name = suggestion;
|
|
112
97
|
}
|
|
113
98
|
}
|
|
114
|
-
const config =
|
|
115
|
-
app: {
|
|
116
|
-
name,
|
|
117
|
-
runtime: detected?.runtime ?? "node",
|
|
118
|
-
...(detected?.framework
|
|
119
|
-
? { framework: detected.framework }
|
|
120
|
-
: {}),
|
|
121
|
-
},
|
|
122
|
-
...(detected?.build ? { build: detected.build } : {}),
|
|
123
|
-
...(detected?.web ? { web: detected.web } : {}),
|
|
124
|
-
...(detected?.data || input.dataMode
|
|
125
|
-
? {
|
|
126
|
-
data: buildDataConfig(input.dataMode ?? detected?.data?.mode ?? "none"),
|
|
127
|
-
}
|
|
128
|
-
: {}),
|
|
129
|
-
};
|
|
99
|
+
const config = configFromDetection(name, detected, input.dataMode);
|
|
130
100
|
const envVars = scanEnvVars(ctx.cwd);
|
|
131
101
|
if (Object.keys(envVars).length > 0) {
|
|
132
102
|
config.env = envVars;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAsB,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/mcp.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import { z } from "zod";
|
|
|
2
2
|
import type { Context } from "../context.js";
|
|
3
3
|
export declare const mcpInputSchema: z.ZodObject<{}, z.core.$strip>;
|
|
4
4
|
export type McpInput = z.infer<typeof mcpInputSchema>;
|
|
5
|
+
/** Public URL of the hosted, OAuth-protected Streamable-HTTP MCP endpoint. */
|
|
6
|
+
export declare const HOSTED_MCP_URL = "https://mcp.percher.app/mcp";
|
|
5
7
|
export interface McpConfigResult {
|
|
6
|
-
/** Canonical mcpServers entry that any MCP-aware client can paste in. */
|
|
8
|
+
/** Canonical local stdio mcpServers entry that any MCP-aware client can paste in. */
|
|
7
9
|
config: {
|
|
8
10
|
mcpServers: {
|
|
9
11
|
percher: {
|
|
@@ -12,18 +14,48 @@ export interface McpConfigResult {
|
|
|
12
14
|
};
|
|
13
15
|
};
|
|
14
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* The hosted connector option. Added as a custom connector in
|
|
19
|
+
* Claude.ai / Cursor / Windsurf — the client runs the OAuth 2.1 flow
|
|
20
|
+
* itself, so there is NO token to paste (no `Authorization` header).
|
|
21
|
+
* `transport: "http"` marks it as a remote/url-based server entry, not
|
|
22
|
+
* a local command.
|
|
23
|
+
*/
|
|
24
|
+
hosted: {
|
|
25
|
+
/** url-based remote server entry (Streamable HTTP). */
|
|
26
|
+
config: {
|
|
27
|
+
mcpServers: {
|
|
28
|
+
percher: {
|
|
29
|
+
transport: "http";
|
|
30
|
+
url: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
url: string;
|
|
35
|
+
/** Auth is browser-based OAuth — there is no bearer token field. */
|
|
36
|
+
auth: "oauth";
|
|
37
|
+
};
|
|
15
38
|
/** Per-client paste-target paths (informational, no install performed). */
|
|
16
39
|
installLocations: Array<{
|
|
17
40
|
client: string;
|
|
18
41
|
path: string;
|
|
19
42
|
note?: string;
|
|
20
43
|
}>;
|
|
44
|
+
/** Human-readable notes printed under the config (CLI surfaces these). */
|
|
45
|
+
notes: string[];
|
|
21
46
|
}
|
|
22
47
|
/**
|
|
23
|
-
* Returns the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
48
|
+
* Returns the Percher MCP server config in BOTH forms — the local stdio
|
|
49
|
+
* `npx -y @percher/mcp` entry and the hosted OAuth connector at
|
|
50
|
+
* mcp.percher.app — plus the file paths each major MCP client reads them
|
|
51
|
+
* from. Intentionally does not install anything: the CLI just prints what
|
|
52
|
+
* to paste (local) or which URL to add as a custom connector (hosted), so
|
|
53
|
+
* the user chooses which tool gets the entry without us touching dotfiles.
|
|
54
|
+
*
|
|
55
|
+
* Local stdio carries the full tool set (incl. first-publish from local
|
|
56
|
+
* files). The hosted connector is the remote-safe subset (operate existing
|
|
57
|
+
* apps + deploy connected repos) and is OAuth-based — there is no token to
|
|
58
|
+
* paste.
|
|
27
59
|
*/
|
|
28
60
|
export declare function mcp(_ctx: Context, _input?: McpInput): McpConfigResult;
|
|
29
61
|
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,cAAc,gCAAe,CAAC;AAC3C,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,cAAc,gCAAe,CAAC;AAC3C,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,8EAA8E;AAC9E,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,MAAM,EAAE;QAAE,UAAU,EAAE;YAAE,OAAO,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,EAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;IACzE;;;;;;OAMG;IACH,MAAM,EAAE;QACN,uDAAuD;QACvD,MAAM,EAAE;YAAE,UAAU,EAAE;gBAAE,OAAO,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAC;oBAAC,GAAG,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC;QACxE,GAAG,EAAE,MAAM,CAAC;QACZ,oEAAoE;QACpE,IAAI,EAAE,OAAO,CAAC;KACf,CAAC;IACF,2EAA2E;IAC3E,gBAAgB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzE,0EAA0E;IAC1E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,GAAE,QAAa,GAAG,eAAe,CAiDzE"}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const mcpInputSchema = z.object({});
|
|
3
|
+
/** Public URL of the hosted, OAuth-protected Streamable-HTTP MCP endpoint. */
|
|
4
|
+
export const HOSTED_MCP_URL = "https://mcp.percher.app/mcp";
|
|
3
5
|
/**
|
|
4
|
-
* Returns the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Returns the Percher MCP server config in BOTH forms — the local stdio
|
|
7
|
+
* `npx -y @percher/mcp` entry and the hosted OAuth connector at
|
|
8
|
+
* mcp.percher.app — plus the file paths each major MCP client reads them
|
|
9
|
+
* from. Intentionally does not install anything: the CLI just prints what
|
|
10
|
+
* to paste (local) or which URL to add as a custom connector (hosted), so
|
|
11
|
+
* the user chooses which tool gets the entry without us touching dotfiles.
|
|
12
|
+
*
|
|
13
|
+
* Local stdio carries the full tool set (incl. first-publish from local
|
|
14
|
+
* files). The hosted connector is the remote-safe subset (operate existing
|
|
15
|
+
* apps + deploy connected repos) and is OAuth-based — there is no token to
|
|
16
|
+
* paste.
|
|
8
17
|
*/
|
|
9
18
|
export function mcp(_ctx, _input = {}) {
|
|
10
19
|
return {
|
|
@@ -16,20 +25,44 @@ export function mcp(_ctx, _input = {}) {
|
|
|
16
25
|
},
|
|
17
26
|
},
|
|
18
27
|
},
|
|
28
|
+
hosted: {
|
|
29
|
+
config: {
|
|
30
|
+
mcpServers: {
|
|
31
|
+
percher: {
|
|
32
|
+
transport: "http",
|
|
33
|
+
url: HOSTED_MCP_URL,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
url: HOSTED_MCP_URL,
|
|
38
|
+
auth: "oauth",
|
|
39
|
+
},
|
|
19
40
|
installLocations: [
|
|
20
41
|
{
|
|
21
42
|
client: "Claude Code",
|
|
22
43
|
path: "~/.claude.json (under mcpServers, or a per-project .mcp.json)",
|
|
44
|
+
note: "Local stdio — recommended for Claude Code (full tool set, incl. publish from local files).",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
client: "Claude.ai (web/desktop)",
|
|
48
|
+
path: `Settings → Connectors → Add custom connector → ${HOSTED_MCP_URL}`,
|
|
49
|
+
note: "Hosted — OAuth, no token to paste. Remote-safe subset (operate existing apps + deploy connected repos).",
|
|
23
50
|
},
|
|
24
51
|
{
|
|
25
52
|
client: "Cursor / Windsurf",
|
|
26
|
-
path: "settings → MCP → add server (
|
|
53
|
+
path: "settings → MCP → add server (local: the same npx command; hosted: add the URL as a connector)",
|
|
27
54
|
},
|
|
28
55
|
{
|
|
29
56
|
client: "VS Code (Continue / Cline)",
|
|
30
|
-
path: "extension settings → MCP servers",
|
|
57
|
+
path: "extension settings → MCP servers (local npx command)",
|
|
31
58
|
},
|
|
32
59
|
],
|
|
60
|
+
notes: [
|
|
61
|
+
"Two ways to connect:",
|
|
62
|
+
" • Local (npx): full tool set, reads your project files — required for first publish from local files. Recommended for Claude Code.",
|
|
63
|
+
` • Hosted connector: add ${HOSTED_MCP_URL} as a custom connector. OAuth login in the browser — no token to paste. Remote-safe subset (operate existing apps + deploy connected repos); first-publish-from-local-files stays on the npx path.`,
|
|
64
|
+
"Manage or revoke hosted connections from the Percher dashboard.",
|
|
65
|
+
],
|
|
33
66
|
};
|
|
34
67
|
}
|
|
35
68
|
//# sourceMappingURL=mcp.js.map
|
package/dist/commands/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAG3C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAyB5D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,GAAG,CAAC,IAAa,EAAE,SAAmB,EAAE;IACtD,OAAO;QACL,MAAM,EAAE;YACN,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,CAAC,IAAI,EAAE,cAAc,CAAC;iBAC7B;aACF;SACF;QACD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,UAAU,EAAE;oBACV,OAAO,EAAE;wBACP,SAAS,EAAE,MAAM;wBACjB,GAAG,EAAE,cAAc;qBACpB;iBACF;aACF;YACD,GAAG,EAAE,cAAc;YACnB,IAAI,EAAE,OAAO;SACd;QACD,gBAAgB,EAAE;YAChB;gBACE,MAAM,EAAE,aAAa;gBACrB,IAAI,EAAE,+DAA+D;gBACrE,IAAI,EAAE,4FAA4F;aACnG;YACD;gBACE,MAAM,EAAE,yBAAyB;gBACjC,IAAI,EAAE,kDAAkD,cAAc,EAAE;gBACxE,IAAI,EAAE,yGAAyG;aAChH;YACD;gBACE,MAAM,EAAE,mBAAmB;gBAC3B,IAAI,EAAE,+FAA+F;aACtG;YACD;gBACE,MAAM,EAAE,4BAA4B;gBACpC,IAAI,EAAE,sDAAsD;aAC7D;SACF;QACD,KAAK,EAAE;YACL,sBAAsB;YACtB,sIAAsI;YACtI,6BAA6B,cAAc,oMAAoM;YAC/O,iEAAiE;SAClE;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Context } from "../context.js";
|
|
3
|
+
import type { PublishResult } from "./publish.js";
|
|
4
|
+
export declare const publishFromRepoInputSchema: z.ZodObject<{
|
|
5
|
+
url: z.ZodString;
|
|
6
|
+
name: z.ZodOptional<z.ZodString>;
|
|
7
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
8
|
+
note: z.ZodOptional<z.ZodString>;
|
|
9
|
+
waitForLive: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type PublishFromRepoInput = z.infer<typeof publishFromRepoInputSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Hosted "publish from a public repo URL" — one-shot clone + deploy of a PUBLIC
|
|
14
|
+
* repo, the URL counterpart to `publishInline`. The server clones the tracked
|
|
15
|
+
* branch HEAD once, reads the repo's percher.toml for the app name + runtime,
|
|
16
|
+
* creates-or-gets the app, and deploys — no persistent connection/webhook is
|
|
17
|
+
* set up (that stays the owner-only `import/*` path). Returns the same
|
|
18
|
+
* PublishResult shape + recovery contract as `publishInline` / `deployRepo`, so
|
|
19
|
+
* the `wait_deploy` chain works identically.
|
|
20
|
+
*/
|
|
21
|
+
export declare function publishFromRepo(ctx: Context, input: PublishFromRepoInput): Promise<PublishResult>;
|
|
22
|
+
//# sourceMappingURL=publish-from-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-from-repo.d.ts","sourceRoot":"","sources":["../../src/commands/publish-from-repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,WAAW,CAAC;AAG7D,eAAO,MAAM,0BAA0B;;;;;;iBAmBrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAgMxB"}
|