@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 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>
@@ -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
- INSTALL_TARGETS,
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
- updateApplyArgs,
31
- updatePreviewArgs,
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 (dsh: unsupported)
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 (dsh: unsupported)
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) => ({ label: target, value: 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, INSTALL_TARGETS, "targetPrompt", routeCanGoBack, allowBack,
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), { cwd });
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, { cwd });
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, UPDATE_TARGETS, "updateTargetPrompt", routeCanGoBack, allowBack,
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
- const updateSelections = selection.global
718
- ? [selection]
719
- : splitTargetSpec(selection.target).map((target) => ({ ...selection, target }));
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.target, "target")}\n`);
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(updateApplyArgs(targetSelection), targetSelection.project);
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(updateApplyArgs(targetSelection), {
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 updateAllPreviewArgs(candidate, channel) {
760
- if (candidate.kind === "global" || candidate.kind === "profile") {
761
- return globalUpdatePreviewArgs(channel, candidate.runtimes, candidate.kit);
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
- return projectUpdatePreviewArgs(candidate.path, candidate.runtime, channel, candidate.kit);
764
- }
765
-
766
- function updateAllApplyArgs(candidate, channel) {
767
- if (candidate.kind === "global" || candidate.kind === "profile") {
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 projectUpdateApplyArgs(candidate.path, candidate.runtime, channel, candidate.kit);
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
- await runAkCommand(updateAllPreviewArgs(candidate, channel), candidate);
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
- printPlan(updateAllApplyArgs(candidate, channel), null, candidate.envOverrides);
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
- await runAkCommand(updateAllApplyArgs(candidate, channel), candidate);
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(["claude-code", "codex", "cursor", "grok", "omp", "pi"]);
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([...INSTALL_TARGETS]);
10
- export const KNOWN_TARGETS = new Set([...INSTALL_TARGETS, ...EXPORT_TARGETS]);
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, INSTALL_TARGETS)) {
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, UPDATE_TARGETS)) {
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
- dshUpdateUnsupported: "dsh not supported by ak update",
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
- dshUpdateUnsupported: "dsh — ak update chưa hỗ trợ",
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)",
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thieung/agentkit-helper",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Community helper for installing and updating AgentKit kits by runtime and channel",
5
5
  "type": "module",
6
6
  "bin": {