@aui.io/apollo 0.1.84 → 0.1.87
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/README.md +4 -4
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js +239 -33
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/hierarchy.js +2 -2
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/hierarchy.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/mockdb.js +9 -8
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/mockdb.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js +31 -12
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/package.json +3 -3
- package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.d.ts +17 -0
- package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.js +4 -0
- package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.d.ts +36 -0
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.js +6 -0
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/api/management.d.ts +108 -4
- package/node_modules/@aui.io/apollo-core/dist/src/api/management.js +198 -18
- package/node_modules/@aui.io/apollo-core/dist/src/api/management.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.d.ts +1 -5
- package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.js +4 -10
- package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.d.ts +12 -2
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.js +67 -15
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.d.ts +13 -0
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.js +20 -0
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/lineage.d.ts +29 -0
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/lineage.js +65 -0
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/lineage.js.map +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.d.ts +25 -4
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.js +78 -8
- package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/config/index.d.ts +2 -0
- package/node_modules/@aui.io/apollo-core/dist/src/config/index.js +7 -0
- package/node_modules/@aui.io/apollo-core/dist/src/config/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.d.ts +3 -0
- package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.js +5 -0
- package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.d.ts +75 -0
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js +109 -0
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/index.d.ts +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.d.ts +2 -0
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.js +5 -1
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.d.ts +76 -2
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js +225 -70
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/doctor.js +4 -3
- package/node_modules/@aui.io/apollo-core/dist/src/services/doctor.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.d.ts +14 -21
- package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.js +17 -27
- package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.d.ts +15 -9
- package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.js +41 -18
- package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.d.ts +4 -3
- package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.js +84 -117
- package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/versions.d.ts +88 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/versions.js +202 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/versions.js.map +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/skills/agents-page.js +2 -2
- package/node_modules/@aui.io/apollo-core/dist/src/skills/agents-page.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/package.json +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/actions/registry.js +13 -13
- package/node_modules/@aui.io/apollo-tui/dist/src/actions/registry.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/activity/operationStore.js +2 -2
- package/node_modules/@aui.io/apollo-tui/dist/src/activity/operationStore.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/author/data.js +3 -2
- package/node_modules/@aui.io/apollo-tui/dist/src/author/data.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.d.ts +11 -19
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.js +90 -81
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.d.ts +2 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js +6 -6
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js +21 -13
- package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/package.json +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -65,10 +65,10 @@ apollo validate
|
|
|
65
65
|
# 5. Talk to it against the live runtime WITHOUT deploying, and read the trace
|
|
66
66
|
apollo chat "I want to return an order" --local . --trace
|
|
67
67
|
|
|
68
|
-
# 6. Push the change
|
|
68
|
+
# 6. Push the change, then make that SAVE the one customers get, when it is ready
|
|
69
69
|
apollo push -m "Describe the change"
|
|
70
|
-
apollo
|
|
71
|
-
apollo
|
|
70
|
+
apollo branch list
|
|
71
|
+
apollo branch live <tag> # `v3.7` ships exactly that save; `v3` ships its newest
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
`apollo status` always tells you where you stand — which profile, organization, project,
|
|
@@ -87,7 +87,7 @@ to that agent.
|
|
|
87
87
|
| **Project** | A container for agents | `project list / use / create` |
|
|
88
88
|
| **Agent** | The program you edit and test | `agent list / create / import / use / unlink` |
|
|
89
89
|
| **Checkout** | A local directory holding one agent: `.apollorc` + `bundle/src/` | `agent create / import` |
|
|
90
|
-
| **Version** | A tagged snapshot of the program: draft → published → archived (publishing an older version is the rollback) | `
|
|
90
|
+
| **Version** | A tagged snapshot of the program: draft → published → archived (publishing an older version is the rollback) | `branch list / get / use / create / publish / archive`, `pull` / `push` |
|
|
91
91
|
| **Runtime** | The engine build the checkout is pinned to | `runtime list / show / use` |
|
|
92
92
|
|
|
93
93
|
## Commands
|
|
@@ -3,18 +3,24 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { renderBundleAudit, renderValidation } from "@aui.io/apollo-core/bundle/validate.js";
|
|
5
5
|
import { defaultCheckoutDir, listCheckouts, registerCheckout, } from "@aui.io/apollo-core/checkouts/registry.js";
|
|
6
|
+
import { branchName, branchState, continuedName, parseVersionTag } from "@aui.io/apollo-core/api/management.js";
|
|
7
|
+
import { requireUserId } from "@aui.io/apollo-core/config/index.js";
|
|
6
8
|
import { ConfigError, ValidationError } from "@aui.io/apollo-core/errors/index.js";
|
|
7
9
|
import { assertRuntimeAvailable } from "@aui.io/apollo-core/runtime-version/availability.js";
|
|
8
10
|
import { adviseLocalBundle } from "@aui.io/apollo-core/services/advisor.js";
|
|
9
11
|
import { buildAgent } from "@aui.io/apollo-core/services/builds.js";
|
|
10
12
|
import { annotateRun, awaitRun, pullRun, receiptId, resolveRunId, startEvaluation, startRegression, } from "@aui.io/apollo-core/services/runs.js";
|
|
11
|
-
import { importBundle, listVersions, localDiff, pullCheckout, pushBundle, remoteDiff, applyBundleFixes, bundleSourceRoot, validateLocalBundle, } from "@aui.io/apollo-core/services/bundles.js";
|
|
13
|
+
import { branchLog, importBundle, listVersions, localDiff, pullCheckout, pushBundle, remoteDiff, applyBundleFixes, bundleSourceRoot, validateLocalBundle, } from "@aui.io/apollo-core/services/bundles.js";
|
|
14
|
+
import { describeMerge, diffAgainst, fetchVersion, mergeFrom, } from "@aui.io/apollo-core/services/versions.js";
|
|
12
15
|
import { checkoutSchemasDir, installSchemas, } from "@aui.io/apollo-core/schemas/install.js";
|
|
13
16
|
import { createClients } from "@aui.io/apollo-core/services/clients.js";
|
|
14
17
|
import { agentRuntimeVersion, listAgents, useVersion, } from "@aui.io/apollo-core/services/hierarchy.js";
|
|
15
18
|
import { installAgentsPage } from "@aui.io/apollo-core/skills/agents-page.js";
|
|
16
19
|
import { installSkills, } from "@aui.io/apollo-core/skills/install.js";
|
|
17
20
|
import { resolvePickerId } from "./picker.js";
|
|
21
|
+
/** `branch log`'s default page, and apollo's internal page cap. */
|
|
22
|
+
const COMMIT_PAGE = 20;
|
|
23
|
+
const MAX_COMMIT_PAGE = 1000;
|
|
18
24
|
function renderDiff(diff) {
|
|
19
25
|
const rows = [
|
|
20
26
|
...diff.added.map((file) => `A ${file}`),
|
|
@@ -173,6 +179,16 @@ async function runAction(run, builder, kind, root, options) {
|
|
|
173
179
|
}
|
|
174
180
|
return true;
|
|
175
181
|
}
|
|
182
|
+
/** A pulled or imported commit that still carries a secret file on the server
|
|
183
|
+
* (pushed before secret files stayed local): the file was not written and a
|
|
184
|
+
* local copy is untouched, but the values are stored with that commit. */
|
|
185
|
+
function warnServerSecrets(run, files, tag) {
|
|
186
|
+
if (!files?.length)
|
|
187
|
+
return;
|
|
188
|
+
run.output.warn(`${tag} still carries ${files.join(", ")} on the server, pushed before secret files stayed local. ` +
|
|
189
|
+
"It was not written here and any local copy is untouched, but its values are stored with that commit: " +
|
|
190
|
+
"rotate those credentials and keep them in the agent's vault (`apollo vault set <NAME>`).");
|
|
191
|
+
}
|
|
176
192
|
function capitalize(word) {
|
|
177
193
|
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
178
194
|
}
|
|
@@ -530,20 +546,46 @@ export function registerBundles(program, runtime) {
|
|
|
530
546
|
});
|
|
531
547
|
program
|
|
532
548
|
.command("diff")
|
|
533
|
-
.description("Compare local files with the last baseline")
|
|
549
|
+
.description("Compare local files with the last baseline, or with another version (a tag, a name, or live)")
|
|
550
|
+
.argument("[ref]", "a version to compare bundle/src with (fetched into bundle/tmp/versions/<tag>)")
|
|
534
551
|
.option("--remote", "compare with the selected remote version")
|
|
535
|
-
.action(async (options) => {
|
|
552
|
+
.action(async (ref, options) => {
|
|
536
553
|
const run = runtime();
|
|
537
554
|
const management = createClients(run.context).management;
|
|
555
|
+
if (ref) {
|
|
556
|
+
const result = await diffAgainst(run.context, management, ref);
|
|
557
|
+
run.output.result(result, () => [
|
|
558
|
+
`${result.fetched.tag} → bundle/src${result.fetched.relation ? ` (${result.fetched.relation}${result.fetched.base ? `; common base ${result.fetched.base}` : ""})` : ""}; their copy: bundle/tmp/versions/${result.fetched.tag}/`,
|
|
559
|
+
renderDiff(result.diff),
|
|
560
|
+
].join("\n"));
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
538
563
|
const diff = options.remote
|
|
539
564
|
? await remoteDiff(run.context, management)
|
|
540
565
|
: await localDiff(run.context);
|
|
541
566
|
run.output.result(diff, (value) => renderDiff(value));
|
|
542
567
|
});
|
|
568
|
+
program
|
|
569
|
+
.command("merge-from")
|
|
570
|
+
.description("Bring another branch's changes into bundle/src (three-way over the commit both came from); disputed regions keep your text and are listed")
|
|
571
|
+
.argument("<ref>", "the version to bring in — a tag, a line (v2), a name, or live")
|
|
572
|
+
.option("--only <paths...>", "bring in only these program paths (a cherry-pick)")
|
|
573
|
+
.option("--dry-run", "report what would change without writing")
|
|
574
|
+
.option("--resolved", "every disputed region is decided at your text: a newer commit of your own branch becomes the checkout's base")
|
|
575
|
+
.action(async (ref, options) => {
|
|
576
|
+
const run = runtime();
|
|
577
|
+
const clients = createClients(run.context);
|
|
578
|
+
const merged = await mergeFrom(run.context, clients, ref, {
|
|
579
|
+
...(options.only ? { only: options.only } : {}),
|
|
580
|
+
dryRun: options.dryRun === true,
|
|
581
|
+
resolved: options.resolved === true,
|
|
582
|
+
});
|
|
583
|
+
run.output.result(merged, () => describeMerge(merged));
|
|
584
|
+
});
|
|
543
585
|
program
|
|
544
586
|
.command("pull")
|
|
545
587
|
.description("Pull the selected agent version plus the schemas, skills and AGENTS.md its runtime serves")
|
|
546
|
-
.option("--tag <
|
|
588
|
+
.option("--tag <branch>", "switch to a branch and pull its newest commit (v2, its name, its newest tag, or live)")
|
|
547
589
|
.option("--dir <directory>", "destination directory")
|
|
548
590
|
.option("--force", "discard local bundle changes and match remote")
|
|
549
591
|
.option("--skills <targets>", "comma-separated cursor,claude,opencode", "cursor,claude")
|
|
@@ -559,6 +601,7 @@ export function registerBundles(program, runtime) {
|
|
|
559
601
|
skills: options.skills === false ? false : targets(String(options.skills)),
|
|
560
602
|
schemas: options.schemas,
|
|
561
603
|
});
|
|
604
|
+
warnServerSecrets(run, result.serverSecretFiles, result.pull.version_tag);
|
|
562
605
|
run.output.result(result, () => {
|
|
563
606
|
const removed = result.removed.length > 0
|
|
564
607
|
? ` Removed ${result.removed.length} local file(s) not in the remote bundle.`
|
|
@@ -566,9 +609,13 @@ export function registerBundles(program, runtime) {
|
|
|
566
609
|
return [
|
|
567
610
|
// Name the tag the pull landed on — a stale pin resolves to the
|
|
568
611
|
// tip of its line, and this is where the checkout learns that.
|
|
569
|
-
`Pulled ${Object.keys(result.files).length} files at ${result.pull.version_tag}${result.runtimeVersion ? ` on runtime ${result.runtimeVersion}` : ""}.${removed}`,
|
|
612
|
+
`Pulled ${Object.keys(result.files).length} files at ${result.pull.version_tag}${result.runtimeVersion ? ` on runtime ${result.runtimeVersion}` : ""}${result.live === result.pull.version_tag ? ", the commit customers get" : ""}.${removed}`,
|
|
613
|
+
...liveGap(result.pull.version_tag, result.live),
|
|
570
614
|
result.build
|
|
571
|
-
? `Build bundle v${result.build.version}: ${result.build.written.length} file(s) into bundle/build.`
|
|
615
|
+
? `Build bundle v${result.build.version}: ${result.build.written.length} file(s) into bundle/build.` +
|
|
616
|
+
(result.build.askedFor
|
|
617
|
+
? ` It belongs with ${result.build.programVersionTag ?? "another commit"}, not the ${result.build.askedFor} you pulled — nothing has been pushed for that commit yet.`
|
|
618
|
+
: "")
|
|
572
619
|
: "",
|
|
573
620
|
result.certificate
|
|
574
621
|
? `Certificate: ${result.certificate.revision ?? result.certificate.version} (${result.certificate.run}), ${result.certificate.cases.length} case(s) — bundle/build/certification.yaml.`
|
|
@@ -590,6 +637,7 @@ export function registerBundles(program, runtime) {
|
|
|
590
637
|
.description("Validate and push local changes — a changed program mints a version, a changed bundle/build ships a build bundle")
|
|
591
638
|
.option("-m, --message <message>", "commit message — recorded on the revision the push mints (not the version's label)")
|
|
592
639
|
.option("--dry-run", "validate and show the diff without pushing")
|
|
640
|
+
.option("--new-version [name]", "push these changes as a new branch cut from the commit they are based on (the way out when the branch moved)")
|
|
593
641
|
.action(async (options) => {
|
|
594
642
|
const run = runtime();
|
|
595
643
|
const clients = createClients(run.context);
|
|
@@ -598,6 +646,7 @@ export function registerBundles(program, runtime) {
|
|
|
598
646
|
const result = await pushBundle(run.context, clients, {
|
|
599
647
|
...(options.message ? { commitMessage: options.message } : {}),
|
|
600
648
|
dryRun: options.dryRun === true,
|
|
649
|
+
...(options.newVersion !== undefined ? { newVersion: options.newVersion } : {}),
|
|
601
650
|
});
|
|
602
651
|
run.output.result(result, () => {
|
|
603
652
|
// One report, both lanes: program paths bare, build paths prefixed —
|
|
@@ -623,10 +672,21 @@ export function registerBundles(program, runtime) {
|
|
|
623
672
|
// one place the CLI shows it, since `version list` lists versions
|
|
624
673
|
// (label, notes) and a revision's commit message lives elsewhere.
|
|
625
674
|
`Pushed ${result.push.new_version_tag}${result.runtimeVersion ? ` on runtime ${result.runtimeVersion}` : ""}${result.push.commit_message ? ` — "${result.push.commit_message}"` : ""}.`,
|
|
675
|
+
...(result.newBranch ? [newBranchLine(result.newBranch)] : []),
|
|
676
|
+
...(result.live
|
|
677
|
+
? [
|
|
678
|
+
`Customers still get ${result.live}; \`apollo branch live ${result.push.new_version_tag}\` ships this.`,
|
|
679
|
+
]
|
|
680
|
+
: []),
|
|
626
681
|
]
|
|
627
682
|
: []),
|
|
628
683
|
...(result.buildPush
|
|
629
|
-
? [
|
|
684
|
+
? [
|
|
685
|
+
`Pushed build bundle v${result.buildPush.version}` +
|
|
686
|
+
(result.buildPush.program_version_tag
|
|
687
|
+
? ` — it belongs with ${result.buildPush.program_version_tag}.`
|
|
688
|
+
: "."),
|
|
689
|
+
]
|
|
630
690
|
: []),
|
|
631
691
|
// Which gate cleared the pre-flight, when it was not the pinned one —
|
|
632
692
|
// a push that rode the fallback says so rather than reading as the
|
|
@@ -651,7 +711,7 @@ export function registerBundles(program, runtime) {
|
|
|
651
711
|
.description("Pull a cloud agent into a local checkout (interactive without an id; shell-init cds)")
|
|
652
712
|
.argument("[agent-id]", "agent id")
|
|
653
713
|
.option("--name <filter>", "filter the interactive picker by name")
|
|
654
|
-
.option("--tag <
|
|
714
|
+
.option("--tag <branch>", "the branch to start on (v2, its name, its newest tag, or live); default: live, the branch customers are on")
|
|
655
715
|
.option("--dir <directory>", "checkout directory (defaults to ~/apollo/<profile>/<env>/<name>-<id>)")
|
|
656
716
|
.option("--skills <targets>", "comma-separated cursor,claude,opencode", "cursor,claude")
|
|
657
717
|
.option("--force", "overwrite an existing local program")
|
|
@@ -705,6 +765,7 @@ export function registerBundles(program, runtime) {
|
|
|
705
765
|
...(options.tag ? { tag: options.tag } : {}),
|
|
706
766
|
...(runtimeVersion ? { runtimeVersion } : {}),
|
|
707
767
|
});
|
|
768
|
+
warnServerSecrets(run, imported.serverSecretFiles, imported.pull.version_tag);
|
|
708
769
|
// The public floor, filtered by the wire: the index the install
|
|
709
770
|
// fetches carries only public skills, and its sweep deletes managed
|
|
710
771
|
// packs the index no longer names (a re-import lands in the existing
|
|
@@ -757,8 +818,13 @@ export function registerBundles(program, runtime) {
|
|
|
757
818
|
: {}),
|
|
758
819
|
}, () => [
|
|
759
820
|
`Imported ${Object.keys(imported.files).length} files into ${destination}${runtimeVersion ? ` on runtime ${runtimeVersion}` : ""}.`,
|
|
821
|
+
`On ${branchName(imported.pull)} at ${imported.pull.version_tag}${imported.live === imported.pull.version_tag ? ", the commit customers get" : ""}.`,
|
|
822
|
+
...liveGap(imported.pull.version_tag, imported.live),
|
|
760
823
|
imported.build
|
|
761
|
-
? `Build bundle v${imported.build.version}: ${imported.build.written.length} file(s) into bundle/build.`
|
|
824
|
+
? `Build bundle v${imported.build.version}: ${imported.build.written.length} file(s) into bundle/build.` +
|
|
825
|
+
(imported.build.askedFor
|
|
826
|
+
? ` It belongs with ${imported.build.programVersionTag ?? "another commit"}, not the ${imported.build.askedFor} you imported.`
|
|
827
|
+
: "")
|
|
762
828
|
: "",
|
|
763
829
|
authoringNote ?? "",
|
|
764
830
|
removedSkills.length > 0
|
|
@@ -771,36 +837,152 @@ export function registerBundles(program, runtime) {
|
|
|
771
837
|
registerVersions(program, runtime);
|
|
772
838
|
}
|
|
773
839
|
function registerVersions(program, runtime) {
|
|
774
|
-
|
|
775
|
-
|
|
840
|
+
// A version IS a branch and a revision IS a commit — the model every
|
|
841
|
+
// surface speaks, so `branch` is the command. `version` stays as an alias:
|
|
842
|
+
// it is what this group was called, and anything already scripted against
|
|
843
|
+
// it keeps working.
|
|
844
|
+
const version = program
|
|
845
|
+
.command("branch")
|
|
846
|
+
.alias("version")
|
|
847
|
+
.description("Manage the agent's branches (lines of commits)");
|
|
848
|
+
version
|
|
849
|
+
.command("list")
|
|
850
|
+
.description("List the branches: name, state, newest commit, and the commit customers get")
|
|
851
|
+
.action(async () => {
|
|
776
852
|
const run = runtime();
|
|
777
853
|
const result = await listVersions(run.context, createClients(run.context).management);
|
|
854
|
+
const liveBranch = result.live_version_tag ? parseVersionTag(result.live_version_tag)?.major : undefined;
|
|
778
855
|
run.output.result(result, (value) => value.results
|
|
779
|
-
.map((item) => `${item
|
|
780
|
-
.join("\n") || "No
|
|
856
|
+
.map((item) => `${branchName(item)}\t${branchState(item.status)}\t${item.label ?? ""}\tnewest ${item.version_tag}${item.version_number === liveBranch ? `\tlive ${result.live_version_tag}` : ""}${item.parent_version_tag ? `\tfrom ${item.parent_version_tag}` : ""}`)
|
|
857
|
+
.join("\n") || "No branches.");
|
|
858
|
+
});
|
|
859
|
+
version
|
|
860
|
+
.command("log")
|
|
861
|
+
.argument("[ref]", "a branch (v2, its name, any of its commits, or live); default: the checkout's")
|
|
862
|
+
.option("--limit <n>", `how many commits, newest first (1 to ${MAX_COMMIT_PAGE})`)
|
|
863
|
+
.description("List a branch's commits, newest first, marking its newest and the live one")
|
|
864
|
+
.action(async (ref, options) => {
|
|
865
|
+
const run = runtime();
|
|
866
|
+
const limit = integer("--limit", options.limit) ?? COMMIT_PAGE;
|
|
867
|
+
if (limit < 1 || limit > MAX_COMMIT_PAGE) {
|
|
868
|
+
throw new ConfigError(`--limit takes 1 to ${MAX_COMMIT_PAGE} (got ${limit}).`);
|
|
869
|
+
}
|
|
870
|
+
const log = await branchLog(run.context, createClients(run.context).management, {
|
|
871
|
+
...(ref ? { ref } : {}),
|
|
872
|
+
limit,
|
|
873
|
+
});
|
|
874
|
+
run.output.result(log, () => [
|
|
875
|
+
`${branchName(log.branch)}${log.branch.label ? ` (${log.branch.label})` : ""}: ${log.total} commit(s)${log.live ? `, live ${log.live}` : ""}`,
|
|
876
|
+
...log.commits.map((commit) => `${commit.tag}\t${commit.created_at.slice(0, 16).replace("T", " ")} UTC\t${commit.author}\t${commit.message ?? ""}${commit.newest ? "\tnewest" : ""}${commit.live ? "\tlive" : ""}`),
|
|
877
|
+
log.total > log.commits.length
|
|
878
|
+
? `${log.total - log.commits.length} older not shown (--limit ${Math.min(log.total, MAX_COMMIT_PAGE)} lists them).`
|
|
879
|
+
: "",
|
|
880
|
+
]
|
|
881
|
+
.filter(Boolean)
|
|
882
|
+
.join("\n"));
|
|
883
|
+
});
|
|
884
|
+
version
|
|
885
|
+
.command("fetch")
|
|
886
|
+
.argument("<ref>", "a commit (v2.7), a branch (v2 = its newest commit), a branch name, or live")
|
|
887
|
+
.description("Pull another branch's program into bundle/tmp/versions/<tag>/ (scratch, never pushed)")
|
|
888
|
+
.action(async (ref) => {
|
|
889
|
+
const run = runtime();
|
|
890
|
+
const fetched = await fetchVersion(run.context, createClients(run.context).management, ref);
|
|
891
|
+
run.output.result(fetched, () => [
|
|
892
|
+
`Fetched ${fetched.tag}${fetched.version.label ? ` (${fetched.version.label})` : ""} — ${Object.keys(fetched.files).length} files into bundle/tmp/versions/${fetched.tag}/.`,
|
|
893
|
+
fetched.relation
|
|
894
|
+
? `Relation to this checkout: ${fetched.relation}${fetched.base ? `; common base ${fetched.base}` : " — no common base, a merge would be two-way"}.`
|
|
895
|
+
: "",
|
|
896
|
+
]
|
|
897
|
+
.filter(Boolean)
|
|
898
|
+
.join("\n"));
|
|
899
|
+
});
|
|
900
|
+
version
|
|
901
|
+
.command("label")
|
|
902
|
+
.argument("<ref>")
|
|
903
|
+
.argument("<name>", "the name people refer to the version by")
|
|
904
|
+
.description("Rename a branch — the name people refer to it by")
|
|
905
|
+
.action(async (ref, name) => {
|
|
906
|
+
const run = runtime();
|
|
907
|
+
const management = createClients(run.context).management;
|
|
908
|
+
const agentId = requiredAgent(run);
|
|
909
|
+
const selected = await management.resolveVersion(agentId, ref);
|
|
910
|
+
const result = await management.updateVersion(agentId, selected.id, { label: name });
|
|
911
|
+
run.output.result(result, () => `Renamed ${result.version_tag} to "${result.label ?? name}".`);
|
|
912
|
+
});
|
|
913
|
+
version
|
|
914
|
+
.command("lock")
|
|
915
|
+
.argument("<ref>")
|
|
916
|
+
.description("Close a branch to further commits — it says nothing about what customers get")
|
|
917
|
+
.action(async (ref) => {
|
|
918
|
+
const run = runtime();
|
|
919
|
+
const management = createClients(run.context).management;
|
|
920
|
+
const agentId = requiredAgent(run);
|
|
921
|
+
const selected = await management.resolveVersion(agentId, ref);
|
|
922
|
+
const result = await management.lockVersion(agentId, selected.id, run.context.userId ?? "apollo-cli");
|
|
923
|
+
run.output.result(result, () => `Locked ${result.version_tag} — no more commits land on it, and what customers get has not changed. ` +
|
|
924
|
+
`\`apollo branch live <ref>\` picks the commit they get; \`apollo branch unlock ${branchName(result)}\` reopens this one; ` +
|
|
925
|
+
`\`apollo branch create --from ${branchName(result)}\` continues the work in a new draft.`);
|
|
926
|
+
});
|
|
927
|
+
version
|
|
928
|
+
.command("unlock")
|
|
929
|
+
.argument("<ref>")
|
|
930
|
+
.description("Reopen a locked branch so commits land on it again")
|
|
931
|
+
.action(async (ref) => {
|
|
932
|
+
const run = runtime();
|
|
933
|
+
const management = createClients(run.context).management;
|
|
934
|
+
const agentId = requiredAgent(run);
|
|
935
|
+
const selected = await management.resolveVersion(agentId, ref);
|
|
936
|
+
const result = await management.unlockVersion(agentId, selected.id);
|
|
937
|
+
run.output.result(result, () => `Unlocked ${result.version_tag} — commits land on it again. ` +
|
|
938
|
+
`What customers get is unchanged: live is a commit, not a branch's status.`);
|
|
939
|
+
});
|
|
940
|
+
version
|
|
941
|
+
.command("live")
|
|
942
|
+
.argument("<ref>")
|
|
943
|
+
.description("Make one COMMIT live — the exact bundle customers get (also how you roll back)")
|
|
944
|
+
.action(async (ref) => {
|
|
945
|
+
const run = runtime();
|
|
946
|
+
const management = createClients(run.context).management;
|
|
947
|
+
const agentId = requiredAgent(run);
|
|
948
|
+
// A ref like `v3.7` names a COMMIT; `v3` or a label names the branch,
|
|
949
|
+
// and its newest commit goes live. `resolveRef` keeps the difference.
|
|
950
|
+
const { version: selected, tag } = await management.resolveRef(agentId, ref);
|
|
951
|
+
const live = await management.activateSave(agentId, selected.id, tag);
|
|
952
|
+
run.output.result(live, () => {
|
|
953
|
+
const got = live.active_version_tag ?? tag;
|
|
954
|
+
return got === tag
|
|
955
|
+
? `Live: ${got}. Pushing to ${branchName(selected)} will not move it — \`apollo branch live\` does.`
|
|
956
|
+
: `Live: ${got} — NOT the ${tag} you asked for. This deployment ships a branch's newest commit only.`;
|
|
957
|
+
});
|
|
781
958
|
});
|
|
782
959
|
version
|
|
783
960
|
.command("get")
|
|
784
|
-
.argument("<
|
|
785
|
-
.
|
|
961
|
+
.argument("<ref>", "a commit (v2.7), a branch (v2 = its newest commit), a branch name, or live")
|
|
962
|
+
.description("Show one commit and its branch")
|
|
963
|
+
.action(async (ref) => {
|
|
786
964
|
const run = runtime();
|
|
787
|
-
const item = await createClients(run.context).management.
|
|
788
|
-
run.output.result(item, () => `${item
|
|
965
|
+
const { version: item, tag: commit } = await createClients(run.context).management.resolveRef(requiredAgent(run), ref);
|
|
966
|
+
run.output.result({ ...item, commit_tag: commit }, () => `${commit}\t${branchName(item)}\t${branchState(item.status)}\t${item.label ?? ""}${item.notes ? `\n${item.notes}` : ""}`);
|
|
789
967
|
});
|
|
790
968
|
version
|
|
791
969
|
.command("use")
|
|
792
|
-
.argument("<
|
|
793
|
-
.description("
|
|
794
|
-
.action(async (
|
|
970
|
+
.argument("<branch>", "v2, its name, its newest commit's tag, or live (the branch customers are on)")
|
|
971
|
+
.description("Work on a branch in this checkout: pushes land on it and pull follows its newest commit")
|
|
972
|
+
.action(async (ref) => {
|
|
795
973
|
const run = runtime();
|
|
796
|
-
const
|
|
797
|
-
run.
|
|
798
|
-
|
|
799
|
-
|
|
974
|
+
const previous = run.context.versionTag;
|
|
975
|
+
const result = await useVersion(run.context, createClients(run.context).management, ref);
|
|
976
|
+
const moved = previous !== result.tag;
|
|
977
|
+
run.output.result(result, () => [
|
|
978
|
+
`Using ${branchName(result.version)} (${branchState(result.version.status)}) at ${result.tag}${result.live === result.tag ? ", the commit customers get" : ""}.${moved ? " `apollo pull` brings its files." : ""}`,
|
|
979
|
+
...liveGap(result.tag, result.live),
|
|
980
|
+
].join("\n"));
|
|
800
981
|
});
|
|
801
982
|
version
|
|
802
983
|
.command("create")
|
|
803
|
-
.
|
|
984
|
+
.description("Cut a new draft branch — from a branch's newest commit, from an exact commit (v3.7), from a template, or empty")
|
|
985
|
+
.option("--from <ref>", "cut from a branch or an exact commit (v3, v3.7, a branch name, or live)")
|
|
804
986
|
.option("--template <id>", "create from a template")
|
|
805
987
|
.option("--label <label>")
|
|
806
988
|
.option("--notes <notes>")
|
|
@@ -808,28 +990,34 @@ function registerVersions(program, runtime) {
|
|
|
808
990
|
const run = runtime();
|
|
809
991
|
const management = createClients(run.context).management;
|
|
810
992
|
const agentId = requiredAgent(run);
|
|
811
|
-
const
|
|
812
|
-
? (await management.resolveVersion(agentId, options.from)).id
|
|
813
|
-
: undefined;
|
|
993
|
+
const from = options.from ? await management.resolveRef(agentId, options.from) : undefined;
|
|
814
994
|
const created = await management.createVersion(agentId, {
|
|
815
|
-
source:
|
|
816
|
-
|
|
995
|
+
source: from ? "version" : options.template ? "template" : "empty",
|
|
996
|
+
createdBy: requireUserId(run.context, "branch"),
|
|
997
|
+
...(from ? { fromVersion: from.version.id, fromVersionTag: from.tag } : {}),
|
|
817
998
|
...(options.template ? { fromTemplate: options.template } : {}),
|
|
818
|
-
...(options.label
|
|
999
|
+
...(options.label
|
|
1000
|
+
? { label: options.label }
|
|
1001
|
+
: from
|
|
1002
|
+
? { label: continuedName(from.version) }
|
|
1003
|
+
: {}),
|
|
819
1004
|
...(options.notes ? { notes: options.notes } : {}),
|
|
820
1005
|
});
|
|
821
|
-
run.output.result(created, () => `Created ${created.version_tag}.`
|
|
1006
|
+
run.output.result(created, () => `Created ${created.version_tag}${from ? ` from ${from.tag}` : ""}.` +
|
|
1007
|
+
` \`apollo branch use ${branchName(created)}\` then \`apollo pull\` to work on it.`);
|
|
822
1008
|
});
|
|
823
1009
|
version
|
|
824
1010
|
.command("publish")
|
|
825
1011
|
.argument("<tag>")
|
|
1012
|
+
.description("The old one-verb ladder: lock the branch AND ship its newest commit. Prefer `branch live`")
|
|
826
1013
|
.action(async (tag) => {
|
|
827
1014
|
const run = runtime();
|
|
828
1015
|
const management = createClients(run.context).management;
|
|
829
1016
|
const agentId = requiredAgent(run);
|
|
830
1017
|
const selected = await management.resolveVersion(agentId, tag);
|
|
831
1018
|
const result = await management.publishVersion(agentId, selected.id);
|
|
832
|
-
run.output.result(result, () => `Published ${result.version_tag}
|
|
1019
|
+
run.output.result(result, () => `Published ${result.version_tag} — locked the branch and shipped its newest commit. ` +
|
|
1020
|
+
`\`apollo branch live <ref>\` ships a commit without locking anything, and can ship an older one.`);
|
|
833
1021
|
});
|
|
834
1022
|
version
|
|
835
1023
|
.command("archive")
|
|
@@ -848,4 +1036,22 @@ function requiredAgent(run) {
|
|
|
848
1036
|
throw new ConfigError("Select or import an agent first.");
|
|
849
1037
|
return run.context.agentId;
|
|
850
1038
|
}
|
|
1039
|
+
/** What a push that started a branch says: which branch, cut from where, and why. */
|
|
1040
|
+
function newBranchLine(started) {
|
|
1041
|
+
const why = started.closed
|
|
1042
|
+
? `${started.closed.branch} is ${branchState(started.closed.status)}, so the push started`
|
|
1043
|
+
: "The push started";
|
|
1044
|
+
return `${why} a new branch: ${started.branch} "${started.label}", cut from ${started.from}. This checkout now works on ${started.branch}.`;
|
|
1045
|
+
}
|
|
1046
|
+
/** When a command followed `live` past the commit customers get: how far behind that is, and how to reach it. */
|
|
1047
|
+
function liveGap(at, live) {
|
|
1048
|
+
if (live === undefined || live === at)
|
|
1049
|
+
return [];
|
|
1050
|
+
const behind = (parseVersionTag(at)?.revision ?? 0) - (parseVersionTag(live)?.revision ?? 0);
|
|
1051
|
+
return [
|
|
1052
|
+
`Customers get ${live}, ${behind} ${behind === 1 ? "commit" : "commits"} behind:`,
|
|
1053
|
+
` apollo chat --at live "…" talk to it`,
|
|
1054
|
+
` apollo branch create --from live start a fix from it`,
|
|
1055
|
+
];
|
|
1056
|
+
}
|
|
851
1057
|
//# sourceMappingURL=bundles.js.map
|