@m-kopa/launchpad-cli 0.23.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 (191) hide show
  1. package/CHANGELOG.md +854 -0
  2. package/README.md +109 -0
  3. package/dist/auth/browser.d.ts +18 -0
  4. package/dist/auth/browser.d.ts.map +1 -0
  5. package/dist/auth/callback-server.d.ts +24 -0
  6. package/dist/auth/callback-server.d.ts.map +1 -0
  7. package/dist/auth/discovery.d.ts +25 -0
  8. package/dist/auth/discovery.d.ts.map +1 -0
  9. package/dist/auth/flow.d.ts +39 -0
  10. package/dist/auth/flow.d.ts.map +1 -0
  11. package/dist/auth/jwt.d.ts +27 -0
  12. package/dist/auth/jwt.d.ts.map +1 -0
  13. package/dist/auth/pkce.d.ts +26 -0
  14. package/dist/auth/pkce.d.ts.map +1 -0
  15. package/dist/auth/registration.d.ts +8 -0
  16. package/dist/auth/registration.d.ts.map +1 -0
  17. package/dist/auth/session.d.ts +54 -0
  18. package/dist/auth/session.d.ts.map +1 -0
  19. package/dist/auth/token.d.ts +37 -0
  20. package/dist/auth/token.d.ts.map +1 -0
  21. package/dist/bundle/cron-bundle.d.ts +77 -0
  22. package/dist/bundle/cron-bundle.d.ts.map +1 -0
  23. package/dist/bundle/cwd-walker.d.ts +43 -0
  24. package/dist/bundle/cwd-walker.d.ts.map +1 -0
  25. package/dist/bundle/orchestrate.d.ts +51 -0
  26. package/dist/bundle/orchestrate.d.ts.map +1 -0
  27. package/dist/bundle/upload.d.ts +66 -0
  28. package/dist/bundle/upload.d.ts.map +1 -0
  29. package/dist/cli.d.ts +3 -0
  30. package/dist/cli.d.ts.map +1 -0
  31. package/dist/cli.js +9757 -0
  32. package/dist/clone/git-init.d.ts +18 -0
  33. package/dist/clone/git-init.d.ts.map +1 -0
  34. package/dist/clone/tar-extract.d.ts +59 -0
  35. package/dist/clone/tar-extract.d.ts.map +1 -0
  36. package/dist/commands/apps.d.ts +14 -0
  37. package/dist/commands/apps.d.ts.map +1 -0
  38. package/dist/commands/channel-auth.d.ts +31 -0
  39. package/dist/commands/channel-auth.d.ts.map +1 -0
  40. package/dist/commands/clone.d.ts +3 -0
  41. package/dist/commands/clone.d.ts.map +1 -0
  42. package/dist/commands/create.d.ts +27 -0
  43. package/dist/commands/create.d.ts.map +1 -0
  44. package/dist/commands/deploy-flags.d.ts +75 -0
  45. package/dist/commands/deploy-flags.d.ts.map +1 -0
  46. package/dist/commands/deploy-modes.d.ts +59 -0
  47. package/dist/commands/deploy-modes.d.ts.map +1 -0
  48. package/dist/commands/deploy.d.ts +29 -0
  49. package/dist/commands/deploy.d.ts.map +1 -0
  50. package/dist/commands/destroy.d.ts +14 -0
  51. package/dist/commands/destroy.d.ts.map +1 -0
  52. package/dist/commands/envvars.d.ts +28 -0
  53. package/dist/commands/envvars.d.ts.map +1 -0
  54. package/dist/commands/generate.d.ts +3 -0
  55. package/dist/commands/generate.d.ts.map +1 -0
  56. package/dist/commands/groups-whoami.d.ts +3 -0
  57. package/dist/commands/groups-whoami.d.ts.map +1 -0
  58. package/dist/commands/groups.d.ts +3 -0
  59. package/dist/commands/groups.d.ts.map +1 -0
  60. package/dist/commands/init.d.ts +44 -0
  61. package/dist/commands/init.d.ts.map +1 -0
  62. package/dist/commands/login.d.ts +3 -0
  63. package/dist/commands/login.d.ts.map +1 -0
  64. package/dist/commands/logout.d.ts +3 -0
  65. package/dist/commands/logout.d.ts.map +1 -0
  66. package/dist/commands/logs.d.ts +16 -0
  67. package/dist/commands/logs.d.ts.map +1 -0
  68. package/dist/commands/merge.d.ts +29 -0
  69. package/dist/commands/merge.d.ts.map +1 -0
  70. package/dist/commands/plan.d.ts +3 -0
  71. package/dist/commands/plan.d.ts.map +1 -0
  72. package/dist/commands/pull.d.ts +12 -0
  73. package/dist/commands/pull.d.ts.map +1 -0
  74. package/dist/commands/review.d.ts +22 -0
  75. package/dist/commands/review.d.ts.map +1 -0
  76. package/dist/commands/rollback.d.ts +3 -0
  77. package/dist/commands/rollback.d.ts.map +1 -0
  78. package/dist/commands/secrets-template.d.ts +3 -0
  79. package/dist/commands/secrets-template.d.ts.map +1 -0
  80. package/dist/commands/secrets.d.ts +3 -0
  81. package/dist/commands/secrets.d.ts.map +1 -0
  82. package/dist/commands/skills.d.ts +13 -0
  83. package/dist/commands/skills.d.ts.map +1 -0
  84. package/dist/commands/status.d.ts +54 -0
  85. package/dist/commands/status.d.ts.map +1 -0
  86. package/dist/commands/update.d.ts +114 -0
  87. package/dist/commands/update.d.ts.map +1 -0
  88. package/dist/commands/validate.d.ts +3 -0
  89. package/dist/commands/validate.d.ts.map +1 -0
  90. package/dist/commands/whoami.d.ts +3 -0
  91. package/dist/commands/whoami.d.ts.map +1 -0
  92. package/dist/config.d.ts +11 -0
  93. package/dist/config.d.ts.map +1 -0
  94. package/dist/deploy/apply.d.ts +29 -0
  95. package/dist/deploy/apply.d.ts.map +1 -0
  96. package/dist/deploy/dry-run.d.ts +13 -0
  97. package/dist/deploy/dry-run.d.ts.map +1 -0
  98. package/dist/deploy/git-files.d.ts +33 -0
  99. package/dist/deploy/git-files.d.ts.map +1 -0
  100. package/dist/deploy/group-pin.d.ts +66 -0
  101. package/dist/deploy/group-pin.d.ts.map +1 -0
  102. package/dist/deploy/manifest-state.d.ts +20 -0
  103. package/dist/deploy/manifest-state.d.ts.map +1 -0
  104. package/dist/deploy/manifest-status.d.ts +11 -0
  105. package/dist/deploy/manifest-status.d.ts.map +1 -0
  106. package/dist/deploy/resolve.d.ts +53 -0
  107. package/dist/deploy/resolve.d.ts.map +1 -0
  108. package/dist/deploy/rollback.d.ts +23 -0
  109. package/dist/deploy/rollback.d.ts.map +1 -0
  110. package/dist/deploy/runner.d.ts +29 -0
  111. package/dist/deploy/runner.d.ts.map +1 -0
  112. package/dist/deploy/stage-exit-codes.d.ts +41 -0
  113. package/dist/deploy/stage-exit-codes.d.ts.map +1 -0
  114. package/dist/deploy/status-polling.d.ts +37 -0
  115. package/dist/deploy/status-polling.d.ts.map +1 -0
  116. package/dist/deploy/tar-pack.d.ts +22 -0
  117. package/dist/deploy/tar-pack.d.ts.map +1 -0
  118. package/dist/detect/index.d.ts +53 -0
  119. package/dist/detect/index.d.ts.map +1 -0
  120. package/dist/dispatcher.d.ts +30 -0
  121. package/dist/dispatcher.d.ts.map +1 -0
  122. package/dist/groups/client.d.ts +62 -0
  123. package/dist/groups/client.d.ts.map +1 -0
  124. package/dist/http/api-client.d.ts +33 -0
  125. package/dist/http/api-client.d.ts.map +1 -0
  126. package/dist/http/errors.d.ts +31 -0
  127. package/dist/http/errors.d.ts.map +1 -0
  128. package/dist/manifest/load.d.ts +38 -0
  129. package/dist/manifest/load.d.ts.map +1 -0
  130. package/dist/manifest/schema.d.ts +3 -0
  131. package/dist/manifest/schema.d.ts.map +1 -0
  132. package/dist/postinstall.d.ts +3 -0
  133. package/dist/postinstall.d.ts.map +1 -0
  134. package/dist/postinstall.js +37 -0
  135. package/dist/secrets/env-parse.d.ts +19 -0
  136. package/dist/secrets/env-parse.d.ts.map +1 -0
  137. package/dist/secrets/push.d.ts +13 -0
  138. package/dist/secrets/push.d.ts.map +1 -0
  139. package/dist/secrets/set.d.ts +19 -0
  140. package/dist/secrets/set.d.ts.map +1 -0
  141. package/dist/secrets/status.d.ts +19 -0
  142. package/dist/secrets/status.d.ts.map +1 -0
  143. package/dist/types/api.d.ts +112 -0
  144. package/dist/types/api.d.ts.map +1 -0
  145. package/dist/update-notifier.d.ts +69 -0
  146. package/dist/update-notifier.d.ts.map +1 -0
  147. package/dist/version.d.ts +2 -0
  148. package/dist/version.d.ts.map +1 -0
  149. package/package.json +62 -0
  150. package/skills/README.md +100 -0
  151. package/skills/_partials/shell-contract.md +42 -0
  152. package/skills/launchpad-content-pr/SKILL.md +255 -0
  153. package/skills/launchpad-deploy/SKILL.md +415 -0
  154. package/skills/launchpad-deploy-status/SKILL.md +231 -0
  155. package/skills/launchpad-destroy/SKILL.md +317 -0
  156. package/skills/launchpad-onboard/SKILL.md +179 -0
  157. package/skills/launchpad-status/SKILL.md +263 -0
  158. package/skills/marquee-share/README.md +155 -0
  159. package/skills/marquee-share/SKILL.md +94 -0
  160. package/skills/marquee-share/SYNC.md +27 -0
  161. package/skills/marquee-share/dist/cli.js +896 -0
  162. package/skills/marquee-share/eslint.config.mjs +71 -0
  163. package/skills/marquee-share/install.sh +103 -0
  164. package/skills/marquee-share/package-lock.json +3946 -0
  165. package/skills/marquee-share/package.json +30 -0
  166. package/skills/marquee-share/src/auth/PROVENANCE.md +103 -0
  167. package/skills/marquee-share/src/auth/browser.ts +75 -0
  168. package/skills/marquee-share/src/auth/callback-server.ts +171 -0
  169. package/skills/marquee-share/src/auth/discovery.ts +171 -0
  170. package/skills/marquee-share/src/auth/flow.ts +262 -0
  171. package/skills/marquee-share/src/auth/index.ts +171 -0
  172. package/skills/marquee-share/src/auth/jwt.ts +77 -0
  173. package/skills/marquee-share/src/auth/pkce.ts +79 -0
  174. package/skills/marquee-share/src/auth/registration.ts +87 -0
  175. package/skills/marquee-share/src/auth/session.ts +205 -0
  176. package/skills/marquee-share/src/auth/token.ts +162 -0
  177. package/skills/marquee-share/src/cli.ts +246 -0
  178. package/skills/marquee-share/src/config.ts +101 -0
  179. package/skills/marquee-share/src/render/template.ts +171 -0
  180. package/skills/marquee-share/src/upload/index.ts +11 -0
  181. package/skills/marquee-share/src/upload/upload.ts +191 -0
  182. package/skills/marquee-share/tests/cli.test.ts +281 -0
  183. package/skills/marquee-share/tests/config.test.ts +119 -0
  184. package/skills/marquee-share/tests/flow.test.ts +356 -0
  185. package/skills/marquee-share/tests/no-token-leak.test.ts +240 -0
  186. package/skills/marquee-share/tests/pkce.test.ts +121 -0
  187. package/skills/marquee-share/tests/session.test.ts +173 -0
  188. package/skills/marquee-share/tests/template.test.ts +170 -0
  189. package/skills/marquee-share/tests/upload.test.ts +311 -0
  190. package/skills/marquee-share/tsconfig.json +23 -0
  191. package/skills/marquee-share/vitest.config.ts +15 -0
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # `@m-kopa/launchpad-cli`
2
+
3
+ The user-facing CLI for Launchpad. Talks to the portal-bot endpoints
4
+ shipped under SCOPE-M-760 / T4 (`/apps/<slug>/source-bundle`,
5
+ `/apps/<slug>/deploy-pr`, `/apps/<slug>/review/<prNumber>`,
6
+ `/apps/<slug>/merge/<prNumber>`).
7
+
8
+ ## Status
9
+
10
+ **Released**, published to **public npm**. The CLI delivers the full
11
+ SCOPE-M-760 command surface plus follow-on commands; every release is
12
+ documented in `CHANGELOG.md`.
13
+
14
+ ```bash
15
+ npm i -g @m-kopa/launchpad-cli # or: bun add -g / pnpm add -g
16
+ launchpad login # authenticate against the M-KOPA SSO
17
+ launchpad skills install # install the Claude Code slash-commands
18
+ ```
19
+
20
+ `@m-kopa/launchpad-cli` is published to **public npmjs** — `npm i -g
21
+ @m-kopa/launchpad-cli` works on any machine with **no `~/.npmrc` setup,
22
+ no auth token, and no antivirus block** (a registry install carries no
23
+ embedded payload, unlike the legacy self-contained installer). Once
24
+ installed, `launchpad update` keeps it current. Access to *apps* is still
25
+ gated by M-KOPA SSO at `launchpad login`; only the install is public.
26
+
27
+ | Command | What it does |
28
+ | ------- | ------------ |
29
+ | `login` / `logout` | Start / clear a Cloudflare Access OAuth session |
30
+ | `whoami` | Show the current session identity + per-app role |
31
+ | `apps` | List the apps the caller can access |
32
+ | `create` | File a new app from the terminal (mirrors the portal wizard) |
33
+ | `clone <slug>` | Fetch an app's source into a local git repo |
34
+ | `deploy` | Package the working tree + open/update a review PR |
35
+ | `review` | Show a PR's review state + findings |
36
+ | `merge` | Squash-merge a review-passed PR |
37
+ | `envvars` | List / set / remove Pages environment variables |
38
+ | `logs` | Show recent deployment history |
39
+ | `skills` | Install / update the Claude Code skill bundle |
40
+ | `update` | Self-update the CLI to the latest published release |
41
+
42
+ Run `launchpad --help` for the list, or `launchpad <command> --help` for
43
+ per-command usage.
44
+
45
+ ## Auth
46
+
47
+ The CLI uses Cloudflare Access **Managed OAuth (PKCE)** — see
48
+ `.planning/research/cf-access-cli-auth.md` for the full flow. `launchpad
49
+ login` opens a browser, completes the PKCE handshake, and stores the
50
+ session at `~/.launchpad/session.json` (mode `0600`). Subsequent commands
51
+ refresh the access token silently until the grant session expires, at
52
+ which point the CLI prompts a re-login.
53
+
54
+ ## Local dev
55
+
56
+ ```bash
57
+ cd packages/launchpad-cli
58
+ bun install
59
+ bun run typecheck
60
+ bun run lint
61
+ bun run test
62
+ bun run build
63
+ node dist/cli.js --help
64
+ ```
65
+
66
+ ## Skills bundle
67
+
68
+ The CLI ships a bundle of Claude Code skills under `skills/`, copied
69
+ into a user's `~/.claude/skills/` by `launchpad skills install`. A public
70
+ npm `npm i -g @m-kopa/launchpad-cli` install needs one explicit
71
+ `launchpad skills install` afterward; the legacy platform installer
72
+ (https://get.launchpad.m-kopa.us) runs that step automatically. See
73
+ `docs/runbooks/launchpad-skills-bundle.md` for both channels.
74
+
75
+ | Skill | Source |
76
+ | ----- | ------ |
77
+ | `launchpad-onboard` | this repo |
78
+ | `launchpad-deploy` | this repo |
79
+ | `launchpad-deploy-status` | this repo |
80
+ | `launchpad-content-pr` | this repo |
81
+ | `marquee-share` | **`M-KOPA/marquee`** (vendored — see below) |
82
+
83
+ ### The `marquee-share` skill (cross-repo, vendored)
84
+
85
+ `marquee-share` is **not** authored here. Its canonical source is the
86
+ `M-KOPA/marquee` repository, under `skill/`. It is *vendored* into
87
+ `skills/marquee-share/` so the CLI can install a working skill straight
88
+ from the published npm package — the CLI cannot reach another repo at
89
+ install time.
90
+
91
+ The vendored copy must never be hand-edited; it would silently drift
92
+ from the canonical source. The single supported way to refresh it is
93
+ the sync script:
94
+
95
+ ```bash
96
+ packages/launchpad-cli/scripts/sync-marquee-share-skill.sh <marquee-checkout> [git-ref]
97
+ ```
98
+
99
+ Run this at marquee-share **release time**, review the diff, and
100
+ commit. The script records the source commit in
101
+ `skills/marquee-share/SYNC.md`. `--check` reports the currently pinned
102
+ commit. This keeps the bundle a deliberate, reviewed mirror rather
103
+ than a hand-maintained second copy.
104
+
105
+ ## Versioning
106
+
107
+ Pre-1.0 consumer-pinning policy (per ADR 0005): consumers must pin
108
+ exact versions until v1.0.0. Caret ranges are forbidden. Each
109
+ minor-version bump may carry breaking changes.
@@ -0,0 +1,18 @@
1
+ import { spawn } from "node:child_process";
2
+ export declare class BrowserOpenError extends Error {
3
+ readonly code: "browser_open_error";
4
+ }
5
+ /**
6
+ * Open `url` in the user's default browser. Resolves once the
7
+ * spawn succeeds; the OS opener is fire-and-forget after that.
8
+ *
9
+ * `platform` is injected for tests so the dispatch table is
10
+ * exercised without actually opening a browser. The default reads
11
+ * `process.platform`.
12
+ */
13
+ export declare function openBrowser(url: string, platform?: NodeJS.Platform, spawner?: typeof spawn): Promise<void>;
14
+ export declare function chooseOpener(platform: NodeJS.Platform, url: string): {
15
+ command: string;
16
+ args: string[];
17
+ };
18
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;CAC/C;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,GAAG,EAAE,MAAM,GACV;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAoCrC"}
@@ -0,0 +1,24 @@
1
+ export interface CallbackResult {
2
+ readonly code: string;
3
+ readonly state: string;
4
+ }
5
+ export interface CallbackServer {
6
+ readonly port: number;
7
+ /** Resolves when the user's browser hits /callback with a valid
8
+ * code + matching state. Rejects on `cancel()`. */
9
+ readonly result: Promise<CallbackResult>;
10
+ /** Tear down the listener. Idempotent. */
11
+ readonly close: () => Promise<void>;
12
+ /** Reject the pending `result` and close. */
13
+ readonly cancel: (reason: string) => Promise<void>;
14
+ }
15
+ export declare class CallbackError extends Error {
16
+ readonly code: "callback_error";
17
+ }
18
+ /**
19
+ * Bind a fresh callback server. `expectedState` is the value the
20
+ * authorization URL will carry in `state`; the server rejects any
21
+ * request whose `state` differs.
22
+ */
23
+ export declare function bindCallbackServer(expectedState: string): Promise<CallbackServer>;
24
+ //# sourceMappingURL=callback-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-server.d.ts","sourceRoot":"","sources":["../../src/auth/callback-server.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;wDACoD;IACpD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;CAC3C;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC,CAoCzB"}
@@ -0,0 +1,25 @@
1
+ export interface OAuthEndpoints {
2
+ readonly authorizationEndpoint: string;
3
+ readonly tokenEndpoint: string;
4
+ readonly registrationEndpoint: string;
5
+ /**
6
+ * The protected resource's canonical URL (per RFC 8707 OAuth 2.0
7
+ * Resource Indicators). Cf Access REQUIRES this parameter on the
8
+ * authorization request — omitting it returns
9
+ * `error=invalid_target, error_description="No resource parameter
10
+ * found"`. Sourced from the protected-resource metadata's
11
+ * `resource` field; falls back to `botUrl` if the metadata omits
12
+ * it (older Cf deployments may not).
13
+ */
14
+ readonly resource: string;
15
+ }
16
+ export declare class DiscoveryError extends Error {
17
+ readonly code: "discovery_error";
18
+ }
19
+ /**
20
+ * Walk the two-step discovery and return the endpoints. `botUrl`
21
+ * is the base of the protected Worker (no trailing slash). The
22
+ * fetcher is injected so tests don't need a network.
23
+ */
24
+ export declare function discoverOauthEndpoints(botUrl: string, fetcher?: typeof fetch): Promise<OAuthEndpoints>;
25
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/auth/discovery.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAG,iBAAiB,CAAU;CAC5C;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,cAAc,CAAC,CA0EzB"}
@@ -0,0 +1,39 @@
1
+ import { type CliSession } from "./session.js";
2
+ export declare class LoginRequiredError extends Error {
3
+ readonly code: "login_required";
4
+ }
5
+ /** Refresh-window buffer: refresh `refreshSkewMs` before expiry
6
+ * so a request fired right at the edge doesn't hit a 401. */
7
+ export declare const REFRESH_SKEW_MS = 30000;
8
+ export interface LoginOptions {
9
+ readonly botUrl: string;
10
+ readonly sessionPath: string;
11
+ /** Receives the auth URL once the localhost server is bound +
12
+ * the browser opener is about to fire. The CLI verb prints it
13
+ * to stdout so a headless dev can copy-paste. */
14
+ readonly onAuthUrl?: (url: string) => void;
15
+ /** Injection points for tests. */
16
+ readonly fetcher?: typeof fetch;
17
+ readonly browserOpener?: (url: string) => Promise<void>;
18
+ }
19
+ /**
20
+ * Run the full PKCE flow and persist the session. Returns the
21
+ * resulting session for the caller (so the verb can print
22
+ * confirmation diagnostics).
23
+ */
24
+ export declare function login(opts: LoginOptions): Promise<CliSession>;
25
+ /**
26
+ * Read the session and return a still-valid access token. If the
27
+ * persisted access token is past (or near) expiry, silently
28
+ * refresh and persist the new pair before returning. If the
29
+ * refresh fails because the grant has expired, throws
30
+ * `LoginRequiredError`.
31
+ *
32
+ * `now` is injected for tests so we can simulate expiry without
33
+ * mocking the system clock.
34
+ */
35
+ export declare function getValidAccessToken(sessionPath: string, fetcher?: typeof fetch, now?: () => number): Promise<{
36
+ accessToken: string;
37
+ session: CliSession;
38
+ }>;
39
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/auth/flow.ts"],"names":[],"mappings":"AAwCA,OAAO,EAGL,KAAK,UAAU,EAEhB,MAAM,cAAc,CAAC;AAGtB,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;CAC3C;AAED;8DAC8D;AAC9D,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;sDAEkD;IAClD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,kCAAkC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA8DnE;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAO,KAAa,EAC7B,GAAG,GAAE,MAAM,MAAiB,GAC3B,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC,CAiDvD"}
@@ -0,0 +1,27 @@
1
+ export interface JwtPayload {
2
+ /** Cf Access user-scoped JWT subject — Entra UUID. */
3
+ readonly sub?: string;
4
+ /** Email / UPN claim. Cloudflare populates this from the IdP. */
5
+ readonly email?: string;
6
+ /** Cf Access aud (the App's UUID). */
7
+ readonly aud?: string | readonly string[];
8
+ /** Issued-at + expiry, seconds since epoch (RFC 7519). */
9
+ readonly iat?: number;
10
+ readonly exp?: number;
11
+ /** Token type — "app" for Cf Access app tokens. */
12
+ readonly type?: string;
13
+ /** Anything else the IdP / Cf added; we don't validate it. */
14
+ readonly [k: string]: unknown;
15
+ }
16
+ export declare class JwtParseError extends Error {
17
+ readonly code: "jwt_parse_error";
18
+ }
19
+ /**
20
+ * Decode the payload of a JWT. Returns `null` for inputs that
21
+ * don't look like a JWT at all (e.g. an opaque token). Throws
22
+ * `JwtParseError` only for shapes that look JWT-like but have an
23
+ * undecodable payload — callers should treat both null and throw
24
+ * as "show empty identity".
25
+ */
26
+ export declare function decodeJwtPayload(token: string): JwtPayload | null;
27
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC1C,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAG,iBAAiB,CAAU;CAC5C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAwBjE"}
@@ -0,0 +1,26 @@
1
+ export interface PkcePair {
2
+ /** Plain-text random secret, kept on the client. */
3
+ readonly verifier: string;
4
+ /** S256 hash of the verifier, sent in the authorization URL. */
5
+ readonly challenge: string;
6
+ }
7
+ /** Hard cap on regeneration attempts — defends against an
8
+ * algorithmic mistake silently spinning forever. The probability
9
+ * of a `-` or `_` first byte is ~2/64 per attempt, so even 5 tries
10
+ * is enough for ~6-nines reliability; we pick a higher bound so a
11
+ * pathological RNG (or a future encoding change) surfaces as a
12
+ * clear error rather than a hang. */
13
+ export declare const MAX_PKCE_REGEN_ATTEMPTS = 32;
14
+ export declare class PkceGenerationError extends Error {
15
+ readonly code: "pkce_generation_failed";
16
+ }
17
+ /**
18
+ * Generate a fresh PKCE pair satisfying both RFC 7636 and the
19
+ * Cloudflare Access "challenge must start with [a-zA-Z0-9]" rule.
20
+ * Pure (modulo `randomBytes`) — caller can re-test by injecting
21
+ * a deterministic RNG via the optional `rng` parameter.
22
+ */
23
+ export declare function generatePkcePair(rng?: (size: number) => Uint8Array): PkcePair;
24
+ /** S256 challenge for an arbitrary verifier. Exposed for tests. */
25
+ export declare function sha256Base64Url(verifier: string): string;
26
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,QAAQ;IACvB,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;sCAKsC;AACtC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAG,wBAAwB,CAAU;CACnD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAkD,GACxE,QAAQ,CAgBV;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGxD"}
@@ -0,0 +1,8 @@
1
+ export interface RegistrationResult {
2
+ readonly clientId: string;
3
+ }
4
+ export declare class RegistrationError extends Error {
5
+ readonly code: "registration_error";
6
+ }
7
+ export declare function registerClient(registrationEndpoint: string, redirectUri: string, fetcher?: typeof fetch): Promise<RegistrationResult>;
8
+ //# sourceMappingURL=registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/auth/registration.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;CAC/C;AAED,wBAAsB,cAAc,CAClC,oBAAoB,EAAE,MAAM,EAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CA6C7B"}
@@ -0,0 +1,54 @@
1
+ export declare const SESSION_VERSION = 1;
2
+ export interface CliSession {
3
+ readonly version: typeof SESSION_VERSION;
4
+ /** OAuth `access_token`. Sent to the bot as `Authorization: Bearer <accessToken>`. */
5
+ readonly accessToken: string;
6
+ /** OAuth `refresh_token` — used to silently mint a fresh
7
+ * access token when the current one expires. */
8
+ readonly refreshToken: string;
9
+ /** Epoch milliseconds at which `accessToken` ceases to be valid.
10
+ * Computed at write-time as `Date.now() + (expires_in * 1000)`. */
11
+ readonly accessTokenExpiresAt: number;
12
+ /** OAuth client id from dynamic-client-registration. Cached so
13
+ * refreshes don't re-register. */
14
+ readonly clientId: string;
15
+ /** Token endpoint discovered at login. Cached for refreshes so
16
+ * refresh doesn't re-walk discovery. */
17
+ readonly tokenEndpoint: string;
18
+ /** RFC 8707 resource indicator (the protected bot's canonical URL).
19
+ * Cached so silent refresh can re-include it without
20
+ * re-discovering — Cf Access binds the access_token's audience to
21
+ * this and the refresh grant must match. Optional in the on-disk
22
+ * schema so pre-0.7.1 sessions (which omit it) still parse —
23
+ * those callers fall through to a forced re-login on the next
24
+ * refresh attempt. */
25
+ readonly resource?: string;
26
+ /** ISO-8601 UTC timestamp of when this session was written. Used
27
+ * by `whoami` (slice 3) for diagnostic display only. */
28
+ readonly issuedAt: string;
29
+ }
30
+ export declare class SessionParseError extends Error {
31
+ readonly code: "session_parse_error";
32
+ }
33
+ /**
34
+ * Read the session file. Returns `null` if the file doesn't exist
35
+ * (the user hasn't logged in yet — a normal state). Throws
36
+ * `SessionParseError` for a corrupt file: better to fail loudly
37
+ * than to silently re-prompt for login when the storage is
38
+ * actually broken.
39
+ */
40
+ export declare function readSession(sessionPath: string): Promise<CliSession | null>;
41
+ /**
42
+ * Atomic-ish write: writes to `<path>.tmp` then renames into
43
+ * place. The whole-directory chmod is best-effort (Windows ignores
44
+ * mode bits) — the per-file mode is the load-bearing one.
45
+ */
46
+ export declare function writeSession(sessionPath: string, session: CliSession): Promise<void>;
47
+ /**
48
+ * `launchpad logout`: zero out the session file. Idempotent —
49
+ * already-absent file is a no-op success. Returns whether a
50
+ * session actually existed (so the verb can render the right
51
+ * message).
52
+ */
53
+ export declare function clearSession(sessionPath: string): Promise<boolean>;
54
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,eAAe,CAAC;IACzC,sFAAsF;IACtF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;qDACiD;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;wEACoE;IACpE,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC;uCACmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;6CACyC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;2BAMuB;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;6DACyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;CAChD;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAmD5B;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE"}
@@ -0,0 +1,37 @@
1
+ export interface TokenResponse {
2
+ readonly accessToken: string;
3
+ readonly refreshToken: string;
4
+ /** Seconds until `accessToken` expiry, as returned by the
5
+ * server. Caller converts to absolute epoch when persisting. */
6
+ readonly expiresInSec: number;
7
+ }
8
+ export declare class TokenError extends Error {
9
+ readonly code: "token_error";
10
+ /** Optional HTTP status — present only for non-2xx responses, not
11
+ * for network errors. Lets the login flow distinguish "user
12
+ * denied at the IdP" from "network is down". */
13
+ readonly httpStatus?: number;
14
+ constructor(message: string, httpStatus?: number);
15
+ }
16
+ export declare function exchangeCodeForTokens(params: {
17
+ readonly tokenEndpoint: string;
18
+ readonly clientId: string;
19
+ readonly code: string;
20
+ readonly codeVerifier: string;
21
+ readonly redirectUri: string;
22
+ /** RFC 8707 resource indicator. Cf Access binds the resulting
23
+ * access_token's audience to this value; the bot's JWT
24
+ * validation MUST see a matching `aud` claim. Always pass it
25
+ * so the token is valid for the right protected app. */
26
+ readonly resource: string;
27
+ }, fetcher?: typeof fetch): Promise<TokenResponse>;
28
+ export declare function refreshTokens(params: {
29
+ readonly tokenEndpoint: string;
30
+ readonly clientId: string;
31
+ readonly refreshToken: string;
32
+ /** RFC 8707 resource indicator — same posture as
33
+ * exchangeCodeForTokens. The refreshed access_token's audience
34
+ * must match what `apiRaw` calls into. */
35
+ readonly resource: string;
36
+ }, fetcher?: typeof fetch): Promise<TokenResponse>;
37
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;qEACiE;IACjE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAG,aAAa,CAAU;IACvC;;qDAEiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBACjB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAKjD;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE;IACN,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;6DAGyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,EACD,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,aAAa,CAAC,CAUxB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE;IACN,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;+CAE2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,EACD,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,aAAa,CAAC,CAQxB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The built cron-Worker artifact the CLI ships alongside the source tarball.
3
+ * `script` must match a `kind: worker` target the bot has registered for the
4
+ * app; the bot re-validates it against the app's surfaces before uploading.
5
+ */
6
+ export interface WorkerArtifact {
7
+ /** Worker script name — must equal the manifest target's `script`. */
8
+ readonly script: string;
9
+ /** The bundled ES-module source (single file, workerd-compatible). */
10
+ readonly moduleContent: string;
11
+ /** Module filename for the multipart upload (e.g. `index.js`). */
12
+ readonly moduleFilename: string;
13
+ /** `compatibility_date` from the worker's wrangler.toml. */
14
+ readonly compatibilityDate: string;
15
+ /** `compatibility_flags` from the worker's wrangler.toml (e.g. nodejs_compat). */
16
+ readonly compatibilityFlags: readonly string[];
17
+ }
18
+ export type BuildWorkerResult = {
19
+ kind: "none";
20
+ } | {
21
+ kind: "ok";
22
+ artifact: WorkerArtifact;
23
+ } | {
24
+ kind: "error";
25
+ message: string;
26
+ };
27
+ /** Top-level scalar/array keys we need out of a worker's wrangler.toml. */
28
+ interface WranglerTopLevel {
29
+ readonly name?: string;
30
+ readonly main?: string;
31
+ readonly compatibility_date?: string;
32
+ readonly compatibility_flags?: readonly string[];
33
+ }
34
+ /**
35
+ * Parse ONLY the top-level keys of a wrangler.toml that precede the first
36
+ * `[section]` / `[[array-of-tables]]`. We need `name`, `main`,
37
+ * `compatibility_date`, `compatibility_flags` — all top-level scalars/string
38
+ * arrays. We deliberately do NOT parse `[triggers]` (crons) or
39
+ * `[[d1_databases]]`: the schedule + D1 binding are the bot-authoritative
40
+ * deploy contract (manifest `targets[]`), not CLI build inputs. A
41
+ * purpose-built reader avoids a TOML dependency for these four keys.
42
+ */
43
+ export declare function parseWranglerTopLevel(tomlText: string): WranglerTopLevel;
44
+ /**
45
+ * Script names of the manifest's **deployable** worker targets — `kind: worker`
46
+ * entries that carry a non-empty `schedule`. The schedule is the discriminator
47
+ * (ADR 0022 Decision #3): a worker target WITH a schedule is a *deploy surface*
48
+ * (build + upload it here); a worker target WITHOUT one is secrets-only (the
49
+ * existing fan-out target) and is NOT built. Keying the CLI build gate on the
50
+ * same `schedule` the bot keys its deploy gate on avoids a build-but-skip
51
+ * mismatch.
52
+ */
53
+ export declare function scheduledWorkerScripts(manifestYaml: string): string[];
54
+ /**
55
+ * Bundle a worker entry into a single workerd-compatible ES module. Config is
56
+ * pinned to what a real ai-cost cron build produced cleanly (sp-tt2cap C3a
57
+ * spike, 2026-06-09): `conditions: [worker, browser]` + `node:*` external
58
+ * (nodejs_compat provides them at runtime). `write: false` returns the module
59
+ * source in-memory so it never touches disk or the source tarball.
60
+ */
61
+ export declare function bundleWorker(entryAbs: string, workerDir: string): Promise<string>;
62
+ /**
63
+ * Build the cron-Worker artifact for an app, if it declares one.
64
+ *
65
+ * Returns `{kind:"none"}` for single-tier apps (no `kind: worker` target) so
66
+ * the caller ships the tarball unchanged. Returns `{kind:"error"}` with a
67
+ * CLI-friendly message when a worker is declared but its build config or
68
+ * bundle can't be produced — a deploy that would silently skip the cron tier
69
+ * is worse than a loud failure.
70
+ *
71
+ * Only the FIRST worker target is built — the two-tier shape (one Pages, one
72
+ * cron Worker) is the only one ADR 0022 supports today. A second worker target
73
+ * is rejected loudly rather than silently dropped.
74
+ */
75
+ export declare function buildWorkerArtifact(cwd: string, manifestYaml: string, walkFiles: readonly string[]): Promise<BuildWorkerResult>;
76
+ export {};
77
+ //# sourceMappingURL=cron-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-bundle.d.ts","sourceRoot":"","sources":["../../src/bundle/cron-bundle.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,2EAA2E;AAC3E,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CA0CxE;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBrE;AAkCD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAgD5B"}
@@ -0,0 +1,43 @@
1
+ import { relative } from "node:path";
2
+ /**
3
+ * Default ignore patterns applied even when no `.gitignore` is
4
+ * present. Mirrors the bot's AC8 ingest policy on dotfiles +
5
+ * common build outputs.
6
+ *
7
+ * Each entry is interpreted as a "match the basename OR a path
8
+ * segment" rule — simpler than full gitignore glob semantics and
9
+ * sufficient for the common cases.
10
+ */
11
+ export declare const DEFAULT_IGNORE: readonly string[];
12
+ export interface WalkResult {
13
+ /** Relative paths from `cwd`, lexicographically sorted for determinism. */
14
+ readonly files: readonly string[];
15
+ /** Skipped paths and their reason — for `--verbose` output. */
16
+ readonly skipped: ReadonlyArray<{
17
+ path: string;
18
+ reason: string;
19
+ }>;
20
+ }
21
+ export interface WalkOptions {
22
+ /**
23
+ * Maximum number of files to return. Beyond this the walk
24
+ * aborts with an error rather than producing a partial result —
25
+ * the bot's AC8 caps at 5000 files; the walker errs lower so
26
+ * `launchpad deploy` surfaces "too many files" with a clearer
27
+ * error than a server-side rejection.
28
+ */
29
+ readonly maxFiles?: number;
30
+ }
31
+ export declare class WalkError extends Error {
32
+ constructor(message: string);
33
+ }
34
+ /**
35
+ * Walk `cwd` and produce the list of files to bundle.
36
+ *
37
+ * Pure FS — no network, no shell-out. Respects `.gitignore` if
38
+ * present + the built-in DEFAULT_IGNORE. Skips symlinks
39
+ * silently (the bot rejects them anyway via AC8).
40
+ */
41
+ export declare function walkCwd(cwd: string, options?: WalkOptions): WalkResult;
42
+ export { relative };
43
+ //# sourceMappingURL=cwd-walker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwd-walker.d.ts","sourceRoot":"","sources":["../../src/bundle/cwd-walker.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAQ,QAAQ,EAAO,MAAM,WAAW,CAAC;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EA+B3C,CAAC;AAIF,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAU1E;AA0LD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { CliConfig } from "../config.js";
2
+ import { type DeployBundleResult } from "./upload.js";
3
+ import { type WalkResult } from "./cwd-walker.js";
4
+ export interface BundleAndDeployArgs {
5
+ readonly cfg: CliConfig;
6
+ readonly cwd: string;
7
+ readonly slug: string;
8
+ }
9
+ export type BundleAndDeployResult = {
10
+ kind: "walk-error";
11
+ message: string;
12
+ } | {
13
+ kind: "no-manifest";
14
+ message: string;
15
+ } | {
16
+ kind: "pack-error";
17
+ message: string;
18
+ } | {
19
+ kind: "worker-build-error";
20
+ message: string;
21
+ } | {
22
+ kind: "upload-error";
23
+ status: number;
24
+ body: unknown;
25
+ } | {
26
+ kind: "ok";
27
+ result: Extract<DeployBundleResult, {
28
+ kind: "ok";
29
+ }>["response"];
30
+ walk: WalkResult;
31
+ fileCount: number;
32
+ compressedBytes: number;
33
+ /** The cron Worker script name that was built + shipped, if any. */
34
+ workerScript: string | null;
35
+ };
36
+ /**
37
+ * Bundle the user's CWD and ship it to the bot.
38
+ *
39
+ * Reads `launchpad.yaml` from `cwd` (it must exist — caller is
40
+ * expected to have invoked `launchpad init` first). Walks the
41
+ * CWD respecting .gitignore + default-ignore, packs the result
42
+ * into a gzipped tar via the existing `packTarGz`, and POSTs the
43
+ * tarball + manifest YAML as multipart/form-data to the bot's
44
+ * `/apps/<slug>/deploy/bundle` endpoint.
45
+ *
46
+ * **What this function does NOT do:** authz pre-flight,
47
+ * provisioning of a not-yet-existing slug, status polling for
48
+ * the live URL. All of those are caller responsibilities.
49
+ */
50
+ export declare function bundleAndDeploy(args: BundleAndDeployArgs): Promise<BundleAndDeployResult>;
51
+ //# sourceMappingURL=orchestrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrate.d.ts","sourceRoot":"","sources":["../../src/bundle/orchestrate.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGtE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACvD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,OAAO,CAAC,kBAAkB,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEN;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,qBAAqB,CAAC,CAoFhC"}