@akanjs/cli 3.1.0-rc.1 → 3.1.0-rc.3

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 (74) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-kyprmy06.js → CodeAgent-ctk4fh2b.js} +2 -2
  3. package/{CodeTui-21mtze3j.js → CodeTui-mrxtrdzw.js} +1 -1
  4. package/TunnelShare-rj74jd6x.js +13 -0
  5. package/{agent.command-f3gsc1gd.js → agent.command-ncre6kwz.js} +5 -5
  6. package/akanCode.js +2 -2
  7. package/{application.command-5s780vnz.js → application.command-54mawreg.js} +52 -41
  8. package/{applicationBuildRunner-1yaqsrdq.js → applicationBuildRunner-8573zr2w.js} +16 -30
  9. package/buildBatch.proc.js +22 -13
  10. package/{cloud.command-yj6xb2a7.js → cloud.command-nyemv0m3.js} +57 -65
  11. package/cloud.script-ht6yb203.js +23 -0
  12. package/{code.command-3wkn4ja5.js → code.command-spsrzg63.js} +6 -6
  13. package/{context.command-9jjn3gcw.js → context.command-768zv7z4.js} +16 -13
  14. package/context.runner-tf1b53qq.js +24 -0
  15. package/{guideline.command-dtczrqpf.js → guideline.command-4ycwc51q.js} +2 -2
  16. package/guidelines/conventions/conventions.instruction.md +28 -15
  17. package/guidelines/cssRule/cssRule.instruction.md +12 -6
  18. package/guidelines/mcpRule/mcpRule.instruction.md +27 -11
  19. package/guidelines/runtimeRule/runtimeRule.instruction.md +24 -15
  20. package/guidelines/transportRule/transportRule.instruction.md +28 -5
  21. package/incrementalBuilder.proc.js +9 -6
  22. package/{index-2etcv0sc.js → index-00seamy5.js} +1 -1
  23. package/{index-jx4bzvwg.js → index-1a7nhq56.js} +92 -52
  24. package/{index-e0cvze1s.js → index-1nyxvz8j.js} +4 -4
  25. package/index-2z3kykvd.js +248 -0
  26. package/{index-rtct7d43.js → index-3675mvjw.js} +1 -1
  27. package/{index-56d2g8ms.js → index-3ddt3qjg.js} +1 -1
  28. package/{index-6jjtnhkw.js → index-3x7yeecy.js} +51 -9
  29. package/{index-ww9bhp67.js → index-4pf8g7ff.js} +1 -1
  30. package/index-8935h3n1.js +33 -0
  31. package/{index-v29746vb.js → index-8eqkxwsx.js} +3 -3
  32. package/{index-c2yrsxdh.js → index-91rt5bye.js} +96 -320
  33. package/{index-55mynnqs.js → index-bv210r6t.js} +459 -210
  34. package/{index-c76k723e.js → index-c4h5b5nq.js} +2 -2
  35. package/{index-qt22xstj.js → index-c9zjb3tw.js} +5 -3
  36. package/{index-c1x0be5j.js → index-dmsvd2rv.js} +2 -2
  37. package/index-ec080x99.js +1124 -0
  38. package/{index-ctanya41.js → index-fjqvd5mx.js} +4 -4
  39. package/{index-aprt7pkz.js → index-fvn6f5wx.js} +229 -1327
  40. package/{index-rc5rwyps.js → index-jj7yapwq.js} +71 -60
  41. package/index-kmamh5bv.js +241 -0
  42. package/{index-fm46xrf1.js → index-q5abh0jq.js} +3 -3
  43. package/{index-1w2qaee2.js → index-qf8g88j9.js} +361 -291
  44. package/{index-gnyf1fqy.js → index-qvghfv6v.js} +2 -2
  45. package/{index-ae5pwhgs.js → index-r5d6rq19.js} +10 -8
  46. package/{index-2mx692qq.js → index-vhfjzda3.js} +2 -2
  47. package/{index-8r4d7cmt.js → index-w9b71b6y.js} +4 -4
  48. package/{index-8ggztp8k.js → index-wanhh011.js} +42 -177
  49. package/{index-05g3jayg.js → index-wdze51wz.js} +1 -1
  50. package/index-wjqbc7sf.js +668 -0
  51. package/{index-rwq3ekqc.js → index-xf40a295.js} +7 -7
  52. package/{index-krq7btbt.js → index-xm5tmpv0.js} +3 -3
  53. package/index.js +22 -22
  54. package/{library.command-gaga5bmq.js → library.command-88ahgych.js} +3 -3
  55. package/{localRegistry.command-vsreyy42.js → localRegistry.command-ykea1m7b.js} +12 -9
  56. package/{module.command-7vpf6db4.js → module.command-zky4b7m9.js} +5 -5
  57. package/{package.command-twmvvf69.js → package.command-vh8pcedh.js} +3 -3
  58. package/package.json +2 -2
  59. package/{page.command-5asq7fdf.js → page.command-fyqeqxc3.js} +3 -3
  60. package/{pipeline.command-d0v38572.js → pipeline.command-r5t30py6.js} +220 -219
  61. package/{primitive.command-dyrs2fm8.js → primitive.command-a0516zfk.js} +6 -6
  62. package/{projectTypecheck-cvtkrzp2.js → projectTypecheck-7djd4z50.js} +1 -1
  63. package/{quality.command-6emsqpbg.js → quality.command-k7jcnfn0.js} +2 -2
  64. package/{repair.command-8t6aegv5.js → repair.command-85zg2an3.js} +5 -5
  65. package/{scalar.command-bnggy1x7.js → scalar.command-g5vmqwca.js} +4 -4
  66. package/{subspace.command-md2teygq.js → subspace.command-mp4evgsj.js} +421 -362
  67. package/{tunnel.command-jx3tdm2d.js → tunnel.command-kbnr99sj.js} +7 -4
  68. package/{workflow.command-jx0wag5r.js → workflow.command-9y9p1n8y.js} +10 -10
  69. package/{workspace.command-yxd7rr7g.js → workspace.command-jmec2kjg.js} +33 -30
  70. package/TunnelShare-q4jq08qg.js +0 -9
  71. package/cloud.script-h6pvcpa2.js +0 -20
  72. package/context.runner-atcrzz5b.js +0 -21
  73. package/index-6w0rbr9d.js +0 -68
  74. package/index-pgj2rt78.js +0 -404
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-6jjtnhkw.js";
5
+ } from "./index-3x7yeecy.js";
6
6
  import {
7
7
  FileSys2
8
8
  } from "./index-52w0fvh8.js";
