percher 0.2.11 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/bin/percher.js +7532 -3049
  2. package/dist/package.json +45 -0
  3. package/dist/src/ci-env.d.ts +6 -0
  4. package/dist/src/ci-env.d.ts.map +1 -0
  5. package/dist/src/ci-env.js +35 -0
  6. package/dist/src/ci-env.js.map +1 -0
  7. package/dist/src/cli-utils.d.ts +44 -0
  8. package/dist/src/cli-utils.d.ts.map +1 -0
  9. package/dist/src/cli-utils.js +129 -0
  10. package/dist/src/cli-utils.js.map +1 -0
  11. package/dist/src/commands/account.d.ts +4 -0
  12. package/dist/src/commands/account.d.ts.map +1 -0
  13. package/dist/src/commands/account.js +280 -0
  14. package/dist/src/commands/account.js.map +1 -0
  15. package/dist/src/commands/apps.d.ts +13 -0
  16. package/dist/src/commands/apps.d.ts.map +1 -0
  17. package/dist/src/commands/apps.js +483 -0
  18. package/dist/src/commands/apps.js.map +1 -0
  19. package/dist/src/commands/auth.d.ts +4 -0
  20. package/dist/src/commands/auth.d.ts.map +1 -0
  21. package/dist/src/commands/auth.js +21 -0
  22. package/dist/src/commands/auth.js.map +1 -0
  23. package/dist/src/commands/data.d.ts +4 -0
  24. package/dist/src/commands/data.d.ts.map +1 -0
  25. package/dist/src/commands/data.js +148 -0
  26. package/dist/src/commands/data.js.map +1 -0
  27. package/dist/src/commands/deploys.d.ts +4 -0
  28. package/dist/src/commands/deploys.d.ts.map +1 -0
  29. package/dist/src/commands/deploys.js +197 -0
  30. package/dist/src/commands/deploys.js.map +1 -0
  31. package/dist/src/commands/env.d.ts +4 -0
  32. package/dist/src/commands/env.d.ts.map +1 -0
  33. package/dist/src/commands/env.js +66 -0
  34. package/dist/src/commands/env.js.map +1 -0
  35. package/dist/src/commands/github.d.ts +4 -0
  36. package/dist/src/commands/github.d.ts.map +1 -0
  37. package/dist/src/commands/github.js +93 -0
  38. package/dist/src/commands/github.js.map +1 -0
  39. package/dist/src/commands/status.d.ts +4 -0
  40. package/dist/src/commands/status.d.ts.map +1 -0
  41. package/dist/src/commands/status.js +53 -0
  42. package/dist/src/commands/status.js.map +1 -0
  43. package/dist/src/env-set-input.d.ts +13 -0
  44. package/dist/src/env-set-input.d.ts.map +1 -0
  45. package/dist/src/env-set-input.js +59 -0
  46. package/dist/src/env-set-input.js.map +1 -0
  47. package/dist/src/index.d.ts.map +1 -1
  48. package/dist/src/index.js +19 -790
  49. package/dist/src/index.js.map +1 -1
  50. package/dist/src/prompt-hidden.d.ts +15 -0
  51. package/dist/src/prompt-hidden.d.ts.map +1 -0
  52. package/dist/src/prompt-hidden.js +104 -0
  53. package/dist/src/prompt-hidden.js.map +1 -0
  54. package/dist/src/telemetry.d.ts +1 -1
  55. package/dist/src/telemetry.d.ts.map +1 -1
  56. package/dist/src/telemetry.js +8 -1
  57. package/dist/src/telemetry.js.map +1 -1
  58. package/package.json +7 -6
