@thieung/agentkit-helper 0.1.4 → 0.1.5
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 -2
- package/README.vi.md +4 -2
- package/bin/agentkit-helper.mjs +108 -45
- package/lib/args.mjs +29 -5
- package/lib/commands.mjs +36 -0
- package/lib/i18n.mjs +6 -2
- package/lib/pi-profiles.mjs +45 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,10 +91,12 @@ akh update --project /path/to/project --dry-run
|
|
|
91
91
|
|
|
92
92
|
Targets:
|
|
93
93
|
|
|
94
|
-
- Install: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`
|
|
95
|
-
- Update: `claude-code`, `codex`, `cursor`, `grok`, `omp`, `pi`
|
|
94
|
+
- Install: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`, `pi-ak`, `pi-omp`
|
|
95
|
+
- Update: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`, `pi-ak`, `pi-omp`
|
|
96
96
|
- Export: `agy`, `portable`
|
|
97
97
|
|
|
98
|
+
`dsh` updates use `ak kit refresh` because remote `ak update` still rejects that runtime. `pi-ak` and `pi-omp` are global-only profile aliases (`--global`); they install/update into the custom Pi/OMP homes instead of the default `pi`/`omp` directories.
|
|
99
|
+
|
|
98
100
|
Run `akh --help` for every command and option.
|
|
99
101
|
|
|
100
102
|
</details>
|
package/README.vi.md
CHANGED
|
@@ -88,10 +88,12 @@ akh update --project /path/to/project --dry-run
|
|
|
88
88
|
|
|
89
89
|
Các target:
|
|
90
90
|
|
|
91
|
-
- Cài đặt: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`
|
|
92
|
-
- Cập nhật: `claude-code`, `codex`, `cursor`, `grok`, `omp`, `pi`
|
|
91
|
+
- Cài đặt: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`, `pi-ak`, `pi-omp`
|
|
92
|
+
- Cập nhật: `claude-code`, `codex`, `cursor`, `dsh`, `grok`, `omp`, `pi`, `pi-ak`, `pi-omp`
|
|
93
93
|
- Export: `agy`, `portable`
|
|
94
94
|
|
|
95
|
+
Update `dsh` đi qua `ak kit refresh` vì `ak update` remote vẫn reject runtime này. `pi-ak` và `pi-omp` là alias profile chỉ dùng với `--global`; chúng cài/cập nhật vào home Pi/OMP custom, không phải thư mục `pi`/`omp` mặc định.
|
|
96
|
+
|
|
95
97
|
Chạy `akh --help` để xem toàn bộ command và option.
|
|
96
98
|
|
|
97
99
|
</details>
|
package/bin/agentkit-helper.mjs
CHANGED
|
@@ -6,9 +6,10 @@ import { dirname, resolve } from "node:path";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import {
|
|
8
8
|
EXPORT_TARGETS,
|
|
9
|
-
|
|
9
|
+
helperRuntimeTargets,
|
|
10
10
|
KITS,
|
|
11
11
|
parseArgs,
|
|
12
|
+
specHasProfileTarget,
|
|
12
13
|
splitTargetSpec,
|
|
13
14
|
targetSpecIsSupported,
|
|
14
15
|
UPDATE_TARGETS,
|
|
@@ -21,14 +22,17 @@ import {
|
|
|
21
22
|
globalUpdateApplyArgs,
|
|
22
23
|
globalUpdatePreviewArgs,
|
|
23
24
|
installArgs,
|
|
25
|
+
kitRefreshArgs,
|
|
24
26
|
projectUpdateApplyArgs,
|
|
25
27
|
projectUpdatePreviewArgs,
|
|
26
28
|
selfUpdateCheckArgs,
|
|
27
29
|
selfUpdateApplyArgs,
|
|
28
30
|
selfUpdateJsonApplyArgs,
|
|
29
31
|
selfUpdateJsonCheckArgs,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
splitRuntimesForUpdate,
|
|
33
|
+
updateApplyArgsForRuntime,
|
|
34
|
+
updatePreviewArgsForRuntime,
|
|
35
|
+
usesKitRefresh,
|
|
32
36
|
} from "../lib/commands.mjs";
|
|
33
37
|
import { readProjectConfig, writeProjectConfig } from "../lib/config.mjs";
|
|
34
38
|
import { colorText } from "../lib/colors.mjs";
|
|
@@ -48,6 +52,7 @@ import { t } from "../lib/i18n.mjs";
|
|
|
48
52
|
import { isUnsafeProjectPath, resolveProjectPath } from "../lib/project.mjs";
|
|
49
53
|
import {
|
|
50
54
|
classifyPiProfiles,
|
|
55
|
+
materializeHelperTarget,
|
|
51
56
|
parsePiProfileInventory,
|
|
52
57
|
piProfileManagerInvocation,
|
|
53
58
|
piProfileProcessOptions,
|
|
@@ -140,8 +145,8 @@ Tùy chọn:
|
|
|
140
145
|
--version, -v Hiện phiên bản
|
|
141
146
|
|
|
142
147
|
Target groups:
|
|
143
|
-
Install claude-code, codex, cursor, dsh, grok, omp, pi
|
|
144
|
-
Update claude-code, codex, cursor, grok, omp, pi
|
|
148
|
+
Install claude-code, codex, cursor, dsh, grok, omp, pi, pi-ak, pi-omp
|
|
149
|
+
Update claude-code, codex, cursor, dsh, grok, omp, pi, pi-ak, pi-omp
|
|
145
150
|
Export agy, portable
|
|
146
151
|
`);
|
|
147
152
|
return;
|
|
@@ -177,8 +182,8 @@ Options:
|
|
|
177
182
|
--version, -v Show version
|
|
178
183
|
|
|
179
184
|
Target groups:
|
|
180
|
-
Install claude-code, codex, cursor, dsh, grok, omp, pi
|
|
181
|
-
Update claude-code, codex, cursor, grok, omp, pi
|
|
185
|
+
Install claude-code, codex, cursor, dsh, grok, omp, pi, pi-ak, pi-omp
|
|
186
|
+
Update claude-code, codex, cursor, dsh, grok, omp, pi, pi-ak, pi-omp
|
|
182
187
|
Export agy, portable
|
|
183
188
|
`);
|
|
184
189
|
}
|
|
@@ -369,15 +374,11 @@ async function selectTarget(
|
|
|
369
374
|
const allRuntimeValue = "__all_runtimes__";
|
|
370
375
|
const choices = [
|
|
371
376
|
{ label: ui("allRuntimes"), value: allRuntimeValue },
|
|
372
|
-
...[...targets].map((target) => ({
|
|
377
|
+
...[...targets].map((target) => ({
|
|
378
|
+
label: target === "pi-ak" ? ui("piAkProfile") : target === "pi-omp" ? ui("piOmpProfile") : target,
|
|
379
|
+
value: target,
|
|
380
|
+
})),
|
|
373
381
|
];
|
|
374
|
-
if (promptKey === "updateTargetPrompt") {
|
|
375
|
-
choices.push({
|
|
376
|
-
label: ui("dshUpdateUnsupported"),
|
|
377
|
-
value: "dsh",
|
|
378
|
-
disabled: true,
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
382
|
const initialValues = [];
|
|
382
383
|
const selected = await (allowBack ? multiChooseWithBack : multiChoose)(
|
|
383
384
|
ui(promptKey, promptValues),
|
|
@@ -468,7 +469,9 @@ async function install(commandOptions, allowBack = false) {
|
|
|
468
469
|
{
|
|
469
470
|
key: "target",
|
|
470
471
|
select: (values) => selectTarget(
|
|
471
|
-
commandOptions, config,
|
|
472
|
+
commandOptions, config, helperRuntimeTargets({
|
|
473
|
+
command: "install", global: scope.global,
|
|
474
|
+
}), "targetPrompt", routeCanGoBack, allowBack,
|
|
472
475
|
{ kit: kitName(values.kit) },
|
|
473
476
|
),
|
|
474
477
|
},
|
|
@@ -478,12 +481,16 @@ async function install(commandOptions, allowBack = false) {
|
|
|
478
481
|
if (!scopeWasPrompted) return BACK;
|
|
479
482
|
}
|
|
480
483
|
const selection = { ...scope, ...route };
|
|
484
|
+
if (specHasProfileTarget(selection.target) && !selection.global) {
|
|
485
|
+
throw new Error(ui("profileTargetsNeedGlobal"));
|
|
486
|
+
}
|
|
487
|
+
const profiles = specHasProfileTarget(selection.target) ? await loadPiProfilesQuiet() : [];
|
|
481
488
|
const installSelections = splitTargetSpec(selection.target)
|
|
482
|
-
.map((target) => ({ ...selection, target }));
|
|
489
|
+
.map((target) => materializeHelperTarget({ ...selection, target }, profiles));
|
|
483
490
|
|
|
484
491
|
printSection(ui("installPlan"));
|
|
485
492
|
for (const targetSelection of installSelections) {
|
|
486
|
-
printPlan(installArgs(targetSelection), targetSelection.project);
|
|
493
|
+
printPlan(installArgs(targetSelection), targetSelection.project, targetSelection.envOverrides);
|
|
487
494
|
}
|
|
488
495
|
if (commandOptions.dryRun) {
|
|
489
496
|
process.stdout.write(`\n${ui("dryRunFiles")}\n`);
|
|
@@ -500,12 +507,17 @@ async function install(commandOptions, allowBack = false) {
|
|
|
500
507
|
|
|
501
508
|
for (const targetSelection of installSelections) {
|
|
502
509
|
const cwd = targetSelection.project || process.cwd();
|
|
510
|
+
const runOptions = {
|
|
511
|
+
cwd,
|
|
512
|
+
envOverrides: targetSelection.envOverrides,
|
|
513
|
+
envUnset: targetSelection.envUnset,
|
|
514
|
+
};
|
|
503
515
|
try {
|
|
504
|
-
await runAkCommand(installArgs(targetSelection),
|
|
516
|
+
await runAkCommand(installArgs(targetSelection), runOptions);
|
|
505
517
|
} catch (error) {
|
|
506
518
|
if (!requiresForceConsent(error)) throw error;
|
|
507
519
|
warning(ui(targetSelection.global ? "globalForceWarning" : "projectForceWarning", {
|
|
508
|
-
target: targetSelection.target,
|
|
520
|
+
target: targetSelection.helperTarget || targetSelection.target,
|
|
509
521
|
}));
|
|
510
522
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
511
523
|
error.message = `${error.message}\n${ui("forceNeedsConsent")}`;
|
|
@@ -517,8 +529,8 @@ async function install(commandOptions, allowBack = false) {
|
|
|
517
529
|
}
|
|
518
530
|
const forceArgs = installArgs(targetSelection, { force: true });
|
|
519
531
|
printSection(ui("forceInstallPlan"));
|
|
520
|
-
printPlan(forceArgs, targetSelection.project);
|
|
521
|
-
await runAkCommand(forceArgs,
|
|
532
|
+
printPlan(forceArgs, targetSelection.project, targetSelection.envOverrides);
|
|
533
|
+
await runAkCommand(forceArgs, runOptions);
|
|
522
534
|
}
|
|
523
535
|
}
|
|
524
536
|
if (selection.project && !commandOptions.noSave) {
|
|
@@ -691,7 +703,9 @@ async function update(commandOptions, allowBack = false) {
|
|
|
691
703
|
{
|
|
692
704
|
key: "target",
|
|
693
705
|
select: (values) => selectTarget(
|
|
694
|
-
commandOptions, config,
|
|
706
|
+
commandOptions, config, helperRuntimeTargets({
|
|
707
|
+
command: "update", global: scope.global,
|
|
708
|
+
}), "updateTargetPrompt", routeCanGoBack, allowBack,
|
|
695
709
|
{ kit: kitName(values.kit) },
|
|
696
710
|
),
|
|
697
711
|
},
|
|
@@ -714,9 +728,13 @@ async function update(commandOptions, allowBack = false) {
|
|
|
714
728
|
...scope,
|
|
715
729
|
channel,
|
|
716
730
|
};
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
731
|
+
if (specHasProfileTarget(selection.target) && !selection.global) {
|
|
732
|
+
throw new Error(ui("profileTargetsNeedGlobal"));
|
|
733
|
+
}
|
|
734
|
+
const profiles = specHasProfileTarget(selection.target) ? await loadPiProfilesQuiet() : [];
|
|
735
|
+
const updateSelections = splitTargetSpec(selection.target).map((target) => (
|
|
736
|
+
materializeHelperTarget({ ...selection, target }, profiles)
|
|
737
|
+
));
|
|
720
738
|
if (selection.global) warning(ui("globalUpdateSafety"));
|
|
721
739
|
if (channel === "beta") {
|
|
722
740
|
const betaBinary = await prepareBetaBinary(commandOptions, { requiresPreview: true });
|
|
@@ -726,15 +744,24 @@ async function update(commandOptions, allowBack = false) {
|
|
|
726
744
|
printSection(ui("updatePreview"));
|
|
727
745
|
for (const targetSelection of updateSelections) {
|
|
728
746
|
if (updateSelections.length > 1) {
|
|
729
|
-
process.stdout.write(`${colorText(targetSelection.
|
|
747
|
+
process.stdout.write(`${colorText(targetSelection.helperTarget, "target")}\n`);
|
|
748
|
+
}
|
|
749
|
+
const previewArgs = updatePreviewArgsForRuntime(targetSelection);
|
|
750
|
+
if (previewArgs) {
|
|
751
|
+
await runAkCommand(previewArgs, {
|
|
752
|
+
cwd: targetSelection.project || process.cwd(),
|
|
753
|
+
envOverrides: targetSelection.envOverrides,
|
|
754
|
+
envUnset: targetSelection.envUnset,
|
|
755
|
+
});
|
|
730
756
|
}
|
|
731
|
-
await runAkCommand(updatePreviewArgs(targetSelection), {
|
|
732
|
-
cwd: targetSelection.project || process.cwd(),
|
|
733
|
-
});
|
|
734
757
|
}
|
|
735
758
|
printSection(ui("applyPlan"));
|
|
736
759
|
for (const targetSelection of updateSelections) {
|
|
737
|
-
printPlan(
|
|
760
|
+
printPlan(
|
|
761
|
+
updateApplyArgsForRuntime(targetSelection),
|
|
762
|
+
targetSelection.project,
|
|
763
|
+
targetSelection.envOverrides,
|
|
764
|
+
);
|
|
738
765
|
}
|
|
739
766
|
if (commandOptions.dryRun) {
|
|
740
767
|
process.stdout.write(`\n${ui("dryRunFiles")}\n`);
|
|
@@ -746,8 +773,10 @@ async function update(commandOptions, allowBack = false) {
|
|
|
746
773
|
}
|
|
747
774
|
|
|
748
775
|
for (const targetSelection of updateSelections) {
|
|
749
|
-
await runAkCommand(
|
|
776
|
+
await runAkCommand(updateApplyArgsForRuntime(targetSelection), {
|
|
750
777
|
cwd: targetSelection.project || process.cwd(),
|
|
778
|
+
envOverrides: targetSelection.envOverrides,
|
|
779
|
+
envUnset: targetSelection.envUnset,
|
|
751
780
|
});
|
|
752
781
|
}
|
|
753
782
|
if (selection.project && !commandOptions.noSave) {
|
|
@@ -756,18 +785,34 @@ async function update(commandOptions, allowBack = false) {
|
|
|
756
785
|
process.stdout.write(`${ui("updateComplete")}\n`);
|
|
757
786
|
}
|
|
758
787
|
|
|
759
|
-
function
|
|
760
|
-
|
|
761
|
-
|
|
788
|
+
function updateAllCommandPlans(candidate, channel) {
|
|
789
|
+
const kit = candidate.kit;
|
|
790
|
+
if (candidate.kind === "project") {
|
|
791
|
+
if (usesKitRefresh(candidate.runtime)) {
|
|
792
|
+
return [{ preview: null, apply: kitRefreshArgs({
|
|
793
|
+
global: false, kit, channel, target: candidate.runtime,
|
|
794
|
+
}) }];
|
|
795
|
+
}
|
|
796
|
+
return [{
|
|
797
|
+
preview: projectUpdatePreviewArgs(candidate.path, candidate.runtime, channel, kit),
|
|
798
|
+
apply: projectUpdateApplyArgs(candidate.path, candidate.runtime, channel, kit),
|
|
799
|
+
}];
|
|
800
|
+
}
|
|
801
|
+
const { update, refresh } = splitRuntimesForUpdate(candidate.runtimes);
|
|
802
|
+
const plans = [];
|
|
803
|
+
if (update.length > 0) {
|
|
804
|
+
plans.push({
|
|
805
|
+
preview: globalUpdatePreviewArgs(channel, update, kit),
|
|
806
|
+
apply: globalUpdateApplyArgs(channel, update, kit),
|
|
807
|
+
});
|
|
762
808
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
return globalUpdateApplyArgs(channel, candidate.runtimes, candidate.kit);
|
|
809
|
+
for (const runtime of refresh) {
|
|
810
|
+
plans.push({
|
|
811
|
+
preview: null,
|
|
812
|
+
apply: kitRefreshArgs({ global: true, kit, channel, target: runtime }),
|
|
813
|
+
});
|
|
769
814
|
}
|
|
770
|
-
return
|
|
815
|
+
return plans;
|
|
771
816
|
}
|
|
772
817
|
|
|
773
818
|
async function askDeepScanRoots() {
|
|
@@ -854,6 +899,18 @@ function orderUpdateCandidates(candidates) {
|
|
|
854
899
|
return [...candidates].sort((left, right) => priority[left.kind] - priority[right.kind]);
|
|
855
900
|
}
|
|
856
901
|
|
|
902
|
+
async function loadPiProfilesQuiet() {
|
|
903
|
+
try {
|
|
904
|
+
const inventory = await runCapture(piProfileManager.binary, [
|
|
905
|
+
...piProfileManager.prefixArgs,
|
|
906
|
+
"profiles", "list", "--json",
|
|
907
|
+
]);
|
|
908
|
+
return parsePiProfileInventory(inventory.stdout);
|
|
909
|
+
} catch {
|
|
910
|
+
return [];
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
857
914
|
async function loadUpdateInventory(commandOptions, deepScanRoots) {
|
|
858
915
|
const registry = await withSpinner(
|
|
859
916
|
ui("loadingRegistry"),
|
|
@@ -1008,11 +1065,15 @@ async function updateAll(commandOptions, allowBack = false) {
|
|
|
1008
1065
|
printSection(ui("updateAllPreview"));
|
|
1009
1066
|
for (const candidate of selected) {
|
|
1010
1067
|
process.stdout.write(`\n${colorText(candidate.label, "target")}\n`);
|
|
1011
|
-
|
|
1068
|
+
for (const plan of updateAllCommandPlans(candidate, channel)) {
|
|
1069
|
+
if (plan.preview) await runAkCommand(plan.preview, candidate);
|
|
1070
|
+
}
|
|
1012
1071
|
}
|
|
1013
1072
|
printSection(ui("updateAllApplyPlan"));
|
|
1014
1073
|
for (const candidate of selected) {
|
|
1015
|
-
|
|
1074
|
+
for (const plan of updateAllCommandPlans(candidate, channel)) {
|
|
1075
|
+
printPlan(plan.apply, null, candidate.envOverrides);
|
|
1076
|
+
}
|
|
1016
1077
|
}
|
|
1017
1078
|
if (commandOptions.dryRun) {
|
|
1018
1079
|
process.stdout.write(`\n${ui("dryRunFiles")}\n`);
|
|
@@ -1028,7 +1089,9 @@ async function updateAll(commandOptions, allowBack = false) {
|
|
|
1028
1089
|
total: selected.length,
|
|
1029
1090
|
label: candidate.label,
|
|
1030
1091
|
})}\n`);
|
|
1031
|
-
|
|
1092
|
+
for (const plan of updateAllCommandPlans(candidate, channel)) {
|
|
1093
|
+
await runAkCommand(plan.apply, candidate);
|
|
1094
|
+
}
|
|
1032
1095
|
}
|
|
1033
1096
|
process.stdout.write(`${ui("updateAllComplete")}\n`);
|
|
1034
1097
|
return;
|
package/lib/args.mjs
CHANGED
|
@@ -4,10 +4,16 @@ export const COMMANDS = new Set([
|
|
|
4
4
|
export const INSTALL_TARGETS = new Set([
|
|
5
5
|
"claude-code", "codex", "cursor", "dsh", "grok", "omp", "pi",
|
|
6
6
|
]);
|
|
7
|
-
export const UPDATE_TARGETS = new Set([
|
|
7
|
+
export const UPDATE_TARGETS = new Set([
|
|
8
|
+
"claude-code", "codex", "cursor", "dsh", "grok", "omp", "pi",
|
|
9
|
+
]);
|
|
10
|
+
export const PROFILE_TARGETS = new Set(["pi-ak", "pi-omp"]);
|
|
11
|
+
export const PROFILE_RUNTIME = { "pi-ak": "pi", "pi-omp": "omp" };
|
|
12
|
+
export const HELPER_INSTALL_TARGETS = new Set([...INSTALL_TARGETS, ...PROFILE_TARGETS]);
|
|
13
|
+
export const HELPER_UPDATE_TARGETS = new Set([...UPDATE_TARGETS, ...PROFILE_TARGETS]);
|
|
8
14
|
export const EXPORT_TARGETS = new Set(["agy", "portable"]);
|
|
9
|
-
export const RUNTIME_TARGETS = new Set([...
|
|
10
|
-
export const KNOWN_TARGETS = new Set([...
|
|
15
|
+
export const RUNTIME_TARGETS = new Set([...HELPER_INSTALL_TARGETS]);
|
|
16
|
+
export const KNOWN_TARGETS = new Set([...HELPER_INSTALL_TARGETS, ...EXPORT_TARGETS]);
|
|
11
17
|
export const CHANNELS = new Set(["stable", "beta"]);
|
|
12
18
|
export const LANGUAGES = new Set(["vi", "en"]);
|
|
13
19
|
export const KITS = new Set(["engineer", "marketing"]);
|
|
@@ -21,6 +27,22 @@ export function targetSpecIsSupported(value, supportedTargets) {
|
|
|
21
27
|
return targets.length > 0 && targets.every((target) => supportedTargets.has(target));
|
|
22
28
|
}
|
|
23
29
|
|
|
30
|
+
export function specHasProfileTarget(value) {
|
|
31
|
+
return splitTargetSpec(value).some((target) => PROFILE_TARGETS.has(target));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function helperRuntimeTargets({ command, global = false } = {}) {
|
|
35
|
+
const base = command === "update" ? UPDATE_TARGETS : INSTALL_TARGETS;
|
|
36
|
+
return global ? new Set([...base, ...PROFILE_TARGETS]) : new Set(base);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function assertProfileTargetsAreGlobal(options) {
|
|
40
|
+
const selectedTarget = options.target || options.runtime;
|
|
41
|
+
if (specHasProfileTarget(selectedTarget) && options.project) {
|
|
42
|
+
throw new Error("pi-ak and pi-omp are global profile targets; use --global");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
24
46
|
export function validateForCommand(options) {
|
|
25
47
|
const selectedTarget = options.target || options.runtime;
|
|
26
48
|
const hasDiscoveryOptions = options.deepScanRoots.length > 0 ||
|
|
@@ -36,18 +58,20 @@ export function validateForCommand(options) {
|
|
|
36
58
|
return;
|
|
37
59
|
}
|
|
38
60
|
if (options.command === "install") {
|
|
39
|
-
if (selectedTarget && !targetSpecIsSupported(selectedTarget,
|
|
61
|
+
if (selectedTarget && !targetSpecIsSupported(selectedTarget, HELPER_INSTALL_TARGETS)) {
|
|
40
62
|
throw new Error(`target ${selectedTarget} is export-only; use the export command`);
|
|
41
63
|
}
|
|
64
|
+
assertProfileTargetsAreGlobal(options);
|
|
42
65
|
if (options.out) throw new Error("--out is valid only with export");
|
|
43
66
|
if (options.allowDowngrade) throw new Error("--allow-downgrade is valid only with self-update or update --binary-only");
|
|
44
67
|
if (hasDiscoveryOptions) throw new Error("deep scan options are valid only with update-all");
|
|
45
68
|
return;
|
|
46
69
|
}
|
|
47
70
|
if (options.command === "update") {
|
|
48
|
-
if (selectedTarget && !targetSpecIsSupported(selectedTarget,
|
|
71
|
+
if (selectedTarget && !targetSpecIsSupported(selectedTarget, HELPER_UPDATE_TARGETS)) {
|
|
49
72
|
throw new Error(`target ${selectedTarget} is not supported by ak update`);
|
|
50
73
|
}
|
|
74
|
+
assertProfileTargetsAreGlobal(options);
|
|
51
75
|
if (options.out) throw new Error("--out is valid only with export");
|
|
52
76
|
if (options.allowDowngrade && !options.binaryOnly) {
|
|
53
77
|
throw new Error("--allow-downgrade requires update --binary-only");
|
package/lib/commands.mjs
CHANGED
|
@@ -51,6 +51,42 @@ export function updateApplyArgs(selection) {
|
|
|
51
51
|
return [...updateBase(selection), "--yes", "--verbose"];
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export function usesKitRefresh(runtime) {
|
|
55
|
+
return runtime === "dsh";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function kitRefreshArgs({
|
|
59
|
+
global, kit = "engineer", channel, target = "dsh",
|
|
60
|
+
}) {
|
|
61
|
+
return [
|
|
62
|
+
"kit",
|
|
63
|
+
"refresh",
|
|
64
|
+
kit,
|
|
65
|
+
"--target",
|
|
66
|
+
target,
|
|
67
|
+
...(global ? ["--global"] : []),
|
|
68
|
+
"--channel",
|
|
69
|
+
channel,
|
|
70
|
+
"--yes",
|
|
71
|
+
"--verbose",
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function updatePreviewArgsForRuntime(selection) {
|
|
76
|
+
return usesKitRefresh(selection.target) ? null : updatePreviewArgs(selection);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function updateApplyArgsForRuntime(selection) {
|
|
80
|
+
return usesKitRefresh(selection.target) ? kitRefreshArgs(selection) : updateApplyArgs(selection);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function splitRuntimesForUpdate(runtimes) {
|
|
84
|
+
return {
|
|
85
|
+
update: runtimes.filter((runtime) => !usesKitRefresh(runtime)),
|
|
86
|
+
refresh: runtimes.filter((runtime) => usesKitRefresh(runtime)),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
54
90
|
export function selfUpdateCheckArgs(channel) {
|
|
55
91
|
return ["self-update", "--check", "--channel", channel];
|
|
56
92
|
}
|
package/lib/i18n.mjs
CHANGED
|
@@ -32,7 +32,9 @@ const messages = {
|
|
|
32
32
|
targetPrompt: "Which coding runtimes should receive {kit}?",
|
|
33
33
|
updateTargetPrompt: "Which installed runtimes should update {kit}?",
|
|
34
34
|
allRuntimes: "All supported runtimes",
|
|
35
|
-
|
|
35
|
+
piAkProfile: "pi-ak (Pi profile)",
|
|
36
|
+
piOmpProfile: "pi-omp (OMP profile)",
|
|
37
|
+
profileTargetsNeedGlobal: "pi-ak and pi-omp are global profile targets; use --global",
|
|
36
38
|
exportTargetPrompt: "Export creates a copy; it does not install a runtime. Choose a format:",
|
|
37
39
|
savedTargetNeedsUpdateRuntime: "Saved project target {target} is install-only. Update supports {supported}. Re-run with --runtime <target> or choose interactively.",
|
|
38
40
|
agyExport: "agy (global-only export)",
|
|
@@ -167,7 +169,9 @@ const messages = {
|
|
|
167
169
|
targetPrompt: "Các runtime nào sẽ nhận {kit}?",
|
|
168
170
|
updateTargetPrompt: "Các runtime nào sẽ cập nhật {kit}?",
|
|
169
171
|
allRuntimes: "Tất cả runtime được hỗ trợ",
|
|
170
|
-
|
|
172
|
+
piAkProfile: "pi-ak (profile Pi)",
|
|
173
|
+
piOmpProfile: "pi-omp (profile OMP)",
|
|
174
|
+
profileTargetsNeedGlobal: "pi-ak và pi-omp là profile global; dùng --global",
|
|
171
175
|
exportTargetPrompt: "Export tạo một bản sao, không cài vào runtime. Chọn dạng export:",
|
|
172
176
|
savedTargetNeedsUpdateRuntime: "Target đã lưu của project là {target} và chỉ dùng cho install. Update chỉ hỗ trợ {supported}. Hãy chạy lại với --runtime <target> hoặc chọn lại trong chế độ interactive.",
|
|
173
177
|
agyExport: "agy (chỉ export global)",
|
package/lib/pi-profiles.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { extname, isAbsolute, resolve, win32 } from "node:path";
|
|
3
|
+
import { extname, isAbsolute, join, resolve, win32 } from "node:path";
|
|
4
|
+
import { PROFILE_RUNTIME } from "./args.mjs";
|
|
4
5
|
|
|
5
6
|
function validPath(value) {
|
|
6
7
|
return typeof value === "string" && (isAbsolute(value) || win32.isAbsolute(value));
|
|
@@ -100,3 +101,46 @@ export function classifyPiProfiles(profiles) {
|
|
|
100
101
|
)),
|
|
101
102
|
};
|
|
102
103
|
}
|
|
104
|
+
|
|
105
|
+
export function isProfileTarget(target) {
|
|
106
|
+
return Object.hasOwn(PROFILE_RUNTIME, target);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function akRuntimeForHelperTarget(target) {
|
|
110
|
+
return PROFILE_RUNTIME[target] || target;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function defaultProfileProcessOptions(id, { home = homedir() } = {}) {
|
|
114
|
+
if (id === "pi-ak") {
|
|
115
|
+
const agentDir = join(home, ".pi", "profiles", "pi-ak");
|
|
116
|
+
return piProfileProcessOptions({
|
|
117
|
+
runtime: "pi", agentDir, sessionDir: join(agentDir, "sessions"),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (id === "pi-omp") {
|
|
121
|
+
return piProfileProcessOptions({
|
|
122
|
+
runtime: "omp",
|
|
123
|
+
agentDir: join(home, ".omp", "profiles", "pi-omp", "agent"),
|
|
124
|
+
sessionDir: null,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return { envOverrides: {}, envUnset: [] };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function resolveProfileProcessOptions(id, profiles = [], { home = homedir() } = {}) {
|
|
131
|
+
const found = profiles.find((profile) => profile.id === id);
|
|
132
|
+
return found ? piProfileProcessOptions(found) : defaultProfileProcessOptions(id, { home });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function materializeHelperTarget(selection, profiles = [], { home = homedir() } = {}) {
|
|
136
|
+
const helperTarget = selection.target;
|
|
137
|
+
const env = isProfileTarget(helperTarget)
|
|
138
|
+
? resolveProfileProcessOptions(helperTarget, profiles, { home })
|
|
139
|
+
: { envOverrides: {}, envUnset: [] };
|
|
140
|
+
return {
|
|
141
|
+
...selection,
|
|
142
|
+
helperTarget,
|
|
143
|
+
target: akRuntimeForHelperTarget(helperTarget),
|
|
144
|
+
...env,
|
|
145
|
+
};
|
|
146
|
+
}
|