9
9
  import {
10
10
  PkgExecutor
11
- } from "./index-55mynnqs.js";
11
+ } from "./index-bv210r6t.js";
12
12
  import {
13
13
  TypeScriptDependencyScanner2
14
14
  } from "./index-2ahj896a.js";
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  AppExecutor
4
- } from "./index-55mynnqs.js";
4
+ } from "./index-bv210r6t.js";
5
5
  import {
6
6
  jsonText,
7
7
  createWorkflowBaselineSummary,
8
8
  buildAkanModuleContextIndex,
9
9
  toolingRolloutGate
10
- } from "./index-05g3jayg.js";
10
+ } from "./index-wdze51wz.js";
11
11
  import {
12
12
  buildResourceList,
13
13
  codexMcpConfigPath,
@@ -17,23 +17,25 @@ import {
17
17
  upsertCodexMcpServerBlock,
18
18
  renderDoctorText,
19
19
  AkanContextAnalyzer
20
- } from "./index-2mx692qq.js";
20
+ } from "./index-vhfjzda3.js";
21
21
  import {
22
22
  runner
23
- } from "./index-6jjtnhkw.js";
23
+ } from "./index-3x7yeecy.js";
24
24
  import {
25
- NativeApp,
26
25
  isPlaceholderAppId
27
- } from "./index-1w2qaee2.js";
26
+ } from "./index-kmamh5bv.js";
27
+ import {
28
+ NativeApp
29
+ } from "./index-qf8g88j9.js";
28
30
  import {
29
31
  Prompter2
30
32
  } from "./index-zzvvc845.js";
