@akanjs/cli 3.0.0-beta.7 → 3.0.0-beta.9

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 (41) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-mjh5ppsq.js → abstractCompactor-gmkc0z8j.js} +2 -1
  3. package/{agent.command-d2gfxfck.js → agent.command-0q17pnrs.js} +2 -2
  4. package/{application.command-pj2m7584.js → application.command-18y0s485.js} +3 -3
  5. package/{cloud.command-jshwdq22.js → cloud.command-av97ndh6.js} +10 -9
  6. package/cloud.script-cm11xjdz.js +20 -0
  7. package/{context.command-ez8a0zyz.js → context.command-5v37ef3n.js} +10 -9
  8. package/{devTui-40ggmd99.js → devTui-m1atgkc9.js} +1 -1
  9. package/{devTuiView-c08ccbat.js → devTuiView-0hc2emhe.js} +1 -1
  10. package/{guideline.command-xmqwx8zm.js → guideline.command-4pz9g1rt.js} +3 -2
  11. package/guidelines/agentRule/agentRule.instruction.md +37 -0
  12. package/{index-fz5q3gd7.js → index-04bk599g.js} +1 -1
  13. package/{index-zry5nz81.js → index-2xp0kfkt.js} +22 -13
  14. package/{index-8pm30m73.js → index-5ystnsd5.js} +5 -5
  15. package/{index-ws5e0j51.js → index-9077wzd2.js} +1 -1
  16. package/{index-rwg2aa4f.js → index-a17x49vg.js} +2 -2
  17. package/{index-4edzf1gr.js → index-d43r08tf.js} +2 -2
  18. package/{index-7737gxcp.js → index-ffvk10zz.js} +1 -1
  19. package/{index-ne2qy0nk.js → index-k2j1hc4r.js} +1 -1
  20. package/index-m0xccmmm.js +228 -0
  21. package/{index-2hq52jq3.js → index-rtxxan88.js} +24 -18
  22. package/{index-v0qh106m.js → index-sj5vxr8f.js} +4 -4
  23. package/{index-kn1h7p1x.js → index-te54x9zm.js} +3 -225
  24. package/{index-259dsnz3.js → index-vxtad5bd.js} +1 -1
  25. package/{index-pnqbkf5p.js → index-vyvre9en.js} +1 -1
  26. package/{index-600zhnve.js → index-y6n8nmny.js} +6 -6
  27. package/index.js +18 -18
  28. package/{library.command-nbsky672.js → library.command-qzzbj6d8.js} +2 -2
  29. package/{localRegistry.command-yeq57wjr.js → localRegistry.command-vyrgg4xw.js} +7 -6
  30. package/{module.command-29vqzrh8.js → module.command-rq5hq3ax.js} +5 -4
  31. package/{package.command-axv0abmn.js → package.command-d9hd6v9n.js} +2 -2
  32. package/package.json +2 -2
  33. package/{page.command-vs9s3zrh.js → page.command-126d56te.js} +2 -2
  34. package/{primitive.command-cbxmqbtc.js → primitive.command-taxd1538.js} +6 -5
  35. package/{quality.command-gmbs7nws.js → quality.command-6gsna0a3.js} +1 -1
  36. package/{repair.command-bqsjptsj.js → repair.command-tq2dgy72.js} +2 -2
  37. package/{scalar.command-6k1vhe9s.js → scalar.command-3bcmrrkv.js} +4 -3
  38. package/{subspace.command-fwjfcts7.js → subspace.command-eddzqpx3.js} +90 -10
  39. package/{workflow.command-nwpcdc8p.js → workflow.command-gtdnzvbz.js} +8 -7
  40. package/{workspace.command-8s050m0h.js → workspace.command-06wvstgr.js} +18 -17
  41. package/{index-mak3cd28.js → index-0g7r8xz3.js} +24 -24