@@ -0,0 +1,148 @@
1
+ import * as core from "@percher/core";
2
+ import pc from "picocolors";
3
+ import { firstNonFlagAfter, printSuperuserResetResult, writeLine } from "../cli-utils";
4
+ export function registerDataCommands(cli, ctx, argv) {
5
+ cli
6
+ // The trailing `[...rest]` is a variadic absorber that exists only
7
+ // to make cac v7's checkUnusedArgs happy. cac matches commands by
8
+ // first-token equality (see Command.isMatched in cac's source), so
9
+ // both `data` and `data reset-superuser foo` route here. Without
10
+ // [...rest], v7 throws "Unused args" on the extra positionals; v6
11
+ // silently dropped them, which is why the in-action manual dispatch
12
+ // below worked there. The dispatch logic is unchanged across the
13
+ // bump — we only needed [...rest] to silence v7's safety check.
14
+ .command("data [app] [...rest]", "Show app data status and collections")
15
+ .option("--json", "Output as JSON")
16
+ .option("--reveal", "(reset-superuser only) also print the plaintext password once")
17
+ .option("--out <path>", "(export only) Output file (default: ./<app>-pb-<timestamp>.tar.gz)")
18
+ .action(async (app, _rest, options) => {
19
+ // cac matches commands by single first-token equality, so
20
+ // `percher data reset-superuser <app>` would otherwise hit this
21
+ // handler with app="reset-superuser" and silently drop the real
22
+ // app name. Detect the documented subcommand here and dispatch
23
+ // to the reset-superuser handler instead. The separate
24
+ // `data reset-superuser [app]` registration below still exists
25
+ // so `--help` lists the subcommand, but its action body is
26
+ // unreachable in practice via that route.
27
+ if (app === "reset-superuser") {
28
+ // Skip flag tokens when looking for the app name so both orderings
29
+ // work: `... reset-superuser my-app --reveal` AND `... reset-superuser
30
+ // --reveal my-app`. cac would handle this if it parsed multi-token
31
+ // commands natively; since we route manually, we mirror cac's
32
+ // "first non-flag positional" rule here.
33
+ const idx = argv.indexOf("reset-superuser");
34
+ const realApp = idx >= 0 ? firstNonFlagAfter(argv, idx) : undefined;
35
+ const reveal = argv.includes("--reveal");
36
+ const r = await core.resetSuperuser(ctx, { app: realApp, reveal });
37
+ await printSuperuserResetResult(ctx, r);
38
+ return;
39
+ }
40
+ if (app === "export") {
41
+ const idx = argv.indexOf("export");
42
+ const realApp = idx >= 0 ? firstNonFlagAfter(argv, idx) : undefined;
43
+ const outIdx = argv.indexOf("--out");
44
+ const out = outIdx >= 0 ? argv[outIdx + 1] : undefined;
45
+ const result = await core.dataExport(ctx, { app: realApp, out });
46
+ const mb = (result.bytes / 1024 / 1024).toFixed(1);
47
+ await writeLine(ctx, `${pc.green("✓")} Exported ${result.app}`);
48
+ await writeLine(ctx, ` Path: ${result.path}`);
49
+ await writeLine(ctx, ` Size: ${mb} MB`);
50
+ return;
51
+ }
52
+ const result = await core.data(ctx, { app, json: options.json });
53
+ if (options.json) {
54
+ await writeLine(ctx, JSON.stringify(result, null, 2));
55
+ }
56
+ else {
57
+ const version = result.version ? ` Version: ${result.version}` : "";
58
+ await writeLine(ctx, `${pc.bold("Data")} Mode: ${result.mode} Status: ${result.status}${version}`);
59
+ await writeLine(ctx, "");
60
+ if (result.collections.length > 0) {
61
+ await writeLine(ctx, pc.bold("Collections"));
62
+ for (const col of result.collections) {
63
+ await writeLine(ctx, ` ${col.name.padEnd(20)} ${pc.dim(col.type)}`);
64
+ }
65
+ await writeLine(ctx, "");
66
+ }
67
+ await writeLine(ctx, `Collections: ${result.stats.collections} Records: ${result.stats.totalRecords}`);
68
+ if (result.adminUrl) {
69
+ await writeLine(ctx, "");
70
+ await writeLine(ctx, `Admin: ${result.adminUrl}`);
71
+ }
72
+ if (result.warning) {
73
+ await writeLine(ctx, "");
74
+ await writeLine(ctx, pc.yellow(`⚠ ${result.warning}`));
75
+ }
76
+ }
77
+ });
78
+ cli
79
+ .command("data reset-superuser [app]", "Reset PocketBase superuser and inject new credentials")
80
+ .option("--reveal", "Also print the plaintext password once (default: hidden)")
81
+ .action(async (app, options) => {
82
+ // Unreachable in practice — handled by the "data [app] [...rest]" action
83
+ // above via the `app === "reset-superuser"` branch (cac only matches the
84
+ // first token). Registered here so `--help` lists the subcommand.
85
+ const result = await core.resetSuperuser(ctx, { app, reveal: options.reveal });
86
+ await printSuperuserResetResult(ctx, result);
87
+ });
88
+ cli
89
+ .command("data export [app]", "Download a snapshot of your app's PocketBase data as a .tar.gz")
90
+ // --out is registered on the parent `data [app] [...rest]` so cac
91
+ // doesn't reject it as unknown when the user runs `data export ... --out`.
92
+ // Don't duplicate it here; this command is unreachable anyway and the
93
+ // duplication just risks drift if the description ever changes.
94
+ .action(async () => {
95
+ // Unreachable in practice — handled by the "data [app] [...rest]" action
96
+ // above via the `app === "export"` branch. Registered here so --help
97
+ // lists the subcommand.
98
+ });
99
+ cli
100
+ .command("backups [app]", "List available backups for an app")
101
+ .action(async (app) => {
102
+ const { backups, skipped } = await core.listBackups(ctx, { app });
103
+ if (backups.length === 0) {
104
+ await writeLine(ctx, `${pc.dim("No backups found.")}`);
105
+ if (skipped.length > 0) {
106
+ await writeLine(ctx, pc.yellow(`(${skipped.length} sidecar(s) skipped — see ops logs)`));
107
+ }
108
+ return;
109
+ }
110
+ for (const b of backups) {
111
+ const components = b.apps[0]?.components.join(", ") ?? "—";
112
+ const size = b.tarball_size_bytes < 1024 * 1024
113
+ ? `${Math.round(b.tarball_size_bytes / 1024)} KB`
114
+ : `${(b.tarball_size_bytes / (1024 * 1024)).toFixed(1)} MB`;
115
+ await writeLine(ctx, `${pc.green("●")} ${pc.bold(b.backup_id)} ${pc.dim(size.padStart(10))} ${pc.dim(`[${components}]`)}`);
116
+ }
117
+ if (skipped.length > 0) {
118
+ await writeLine(ctx, pc.yellow(`\n${skipped.length} sidecar(s) skipped — older backups predating the manifest schema.`));
119
+ }
120
+ });
121
+ cli
122
+ .command("restore <source> [app]", "Restore an app's data from a backup")
123
+ .option("--components <list>", "Comma-separated: appdata,pocketbase (default: both)")
124
+ .option("--dry-run", "Show what would be restored without doing it")
125
+ .action(async (source, app, options) => {
126
+ const components = options.components
127
+ ? options.components
128
+ .split(",")
129
+ .map((c) => c.trim())
130
+ .filter((c) => c === "appdata" || c === "pocketbase")
131
+ : undefined;
132
+ const result = await core.restore(ctx, {
133
+ app,
134
+ source,
135
+ components,
136
+ dryRun: options.dryRun ?? false,
137
+ });
138
+ if ("kind" in result) {
139
+ await writeLine(ctx, `${pc.cyan("dry-run")} would restore ${pc.bold(result.app)} from ${pc.bold(result.resolvedBackup.backup_id)}`);
140
+ await writeLine(ctx, ` components: ${pc.dim(result.components.join(", "))}`);
141
+ await writeLine(ctx, ` sha: ${pc.dim(`${result.resolvedBackup.tarball_sha256.slice(0, 16)}…`)}`);
142
+ await writeLine(ctx, pc.dim("\nRun without --dry-run to actually restore. Expect 30–120s of downtime."));
143
+ return;
144
+ }
145
+ await writeLine(ctx, `${pc.green("✓")} restored from ${result.sourceBackupId} (job ${result.id.slice(0, 12)})`);
146
+ });
147
+ }
148
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/commands/data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@percher/core";
2
+ import type { CAC } from "cac";
3
+ export declare function registerDeploysCommands(cli: CAC, ctx: Context, argv: string[]): void;
4
+ //# sourceMappingURL=deploys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploys.d.ts","sourceRoot":"","sources":["../../../src/commands/deploys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAW/B,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsNpF"}
@@ -0,0 +1,197 @@
1
+ import * as core from "@percher/core";
2
+ import pc from "picocolors";
3
+ import { SilentExitError, firstNonFlagAfter, formatDeployTimestamp, formatStatus, runDeploysInspect, writeLine, } from "../cli-utils";
4
+ export function registerDeploysCommands(cli, ctx, argv) {
5
+ cli
6
+ // The trailing `[...rest]` is a variadic absorber that exists only
7
+ // to make cac v7's checkUnusedArgs happy. cac matches commands by
8
+ // first-token equality (Command.isMatched in cac's source), so
9
+ // `deploys inspect dep_42` routes here with app="inspect" and the
10
+ // deploy id as an extra positional. v6 silently dropped extras; v7
11
+ // throws "Unused args" without a variadic absorber.
12
+ .command("deploys [app] [...rest]", "List recent deploys (id, status, created, error) for an app")
13
+ .option("--limit <n>", "Number of deploys to show (default: 10, max: 100)")
14
+ // Parent must accept the inspect-subcommand's flags too, since cac
15
+ // matches `deploys inspect ...` here (see in-action dispatch below)
16
+ // and rejects unknown options at parse time.
17
+ .option("--app <name>", "(inspect only) App name (defaults to percher.toml in cwd)")
18
+ .option("--latest-failed", "(inspect only) Resolve to the most recent failed deploy")
19
+ .action(async (app, _rest, options) => {
20
+ // Subcommand collision: `percher deploys inspect <id>` would otherwise
21
+ // hit this handler with app="inspect" because cac matches on first
22
+ // token only. Dispatch the documented form to the inspect handler.
23
+ if (app === "inspect") {
24
+ // Same flag-skip rule as the data reset-superuser dispatch — both
25
+ // `deploys inspect <id> --latest-failed` and `deploys inspect
26
+ // --latest-failed` should work. `--app` consumes the next argv
27
+ // token as its value (e.g. `--app my-app`), so we tell the
28
+ // walker to skip those pairs and not mistake `my-app` for the
29
+ // deploy id.
30
+ const idx = argv.indexOf("inspect");
31
+ const id = idx >= 0 ? firstNonFlagAfter(argv, idx, new Set(["--app"])) : undefined;
32
+ await runDeploysInspect(ctx, {
33
+ id,
34
+ // Forward --app + --latest-failed if the user passed them. Their
35
+ // flag values land in `options` even though we registered them
36
+ // on the sibling command, because cac merges argv flags onto the
37
+ // matched command's options.
38
+ app: options.app,
39
+ latestFailed: Boolean(options.latestFailed),
40
+ });
41
+ return;
42
+ }
43
+ const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
44
+ const list = await core.deploysList(ctx, { app, limit });
45
+ if (list.length === 0) {
46
+ await writeLine(ctx, pc.dim("No deploys yet."));
47
+ return;
48
+ }
49
+ await writeLine(ctx, `${pc.bold("ID".padEnd(22))} ${pc.bold("STATUS".padEnd(10))} ${pc.bold("CREATED".padEnd(20))} ${pc.bold("ERROR")}`);
50
+ for (const d of list) {
51
+ const id = d.id.padEnd(22);
52
+ const status = d.status.padEnd(10);
53
+ const created = formatDeployTimestamp(d.createdAt).padEnd(20);
54
+ const err = d.errorMessage
55
+ ? (d.errorMessage.split("\n")[0]?.slice(0, 60) ?? "—")
56
+ : pc.dim("—");
57
+ const colored = d.status === "live"
58
+ ? pc.green(status)
59
+ : d.status === "failed"
60
+ ? pc.red(status)
61
+ : pc.yellow(status);
62
+ await writeLine(ctx, `${pc.dim(id)} ${colored} ${pc.dim(created)} ${err}`);
63
+ }
64
+ });
65
+ cli
66
+ .command("deploys inspect [id]", "Inspect a deploy: status, error, build log")
67
+ .option("--app <name>", "App name (defaults to percher.toml in cwd)")
68
+ .option("--latest-failed", "Resolve to the most recent failed deploy")
69
+ .action(async (id, options) => {
70
+ // Unreachable in practice — the parent `deploys [app] [...rest]`
71
+ // action above intercepts `deploys inspect` and dispatches via
72
+ // runDeploysInspect, since cac only matches the first token.
73
+ // Kept registered so cac surfaces the subcommand in `--help`.
74
+ await runDeploysInspect(ctx, { id, app: options.app, latestFailed: options.latestFailed });
75
+ });
76
+ cli
77
+ .command("rollback <sha> [app]", "Roll back to a previous version")
78
+ .action(async (sha, app) => {
79
+ const result = await core.rollback(ctx, { app, commitSha: sha });
80
+ await writeLine(ctx, `${pc.green("✓")} rolled back to ${sha.slice(0, 10)} (status: ${result.status})`);
81
+ });
82
+ cli
83
+ .command("reproduce <deployId>", "Download a deploy's source and reproduce the build locally")
84
+ .option("--app <name>", "App name (defaults to percher.toml app.name)")
85
+ .action(async (deployId, options) => {
86
+ const result = await core.reproduce(ctx, {
87
+ app: options.app,
88
+ deployId,
89
+ });
90
+ if (result.status === "needs_login") {
91
+ await writeLine(ctx, `${pc.red("✗")} Not logged in. Run: percher login`);
92
+ throw new SilentExitError();
93
+ }
94
+ if (result.status === "failed") {
95
+ await writeLine(ctx, `${pc.red("✗")} ${result.error?.title ?? "Reproduce failed"}`);
96
+ if (result.error?.explanation) {
97
+ await writeLine(ctx, ` ${result.error.explanation}`);
98
+ }
99
+ if (result.error?.suggestion) {
100
+ await writeLine(ctx, ` ${pc.dim(result.error.suggestion)}`);
101
+ }
102
+ throw new SilentExitError();
103
+ }
104
+ await writeLine(ctx, `${pc.green("✓")} ${result.summary}`);
105
+ if (result.currentAppEnvKeys && result.currentAppEnvKeys.length > 0) {
106
+ await writeLine(ctx, "");
107
+ await writeLine(ctx, pc.bold("Current app env keys:"));
108
+ for (const k of result.currentAppEnvKeys) {
109
+ await writeLine(ctx, ` ${k}`);
110
+ }
111
+ await writeLine(ctx, pc.dim(" (values not exfiltrated — set them locally before building. Note: this is the CURRENT app env, not a deploy-time snapshot.)"));
112
+ }
113
+ });
114
+ cli
115
+ .command("logs [app]", "Stream application logs")
116
+ .option("--tail <n>", "Return the last N lines and exit", { type: [Number] })
117
+ .option("--no-follow", "Don't stream new lines")
118
+ .option("--build [deployId]", "Show the BUILD log instead of runtime logs (defaults to latest failed deploy)")
119
+ .action(async (app, options) => {
120
+ // --build routes to the same logic as `deploys inspect`. We default
121
+ // to latest-failed when no deploy id is given because that's the
122
+ // common case (debugging the build that just failed).
123
+ if (options.build !== undefined) {
124
+ const deployId = typeof options.build === "string" && options.build.length > 0 ? options.build : undefined;
125
+ const result = await core.deploysInspect(ctx, {
126
+ app,
127
+ id: deployId,
128
+ latestFailed: deployId ? undefined : true,
129
+ });
130
+ const { deploy, buildLog } = result;
131
+ await writeLine(ctx, `${pc.bold("Deploy:")} ${deploy.id}`);
132
+ await writeLine(ctx, `${pc.bold("Status:")} ${formatStatus(deploy.status)}`);
133
+ await writeLine(ctx, `${pc.bold("Created:")} ${formatDeployTimestamp(deploy.createdAt)}`);
134
+ if (deploy.errorMessage) {
135
+ await writeLine(ctx, "");
136
+ await writeLine(ctx, pc.bold(pc.red("Error:")));
137
+ for (const line of deploy.errorMessage.split("\n")) {
138
+ await writeLine(ctx, ` ${line}`);
139
+ }
140
+ }
141
+ if (buildLog) {
142
+ await writeLine(ctx, "");
143
+ const lines = buildLog.split("\n");
144
+ const tailN = options.tail ? Number(options.tail) : 200;
145
+ const tail = lines.slice(-tailN);
146
+ const header = lines.length > tail.length
147
+ ? `${pc.bold("Build log")} ${pc.dim(`(last ${tail.length} of ${lines.length} lines)`)}`
148
+ : pc.bold("Build log");
149
+ await writeLine(ctx, header);
150
+ for (const line of tail) {
151
+ await writeLine(ctx, ` ${line}`);
152
+ }
153
+ }
154
+ else {
155
+ await writeLine(ctx, pc.dim("(no build log available for this deploy)"));
156
+ }
157
+ return;
158
+ }
159
+ await core.logs(ctx, {
160
+ app,
161
+ tail: options.tail ? Number(options.tail) : undefined,
162
+ follow: options.follow !== false,
163
+ });
164
+ });
165
+ cli
166
+ .command("versions [app]", "List deployed versions for an app")
167
+ .action(async (app) => {
168
+ const list = await core.versions(ctx, { app });
169
+ for (const v of list) {
170
+ await writeLine(ctx, `${v.sha.slice(0, 10)} ${v.timestamp} ${v.message}`);
171
+ }
172
+ });
173
+ cli
174
+ .command("preview <action> [deployId]", "Manage preview deploys (promote | discard)")
175
+ .option("--app <name>", "App name (overrides percher.toml)")
176
+ .action(async (action, deployId, options) => {
177
+ const appRef = options.app ?? core.readPercherTomlAppName(ctx.cwd);
178
+ if (!appRef)
179
+ throw new Error("App name required. Use --app or run from a project directory.");
180
+ if (action === "promote") {
181
+ if (!deployId)
182
+ throw new Error("Deploy ID required. Usage: percher preview promote <id>");
183
+ const result = await ctx.client.apps.promotePreview(appRef, deployId);
184
+ await writeLine(ctx, `${pc.green("✓")} Preview promoted to live. Status: ${result.status}`);
185
+ }
186
+ else if (action === "discard") {
187
+ if (!deployId)
188
+ throw new Error("Deploy ID required. Usage: percher preview discard <id>");
189
+ await ctx.client.apps.discardPreview(appRef, deployId);
190
+ await writeLine(ctx, `${pc.green("✓")} Preview discarded.`);
191
+ }
192
+ else {
193
+ throw new Error(`Unknown preview action "${action}". Use promote | discard.`);
194
+ }
195
+ });
196
+ }
197
+ //# sourceMappingURL=deploys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploys.js","sourceRoot":"","sources":["../../../src/commands/deploys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@percher/core";
2
+ import type { CAC } from "cac";
3
+ export declare function registerEnvCommands(cli: CAC, ctx: Context): void;
4
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAI/B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CA2DhE"}
@@ -0,0 +1,66 @@
1
+ import * as core from "@percher/core";
2
+ import pc from "picocolors";
3
+ import { SilentExitError, writeLine } from "../cli-utils";
4
+ export function registerEnvCommands(cli, ctx) {
5
+ cli
6
+ .command("env <action> [...args]", "Manage env vars (set KEY=VALUE | set KEY --from-stdin | set KEY --from-file <path> | set KEY (prompts) | unset KEY | list)")
7
+ .option("--app <name>", "App name (overrides percher.toml)")
8
+ .option("--from-stdin", "(set) Read value for the single KEY from stdin")
9
+ .option("--from-file <path>", "(set) Read value for the single KEY from file")
10
+ .action(async (action, args, options) => {
11
+ if (action === "set") {
12
+ const { resolveEnvSetInputs, EnvSetInputError } = await import("../env-set-input");
13
+ const { promptHidden } = await import("../prompt-hidden");
14
+ const { readFile } = await import("node:fs/promises");
15
+ try {
16
+ const values = await resolveEnvSetInputs({
17
+ args,
18
+ fromStdin: options.fromStdin,
19
+ fromFile: options.fromFile,
20
+ readStdin: async () => {
21
+ const chunks = [];
22
+ for await (const c of process.stdin)
23
+ chunks.push(c);
24
+ return Buffer.concat(chunks).toString("utf8");
25
+ },
26
+ readFile: async (p) => readFile(p, "utf8"),
27
+ promptHidden,
28
+ });
29
+ await core.envSet(ctx, { app: options.app, values });
30
+ await writeLine(ctx, `${pc.green("✓")} env vars updated (${Object.keys(values).length})`);
31
+ }
32
+ catch (err) {
33
+ if (err instanceof EnvSetInputError) {
34
+ await writeLine(ctx, `${pc.red("✗")} ${err.message}`);
35
+ throw new SilentExitError();
36
+ }
37
+ throw err;
38
+ }
39
+ }
40
+ else if (action === "unset") {
41
+ const key = args[0];
42
+ if (!key)
43
+ throw new Error("Expected key to unset");
44
+ await core.envUnset(ctx, { app: options.app, key });
45
+ await writeLine(ctx, `${pc.green("✓")} unset ${key}`);
46
+ }
47
+ else if (action === "list") {
48
+ const env = await core.envList(ctx, { app: options.app });
49
+ for (const [k, v] of Object.entries(env)) {
50
+ await writeLine(ctx, `${k}=${v}`);
51
+ }
52
+ }
53
+ else {
54
+ throw new Error(`Unknown env action "${action}". Use set | unset | list.`);
55
+ }
56
+ });
57
+ cli
58
+ .command("generate", "Generate .env.example and TypeScript types from percher.toml")
59
+ .action(async () => {
60
+ const result = await core.generate(ctx);
61
+ for (const f of result.files) {
62
+ await writeLine(ctx, `${pc.green("✓")} ${f}`);
63
+ }
64
+ });
65
+ }
66
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/commands/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,mBAAmB,CAAC,GAAQ,EAAE,GAAY;IACxD,GAAG;SACA,OAAO,CACN,wBAAwB,EACxB,4HAA4H,CAC7H;SACA,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC;SAC3D,MAAM,CAAC,cAAc,EAAE,gDAAgD,CAAC;SACxE,MAAM,CAAC,oBAAoB,EAAE,+CAA+C,CAAC;SAC7E,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAc,EAAE,OAAO,EAAE,EAAE;QACxD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,MAAM,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACnF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC1D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACtD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;oBACvC,IAAI;oBACJ,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,SAAS,EAAE,KAAK,IAAI,EAAE;wBACpB,MAAM,MAAM,GAAa,EAAE,CAAC;wBAC5B,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK;4BAAE,MAAM,CAAC,IAAI,CAAC,CAAW,CAAC,CAAC;wBAC9D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAChD,CAAC;oBACD,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;oBAC1C,YAAY;iBACb,CAAC,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;gBACrD,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5F,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;oBACpC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAK,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;oBACjE,MAAM,IAAI,eAAe,EAAE,CAAC;gBAC9B,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACnD,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1D,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,4BAA4B,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,UAAU,EAAE,8DAA8D,CAAC;SACnF,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@percher/core";
2
+ import type { CAC } from "cac";
3
+ export declare function registerGithubCommands(cli: CAC, ctx: Context): void;
4
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/commands/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAkC/B,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CA8GnE"}
@@ -0,0 +1,93 @@
1
+ import * as core from "@percher/core";
2
+ import pc from "picocolors";
3
+ import { writeLine } from "../cli-utils";
4
+ async function printWebhookInstructions(ctx, instructions, branch) {
5
+ await writeLine(ctx, pc.bold("Add this webhook in GitHub to enable auto-deploy on push:"));
6
+ await writeLine(ctx, ` URL: ${instructions.settingsUrl}`);
7
+ await writeLine(ctx, "");
8
+ await writeLine(ctx, " Field Value");
9
+ await writeLine(ctx, " ─────────────────────────────────────────────────");
10
+ await writeLine(ctx, ` Payload URL ${instructions.payloadUrl}`);
11
+ await writeLine(ctx, " Content type application/json");
12
+ await writeLine(ctx, ` Secret ${instructions.secret}`);
13
+ await writeLine(ctx, " Which events? Just the push event");
14
+ await writeLine(ctx, "");
15
+ await writeLine(ctx, pc.yellow(" ⚠ Treat this secret like a password — save it now, it won't be shown again."));
16
+ await writeLine(ctx, "");
17
+ await writeLine(ctx, pc.dim(`After adding the webhook, every push to ${branch} will auto-deploy.`));
18
+ }
19
+ export function registerGithubCommands(cli, ctx) {
20
+ // cac matches commands by single first-token equality (Command.isMatched
21
+ // in cac's source compares parsed.args[0] only), so multi-word commands
22
+ // like `github connect <repoUrl>` never match — argv[0] is just "github"
23
+ // and there's no plain `github` command registered. Pre-cac-v7 the
24
+ // result was a silent no-op (action body never ran, exit 0); v7's
25
+ // checkUnusedArgs surfaces the unused tokens as errors. Either way the
26
+ // user gets bad UX.
27
+ //
28
+ // Fix mirrors the data/deploys pattern: register a parent `github
29
+ // [action] ...` that dispatches on the action argument, plus keep the
30
+ // multi-word registrations below for `--help` discoverability (their
31
+ // action bodies are unreachable in practice).
32
+ cli
33
+ .command("github [action] [repoUrl] [...rest]", "GitHub integration: connect | setup-webhook")
34
+ .option("--app <name>", "App name (overrides percher.toml)")
35
+ .option("--branch <branch>", "(connect only) Branch to track (default: main)")
36
+ .action(async (action, repoUrl, _rest, options) => {
37
+ if (action === "connect") {
38
+ if (!repoUrl) {
39
+ throw new Error("repoUrl required. Usage: percher github connect <repoUrl>");
40
+ }
41
+ const result = await core.githubConnect(ctx, {
42
+ app: options.app,
43
+ repoUrl,
44
+ branch: options.branch,
45
+ });
46
+ await writeLine(ctx, `${pc.green("✓")} Connected to ${result.repoUrl} (branch: ${result.branch})`);
47
+ await writeLine(ctx, `${pc.green("✓")} Deploy started: ${result.deployId}`);
48
+ await writeLine(ctx, "");
49
+ if (result.webhookSetupFailed) {
50
+ await writeLine(ctx, pc.yellow(`⚠ Webhook setup failed: ${result.webhookSetupError ?? "unknown error"}`));
51
+ await writeLine(ctx, pc.yellow(" Auto-deploy will NOT work until you re-run webhook setup:"));
52
+ await writeLine(ctx, ` ${pc.bold(`percher github setup-webhook${options.app ? ` --app ${options.app}` : ""}`)}`);
53
+ return;
54
+ }
55
+ if (result.webhookInstructions) {
56
+ await printWebhookInstructions(ctx, result.webhookInstructions, result.branch);
57
+ }
58
+ await writeLine(ctx, pc.dim(`Track the initial deploy: percher deploys inspect ${result.deployId}`));
59
+ return;
60
+ }
61
+ if (action === "setup-webhook") {
62
+ const result = await core.githubSetupWebhook(ctx, { app: options.app });
63
+ await writeLine(ctx, `${pc.green("✓")} Webhook regenerated for ${result.app}`);
64
+ await writeLine(ctx, "");
65
+ await printWebhookInstructions(ctx, result.webhookInstructions, result.branch);
66
+ return;
67
+ }
68
+ throw new Error(`Unknown github action "${action ?? ""}". Use: connect <repoUrl> | setup-webhook.`);
69
+ });
70
+ // Help-only registrations. Unreachable in practice (cac single-token
71
+ // matching falls through to the parent `github [action] ...` above),
72
+ // but kept so `percher --help` lists the documented subcommands with
73
+ // their full signatures.
74
+ cli
75
+ // [repoUrl] (optional) rather than <repoUrl> (required) so cac's
76
+ // checkRequiredArgs doesn't throw on this unreachable registration
77
+ // if cac's matching ever shifts to support multi-word commands. The
78
+ // parent `github [action] ...` action's own `if (!repoUrl) throw`
79
+ // guard produces the better user-facing error.
80
+ .command("github connect [repoUrl]", "Connect a Percher app to a GitHub repo: clones it, deploys it, and sets up auto-deploy on push")
81
+ .option("--app <name>", "App name (overrides percher.toml)")
82
+ .option("--branch <branch>", "Branch to track (default: main)")
83
+ .action(async () => {
84
+ // Unreachable — handled by parent `github [action] ...` action.
85
+ });
86
+ cli
87
+ .command("github setup-webhook", "Regenerate the GitHub webhook secret for an app (use after a failed `github connect`)")
88
+ .option("--app <name>", "App name (overrides percher.toml)")
89
+ .action(async () => {
90
+ // Unreachable — handled by parent `github [action] ...` action.
91
+ });
92
+ }
93
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/commands/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@percher/core";
2
+ import type { CAC } from "cac";
3
+ export declare function registerStatusCommands(cli: CAC, ctx: Context): void;
4
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAC;AAE3D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAI/B,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAcnE"}