31
33
  import {
32
34
  RepairRunner
33
- } from "./index-fm46xrf1.js";
35
+ } from "./index-q5abh0jq.js";
34
36
  import {
35
37
  WorkflowRunner
36
- } from "./index-rwq3ekqc.js";
38
+ } from "./index-xf40a295.js";
37
39
  import {
38
40
  getMobileTargets,
39
41
  appIdsOf
@@ -10,7 +10,7 @@ import {
10
10
  isScannedRootEntry,
11
11
  AppExecutor,
12
12
  LibExecutor
13
- } from "./index-55mynnqs.js";
13
+ } from "./index-bv210r6t.js";
14
14
  import {
15
15
  FileSys2
16
16
  } from "./index-52w0fvh8.js";
@@ -23,7 +23,7 @@ import {
23
23
  workflowPathsForPlan,
24
24
  workflowRunArtifactPath,
25
25
  workflowSyncDir
26
- } from "./index-05g3jayg.js";
26
+ } from "./index-wdze51wz.js";
27
27
 
28
28
  // pkgs/@akanjs/devkit/akanContext.ts
29
29
  import { readdir } from "fs/promises";
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  import {
3
3
  jsonText
4
- } from "./index-05g3jayg.js";
4
+ } from "./index-wdze51wz.js";
5
5
  import {
6
6
  akanMcpInstallTargets
7
- } from "./index-2mx692qq.js";
7
+ } from "./index-vhfjzda3.js";
8
8
  import {
9
9
  script
10
- } from "./index-6jjtnhkw.js";
10
+ } from "./index-3x7yeecy.js";
11
11
  import {
12
12
  ContextRunner2
13
- } from "./index-ae5pwhgs.js";
13
+ } from "./index-r5d6rq19.js";
14
14
 
15
15
  // pkgs/@akanjs/cli/context/context.script.ts
16
16
  import { Logger } from "akanjs/common";
@@ -3,24 +3,20 @@ import {
3
3
  getDefaultHostConfig,
4
4
  GlobalConfig,
5
5
  CloudApi,
6
- UpdatePackUpload
7
- } from "./index-pgj2rt78.js";
8
- import {
9
- runner
10
- } from "./index-6jjtnhkw.js";
6
+ CloudUpdates,
7
+ PipelineSecrets
8
+ } from "./index-wjqbc7sf.js";
11
9
  import {
12
10
  WorkspaceExecutor,
13
11
  AppExecutor
14
- } from "./index-55mynnqs.js";
12
+ } from "./index-bv210r6t.js";
15
13
  import {
16
- NativeApp
17
- } from "./index-1w2qaee2.js";
14
+ runner,
15
+ assertPromptable
16
+ } from "./index-3x7yeecy.js";
18
17
  import {
19
18
  SubspaceConfig
20
- } from "./index-ww9bhp67.js";
21
- import {
22
- resolveMobileTargets
23
- } from "./index-q958tqqg.js";
19
+ } from "./index-4pf8g7ff.js";
24
20
  import {
25
21
  openBrowser
26
22
  } from "./index-9dp031by.js";
@@ -657,11 +653,9 @@ class PlatformTestRun {
657
653
  }
658
654
 
659
655
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
660
- import { rm } from "fs/promises";
661
- import os3 from "os";
662
656
  import path7 from "path";
663
- import { confirm, input, password, select } from "@inquirer/prompts";
664
- import { Logger, PipelineNames, sleep } from "akanjs/common";
657
+ import { confirm, input, select } from "@inquirer/prompts";
658
+ import { Logger, sleep } from "akanjs/common";
665
659
  import chalk2 from "chalk";
666
660
  import * as QRcode from "qrcode";
667
661
 
@@ -766,6 +760,9 @@ class CloudRunner extends runner("cloud") {
766
760
  return { name: `${name} (${this.#getSshTarget(config)}${config.port ? `:${config.port}` : ""})`, value: name };
767
761
  }
768
762
  async#getRemoteEnvServerWithUsername() {
763
+ assertPromptable("The env archive goes over scp to a remote server picked here, as AKAN_WORKSPACE_ID is not set", {
764
+ remedy: "set AKAN_WORKSPACE_ID in the workspace .env to use Akan Cloud, or run it once in a terminal"
765
+ });
769
766
  const remoteServer = await this.#selectRemoteEnvServer();
770
767
  if (remoteServer.config.username)