@@ -2,18 +2,19 @@
2
2
  import {
3
3
  Sys,
4
4
  command
5
- } from "./index-mak3cd28.js";
5
+ } from "./index-0g7r8xz3.js";
6
6
  import"./index-q0y2jq9j.js";
7
7
  import"./index-2tv3fdx4.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import {
10
10
  renderPrimitiveReport
11
11
  } from "./index-gyd220p2.js";
12
- import"./index-kn1h7p1x.js";
12
+ import"./index-m0xccmmm.js";
13
+ import"./index-te54x9zm.js";
13
14
  import"./index-h7yw2z9n.js";
14
15
  import {
15
16
  ScalarScript
16
- } from "./index-rwg2aa4f.js";
17
+ } from "./index-a17x49vg.js";
17
18
 
18
19
  // pkgs/@akanjs/cli/scalar/scalar.command.ts
19
20
  import { Logger, lowerlize } from "akanjs/common";
@@ -1,13 +1,17 @@
1
1
  // @bun
2
+ import {
3
+ FileSys
4
+ } from "./index-q0y2jq9j.js";
5
+ import {
6
+ GlobalConfig
7
+ } from "./index-m0xccmmm.js";
2
8
  import {
3
9
  Workspace,
10
+ CommandContainer,
4
11
  runner,
5
12
  script,
6
13
  command
7
- } from "./index-mak3cd28.js";
8
- import {
9
- FileSys
10
- } from "./index-q0y2jq9j.js";
14
+ } from "./index-0g7r8xz3.js";
11
15
  import {
12
16
  Executor,
13
17
  WorkspaceExecutor,
@@ -45,6 +49,9 @@ class Subspace {
45
49
  get apps() {
46
50
  return this.#declaration.apps;
47
51
  }
52
+ get workspaceId() {
53
+ return this.#declaration.workspaceId;
54
+ }
48
55
  get #remote() {
49
56
  return `subspace-${this.#declaration.name}`;
50
57
  }
@@ -522,6 +529,23 @@ function formatSubspacePullResult(result) {
522
529
  return sections.join(`
523
530
  `);
524
531
  }
532
+ function formatSubspaceEnvUpload(result) {
533
+ const sections = [
534
+ `Akan Subspace Env Upload \u2014 ${result.name}`,
535
+ `cloud workspace: ${result.workspaceId} \xB7 host: ${result.host}`,
536
+ "",
537
+ ...result.outcome === "cancelled" ? [" cancelled \u2014 the subspace's env archive is untouched."] : [
538
+ `Uploaded (${result.files.length}), replacing that workspace's whole archive:`,
539
+ "",
540
+ ...result.files.map((file) => ` ${file}`),
541
+ "",
542
+ ` apps: ${result.apps.join(", ")}`,
543
+ ` libs: ${result.libs.join(", ") || "(none)"}`
544
+ ]
545
+ ];
546
+ return sections.join(`
547
+ `);
548
+ }
525
549
  function formatSubspaceDiff(result) {
526
550
  const total = result.app.files.length + result.libs.files.length;
527
551
  const sections = [
@@ -575,6 +599,7 @@ class SubspaceConfig {
575
599
  #assertValid() {
576
600
  const seenNames = new Set;
577
601
  const appOwners = new Map;
602
+ const idOwners = new Map;
578
603
  for (const subspace of this.subspaces) {
579
604
  if (!subspace.name || !subspace.repo)
580
605
  throw new Error(`${SubspaceConfig.fileName}: every subspace needs a name and a repo`);
@@ -589,6 +614,12 @@ class SubspaceConfig {
589
614
  throw new Error(`${SubspaceConfig.fileName}: app "${app}" is claimed by both "${owner}" and "${subspace.name}"`);
590
615
  appOwners.set(app, subspace.name);
591
616
  }
617
+ if (!subspace.workspaceId)
618
+ continue;
619
+ const idOwner = idOwners.get(subspace.workspaceId);
620
+ if (idOwner)
621
+ throw new Error(`${SubspaceConfig.fileName}: subspaces "${idOwner}" and "${subspace.name}" declare the same workspaceId`);
622
+ idOwners.set(subspace.workspaceId, subspace.name);
592
623
  }
593
624
  }
594
625
  select(names) {
@@ -625,10 +656,12 @@ class SubspaceRunner extends runner("subspace") {
625
656
  const branch = (await workspace.spawn("git", ["rev-parse", "--abbrev-ref", "HEAD"])).trim();
626
657
  return { config, subspaces, branch };
627
658
  }
659
+ static #isInteractive() {
660
+ return process.stdin.isTTY === true && process.stdout.isTTY === true;
661
+ }
628
662
  async selectNames(workspace, action) {
629
663
  const config = await this.config(workspace);
630
- const interactive = process.stdin.isTTY === true && process.stdout.isTTY === true;
631
- return await SubspaceRunner.chooseNames(config, action, { interactive });
664
+ return await SubspaceRunner.chooseNames(config, action, { interactive: SubspaceRunner.#isInteractive() });
632
665
  }
633
666
  static async chooseNames(config, action, { interactive, prompts }) {
634
667
  const multiple = SubspaceRunner.multiTargetActions.includes(action);
@@ -676,6 +709,43 @@ class SubspaceRunner extends runner("subspace") {
676
709
  throw new Error(`Unknown subspace "${name}"`);
677
710
  return await subspace.pull(branch, { adoptLibs });
678
711
  }
712
+ async uploadEnv(workspace, name, { host, force }) {
713
+ const config = await this.config(workspace);
714
+ const [declaration] = config.select([name]);
715
+ if (!declaration)
716
+ throw new Error(`Unknown subspace "${name}"`);
717
+ const subspace = new Subspace(workspace, config, declaration);
718
+ const { workspaceId } = subspace;
719
+ if (!workspaceId)
720
+ throw new Error(`Subspace "${subspace.name}" declares no workspaceId. Add its cloud workspace id to ${SubspaceConfig.fileName}.`);
721
+ if (workspaceId === workspace.getWorkspaceId({ allowEmpty: true }))
722
+ throw new Error(`Subspace "${subspace.name}" declares this workspace's own id. Uploading a slice there would replace the workspace's env archive with a subset of it.`);
723
+ const apps = subspace.apps;
724
+ const asked = await SubspaceRunner.confirmEnvUpload({ name: subspace.name, workspaceId, apps, force }, { interactive: SubspaceRunner.#isInteractive() });
725
+ if (!asked)
726
+ return { name: subspace.name, workspaceId, host, apps, libs: [], outcome: "cancelled", files: [] };
727
+ const { libs } = await subspace.slice();
728
+ const { CloudScript } = await import("./cloud.script-cm11xjdz.js");
729
+ const { files } = await CommandContainer.get(CloudScript).uploadEnv(workspace, {
730
+ host,
731
+ workspaceId,
732
+ scope: { apps, libs },
733
+ archivePath: `local/env.${subspace.name}.tar`
734
+ });
735
+ return { name: subspace.name, workspaceId, host, apps, libs, outcome: "uploaded", files };
736
+ }
737
+ static async confirmEnvUpload({ name, workspaceId, apps, force }, { interactive, prompts }) {
738
+ if (force)
739
+ return true;
740
+ const target = `subspace "${name}" (cloud workspace ${workspaceId})`;
741
+ if (!interactive)
742
+ throw new Error(`Refusing to replace the env archive of ${target} with no terminal to ask in. Pass --force.`);
743
+ const { confirm } = prompts ?? await loadPrompts();
744
+ return await confirm({
745
+ message: `Replace the env archive of ${target} with this workspace's env for ${apps.join(", ")} and the libraries they pull in?`,
746
+ default: false
747
+ });
748
+ }
679
749
  }
680
750
 
681
751
  // pkgs/@akanjs/cli/subspace/subspace.script.ts
@@ -706,6 +776,10 @@ class SubspaceScript extends script("subspace", [SubspaceRunner]) {
706
776
  spinner.succeed(`${total} file(s) differ (${result.libs.files.length} in shared libraries)`);
707
777
  Logger.rawLog(format === "json" ? JSON.stringify(result, null, 2) : formatSubspaceDiff(result));
708
778
  }
779
+ async uploadEnv(workspace, name, { host, force, format }) {
780
+ const result = await this.subspaceRunner.uploadEnv(workspace, name, { host, force });
781
+ Logger.rawLog(format === "json" ? JSON.stringify(result, null, 2) : formatSubspaceEnvUpload(result));
782
+ }
709
783
  async pull(workspace, name, { adoptLibs, format }) {
710
784
  const spinner = workspace.spinning(`Pulling customer commits from ${name}...`);
711
785
  const result = await this.subspaceRunner.pull(workspace, name, { adoptLibs });
@@ -719,7 +793,7 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
719
793
  subspace: target({ desc: "Mirror apps and libraries between this workspace and the customer repos it serves" }).arg("action", String, {
720
794
  desc: "subspace action; status-all and push-all take every declared subspace",
721
795
  default: "status",
722
- enum: ["status", "status-all", "diff", "push", "push-all", "pull"]
796
+ enum: ["status", "status-all", "diff", "push", "push-all", "pull", "upload-env"]
723
797
  }).arg("subspace", String, {
724
798
  desc: "subspace name; asks which one(s) when omitted, and is refused by status-all / push-all",
725
799
  nullable: true
@@ -727,12 +801,16 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
727
801
  flag: "y",
728
802
  desc: "run bun install + akan sync in the subspace before committing",
729
803
  default: true
730
- }).option("adoptLibs", Boolean, { desc: "pull: also apply the subspace's library edits", default: false }).option("path", String, { desc: "diff: limit to one path", nullable: true }).exec(async function(action, subspace, workspace, format, verify, adoptLibs, filePath) {
804
+ }).option("adoptLibs", Boolean, { desc: "pull: also apply the subspace's library edits", default: false }).option("path", String, { desc: "diff: limit to one path", nullable: true }).option("host", String, { desc: "upload-env: host of the cloud to target", default: GlobalConfig.akanCloudHost }).option("force", Boolean, {
805
+ flag: "F",
806
+ desc: "upload-env: replace the subspace's env archive without asking",
807
+ default: false
808
+ }).exec(async function(action, subspace, workspace, format, verify, adoptLibs, filePath, host, force) {
731
809
  const output = format;
732
810
  const all = action === "status-all" || action === "push-all";
733
811
  const base = all ? action.slice(0, -"-all".length) : action;
734
- if (base !== "status" && base !== "diff" && base !== "push" && base !== "pull")
735
- throw new Error(`Unknown subspace action: ${action}. Use status, status-all, diff, push, push-all or pull.`);
812
+ if (base !== "status" && base !== "diff" && base !== "push" && base !== "pull" && base !== "upload-env")
813
+ throw new Error(`Unknown subspace action: ${action}. Use status, status-all, diff, push, push-all, pull or upload-env.`);
736
814
  if (all && subspace)
737
815
  throw new Error(`\`akan subspace ${action}\` takes no name. Run \`akan subspace ${base} ${subspace}\` instead.`);
738
816
  const names = subspace ? [subspace] : all ? [] : await this.subspaceScript.select(workspace, base);
@@ -746,6 +824,8 @@ class SubspaceCommand extends command("subspace", [SubspaceScript], ({ public: t
746
824
  throw new Error(`\`akan subspace ${base}\` needs a name \u2014 it is reviewed one repo at a time.`);
747
825
  if (base === "diff")
748
826
  await this.subspaceScript.diff(workspace, name, filePath, output);
827
+ else if (base === "upload-env")
828
+ await this.subspaceScript.uploadEnv(workspace, name, { host, force, format: output });
749
829
  else
750
830
  await this.subspaceScript.pull(workspace, name, { adoptLibs, format: output });
751
831
  }
@@ -3,30 +3,31 @@ import {
3
3
  Workspace,
4
4
  script,
5
5
  command
6
- } from "./index-mak3cd28.js";
6
+ } from "./index-0g7r8xz3.js";
7
7
  import"./index-q0y2jq9j.js";
8
8
  import"./index-2tv3fdx4.js";
9
9
  import"./index-6wwzs1bc.js";
10
10
  import {
11
11
  createWorkflowStepRegistry
12
12
  } from "./index-gyd220p2.js";
13
- import"./index-kn1h7p1x.js";
13
+ import"./index-m0xccmmm.js";
14
+ import"./index-te54x9zm.js";
14
15
  import {
15
16
  ModuleScript
16
- } from "./index-8pm30m73.js";
17
- import"./index-pnqbkf5p.js";
17
+ } from "./index-5ystnsd5.js";
18
+ import"./index-vyvre9en.js";
18
19
  import"./index-h7yw2z9n.js";
19
20
  import {
20
21
  PrimitiveScript
21
- } from "./index-4edzf1gr.js";
22
+ } from "./index-d43r08tf.js";
22
23
  import {
23
24
  ScalarScript
24
- } from "./index-rwg2aa4f.js";
25
+ } from "./index-a17x49vg.js";
25
26
  import"./index-by5gpp8x.js";
26
27
  import"./index-ktb5njgy.js";
27
28
  import {
28
29
  WorkflowRunner
29
- } from "./index-7737gxcp.js";
30
+ } from "./index-ffvk10zz.js";
30
31
 
31
32
  // pkgs/@akanjs/cli/workflow/workflow.script.ts
32
33
  import { Logger } from "akanjs/common";
@@ -4,14 +4,14 @@ import {
4
4
  } from "./index-q0y2jq9j.js";
5
5
  import {
6
6
  GlobalConfig
7
- } from "./index-kn1h7p1x.js";
7
+ } from "./index-m0xccmmm.js";
8
8
  import {
9
9
  Exec,
10
10
  Workspace,
11
11
  runner,
12
12
  script,
13
13
  command
14
- } from "./index-mak3cd28.js";
14
+ } from "./index-0g7r8xz3.js";
15
15
  import {
16
16
  extractAgentBlock,
17
17
  collectScopeRecipeSources,
@@ -37,35 +37,36 @@ import"./index-ktb5njgy.js";
37
37
  import"./index-h7yw2z9n.js";
38
38
  import {
39
39
  AgentScript
40
- } from "./index-ne2qy0nk.js";
40
+ } from "./index-k2j1hc4r.js";
41
41
  import {
42
42
  ApplicationScript
43
- } from "./index-v0qh106m.js";
43
+ } from "./index-sj5vxr8f.js";
44
44
  import {
45
45
  LibraryScript
46
- } from "./index-259dsnz3.js";
46
+ } from "./index-vxtad5bd.js";
47
47
  import"./index-hwkygn9s.js";
48
+ import"./index-te54x9zm.js";
48
49
  import"./index-kcxmv48c.js";
49
50
  import {
50
51
  PackageScript
51
- } from "./index-ws5e0j51.js";
52
+ } from "./index-9077wzd2.js";
52
53
  import {
53
54
  getNpmRegistryUrl,
54
55
  getLatestPackageVersion
55
- } from "./index-2hq52jq3.js";
56
+ } from "./index-rtxxan88.js";
56
57
  import {
57
- CloudScript
58
- } from "./index-zry5nz81.js";
58
+ CloudScript2
59
+ } from "./index-2xp0kfkt.js";
59
60
  import {
60
61
  ContextScript
61
- } from "./index-600zhnve.js";
62
+ } from "./index-y6n8nmny.js";
62
63
  import"./index-wt7qrtd4.js";
