@nalvietnam/avatar-cli 1.7.0 → 1.8.0
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/dist/index.js
CHANGED
|
@@ -1297,13 +1297,22 @@ async function checkoutTagInSubmodule(submodulePath, tag, cwd = process.cwd()) {
|
|
|
1297
1297
|
await git(submoduleCwd).fetch(["--tags"]);
|
|
1298
1298
|
await git(submoduleCwd).checkout(tag);
|
|
1299
1299
|
}
|
|
1300
|
+
async function checkoutBranchHeadInSubmodule(submodulePath, branch, cwd = process.cwd()) {
|
|
1301
|
+
const submoduleCwd = join8(cwd, submodulePath);
|
|
1302
|
+
await git(submoduleCwd).fetch(["origin"]);
|
|
1303
|
+
await git(submoduleCwd).checkout(["-B", branch, `origin/${branch}`]);
|
|
1304
|
+
}
|
|
1300
1305
|
async function listTags(cwd = process.cwd()) {
|
|
1301
1306
|
const result = await git(cwd).tags();
|
|
1302
1307
|
return result.all;
|
|
1303
1308
|
}
|
|
1304
|
-
async function
|
|
1305
|
-
|
|
1306
|
-
|
|
1309
|
+
async function tagAtHead(cwd = process.cwd()) {
|
|
1310
|
+
try {
|
|
1311
|
+
const result = await git(cwd).raw(["describe", "--tags", "--exact-match", "HEAD"]);
|
|
1312
|
+
return result.trim() || null;
|
|
1313
|
+
} catch {
|
|
1314
|
+
return null;
|
|
1315
|
+
}
|
|
1307
1316
|
}
|
|
1308
1317
|
async function currentCommitSha(cwd = process.cwd()) {
|
|
1309
1318
|
const result = await git(cwd).revparse(["HEAD"]);
|
|
@@ -2430,6 +2439,31 @@ async function ensureTeamPackAccessWithRetry(args) {
|
|
|
2430
2439
|
}
|
|
2431
2440
|
}
|
|
2432
2441
|
|
|
2442
|
+
// src/lib/pick-latest-stable-semver-tag.ts
|
|
2443
|
+
var SEMVER_REGEX3 = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
2444
|
+
function parseSemVerTag(tag) {
|
|
2445
|
+
const match = tag.match(SEMVER_REGEX3);
|
|
2446
|
+
if (!match) return null;
|
|
2447
|
+
const [, major, minor, patch, prerelease] = match;
|
|
2448
|
+
return {
|
|
2449
|
+
raw: tag,
|
|
2450
|
+
major: Number.parseInt(major ?? "0", 10),
|
|
2451
|
+
minor: Number.parseInt(minor ?? "0", 10),
|
|
2452
|
+
patch: Number.parseInt(patch ?? "0", 10),
|
|
2453
|
+
prerelease: prerelease ?? null
|
|
2454
|
+
};
|
|
2455
|
+
}
|
|
2456
|
+
function pickLatestStableSemVerTag(tags, includePrerelease = false) {
|
|
2457
|
+
const parsed = tags.map(parseSemVerTag).filter((t) => t !== null).filter((t) => includePrerelease || t.prerelease === null);
|
|
2458
|
+
if (parsed.length === 0) return null;
|
|
2459
|
+
parsed.sort((a, b) => {
|
|
2460
|
+
if (a.major !== b.major) return a.major - b.major;
|
|
2461
|
+
if (a.minor !== b.minor) return a.minor - b.minor;
|
|
2462
|
+
return a.patch - b.patch;
|
|
2463
|
+
});
|
|
2464
|
+
return parsed[parsed.length - 1]?.raw ?? null;
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2433
2467
|
// src/lib/resolve-team-pack-repo-url.ts
|
|
2434
2468
|
var ORG_DEFAULT = "git@github.com:nalvn/team-ai-pack.git";
|
|
2435
2469
|
function resolveTeamPackRepoUrl() {
|
|
@@ -2476,7 +2510,9 @@ async function addTeamPackSubmodule(projectRoot, tag, ssoEmail) {
|
|
|
2476
2510
|
}
|
|
2477
2511
|
let target = tag ?? null;
|
|
2478
2512
|
if (!target) {
|
|
2479
|
-
|
|
2513
|
+
const submoduleDir = join16(projectRoot, TEAM_PACK_RELATIVE_PATH);
|
|
2514
|
+
const allTags = await listTags(submoduleDir);
|
|
2515
|
+
target = pickLatestStableSemVerTag(allTags);
|
|
2480
2516
|
}
|
|
2481
2517
|
if (target) {
|
|
2482
2518
|
await checkoutTagInSubmodule(TEAM_PACK_RELATIVE_PATH, target, projectRoot);
|
|
@@ -2485,7 +2521,7 @@ async function addTeamPackSubmodule(projectRoot, tag, ssoEmail) {
|
|
|
2485
2521
|
}
|
|
2486
2522
|
async function readPinnedPackVersion(projectRoot) {
|
|
2487
2523
|
const submoduleRoot = join16(projectRoot, TEAM_PACK_RELATIVE_PATH);
|
|
2488
|
-
const tag = await
|
|
2524
|
+
const tag = await tagAtHead(submoduleRoot);
|
|
2489
2525
|
if (tag) return tag;
|
|
2490
2526
|
const sha = await currentCommitSha(submoduleRoot);
|
|
2491
2527
|
return sha.slice(0, 7);
|
|
@@ -4636,9 +4672,11 @@ async function listCommitsBetween(packDir, fromSha, toRef) {
|
|
|
4636
4672
|
}
|
|
4637
4673
|
}
|
|
4638
4674
|
async function buildSyncPreview(packDir, claudeDir, targetVersion) {
|
|
4675
|
+
const currentTagOrNull = await tagAtHead(packDir);
|
|
4639
4676
|
const currentSha = await currentCommitSha(packDir);
|
|
4640
|
-
const currentVersion = currentSha.slice(0, 7);
|
|
4641
|
-
const
|
|
4677
|
+
const currentVersion = currentTagOrNull ?? currentSha.slice(0, 7);
|
|
4678
|
+
const allTags = await listTags(packDir);
|
|
4679
|
+
const target = targetVersion ?? pickLatestStableSemVerTag(allTags) ?? "HEAD";
|
|
4642
4680
|
const commits = await listCommitsBetween(packDir, currentSha, target);
|
|
4643
4681
|
const mountStatuses = [];
|
|
4644
4682
|
for (const dir of TEAM_PACK_MOUNT_DIRS) {
|
|
@@ -4656,6 +4694,7 @@ async function buildSyncPreview(packDir, claudeDir, targetVersion) {
|
|
|
4656
4694
|
}
|
|
4657
4695
|
|
|
4658
4696
|
// src/commands/sync.ts
|
|
4697
|
+
var DEFAULT_PACK_BRANCH = "main";
|
|
4659
4698
|
async function syncAction(opts) {
|
|
4660
4699
|
const projectRoot = process.cwd();
|
|
4661
4700
|
const claudeDir = join28(projectRoot, ".claude");
|
|
@@ -4675,13 +4714,23 @@ async function syncAction(opts) {
|
|
|
4675
4714
|
`Kh\xF4ng fetch \u0111\u01B0\u1EE3c tags t\u1EEB origin (${err instanceof Error ? err.message : err}). S\u1EBD d\xF9ng tag local hi\u1EC7n c\xF3.`
|
|
4676
4715
|
);
|
|
4677
4716
|
}
|
|
4678
|
-
const
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
)
|
|
4683
|
-
|
|
4684
|
-
|
|
4717
|
+
const useLatestMode = opts.latest === true && !opts.version;
|
|
4718
|
+
const allTags = await listTags(packDir);
|
|
4719
|
+
let targetVersion;
|
|
4720
|
+
if (useLatestMode) {
|
|
4721
|
+
targetVersion = `${DEFAULT_PACK_BRANCH} (HEAD)`;
|
|
4722
|
+
} else {
|
|
4723
|
+
const picked = opts.version ?? pickLatestStableSemVerTag(allTags);
|
|
4724
|
+
if (!picked) {
|
|
4725
|
+
log.error(
|
|
4726
|
+
`Kh\xF4ng t\xECm th\u1EA5y stable SemVer tag (vMAJOR.MINOR.PATCH) trong team-ai-pack submodule.
|
|
4727
|
+
Tags hi\u1EC7n c\xF3: ${allTags.length > 0 ? allTags.join(", ") : "(none)"}
|
|
4728
|
+
Pass --version <tag> r\xF5 r\xE0ng, ho\u1EB7c d\xF9ng --latest \u0111\u1EC3 pull HEAD branch ${DEFAULT_PACK_BRANCH}.`
|
|
4729
|
+
);
|
|
4730
|
+
process.exit(1);
|
|
4731
|
+
return;
|
|
4732
|
+
}
|
|
4733
|
+
targetVersion = picked;
|
|
4685
4734
|
}
|
|
4686
4735
|
if (opts.dryRun) {
|
|
4687
4736
|
const preview = await buildSyncPreview(packDir, claudeDir, targetVersion);
|
|
@@ -4705,8 +4754,18 @@ async function syncAction(opts) {
|
|
|
4705
4754
|
log.info("\nDry-run done. Kh\xF4ng apply thay \u0111\u1ED5i. B\u1ECF --dry-run \u0111\u1EC3 th\u1EF1c thi.");
|
|
4706
4755
|
return;
|
|
4707
4756
|
}
|
|
4708
|
-
|
|
4709
|
-
|
|
4757
|
+
if (useLatestMode) {
|
|
4758
|
+
log.info(`Pulling HEAD c\u1EE7a branch ${DEFAULT_PACK_BRANCH} (bleeding-edge mode)...`);
|
|
4759
|
+
await checkoutBranchHeadInSubmodule(TEAM_PACK_RELATIVE_PATH, DEFAULT_PACK_BRANCH, projectRoot);
|
|
4760
|
+
const sha = await currentCommitSha(packDir);
|
|
4761
|
+
log.dim(` HEAD = ${sha.slice(0, 7)}`);
|
|
4762
|
+
log.warn(
|
|
4763
|
+
"\u26A0 --latest mode: workspace pin v\xE0o commit floating, kh\xF4ng reproducible. Chuy\u1EC3n v\u1EC1 tag stable: avatar sync (no flag)."
|
|
4764
|
+
);
|
|
4765
|
+
} else {
|
|
4766
|
+
log.info(`Checking out ${targetVersion} trong submodule...`);
|
|
4767
|
+
await checkoutTagInSubmodule(TEAM_PACK_RELATIVE_PATH, targetVersion, projectRoot);
|
|
4768
|
+
}
|
|
4710
4769
|
log.info("Creating symlink farm...");
|
|
4711
4770
|
const results = await syncAllMountDirs(packDir, claudeDir, opts.force === true);
|
|
4712
4771
|
reportResults(results, opts.force === true);
|
|
@@ -4763,7 +4822,7 @@ function reportResults(results, force) {
|
|
|
4763
4822
|
}
|
|
4764
4823
|
}
|
|
4765
4824
|
function registerSyncCommand(program2) {
|
|
4766
|
-
program2.command("sync").description("Pull team-ai-pack m\u1EDBi nh\u1EA5t + t\u1EA1o symlink farm v\xE0o .claude/").option("--force", "Override .claude/<dir>/ n\u1EBFu l\xE0 real dir (backup tr\u01B0\u1EDBc)").option("--version <tag>", "Pin v\xE0o version c\u1EE5 th\u1EC3 (vd: v0.2.0)").option("--dry-run", "Hi\u1EC3n th\u1ECB preview, kh\xF4ng apply thay \u0111\u1ED5i").action(syncAction);
|
|
4825
|
+
program2.command("sync").description("Pull team-ai-pack m\u1EDBi nh\u1EA5t + t\u1EA1o symlink farm v\xE0o .claude/").option("--force", "Override .claude/<dir>/ n\u1EBFu l\xE0 real dir (backup tr\u01B0\u1EDBc)").option("--version <tag>", "Pin v\xE0o version c\u1EE5 th\u1EC3 (vd: v0.2.0)").option("--latest", "Bleeding-edge: pull HEAD c\u1EE7a main branch (b\u1ECF qua tag SemVer)").option("--dry-run", "Hi\u1EC3n th\u1ECB preview, kh\xF4ng apply thay \u0111\u1ED5i").action(syncAction);
|
|
4767
4826
|
}
|
|
4768
4827
|
|
|
4769
4828
|
// src/commands/tools.ts
|
|
@@ -4931,7 +4990,7 @@ async function removeSubmoduleEntry(gitmodulesPath, submodulePath) {
|
|
|
4931
4990
|
}
|
|
4932
4991
|
|
|
4933
4992
|
// src/commands/uninstall.ts
|
|
4934
|
-
var CLI_VERSION = "1.
|
|
4993
|
+
var CLI_VERSION = "1.8.0";
|
|
4935
4994
|
function registerUninstallCommand(program2) {
|
|
4936
4995
|
program2.command("uninstall").description("G\u1EE1 Avatar kh\u1ECFi project \u2014 backup t\u1EF1 \u0111\u1ED9ng (M11)").option("--yes", "Skip confirm prompt").option("--no-backup", "Kh\xF4ng t\u1EA1o backup tr\u01B0\u1EDBc khi x\xF3a (nguy hi\u1EC3m)").option("--keep-submodule", "Gi\u1EEF submodule .claude/pack/").option("--keep-hooks", "Gi\u1EEF git hooks post-merge, pre-push").option("--dry-run", "Hi\u1EC3n th\u1ECB danh s\xE1ch s\u1EBD x\xF3a, kh\xF4ng th\u1EF1c thi").action(async (opts) => {
|
|
4937
4996
|
try {
|
|
@@ -5013,7 +5072,7 @@ function printUninstallSuccessBox(backupPath) {
|
|
|
5013
5072
|
}
|
|
5014
5073
|
|
|
5015
5074
|
// src/index.ts
|
|
5016
|
-
var CLI_VERSION2 = "1.
|
|
5075
|
+
var CLI_VERSION2 = "1.8.0";
|
|
5017
5076
|
var program = new Command();
|
|
5018
5077
|
program.name("avatar").description("AI harness CLI for NAL Vietnam engineering").version(CLI_VERSION2, "-v, --version", "Hi\u1EC3n th\u1ECB phi\xEAn b\u1EA3n Avatar CLI").addHelpText(
|
|
5019
5078
|
"beforeAll",
|