771
768
  return remoteServer;
@@ -891,6 +888,9 @@ ${run.format(results)}
891
888
  const reason = result.infraError ?? "failing tests";
892
889
  if (!interactive)
893
890
  continue;
891
+ assertPromptable(`${result.platform} did not pass (${reason}) \u2014 ${run.logDir}`, {
892
+ remedy: "leave it out of --platforms to publish without it, or run it in a terminal to be asked"
893
+ });
894
894
  const proceed = await confirm({
895
895
  message: `${result.platform} did not pass (${reason}). Continue without it?`,
896
896
  default: false
@@ -909,6 +909,9 @@ ${run.format(results)}
909
909
  return results;
910
910
  }
911
911
  async#askWindowsTestTarget() {
912
+ assertPromptable("No Windows test target is configured", {
913
+ remedy: "run it once in a terminal, which saves the target to ~/.akan/config.json"
914
+ });
912
915
  Logger.info("No Windows test target is configured yet; it is saved to ~/.akan/config.json once entered.");
913
916
  const required = (value) => !!value.trim();
914
917
  const host = await this.#ask("Windows host (ip or name): ", required);
@@ -944,11 +947,15 @@ ${run.format(results)}
944
947
  for (const library of akanPkgs) {
945
948
  const packageJson = await workspace.readJson(`pkgs/${library}/package.json`);
946
949
  const newPackageJson = this.#normalizeAkanPackageJson(packageJson, library, nextVersion);
947
- await workspace.writeFile(`pkgs/${library}/package.json`, JSON.stringify(newPackageJson, null, 2));
950
+ await workspace.writeJson(`pkgs/${library}/package.json`, newPackageJson);
948
951
  const distPackageJson = await workspace.readJson(`dist/pkgs/${library}/package.json`);
949
952
  const newDistPackageJson = this.#normalizeAkanPackageJson(distPackageJson, library, nextVersion);
950
953
  await workspace.writeJson(`dist/pkgs/${library}/package.json`, newDistPackageJson);
951
954
  }
955
+ if (confirmPublish)
956
+ assertPromptable(`Publishing ${akanPkgs.join(", ")}@${nextVersion} asks for a confirmation`, {
957
+ remedy: "run it in a terminal"
958
+ });
952
959
  if (confirmPublish && !await confirm({ message: "Are you sure you want to deploy the libraries?" })) {
953
960
  Logger.error("Deployment cancelled");
954
961
  return;
@@ -1014,7 +1021,7 @@ ${run.format(results)}
1014
1021
  async downloadEnv(cloudApi, workspace, workspaceId) {
1015
1022
  await workspace.mkdir("local");
1016
1023
  const localPath = await cloudApi.downloadEnv(workspaceId).catch((error) => {
1017
- throw CloudRunner.#refusal(error, "downloading its env archive takes the project owner's own `akan login`");
1024
+ throw CloudApi.refusal(error, "downloading its env archive takes the project owner's own `akan login`");
1018
1025
  });
1019
1026
  const relativePath = path7.relative(workspace.workspaceRoot, localPath).split(path7.sep).join("/");
1020
1027
  await workspace.spawn("tar", ["-xf", relativePath], { cwd: workspace.workspaceRoot });
@@ -1023,7 +1030,7 @@ ${run.format(results)}
1023
1030
  async uploadEnv(cloudApi, workspaceId, filePath) {
1024
1031
  const file = new File([Bun.file(filePath)], path7.basename(filePath));
1025
1032
  await cloudApi.uploadEnv(workspaceId, file).catch((error) => {
1026
- throw CloudRunner.#refusal(error, "an env archive is uploaded by a project member signed in with `akan login`");
1033
+ throw CloudApi.refusal(error, "an env archive is uploaded by a project member signed in with `akan login`");
1027
1034
  });
1028
1035
  }
1029
1036
  async downloadEnvByScp(workspace) {
@@ -1096,7 +1103,7 @@ ${run.format(results)}
1096
1103
  }));
1097
1104
  return secretPaths.flat();
1098
1105
  }