63
- import"./index-fz5q3gd7.js";
64
- import"./index-7737gxcp.js";
65
- import"./index-8pm30m73.js";
66
- import"./index-pnqbkf5p.js";
67
- import"./index-4edzf1gr.js";
68
- import"./index-rwg2aa4f.js";
64
+ import"./index-04bk599g.js";
65
+ import"./index-ffvk10zz.js";
66
+ import"./index-5ystnsd5.js";
67
+ import"./index-vyvre9en.js";
68
+ import"./index-d43r08tf.js";
69
+ import"./index-a17x49vg.js";
69
70
  import"./index-j9yhg404.js";
70
71
 
71
72
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
@@ -327,7 +328,7 @@ class WorkspaceScript extends script("workspace", [
327
328
  ApplicationScript,
328
329
  LibraryScript,
329
330
  PackageScript,
330
- CloudScript,
331
+ CloudScript2,
331
332
  ContextScript,
332
333
  AgentScript
333
334
  ]) {
@@ -59,30 +59,6 @@ var Pkg = createInternalArgToken("Pkg");
59
59
  var Module = createInternalArgToken("Module");
60
60
  var Workspace = createInternalArgToken("Workspace");
61
61
 
62
- // pkgs/@akanjs/devkit/commandDecorators/command.ts
63
- import path2 from "path";
64
- import { Logger } from "akanjs/common";
65
- import chalk2 from "chalk";
66
- import { program } from "commander";
67
-
68
- // pkgs/@akanjs/devkit/appSelectionMemory.ts
69
- import path from "path";
70
- class AppSelectionMemory {
71
- static pathIn(workspaceRoot) {
72
- return path.join(workspaceRoot, "local", ".akan", "lastStart.json");
73
- }
74
- static async read(workspaceRoot) {
75
- const stored = await Bun.file(AppSelectionMemory.pathIn(workspaceRoot)).json().catch(() => null);
76
- const apps = stored?.apps;
77
- return Array.isArray(apps) ? apps.filter((name) => typeof name === "string") : [];
78
- }
79
- static async write(workspaceRoot, apps) {
80
- await FileSys.writeJson(AppSelectionMemory.pathIn(workspaceRoot), { apps }).catch(() => {
81
- return;
82
- });
83
- }
84
- }
85
-
86
62
  // pkgs/@akanjs/devkit/commandDecorators/dependencyBuilder.ts
87
63
  var capitalize = (value) => value.slice(0, 1).toUpperCase() + value.slice(1);
88
64
  var createDependencyKey = (refName, kind) => `${refName}${capitalize(kind)}`;
@@ -160,6 +136,30 @@ var script = (refName, deps = []) => {
160
136
  return ScriptBase;
161
137
  };
162
138
 
139
+ // pkgs/@akanjs/devkit/commandDecorators/command.ts
140
+ import path2 from "path";
141
+ import { Logger } from "akanjs/common";
142
+ import chalk2 from "chalk";
143
+ import { program } from "commander";
144
+
145
+ // pkgs/@akanjs/devkit/appSelectionMemory.ts
146
+ import path from "path";
147
+ class AppSelectionMemory {
148
+ static pathIn(workspaceRoot) {
149
+ return path.join(workspaceRoot, "local", ".akan", "lastStart.json");
150
+ }
151
+ static async read(workspaceRoot) {
152
+ const stored = await Bun.file(AppSelectionMemory.pathIn(workspaceRoot)).json().catch(() => null);
153
+ const apps = stored?.apps;
154
+ return Array.isArray(apps) ? apps.filter((name) => typeof name === "string") : [];
155
+ }
156
+ static async write(workspaceRoot, apps) {
157
+ await FileSys.writeJson(AppSelectionMemory.pathIn(workspaceRoot), { apps }).catch(() => {
158
+ return;
159
+ });
160
+ }
161
+ }
162
+
163
163
  // pkgs/@akanjs/devkit/commandDecorators/helpFormatter.ts
164
164
  import chalk from "chalk";
165
165
  var camelToKebabCase2 = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();