@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.
- package/CHANGELOG.md +854 -0
- package/README.md +109 -0
- package/dist/auth/browser.d.ts +18 -0
- package/dist/auth/browser.d.ts.map +1 -0
- package/dist/auth/callback-server.d.ts +24 -0
- package/dist/auth/callback-server.d.ts.map +1 -0
- package/dist/auth/discovery.d.ts +25 -0
- package/dist/auth/discovery.d.ts.map +1 -0
- package/dist/auth/flow.d.ts +39 -0
- package/dist/auth/flow.d.ts.map +1 -0
- package/dist/auth/jwt.d.ts +27 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/pkce.d.ts +26 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/registration.d.ts +8 -0
- package/dist/auth/registration.d.ts.map +1 -0
- package/dist/auth/session.d.ts +54 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/token.d.ts +37 -0
- package/dist/auth/token.d.ts.map +1 -0
- package/dist/bundle/cron-bundle.d.ts +77 -0
- package/dist/bundle/cron-bundle.d.ts.map +1 -0
- package/dist/bundle/cwd-walker.d.ts +43 -0
- package/dist/bundle/cwd-walker.d.ts.map +1 -0
- package/dist/bundle/orchestrate.d.ts +51 -0
- package/dist/bundle/orchestrate.d.ts.map +1 -0
- package/dist/bundle/upload.d.ts +66 -0
- package/dist/bundle/upload.d.ts.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +9757 -0
- package/dist/clone/git-init.d.ts +18 -0
- package/dist/clone/git-init.d.ts.map +1 -0
- package/dist/clone/tar-extract.d.ts +59 -0
- package/dist/clone/tar-extract.d.ts.map +1 -0
- package/dist/commands/apps.d.ts +14 -0
- package/dist/commands/apps.d.ts.map +1 -0
- package/dist/commands/channel-auth.d.ts +31 -0
- package/dist/commands/channel-auth.d.ts.map +1 -0
- package/dist/commands/clone.d.ts +3 -0
- package/dist/commands/clone.d.ts.map +1 -0
- package/dist/commands/create.d.ts +27 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/deploy-flags.d.ts +75 -0
- package/dist/commands/deploy-flags.d.ts.map +1 -0
- package/dist/commands/deploy-modes.d.ts +59 -0
- package/dist/commands/deploy-modes.d.ts.map +1 -0
- package/dist/commands/deploy.d.ts +29 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/destroy.d.ts +14 -0
- package/dist/commands/destroy.d.ts.map +1 -0
- package/dist/commands/envvars.d.ts +28 -0
- package/dist/commands/envvars.d.ts.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/groups-whoami.d.ts +3 -0
- package/dist/commands/groups-whoami.d.ts.map +1 -0
- package/dist/commands/groups.d.ts +3 -0
- package/dist/commands/groups.d.ts.map +1 -0
- package/dist/commands/init.d.ts +44 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logs.d.ts +16 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/merge.d.ts +29 -0
- package/dist/commands/merge.d.ts.map +1 -0
- package/dist/commands/plan.d.ts +3 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/pull.d.ts +12 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/review.d.ts +22 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/rollback.d.ts +3 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/secrets-template.d.ts +3 -0
- package/dist/commands/secrets-template.d.ts.map +1 -0
- package/dist/commands/secrets.d.ts +3 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/skills.d.ts +13 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/status.d.ts +54 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/update.d.ts +114 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/deploy/apply.d.ts +29 -0
- package/dist/deploy/apply.d.ts.map +1 -0
- package/dist/deploy/dry-run.d.ts +13 -0
- package/dist/deploy/dry-run.d.ts.map +1 -0
- package/dist/deploy/git-files.d.ts +33 -0
- package/dist/deploy/git-files.d.ts.map +1 -0
- package/dist/deploy/group-pin.d.ts +66 -0
- package/dist/deploy/group-pin.d.ts.map +1 -0
- package/dist/deploy/manifest-state.d.ts +20 -0
- package/dist/deploy/manifest-state.d.ts.map +1 -0
- package/dist/deploy/manifest-status.d.ts +11 -0
- package/dist/deploy/manifest-status.d.ts.map +1 -0
- package/dist/deploy/resolve.d.ts +53 -0
- package/dist/deploy/resolve.d.ts.map +1 -0
- package/dist/deploy/rollback.d.ts +23 -0
- package/dist/deploy/rollback.d.ts.map +1 -0
- package/dist/deploy/runner.d.ts +29 -0
- package/dist/deploy/runner.d.ts.map +1 -0
- package/dist/deploy/stage-exit-codes.d.ts +41 -0
- package/dist/deploy/stage-exit-codes.d.ts.map +1 -0
- package/dist/deploy/status-polling.d.ts +37 -0
- package/dist/deploy/status-polling.d.ts.map +1 -0
- package/dist/deploy/tar-pack.d.ts +22 -0
- package/dist/deploy/tar-pack.d.ts.map +1 -0
- package/dist/detect/index.d.ts +53 -0
- package/dist/detect/index.d.ts.map +1 -0
- package/dist/dispatcher.d.ts +30 -0
- package/dist/dispatcher.d.ts.map +1 -0
- package/dist/groups/client.d.ts +62 -0
- package/dist/groups/client.d.ts.map +1 -0
- package/dist/http/api-client.d.ts +33 -0
- package/dist/http/api-client.d.ts.map +1 -0
- package/dist/http/errors.d.ts +31 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/manifest/load.d.ts +38 -0
- package/dist/manifest/load.d.ts.map +1 -0
- package/dist/manifest/schema.d.ts +3 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/postinstall.d.ts +3 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +37 -0
- package/dist/secrets/env-parse.d.ts +19 -0
- package/dist/secrets/env-parse.d.ts.map +1 -0
- package/dist/secrets/push.d.ts +13 -0
- package/dist/secrets/push.d.ts.map +1 -0
- package/dist/secrets/set.d.ts +19 -0
- package/dist/secrets/set.d.ts.map +1 -0
- package/dist/secrets/status.d.ts +19 -0
- package/dist/secrets/status.d.ts.map +1 -0
- package/dist/types/api.d.ts +112 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/update-notifier.d.ts +69 -0
- package/dist/update-notifier.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +62 -0
- package/skills/README.md +100 -0
- package/skills/_partials/shell-contract.md +42 -0
- package/skills/launchpad-content-pr/SKILL.md +255 -0
- package/skills/launchpad-deploy/SKILL.md +415 -0
- package/skills/launchpad-deploy-status/SKILL.md +231 -0
- package/skills/launchpad-destroy/SKILL.md +317 -0
- package/skills/launchpad-onboard/SKILL.md +179 -0
- package/skills/launchpad-status/SKILL.md +263 -0
- package/skills/marquee-share/README.md +155 -0
- package/skills/marquee-share/SKILL.md +94 -0
- package/skills/marquee-share/SYNC.md +27 -0
- package/skills/marquee-share/dist/cli.js +896 -0
- package/skills/marquee-share/eslint.config.mjs +71 -0
- package/skills/marquee-share/install.sh +103 -0
- package/skills/marquee-share/package-lock.json +3946 -0
- package/skills/marquee-share/package.json +30 -0
- package/skills/marquee-share/src/auth/PROVENANCE.md +103 -0
- package/skills/marquee-share/src/auth/browser.ts +75 -0
- package/skills/marquee-share/src/auth/callback-server.ts +171 -0
- package/skills/marquee-share/src/auth/discovery.ts +171 -0
- package/skills/marquee-share/src/auth/flow.ts +262 -0
- package/skills/marquee-share/src/auth/index.ts +171 -0
- package/skills/marquee-share/src/auth/jwt.ts +77 -0
- package/skills/marquee-share/src/auth/pkce.ts +79 -0
- package/skills/marquee-share/src/auth/registration.ts +87 -0
- package/skills/marquee-share/src/auth/session.ts +205 -0
- package/skills/marquee-share/src/auth/token.ts +162 -0
- package/skills/marquee-share/src/cli.ts +246 -0
- package/skills/marquee-share/src/config.ts +101 -0
- package/skills/marquee-share/src/render/template.ts +171 -0
- package/skills/marquee-share/src/upload/index.ts +11 -0
- package/skills/marquee-share/src/upload/upload.ts +191 -0
- package/skills/marquee-share/tests/cli.test.ts +281 -0
- package/skills/marquee-share/tests/config.test.ts +119 -0
- package/skills/marquee-share/tests/flow.test.ts +356 -0
- package/skills/marquee-share/tests/no-token-leak.test.ts +240 -0
- package/skills/marquee-share/tests/pkce.test.ts +121 -0
- package/skills/marquee-share/tests/session.test.ts +173 -0
- package/skills/marquee-share/tests/template.test.ts +170 -0
- package/skills/marquee-share/tests/upload.test.ts +311 -0
- package/skills/marquee-share/tsconfig.json +23 -0
- package/skills/marquee-share/vitest.config.ts +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAEjE,eAAO,MAAM,eAAe,EAAE,OAI7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-template.d.ts","sourceRoot":"","sources":["../../src/commands/secrets-template.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAgBxD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,KAAK,GACR,OAAO,CAAC,QAAQ,CAAC,CAiDnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/commands/secrets.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAgBjE,eAAO,MAAM,cAAc,EAAE,OAI5B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Command } from "../dispatcher.js";
|
|
2
|
+
export declare const skillsCommand: Command;
|
|
3
|
+
interface InstallEnv {
|
|
4
|
+
readonly bundleDir: string;
|
|
5
|
+
readonly userSkillsDir: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Compute install paths. Factored out so tests can swap `homedir()`
|
|
9
|
+
* + the bundle dir via env without rewiring fs internals.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveInstallEnv(): InstallEnv;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAoCjE,eAAO,MAAM,aAAa,EAAE,OAK3B,CAAC;AA2CF,UAAU,UAAU;IAClB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAQ9C"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Manifest } from "@m-kopa/launchpad-engine";
|
|
2
|
+
import type { Command } from "../dispatcher.js";
|
|
3
|
+
export declare const statusCommand: Command;
|
|
4
|
+
interface StatusArgs {
|
|
5
|
+
readonly slug: string;
|
|
6
|
+
readonly file: string;
|
|
7
|
+
readonly json: boolean;
|
|
8
|
+
readonly strict: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** What status reports, in machine-readable form for downstream
|
|
11
|
+
* consumers (M-1187 destroy, M-1189 update-skill). The lifecycle states
|
|
12
|
+
* (provisioning / provisioning_failed / live_no_content) were added by
|
|
13
|
+
* sp-st5hw9; in_sync / drift / no_deployed_manifest are unchanged. */
|
|
14
|
+
export interface StatusJsonOutput {
|
|
15
|
+
readonly state: "provisioning" | "provisioning_failed" | "live_no_content" | "in_sync" | "drift" | "no_deployed_manifest" | "destroying" | "destroyed" | "destroy_failed";
|
|
16
|
+
readonly slug: string;
|
|
17
|
+
/** Provisioning/failed only — the current (or failing) workflow stage. */
|
|
18
|
+
readonly stage?: string | null;
|
|
19
|
+
/** provisioning_failed only — the failure message. */
|
|
20
|
+
readonly failedReason?: string | null;
|
|
21
|
+
/** Provisioning/failed only — the workflow submission id. */
|
|
22
|
+
readonly submissionId?: string | null;
|
|
23
|
+
readonly deployedSha: string | null;
|
|
24
|
+
readonly headSha: string | null;
|
|
25
|
+
readonly hasOpenPr: boolean;
|
|
26
|
+
readonly openPrNumber: number | null;
|
|
27
|
+
/** Field paths that differ (e.g. ["metadata.owner", "production_env.API_BASE"]). */
|
|
28
|
+
readonly driftFields: readonly string[];
|
|
29
|
+
/** Per-field detail: local-value vs deployed-value for each drift field. */
|
|
30
|
+
readonly driftDetails: ReadonlyArray<{
|
|
31
|
+
readonly path: string;
|
|
32
|
+
readonly local: unknown;
|
|
33
|
+
readonly deployed: unknown;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute drift over the v1 closed field set (AC5).
|
|
38
|
+
*
|
|
39
|
+
* The visitor is hand-rolled (one switch per path) rather than a
|
|
40
|
+
* generic deep-diff. This is the implementation of the equivalence
|
|
41
|
+
* relation defined in M-1188 AC3: the v1 field set IS the contract;
|
|
42
|
+
* fields outside it are ignored.
|
|
43
|
+
*
|
|
44
|
+
* Returns an empty array iff `local` and `deployed` are equivalent.
|
|
45
|
+
*/
|
|
46
|
+
export declare function computeDrift(local: Manifest, deployed: Manifest): ReadonlyArray<{
|
|
47
|
+
path: string;
|
|
48
|
+
local: unknown;
|
|
49
|
+
deployed: unknown;
|
|
50
|
+
}>;
|
|
51
|
+
/** Pure arg parser. Exported for tests. */
|
|
52
|
+
export declare function parseArgs(args: readonly string[], cwd?: string): StatusArgs | string;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAiDA,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAEjE,eAAO,MAAM,aAAa,EAAE,OAI3B,CAAC;AAEF,UAAU,UAAU;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAuBD;;;uEAGuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EACV,cAAc,GACd,qBAAqB,GACrB,iBAAiB,GACjB,SAAS,GACT,OAAO,GACP,sBAAsB,GACtB,YAAY,GACZ,WAAW,GACX,gBAAgB,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC;QACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;KAC5B,CAAC,CAAC;CACJ;AAwLD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,QAAQ,GACjB,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CA2DpE;AAgJD,2CAA2C;AAC3C,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAsB,GAC1B,UAAU,GAAG,MAAM,CAgErB"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type ChannelUpdateResult } from "./channel-auth.js";
|
|
2
|
+
import type { CliIo, Command, ExitCode } from "../dispatcher.js";
|
|
3
|
+
/** Browser-based installer the platform channel directs users to for upgrades. */
|
|
4
|
+
export declare const CHANNEL_INSTALL_URL = "https://get.launchpad.m-kopa.us";
|
|
5
|
+
export type PackageManager = "npm" | "bun" | "pnpm";
|
|
6
|
+
/** Which distribution channel installed this CLI (ADR 0014). */
|
|
7
|
+
export type InstallChannel = "github" | "platform";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a package-manager binary name for the current platform.
|
|
10
|
+
*
|
|
11
|
+
* On Windows, `npm` and `pnpm` are shipped as `.cmd` shims (there is
|
|
12
|
+
* no bare `npm.exe` / `pnpm.exe`). Node's `child_process.execFile` /
|
|
13
|
+
* `spawn` invoke `CreateProcess`, which does NOT consult `PATHEXT`
|
|
14
|
+
* — libuv tries only the literal filename and `<name>.exe`. So
|
|
15
|
+
* `execFile("npm", …)` fails with `ENOENT` on every Windows host,
|
|
16
|
+
* even when `npm` works perfectly from `cmd` / PowerShell (which DO
|
|
17
|
+
* consult `PATHEXT`). The user's `~$ launchpad update` then
|
|
18
|
+
* surfaced as "npm was not found on PATH" — misleading; npm is on
|
|
19
|
+
* PATH, libuv just won't resolve the shim (M-1056).
|
|
20
|
+
*
|
|
21
|
+
* Appending `.cmd` lets libuv find the shim — but finding it is
|
|
22
|
+
* necessary, not sufficient. `.cmd` is a batch script, not a PE
|
|
23
|
+
* binary; `CreateProcess` cannot execute it directly and fails the
|
|
24
|
+
* spawn with `EINVAL`. The shell wrapper supplied by
|
|
25
|
+
* `pmSpawnOptions` (below) is what actually runs the script — see
|
|
26
|
+
* that helper for the full story. `bun` ships as `bun.exe`, which
|
|
27
|
+
* libuv finds via its `.exe` fallback and `CreateProcess` can
|
|
28
|
+
* execute natively, so `bun` is left unchanged. Non-Windows
|
|
29
|
+
* platforms keep the bare name.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolvePmBin(pm: PackageManager): string;
|
|
32
|
+
/**
|
|
33
|
+
* Spawn options needed to execute the resolved PM binary on the
|
|
34
|
+
* current platform. On Windows, `npm.cmd` / `pnpm.cmd` are batch
|
|
35
|
+
* scripts — even with the explicit `.cmd` suffix from `resolvePmBin`,
|
|
36
|
+
* `CreateProcess` cannot run them directly and fails with `EINVAL`.
|
|
37
|
+
* Going through `cmd.exe` via `shell: true` is the documented Node
|
|
38
|
+
* fix. Every arg passed to a PM in this file is hardcoded (PKG /
|
|
39
|
+
* REGISTRY / UPGRADE_ARGS / the literal subcommand strings), so no
|
|
40
|
+
* user input ever reaches the shell — `shell: true` is safe here.
|
|
41
|
+
*/
|
|
42
|
+
export declare function pmSpawnOptions(platform?: NodeJS.Platform): {
|
|
43
|
+
shell: boolean;
|
|
44
|
+
};
|
|
45
|
+
export declare const updateCommand: Command;
|
|
46
|
+
export interface UpdateArgs {
|
|
47
|
+
readonly check: boolean;
|
|
48
|
+
readonly via: PackageManager | null;
|
|
49
|
+
readonly help: boolean;
|
|
50
|
+
/** Non-null when the argv was malformed (unknown flag / bad --via). */
|
|
51
|
+
readonly error: string | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parse `launchpad update` argv. Supports `--check`, `--help`/`-h`,
|
|
55
|
+
* and `--via <pm>` / `--via=<pm>`. Anything else is an error.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseUpdateArgs(args: readonly string[]): UpdateArgs;
|
|
58
|
+
/**
|
|
59
|
+
* Compare two `MAJOR.MINOR.PATCH` version strings. Pre-release and
|
|
60
|
+
* build metadata (anything after `-` or `+`) is stripped — the CLI
|
|
61
|
+
* publishes plain numeric versions. Returns -1 / 0 / 1 for
|
|
62
|
+
* a < b / a == b / a > b. Unparseable segments coerce to 0.
|
|
63
|
+
*/
|
|
64
|
+
export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
|
|
65
|
+
export type LatestResult = {
|
|
66
|
+
readonly kind: "ok";
|
|
67
|
+
readonly version: string;
|
|
68
|
+
} | {
|
|
69
|
+
readonly kind: "auth";
|
|
70
|
+
readonly detail: string;
|
|
71
|
+
} | {
|
|
72
|
+
readonly kind: "registry";
|
|
73
|
+
readonly detail: string;
|
|
74
|
+
};
|
|
75
|
+
export type { ChannelUpdateResult };
|
|
76
|
+
export interface UpdateDeps {
|
|
77
|
+
readonly cliVersion: string;
|
|
78
|
+
/** Distribution channel this CLI was installed from (ADR 0014). */
|
|
79
|
+
readonly channel: InstallChannel;
|
|
80
|
+
readonly fetchLatestVersion: () => Promise<LatestResult>;
|
|
81
|
+
readonly detectPm: () => Promise<PackageManager | null>;
|
|
82
|
+
readonly runUpgrade: (pm: PackageManager) => Promise<number>;
|
|
83
|
+
/**
|
|
84
|
+
* Platform-channel self-update: authenticate to the Entra-OIDC gateway via
|
|
85
|
+
* the loopback CLI-auth grant (one browser bounce, no manual step; ADR 0023),
|
|
86
|
+
* fetch the staff-gated installer from get.launchpad.m-kopa.us with the
|
|
87
|
+
* short-lived bearer, and run it (the installer is self-contained and
|
|
88
|
+
* SHA-256 self-verifying — it `npm install -g`s the embedded package).
|
|
89
|
+
*/
|
|
90
|
+
readonly runChannelInstaller: () => Promise<ChannelUpdateResult>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Channel-aware "what is the latest published version" resolver, shared
|
|
94
|
+
* by the explicit `update` command and the passive startup notifier's
|
|
95
|
+
* background refresh (`update-notifier.ts`). Single source of truth for
|
|
96
|
+
* the channel→fetcher mapping so the notifier can never drift from what
|
|
97
|
+
* `update` itself reports.
|
|
98
|
+
*/
|
|
99
|
+
export declare function resolveLatestVersion(): Promise<LatestResult>;
|
|
100
|
+
/**
|
|
101
|
+
* Which channel installed this CLI. The platform installer (M-1047)
|
|
102
|
+
* writes `~/.launchpad/channel` containing `platform`; a GitHub
|
|
103
|
+
* Packages install writes nothing. Absence — or any unreadable /
|
|
104
|
+
* unrecognised marker — resolves to `github`, the safe default that
|
|
105
|
+
* covers every install predating the platform channel.
|
|
106
|
+
*/
|
|
107
|
+
export declare function detectInstallChannel(): InstallChannel;
|
|
108
|
+
/**
|
|
109
|
+
* Pure(ish) command core — all external effects arrive via `deps`,
|
|
110
|
+
* so unit tests drive every branch without touching the network or
|
|
111
|
+
* spawning a package manager.
|
|
112
|
+
*/
|
|
113
|
+
export declare function runUpdate(args: readonly string[], io: CliIo, deps: UpdateDeps): Promise<ExitCode>;
|
|
114
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAuDA,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAWjE,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,oCAAoC,CAAC;AAYrE,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,CAAC;AASnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAGvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAEpB;AAED,eAAO,MAAM,aAAa,EAAE,OAI3B,CAAC;AAIF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CA4BnE;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAiBhE;AAID,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAI3D,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAClE;AA0DD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAI5D;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAQrD;AA0JD;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,KAAK,EACT,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,QAAQ,CAAC,CAqGnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAEjE,eAAO,MAAM,eAAe,EAAE,OAI7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAS,OAAO,EAAY,MAAM,kBAAkB,CAAC;AAGjE,eAAO,MAAM,aAAa,EAAE,OAI3B,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Production bot URL (Cloudflare Workers `*.workers.dev` host). */
|
|
2
|
+
export declare const DEFAULT_BOT_URL = "https://launchpad-portal-bot.mkopa-launchpad.workers.dev";
|
|
3
|
+
export interface CliConfig {
|
|
4
|
+
readonly botUrl: string;
|
|
5
|
+
readonly sessionPath: string;
|
|
6
|
+
readonly cacheDir: string;
|
|
7
|
+
readonly stateDir: string;
|
|
8
|
+
readonly platformRepoPath: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function loadConfig(env?: NodeJS.ProcessEnv): CliConfig;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA4CA,oEAAoE;AACpE,eAAO,MAAM,eAAe,6DACgC,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,CAgB1E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type CliConfig } from "../config.js";
|
|
2
|
+
import type { CliIo, ExitCode } from "../dispatcher.js";
|
|
3
|
+
export interface ApplyOptions {
|
|
4
|
+
readonly file: string | null;
|
|
5
|
+
/** Refused with exit 64 — kept for one release of deprecation
|
|
6
|
+
* visibility per AC-OC1. */
|
|
7
|
+
readonly platformRepo: string | null;
|
|
8
|
+
/** Accepted-but-ignored (group resolution is bot-side now).
|
|
9
|
+
* Removal in v0.13 alongside `--platform-repo`. */
|
|
10
|
+
readonly rePin: boolean;
|
|
11
|
+
readonly yes: boolean;
|
|
12
|
+
/** Re-attach to an in-flight apply for `--resume <prNumber>`. */
|
|
13
|
+
readonly resumePrNumber?: number;
|
|
14
|
+
/** Override the 90-minute default polling timeout (AC-U2). */
|
|
15
|
+
readonly timeoutMinutes?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ApplyDeps {
|
|
18
|
+
readonly prompt?: (question: string) => Promise<string>;
|
|
19
|
+
readonly clock?: () => Date;
|
|
20
|
+
readonly config?: CliConfig;
|
|
21
|
+
/** Inject `fetch` for tests; defaults to `globalThis.fetch`. */
|
|
22
|
+
readonly fetcher?: typeof fetch;
|
|
23
|
+
/** Inject `git rev-parse` resolution for tests. */
|
|
24
|
+
readonly gitHeadSha?: (cwd: string) => string;
|
|
25
|
+
/** Polling interval seconds (defaults to 10s; tests use 0). */
|
|
26
|
+
readonly pollIntervalSeconds?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function runDeployApply(opts: ApplyOptions, io: CliIo, deps?: ApplyDeps): Promise<ExitCode>;
|
|
29
|
+
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/deploy/apply.ts"],"names":[],"mappings":"AA8CA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAU1D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;iCAC6B;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;wDACoD;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAwCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC,QAAQ,CAAC,CAyLnB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CliIo, ExitCode } from "../dispatcher.js";
|
|
2
|
+
import type { CliConfig } from "../config.js";
|
|
3
|
+
export interface DryRunOptions {
|
|
4
|
+
readonly file: string | null;
|
|
5
|
+
readonly json: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface DryRunDeps {
|
|
8
|
+
readonly config?: CliConfig;
|
|
9
|
+
readonly fetcher?: typeof fetch;
|
|
10
|
+
readonly gitHeadSha?: (cwd: string) => string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runDeployDryRun(opts: DryRunOptions, io: CliIo, deps?: DryRunDeps): Promise<ExitCode>;
|
|
13
|
+
//# sourceMappingURL=dry-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dry-run.d.ts","sourceRoot":"","sources":["../../src/deploy/dry-run.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/C;AAgBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,QAAQ,CAAC,CAmEnB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export declare class GitFilesError extends Error {
|
|
3
|
+
readonly code: "git_files_error";
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Paths the bot owns and rejects unconditionally on `deploy-pr`
|
|
7
|
+
* (see `PROTECTED_PATHS` in `portal-bot/src/deploy-pr.ts`). Mirrored
|
|
8
|
+
* here so the CLI excludes them up front rather than shipping a
|
|
9
|
+
* tarball the bot will reject.
|
|
10
|
+
*
|
|
11
|
+
* The bot uses `base_tree` mode on the commit, so files we omit
|
|
12
|
+
* from the tarball keep their base-branch contents — there's no
|
|
13
|
+
* destructive consequence to filtering these out.
|
|
14
|
+
*
|
|
15
|
+
* Keep in lock-step with the bot's list. A future endpoint that
|
|
16
|
+
* exposes this list would let the CLI fetch it dynamically; for
|
|
17
|
+
* v1 the set is small and rarely changes.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PROTECTED_PATHS: ReadonlySet<string>;
|
|
20
|
+
export interface ListFilesOptions {
|
|
21
|
+
readonly cwd: string;
|
|
22
|
+
readonly spawner?: typeof spawn;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Return the deploy-eligible file paths under `cwd`, relative to
|
|
26
|
+
* `cwd`. Paths use forward slashes (git's native format) so they
|
|
27
|
+
* tar-pack cleanly cross-platform.
|
|
28
|
+
*
|
|
29
|
+
* Throws `GitFilesError` if git isn't installed or `cwd` isn't a
|
|
30
|
+
* git working tree.
|
|
31
|
+
*/
|
|
32
|
+
export declare function listDeployFiles(opts: ListFilesOptions): Promise<readonly string[]>;
|
|
33
|
+
//# sourceMappingURL=git-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-files.d.ts","sourceRoot":"","sources":["../../src/deploy/git-files.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAE9D,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAG,iBAAiB,CAAU;CAC5C;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAU9C,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAqBxF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface GroupPin {
|
|
2
|
+
/** The manifest's `access.allowed_entra_group` at the moment of
|
|
3
|
+
* pinning. Treated as a label; rename in Entra doesn't break
|
|
4
|
+
* the pin. */
|
|
5
|
+
readonly pinnedName: string;
|
|
6
|
+
/** Entra Object ID UUID. The canonical identifier from this
|
|
7
|
+
* pin onwards. */
|
|
8
|
+
readonly pinnedUuid: string;
|
|
9
|
+
/** ISO-8601 UTC timestamp of when the pin was written. */
|
|
10
|
+
readonly pinnedAt: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Read the per-app group pin. Returns `null` when the file is
|
|
14
|
+
* missing, malformed, or has the wrong shape — every "not a
|
|
15
|
+
* valid pin" state collapses to `null` so callers can branch
|
|
16
|
+
* on a single check.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readGroupPin(stateDir: string, slug: string): GroupPin | null;
|
|
19
|
+
/**
|
|
20
|
+
* Write the per-app group pin, creating the slug directory if
|
|
21
|
+
* needed. Throws if the write fails (apply needs to know).
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeGroupPin(stateDir: string, slug: string, pin: GroupPin): void;
|
|
24
|
+
/**
|
|
25
|
+
* Compare an existing pin against the manifest's current group
|
|
26
|
+
* name and a freshly-resolved UUID for that name. The four
|
|
27
|
+
* outcomes drive the apply verb's UX:
|
|
28
|
+
*
|
|
29
|
+
* - `consistent` — pin matches both the manifest's name
|
|
30
|
+
* AND the fresh resolution. Apply uses
|
|
31
|
+
* the pinned UUID unchanged.
|
|
32
|
+
* - `manifest-renamed` — pin's UUID is still the right group
|
|
33
|
+
* but the manifest's name field has
|
|
34
|
+
* changed. Apply uses the pinned UUID;
|
|
35
|
+
* the manifest can be updated at the
|
|
36
|
+
* caller's leisure.
|
|
37
|
+
* - `entra-renamed` — manifest's name no longer resolves to
|
|
38
|
+
* the pinned UUID. Either the group was
|
|
39
|
+
* renamed in Entra (a fresh resolve of
|
|
40
|
+
* the manifest's name now returns a
|
|
41
|
+
* DIFFERENT UUID), or the operator
|
|
42
|
+
* intends to switch to a different group.
|
|
43
|
+
* Apply should surface this loudly and
|
|
44
|
+
* require explicit re-pin.
|
|
45
|
+
* - `pin-missing` — no pin yet. First-deploy case; apply
|
|
46
|
+
* writes the pin.
|
|
47
|
+
*/
|
|
48
|
+
export type PinComparison = {
|
|
49
|
+
kind: "pin-missing";
|
|
50
|
+
} | {
|
|
51
|
+
kind: "consistent";
|
|
52
|
+
pinnedUuid: string;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "manifest-renamed";
|
|
55
|
+
pinnedUuid: string;
|
|
56
|
+
oldName: string;
|
|
57
|
+
newName: string;
|
|
58
|
+
} | {
|
|
59
|
+
kind: "entra-renamed";
|
|
60
|
+
pinnedUuid: string;
|
|
61
|
+
pinnedName: string;
|
|
62
|
+
currentResolvedUuid: string;
|
|
63
|
+
manifestName: string;
|
|
64
|
+
};
|
|
65
|
+
export declare function comparePin(pin: GroupPin | null, manifestName: string, freshUuid: string): PinComparison;
|
|
66
|
+
//# sourceMappingURL=group-pin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-pin.d.ts","sourceRoot":"","sources":["../../src/deploy/group-pin.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,QAAQ;IACvB;;mBAEe;IACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;uBACmB;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAiC5E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAIjF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,wBAAgB,UAAU,CACxB,GAAG,EAAE,QAAQ,GAAG,IAAI,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,aAAa,CA6Bf"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CliConfig } from "../config.js";
|
|
2
|
+
export interface ManifestStateResponse {
|
|
3
|
+
readonly slug: string;
|
|
4
|
+
readonly hasAppFile: boolean;
|
|
5
|
+
readonly lastAppliedManifestSha: string | null;
|
|
6
|
+
readonly appRepoHeadSha: string | null;
|
|
7
|
+
readonly openPr: {
|
|
8
|
+
readonly number: number;
|
|
9
|
+
readonly url: string;
|
|
10
|
+
readonly branch: string;
|
|
11
|
+
} | null;
|
|
12
|
+
readonly manifestYaml?: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Fetch `/apps/<slug>/manifest/state`. With `includeManifest: true`,
|
|
15
|
+
* the response also carries the deployed `launchpad.yaml` body at
|
|
16
|
+
* `lastAppliedManifestSha`. */
|
|
17
|
+
export declare function fetchManifestState(cfg: CliConfig, slug: string, opts?: {
|
|
18
|
+
includeManifest?: boolean;
|
|
19
|
+
}, fetcher?: typeof fetch): Promise<ManifestStateResponse>;
|
|
20
|
+
//# sourceMappingURL=manifest-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-state.d.ts","sourceRoot":"","sources":["../../src/deploy/manifest-state.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAcD;;gCAEgC;AAChC,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,EACxC,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAehC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CliConfig } from "../config.js";
|
|
2
|
+
export interface ManifestStatusResponse {
|
|
3
|
+
readonly slug: string;
|
|
4
|
+
readonly role: string;
|
|
5
|
+
readonly lastAppliedManifestSha: string;
|
|
6
|
+
readonly hasStatus: boolean;
|
|
7
|
+
readonly status: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/** Fetch `/apps/<slug>/manifest/status` (role-redacted by the bot). */
|
|
10
|
+
export declare function fetchManifestStatus(cfg: CliConfig, slug: string, fetcher?: typeof fetch): Promise<ManifestStatusResponse>;
|
|
11
|
+
//# sourceMappingURL=manifest-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-status.d.ts","sourceRoot":"","sources":["../../src/deploy/manifest-status.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,uEAAuE;AACvE,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAGjC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type PinComparison } from "./group-pin.js";
|
|
2
|
+
import type { CliConfig } from "../config.js";
|
|
3
|
+
import type { Manifest } from "../manifest/schema.js";
|
|
4
|
+
export type ResolutionResult = {
|
|
5
|
+
kind: "ok";
|
|
6
|
+
/** UUID emitted into the TF block. Comes from the pin when
|
|
7
|
+
* present (D3); otherwise from the fresh Graph resolution. */
|
|
8
|
+
uuid: string;
|
|
9
|
+
/** UUID returned by the *fresh* graph lookup (irrespective of
|
|
10
|
+
* the pin). Apply uses this to decide whether the pin is
|
|
11
|
+
* drifted relative to current Entra state. Empty string when
|
|
12
|
+
* the manifest's name no longer resolves at all (deleted
|
|
13
|
+
* group with a stale pin still on disk). */
|
|
14
|
+
freshUuid: string;
|
|
15
|
+
/** Display name of the resolved group at the time of the
|
|
16
|
+
* fresh lookup (`displayName` in the bot's response). */
|
|
17
|
+
displayName: string;
|
|
18
|
+
/** Whether the bot's groups list came from cache or a fresh
|
|
19
|
+
* fetch. Separate from the pin status below. */
|
|
20
|
+
source: "cache" | "fresh";
|
|
21
|
+
/** D3 pin comparison against the fresh resolve. Drives the
|
|
22
|
+
* output: "would-be-pinned", "consistent", "manifest
|
|
23
|
+
* renamed", or "Entra-side rename detected". */
|
|
24
|
+
pin: PinComparison;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "not-found";
|
|
27
|
+
key: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "ambiguous";
|
|
30
|
+
key: string;
|
|
31
|
+
matches: readonly {
|
|
32
|
+
id: string;
|
|
33
|
+
displayName: string;
|
|
34
|
+
}[];
|
|
35
|
+
} | {
|
|
36
|
+
kind: "unauthenticated";
|
|
37
|
+
message: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "forbidden";
|
|
40
|
+
message: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "network";
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the manifest's group reference against the visible
|
|
47
|
+
* groups list + D3 pin file. Pure read-side — never writes the
|
|
48
|
+
* pin, never invalidates the cache. The apply path writes the
|
|
49
|
+
* pin only after `terraform apply` succeeds; the dry-run never
|
|
50
|
+
* writes it at all.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveGroup(manifest: Manifest, cfg: CliConfig): Promise<ResolutionResult>;
|
|
53
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/deploy/resolve.ts"],"names":[],"mappings":"AA0BA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,MAAM,MAAM,gBAAgB,GACxB;IACE,IAAI,EAAE,IAAI,CAAC;IACX;mEAC+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb;;;;iDAI6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB;8DAC0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB;qDACiD;IACjD,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1B;;qDAEiD;IACjD,GAAG,EAAE,aAAa,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,gBAAgB,CAAC,CA8E3B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ApplyDeps } from "./apply.js";
|
|
2
|
+
import { type CommandRunner } from "./runner.js";
|
|
3
|
+
import type { CliIo, ExitCode } from "../dispatcher.js";
|
|
4
|
+
export interface RollbackOptions {
|
|
5
|
+
readonly sha: string;
|
|
6
|
+
readonly file: string | null;
|
|
7
|
+
/** Accepted-but-warned (no-op). Removed in v0.13. */
|
|
8
|
+
readonly platformRepo: string | null;
|
|
9
|
+
/** Accepted-but-warned (no-op). Removed in v0.13. */
|
|
10
|
+
readonly rePin: boolean;
|
|
11
|
+
readonly yes: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface RollbackDeps {
|
|
14
|
+
readonly runner?: CommandRunner;
|
|
15
|
+
readonly prompt?: (question: string) => Promise<string>;
|
|
16
|
+
/** Inject the apply dep bag so tests share one runner + one
|
|
17
|
+
* clock between the rollback verification + the inner apply
|
|
18
|
+
* call. Defaults pass `undefined`, which makes the inner apply
|
|
19
|
+
* fall back to nodeRunner / real clock. */
|
|
20
|
+
readonly applyDeps?: ApplyDeps;
|
|
21
|
+
}
|
|
22
|
+
export declare function runRollback(opts: RollbackOptions, io: CliIo, deps?: RollbackDeps): Promise<ExitCode>;
|
|
23
|
+
//# sourceMappingURL=rollback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/deploy/rollback.ts"],"names":[],"mappings":"AAkDA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD;;;gDAG4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAChC;AAUD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,eAAe,EACrB,EAAE,EAAE,KAAK,EACT,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,QAAQ,CAAC,CAmInB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface CommandResult {
|
|
2
|
+
/** Process exit code. `null` from spawn → -1 here so callers
|
|
3
|
+
* always have a numeric comparison target. */
|
|
4
|
+
readonly exitCode: number;
|
|
5
|
+
readonly stdout: string;
|
|
6
|
+
readonly stderr: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandRunner {
|
|
9
|
+
run(cmd: string, args: readonly string[], opts?: {
|
|
10
|
+
cwd?: string;
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
/** Optional stdin payload written to the child after spawn.
|
|
13
|
+
* Required by `secrets push`'s `wrangler secret put` calls,
|
|
14
|
+
* which read the value from stdin. Existing callers
|
|
15
|
+
* (terraform plan/apply/show via apply/pull/drift) pass
|
|
16
|
+
* nothing and continue to get `stdio: ["ignore", …]`. */
|
|
17
|
+
stdin?: string;
|
|
18
|
+
}): Promise<CommandResult>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Production runner — shells out via `child_process.spawn`.
|
|
22
|
+
*
|
|
23
|
+
* Exposed as a const (not a class) so tests that want to stub
|
|
24
|
+
* a single method can spread it: `{ ...nodeRunner, run: stub }`.
|
|
25
|
+
* The exported binding is the type-aware singleton; do not
|
|
26
|
+
* mutate it at runtime.
|
|
27
|
+
*/
|
|
28
|
+
export declare const nodeRunner: CommandRunner;
|
|
29
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/deploy/runner.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,aAAa;IAC5B;mDAC+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CACD,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;QACxB;;;;kEAI0D;QAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GACA,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,aAyCxB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Closed enum of terminal-failure stages the workflow may halt at.
|
|
3
|
+
* Mirrors `TERMINAL_FAILURE_STAGES` in `portal-bot/src/stages.ts`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const TERMINAL_FAILURE_STAGES: readonly ["validator_rejected", "tf_apply_failed", "bot_pr_ci_failed", "abandoned", "failed"];
|
|
6
|
+
export type TerminalFailureStage = (typeof TERMINAL_FAILURE_STAGES)[number];
|
|
7
|
+
/**
|
|
8
|
+
* Stage → exit code map. Numbers are deliberately chosen so a wrapper
|
|
9
|
+
* can `case $? in 32) … 33) … esac` and tell apart the failure
|
|
10
|
+
* classes without parsing CLI stdout.
|
|
11
|
+
*
|
|
12
|
+
* | Stage | Code | Meaning (operator-facing) |
|
|
13
|
+
* |------------------------|------|----------------------------------------------------------|
|
|
14
|
+
* | validator_rejected | 32 | Bot's PR failed shape-validator. Operator must fix the |
|
|
15
|
+
* | | | template / generator drift, then re-file. |
|
|
16
|
+
* | tf_apply_failed | 33 | `terraform apply` failed. Usually transient (Cf API |
|
|
17
|
+
* | | | rate limit / cert issuance latency). Use `--resume`. |
|
|
18
|
+
* | bot_pr_ci_failed | 34 | A required check (lint/audit/typecheck/etc) failed on |
|
|
19
|
+
* | | | the bot's PR. Operator must push a fix to the bot PR. |
|
|
20
|
+
* | abandoned | 35 | Operator released the slug via `--abandon`. |
|
|
21
|
+
* | failed | 36 | Generic terminal failure (legacy; pre-M-892). |
|
|
22
|
+
*
|
|
23
|
+
* 0 = success / `ready_for_content`. 1 = generic CLI error (network,
|
|
24
|
+
* auth, bad argv) per the dispatcher's existing contract. 64 = usage
|
|
25
|
+
* (EX_USAGE). The 32-36 band sits clear of both.
|
|
26
|
+
*/
|
|
27
|
+
export declare const STAGE_EXIT_CODES: Readonly<Record<TerminalFailureStage, number>>;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the exit code for a stage. Defaults to 36 (`failed`'s code)
|
|
30
|
+
* for any unknown stage — defensive against the bot growing a new
|
|
31
|
+
* stage string before the CLI catches up. The CLI also surfaces the
|
|
32
|
+
* unknown stage name verbatim in stderr so operators see what they
|
|
33
|
+
* got.
|
|
34
|
+
*/
|
|
35
|
+
export declare function exitCodeForStage(stage: string): number;
|
|
36
|
+
/**
|
|
37
|
+
* Type guard: is this stage one the CLI considers terminal-failure?
|
|
38
|
+
* Used to break out of the polling loop.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isTerminalFailureStage(stage: string): stage is TerminalFailureStage;
|
|
41
|
+
//# sourceMappingURL=stage-exit-codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage-exit-codes.d.ts","sourceRoot":"","sources":["../../src/deploy/stage-exit-codes.ts"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,eAAO,MAAM,uBAAuB,+FAM1B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CACrC,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAO5B,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,oBAAoB,CAE/B"}
|