1099
- async secretProject(workspace, subspace) {
1106
+ async projectOf(workspace, subspace, appName) {
1100
1107
  if (!subspace) {
1101
1108
  const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
1102
1109
  if (!workspaceId)
@@ -1109,172 +1116,30 @@ ${run.format(results)}
1109
1116
  const [declaration] = config.select([subspace]);
1110
1117
  if (!declaration?.workspaceId)
1111
1118
  throw new Error(`Subspace "${subspace}" declares no workspaceId in ${SubspaceConfig.source}.`);
1119
+ if (appName && !declaration.apps.includes(appName))
1120
+ throw new Error(`Subspace "${subspace}" declares no app ${appName} in ${SubspaceConfig.source}; it serves ${declaration.apps.join(", ")}.`);
1112
1121
  return declaration.workspaceId;
1113
1122
  }
1114
1123
  async readSecretValue(name, file) {
1115
- const raw = file ? await Bun.file(file).text() : process.stdin.isTTY ? await password({ message: `Value of ${name} (hidden; it can never be read back)`, mask: "*" }) : await Bun.stdin.text();
1116
- const value = raw.replace(/\r?\n$/, "");
1117
- if (!value)
1118
- throw new Error(`The value of ${name} is empty.`);
1119
- const bytes = new TextEncoder().encode(value).length;
1120
- if (bytes > CloudRunner.#secretBytes)
1121
- throw new Error(`The value of ${name} is ${bytes} bytes, over ${CloudRunner.#secretBytes}.`);
1122
- return value;
1123
- }
1124
- async uploadSecret(cloudApi, devProjectId, { name, branch, value }) {
1125
- CloudRunner.#assertSecretName(name);
1126
- CloudRunner.#assertSecretBranch(branch);
1127
- const saved = await cloudApi.uploadSecret(devProjectId, { scope: branch ?? "*", name, value }).catch((error) => {
1128
- throw CloudRunner.#refusal(error, "a secret is written by a project member signed in with `akan login`", {
1129
- unavailable: CloudRunner.#secretsUnavailable
1130
- });
1131
- });
1132
- Logger.rawLog(`Saved ${saved.name} for ${saved.scope === "*" ? "every branch" : `branch ${saved.scope}`}. Builds that start from now on use it.`);
1124
+ return await PipelineSecrets.readValue(name, file);
1125
+ }
1126
+ async uploadSecret(cloudApi, devProjectId, secret) {
1127
+ await new PipelineSecrets(cloudApi, devProjectId).upload(secret);
1133
1128
  }
1134
1129
  async listSecrets(cloudApi, devProjectId, branch) {
1135
- CloudRunner.#assertSecretBranch(branch);
1136
- const listed = await cloudApi.listSecrets(devProjectId).catch((error) => {
1137
- throw CloudRunner.#refusal(error, "the secrets are listed for a project member", {
1138
- unavailable: CloudRunner.#secretsUnavailable
1139
- });
1140
- });
1141
- const secrets = listed.filter((secret) => !branch || secret.scope === "*" || secret.scope === branch);
1142
- Logger.rawLog(CloudRunner.formatSecrets(secrets));
1143
- }
1144
- async removeSecret(cloudApi, devProjectId, { name, branch }) {
1145
- CloudRunner.#assertSecretName(name);
1146
- CloudRunner.#assertSecretBranch(branch);
1147
- const removed = await cloudApi.removeSecret(devProjectId, { scope: branch ?? "*", name }).catch((error) => {
1148
- throw CloudRunner.#refusal(error, "a secret is removed by a project member signed in with `akan login`", {
1149
- unavailable: CloudRunner.#secretsUnavailable
1150
- });
1151
- });
1152
- Logger.rawLog(removed ? `Removed ${name} for ${branch ? `branch ${branch}` : "every branch"}.` : `No ${name} for ${branch ? `branch ${branch}` : "every branch"} to remove.`);
1153
- }
1154
- static #packRecords = ["manifest.template.json", "bundle.json", "pack.json", "compat.json"];
1155
- static async#tarPack(pack) {
1156
- const templateFile = Bun.file(path7.join(pack.out, "manifest.template.json"));
1157
- if (!await templateFile.exists())
1158
- throw new Error(`${pack.out} holds no manifest.template.json: give the folder \`akan pack-update\` wrote.`);
1159
- const template = await templateFile.json();
1160
- const hashes = new Set((template.files ?? []).map((file) => file.sha256));
1161
- if (![...hashes].every((hash) => typeof hash === "string" && /^[0-9a-f]{64}$/.test(hash)))
1162
- throw new Error(`${pack.out}/manifest.template.json lists a file whose sha256 is not 64 hex digits.`);
1163
- const present = await Promise.all(CloudRunner.#packRecords.map((name) => Bun.file(path7.join(pack.out, name)).exists()));
1164
- const entries = [
1165
- ...CloudRunner.#packRecords.filter((_, idx) => present[idx]),
1166
- ...[...hashes].map((hash) => `files/${hash}`)
1167
- ];
1168
- const base = path7.join(os3.tmpdir(), `akan-pack-${pack.app}-${pack.target}-${pack.platform}-${process.pid}`);
1169
- await Bun.write(`${base}.list`, entries.map((entry) => `./${entry}
1170
- `).join(""));
1171
- try {
1172
- const tar = Bun.spawn(["tar", "-czf", `${base}.tgz`, "-C", pack.out, "-T", `${base}.list`], {
1173
- stdout: "ignore",
1174
- stderr: "pipe"
1175
- });
1176
- if (await tar.exited !== 0)
1177
- throw new Error(`tar of ${pack.out} failed: ${(await new Response(tar.stderr).text()).trim()}`);
1178
- } finally {
1179
- await rm(`${base}.list`, { force: true });
1180
- }
1181
- return `${base}.tgz`;
1130
+ await new PipelineSecrets(cloudApi, devProjectId).list(branch);
1182
1131
  }
1183
- async pushUpdate(cloudApi, devProjectId, pack, { channel, notes }) {
1184
- const archive = await CloudRunner.#tarPack(pack);
1185
- const target = channel ?? pack.channel;
1186
- try {
1187
- const release = await new UpdatePackUpload(cloudApi, devProjectId).send(archive, { appName: pack.app, target: pack.target, platform: pack.platform, channel: target, notes }).catch((error) => {
1188
- throw CloudRunner.#refusal(error, "a pack is uploaded by a project member signed in with `akan login`");
1189
- });
1190
- const label = `${pack.app} ${pack.target} ${pack.platform} on channel ${target}: release ${release.id}`;
1191
- if (release.status === "rejected") {
1192
- process.exitCode = 2;
1193
- Logger.error(`The project rejected ${label}:
1194
- ${(release.problems ?? []).map((problem) => ` - ${problem}`).join(`
1195
- `)}`);
1196
- } else if (release.status === "published")
1197
- Logger.rawLog(`Published ${label} (${pack.files} files, native API ${pack.nativeApi}).`);
1198
- else
1199
- Logger.rawLog(`Staged ${label} (${pack.files} files, native API ${pack.nativeApi}). Publish it from the project's release screen.`);
1200
- return release;
1201
- } finally {
1202
- await rm(archive, { force: true });
1203
- }
1132
+ async removeSecret(cloudApi, devProjectId, secret) {
1133
+ await new PipelineSecrets(cloudApi, devProjectId).remove(secret);
1204
1134
  }
1205
- async registerBinary(cloudApi, devProjectId, app, pack, { distribution, env }) {
1206
- const [mobileTarget] = await resolveMobileTargets(app, pack.target);
1207
- if (!mobileTarget)
1208
- throw new Error(`Native target '${pack.target}' was not found.`);
1209
- const bundlePath = path7.join(new NativeApp(app, mobileTarget).outDir(pack.platform), "bundle.json");
1210
- const bundleFile = Bun.file(bundlePath);
1211
- if (!await bundleFile.exists())
1212
- throw new Error(`No store build at ${bundlePath}: run \`akan release-${pack.platform} ${app.name} --target ${pack.target} --env ${env}\` first.`);
1213
- const bundle = await bundleFile.json();
1214
- if (!bundle.updates)
1215
- throw new Error(`The store build at ${bundlePath} takes no updates: give the target native.updates.`);
1216
- if (bundle.nativeApi?.hash !== pack.nativeApi)
1217
- throw new Error(`The store build at ${bundlePath} provides native API ${bundle.nativeApi?.hash}, and this commit's pack needs ${pack.nativeApi}: build the store binary from this commit.`);
1218
- const archive = await CloudRunner.#tarPack(pack);
1219
- const channel = bundle.updates.channel ?? pack.channel;
1220
- const upload = new UpdatePackUpload(cloudApi, devProjectId);
1221
- try {
1222
- const binary = await upload.stage(archive, { appName: pack.app, target: pack.target, platform: pack.platform, channel, notes: null }).then((packUploadId) => upload.settle(() => cloudApi.registerAppBinary(devProjectId, {
1223
- appName: pack.app,
1224
- target: pack.target,
1225
- distribution,
1226
- bundle: bundleFile,
1227
- packUploadId,
1228
- channel
1229
- }))).catch((error) => {
1230
- throw CloudRunner.#refusal(error, "a binary is registered by a project member signed in with `akan login`");
1231
- });
1232
- Logger.rawLog(`Registered ${pack.app} ${pack.target} ${pack.platform} (${distribution}): binary ${binary.id}, native API ${pack.nativeApi}.`);
1233
- return binary;
1234
- } finally {
1235
- await rm(archive, { force: true });
1236
- }
1135
+ async readPack(app, dir, flags) {
1136
+ return await CloudUpdates.readPack(app, dir, flags);
1237
1137
  }
1238
- static formatSecrets(secrets) {
1239
- if (!secrets.length)
1240
- return "No pipeline secrets.";
1241
- const rows = [...secrets].sort((a, b) => a.name.localeCompare(b.name) || a.scope.localeCompare(b.scope)).map((secret) => [
1242
- secret.name,
1243
- secret.scope === "*" ? "every branch" : secret.scope,
1244
- secret.updatedAt,
1245
- secret.updatedBy
1246
- ]);
1247
- const header = ["NAME", "SCOPE", "UPDATED", "BY"];
1248
- const widths = header.map((title, column) => Math.max(title.length, ...rows.map((row) => row[column]?.length ?? 0)));
1249
- return [header, ...rows].map((row) => row.map((cell, column) => cell.padEnd(widths[column] ?? 0)).join(" ").trimEnd()).join(`
1250
- `);
1138
+ async pushUpdate(cloudApi, devProjectId, pack, options) {
1139
+ return await new CloudUpdates(cloudApi, devProjectId).push(pack, options);
1251
1140
  }
1252
- static #secretBytes = 64 * 1024;
1253
- static #secretBranches = ["debug", "develop", "main"];
1254
- static #secretsUnavailable = "The server is not configured for pipeline secrets yet.";
1255
- static #assertSecretName(name) {
1256
- const problem = PipelineNames.secretNameError(name);
1257
- if (problem)
1258
- throw new Error(problem);
1259
- }
1260
- static #assertSecretBranch(branch) {
1261
- if (branch !== null && !CloudRunner.#secretBranches.includes(branch))
1262
- throw new Error(`--branch ${branch} is not a deployed branch: ${CloudRunner.#secretBranches.join(", ")}.`);
1263
- }
1264
- static #refusal(error, who, { unavailable } = {}) {
1265
- const message = error instanceof Error ? error.message : String(error);
1266
- const status = CloudApi.statusOf(error);
1267
- if (status === 401)
1268
- return new Error("The server did not accept your sign-in: run `akan login`, then try again.");
1269
- if (status === 403)
1270
- return new Error(`The project refused: ${who}.`);
1271
- if (status === 400) {
1272
- const key = /"error"\s*:\s*"([^"]+)"/.exec(message)?.[1];
1273
- return new Error(`The project refused the request${key ? `: ${key}` : ""}.`);
1274
- }
1275
- if (status === 503 && unavailable)
1276
- return new Error(unavailable);
1277
- return error;
1141
+ async registerBinary(cloudApi, devProjectId, app, pack, options) {
1142
+ return await new CloudUpdates(cloudApi, devProjectId).registerBinary(app, pack, options);
1278
1143
  }
1279
1144
  async#syncSecretGitignore(workspace, appNames) {
1280
1145
  const patterns = (await Promise.all(appNames.map(async (appName) => {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-55mynnqs.js";
5
+ } from "./index-bv210r6t.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `