@nalvietnam/avatar-cli 1.7.1 → 1.9.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,6 +1297,11 @@ 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;
|
|
@@ -2308,7 +2313,7 @@ function registerGitnexusCommand(program2) {
|
|
|
2308
2313
|
// src/commands/init.ts
|
|
2309
2314
|
import { basename, join as join24, relative as relative3, resolve } from "path";
|
|
2310
2315
|
import { confirm as confirm5, input as input5, select as select9 } from "@inquirer/prompts";
|
|
2311
|
-
import
|
|
2316
|
+
import boxen6 from "boxen";
|
|
2312
2317
|
|
|
2313
2318
|
// src/lib/add-team-pack-submodule-with-retry-on-network-fail.ts
|
|
2314
2319
|
import { spawnSync as spawnSync13 } from "child_process";
|
|
@@ -3196,6 +3201,42 @@ function linkExistingRemoteToWorkspace(args) {
|
|
|
3196
3201
|
return { sshUrl, httpsUrl };
|
|
3197
3202
|
}
|
|
3198
3203
|
|
|
3204
|
+
// src/lib/format-pack-commands-cheatsheet-box.ts
|
|
3205
|
+
import boxen4 from "boxen";
|
|
3206
|
+
var PACK_COMMAND_CHEATSHEET = [
|
|
3207
|
+
{ cmd: "/avatar:help", desc: "H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng Avatar \u2014 ch\u1EC9 c\u1EA7n g\xF5 t\u1EF1 nhi\xEAn" },
|
|
3208
|
+
{ cmd: "/avatar:brainstorm", desc: "Brainstorm \xFD t\u01B0\u1EDFng cho m\u1ED9t feature" },
|
|
3209
|
+
{ cmd: "/avatar:plan", desc: "T\u1EA1o plan th\xF4ng minh v\u1EDBi prompt enhancement" },
|
|
3210
|
+
{ cmd: "/avatar:scout", desc: "T\xECm file li\xEAn quan trong codebase, ti\u1EBFt ki\u1EC7m token" },
|
|
3211
|
+
{ cmd: "/avatar:implement", desc: "B\u1EAFt \u0111\u1EA7u code & test theo plan c\xF3 s\u1EB5n" },
|
|
3212
|
+
{ cmd: "/avatar:build-full-flow", desc: "Implement m\u1ED9t feature t\u1EEBng b\u01B0\u1EDBc (end-to-end)" },
|
|
3213
|
+
{ cmd: "/avatar:fix", desc: "Ph\xE2n t\xEDch v\xE0 fix v\u1EA5n \u0111\u1EC1 t\u1EF1 \u0111i\u1EC1u h\u01B0\u1EDBng" },
|
|
3214
|
+
{ cmd: "/avatar:debug", desc: "Debug v\u1EA5n \u0111\u1EC1 k\u1EF9 thu\u1EADt + \u0111\u01B0a ra gi\u1EA3i ph\xE1p" },
|
|
3215
|
+
{ cmd: "/avatar:test", desc: "Ch\u1EA1y test tr\xEAn m\xE1y + ph\xE2n t\xEDch b\xE1o c\xE1o t\u1ED5ng h\u1EE3p" },
|
|
3216
|
+
{ cmd: "/avatar:design:good", desc: "T\u1EA1o thi\u1EBFt k\u1EBF ch\u1EC9n chu, s\u1ED1ng \u0111\u1ED9ng" },
|
|
3217
|
+
{ cmd: "/avatar:docs:init", desc: "Ph\xE2n t\xEDch codebase + t\u1EA1o t\xE0i li\u1EC7u kh\u1EDFi \u0111\u1EA7u" },
|
|
3218
|
+
{ cmd: "/avatar:status", desc: "Xem l\u1EA1i thay \u0111\u1ED5i g\u1EA7n \u0111\xE2y + t\u1ED5ng k\u1EBFt c\xF4ng vi\u1EC7c" },
|
|
3219
|
+
{ cmd: "/avatar:journal", desc: "Ghi nh\u1EADt k\xFD session" }
|
|
3220
|
+
];
|
|
3221
|
+
function formatPackCommandsCheatsheetBox() {
|
|
3222
|
+
const maxCmdWidth = Math.max(...PACK_COMMAND_CHEATSHEET.map((e) => e.cmd.length));
|
|
3223
|
+
const header = chalk.bold("\u{1F3AF} Slash commands t\u1EEB team-ai-pack");
|
|
3224
|
+
const subheader = chalk.dim("G\xF5 trong Claude Code session \u0111\u1EC3 g\u1ECDi capability c\u1EE7a pack:");
|
|
3225
|
+
const lines = PACK_COMMAND_CHEATSHEET.map((e) => {
|
|
3226
|
+
const cmdPadded = chalk.cyan(e.cmd.padEnd(maxCmdWidth));
|
|
3227
|
+
return ` ${cmdPadded} ${chalk.dim(e.desc)}`;
|
|
3228
|
+
});
|
|
3229
|
+
const footer = chalk.dim(
|
|
3230
|
+
"Catalog \u0111\u1EA7y \u0111\u1EE7 46 commands: cat .claude/pack/scripts/commands_data.yaml"
|
|
3231
|
+
);
|
|
3232
|
+
const content = [header, subheader, "", ...lines, "", footer].join("\n");
|
|
3233
|
+
return boxen4(content, {
|
|
3234
|
+
padding: 1,
|
|
3235
|
+
borderStyle: "round",
|
|
3236
|
+
borderColor: "cyan"
|
|
3237
|
+
});
|
|
3238
|
+
}
|
|
3239
|
+
|
|
3199
3240
|
// src/lib/merge-pack-settings-into-project-settings.ts
|
|
3200
3241
|
import { promises as fs9 } from "fs";
|
|
3201
3242
|
import { join as join17 } from "path";
|
|
@@ -3756,7 +3797,7 @@ function buildScaffoldVariables(args) {
|
|
|
3756
3797
|
}
|
|
3757
3798
|
|
|
3758
3799
|
// src/commands/login.ts
|
|
3759
|
-
import
|
|
3800
|
+
import boxen5 from "boxen";
|
|
3760
3801
|
import open from "open";
|
|
3761
3802
|
|
|
3762
3803
|
// src/lib/google-oauth-device-flow.ts
|
|
@@ -3903,7 +3944,7 @@ async function runLogin(opts) {
|
|
|
3903
3944
|
"",
|
|
3904
3945
|
`Ho\u1EB7c Avatar t\u1EF1 m\u1EDF browser, click ${chalk.green("Allow")}...`
|
|
3905
3946
|
].join("\n");
|
|
3906
|
-
process.stdout.write(`${
|
|
3947
|
+
process.stdout.write(`${boxen5(instructions, { padding: 1, borderStyle: "round" })}
|
|
3907
3948
|
`);
|
|
3908
3949
|
void open(verificationUrl).catch(() => {
|
|
3909
3950
|
log.dim("(Kh\xF4ng m\u1EDF \u0111\u01B0\u1EE3c browser t\u1EF1 \u0111\u1ED9ng \u2014 copy URL \u1EDF tr\xEAn)");
|
|
@@ -4300,7 +4341,7 @@ async function finalizeWorkspaceScaffold(args) {
|
|
|
4300
4341
|
await writeRootClaudeMd(args.workspacePath, updatedVars);
|
|
4301
4342
|
log.dim("Updated CLAUDE.md v\u1EDBi GitNexus section");
|
|
4302
4343
|
}
|
|
4303
|
-
printInitSuccessBox(args.workspacePath, args.flow, aiResult, gitnexusResult);
|
|
4344
|
+
await printInitSuccessBox(args.workspacePath, args.flow, aiResult, gitnexusResult);
|
|
4304
4345
|
}
|
|
4305
4346
|
async function autoSyncPackOnInit(workspacePath) {
|
|
4306
4347
|
const packDir = join24(workspacePath, TEAM_PACK_RELATIVE_PATH);
|
|
@@ -4494,7 +4535,7 @@ function formatGitnexusStatusLine(result) {
|
|
|
4494
4535
|
}
|
|
4495
4536
|
return ` ${chalk.yellow("GitNexus:")} skipped (${(result.reason ?? "unknown").slice(0, 40)}) \xB7 th\u1EED ${chalk.cyan("avatar gitnexus install")}`;
|
|
4496
4537
|
}
|
|
4497
|
-
function printInitSuccessBox(rootPath, flow, aiResult = null, gitnexusResult = null) {
|
|
4538
|
+
async function printInitSuccessBox(rootPath, flow, aiResult = null, gitnexusResult = null) {
|
|
4498
4539
|
const lines = [
|
|
4499
4540
|
`${chalk.green("\u2713")} Workspace s\u1EB5n s\xE0ng: ${relative3(process.cwd(), rootPath) || rootPath}`,
|
|
4500
4541
|
` ${chalk.dim(`(flow: ${flow})`)}`,
|
|
@@ -4508,8 +4549,14 @@ function printInitSuccessBox(rootPath, flow, aiResult = null, gitnexusResult = n
|
|
|
4508
4549
|
` ${chalk.cyan("avatar sync")} Pull team-ai-pack m\u1EDBi`,
|
|
4509
4550
|
` ${chalk.cyan("avatar uninstall")} G\u1EE1 Avatar (gi\u1EEF code)`
|
|
4510
4551
|
];
|
|
4511
|
-
process.stdout.write(`${
|
|
4552
|
+
process.stdout.write(`${boxen6(lines.join("\n"), { padding: 1, borderStyle: "round" })}
|
|
4512
4553
|
`);
|
|
4554
|
+
const packDir = join24(rootPath, TEAM_PACK_RELATIVE_PATH);
|
|
4555
|
+
if (await pathExists(packDir)) {
|
|
4556
|
+
process.stdout.write(`
|
|
4557
|
+
${formatPackCommandsCheatsheetBox()}
|
|
4558
|
+
`);
|
|
4559
|
+
}
|
|
4513
4560
|
}
|
|
4514
4561
|
|
|
4515
4562
|
// src/lib/not-implemented-stub.ts
|
|
@@ -4561,7 +4608,7 @@ function registerSecretsCommand(program2) {
|
|
|
4561
4608
|
// src/commands/status.ts
|
|
4562
4609
|
import { promises as fs13 } from "fs";
|
|
4563
4610
|
import { join as join26 } from "path";
|
|
4564
|
-
import
|
|
4611
|
+
import boxen7 from "boxen";
|
|
4565
4612
|
|
|
4566
4613
|
// src/lib/pack-backup-manager.ts
|
|
4567
4614
|
import { promises as fs12 } from "fs";
|
|
@@ -4639,7 +4686,7 @@ function renderStatusBox(s) {
|
|
|
4639
4686
|
`${chalk.dim("Backups:")} ${s.backupCount}`,
|
|
4640
4687
|
`${chalk.dim("Tech stack:")} ${s.techStackSummary}`
|
|
4641
4688
|
];
|
|
4642
|
-
process.stdout.write(`${
|
|
4689
|
+
process.stdout.write(`${boxen7(lines.join("\n"), { padding: 1, borderStyle: "round" })}
|
|
4643
4690
|
`);
|
|
4644
4691
|
}
|
|
4645
4692
|
|
|
@@ -4689,6 +4736,7 @@ async function buildSyncPreview(packDir, claudeDir, targetVersion) {
|
|
|
4689
4736
|
}
|
|
4690
4737
|
|
|
4691
4738
|
// src/commands/sync.ts
|
|
4739
|
+
var DEFAULT_PACK_BRANCH = "main";
|
|
4692
4740
|
async function syncAction(opts) {
|
|
4693
4741
|
const projectRoot = process.cwd();
|
|
4694
4742
|
const claudeDir = join28(projectRoot, ".claude");
|
|
@@ -4708,16 +4756,23 @@ async function syncAction(opts) {
|
|
|
4708
4756
|
`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.`
|
|
4709
4757
|
);
|
|
4710
4758
|
}
|
|
4759
|
+
const useLatestMode = opts.latest === true && !opts.version;
|
|
4711
4760
|
const allTags = await listTags(packDir);
|
|
4712
|
-
|
|
4713
|
-
if (
|
|
4714
|
-
|
|
4715
|
-
|
|
4761
|
+
let targetVersion;
|
|
4762
|
+
if (useLatestMode) {
|
|
4763
|
+
targetVersion = `${DEFAULT_PACK_BRANCH} (HEAD)`;
|
|
4764
|
+
} else {
|
|
4765
|
+
const picked = opts.version ?? pickLatestStableSemVerTag(allTags);
|
|
4766
|
+
if (!picked) {
|
|
4767
|
+
log.error(
|
|
4768
|
+
`Kh\xF4ng t\xECm th\u1EA5y stable SemVer tag (vMAJOR.MINOR.PATCH) trong team-ai-pack submodule.
|
|
4716
4769
|
Tags hi\u1EC7n c\xF3: ${allTags.length > 0 ? allTags.join(", ") : "(none)"}
|
|
4717
|
-
Pass --version <tag> r\xF5 r\xE0ng, ho\u1EB7c
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4770
|
+
Pass --version <tag> r\xF5 r\xE0ng, ho\u1EB7c d\xF9ng --latest \u0111\u1EC3 pull HEAD branch ${DEFAULT_PACK_BRANCH}.`
|
|
4771
|
+
);
|
|
4772
|
+
process.exit(1);
|
|
4773
|
+
return;
|
|
4774
|
+
}
|
|
4775
|
+
targetVersion = picked;
|
|
4721
4776
|
}
|
|
4722
4777
|
if (opts.dryRun) {
|
|
4723
4778
|
const preview = await buildSyncPreview(packDir, claudeDir, targetVersion);
|
|
@@ -4741,8 +4796,18 @@ async function syncAction(opts) {
|
|
|
4741
4796
|
log.info("\nDry-run done. Kh\xF4ng apply thay \u0111\u1ED5i. B\u1ECF --dry-run \u0111\u1EC3 th\u1EF1c thi.");
|
|
4742
4797
|
return;
|
|
4743
4798
|
}
|
|
4744
|
-
|
|
4745
|
-
|
|
4799
|
+
if (useLatestMode) {
|
|
4800
|
+
log.info(`Pulling HEAD c\u1EE7a branch ${DEFAULT_PACK_BRANCH} (bleeding-edge mode)...`);
|
|
4801
|
+
await checkoutBranchHeadInSubmodule(TEAM_PACK_RELATIVE_PATH, DEFAULT_PACK_BRANCH, projectRoot);
|
|
4802
|
+
const sha = await currentCommitSha(packDir);
|
|
4803
|
+
log.dim(` HEAD = ${sha.slice(0, 7)}`);
|
|
4804
|
+
log.warn(
|
|
4805
|
+
"\u26A0 --latest mode: workspace pin v\xE0o commit floating, kh\xF4ng reproducible. Chuy\u1EC3n v\u1EC1 tag stable: avatar sync (no flag)."
|
|
4806
|
+
);
|
|
4807
|
+
} else {
|
|
4808
|
+
log.info(`Checking out ${targetVersion} trong submodule...`);
|
|
4809
|
+
await checkoutTagInSubmodule(TEAM_PACK_RELATIVE_PATH, targetVersion, projectRoot);
|
|
4810
|
+
}
|
|
4746
4811
|
log.info("Creating symlink farm...");
|
|
4747
4812
|
const results = await syncAllMountDirs(packDir, claudeDir, opts.force === true);
|
|
4748
4813
|
reportResults(results, opts.force === true);
|
|
@@ -4799,7 +4864,7 @@ function reportResults(results, force) {
|
|
|
4799
4864
|
}
|
|
4800
4865
|
}
|
|
4801
4866
|
function registerSyncCommand(program2) {
|
|
4802
|
-
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);
|
|
4867
|
+
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);
|
|
4803
4868
|
}
|
|
4804
4869
|
|
|
4805
4870
|
// src/commands/tools.ts
|
|
@@ -4813,7 +4878,7 @@ function registerToolsCommand(program2) {
|
|
|
4813
4878
|
// src/commands/uninstall.ts
|
|
4814
4879
|
import { relative as relative4 } from "path";
|
|
4815
4880
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
4816
|
-
import
|
|
4881
|
+
import boxen8 from "boxen";
|
|
4817
4882
|
|
|
4818
4883
|
// src/lib/create-uninstall-backup-snapshot.ts
|
|
4819
4884
|
import { cp, mkdir, writeFile } from "fs/promises";
|
|
@@ -4967,7 +5032,7 @@ async function removeSubmoduleEntry(gitmodulesPath, submodulePath) {
|
|
|
4967
5032
|
}
|
|
4968
5033
|
|
|
4969
5034
|
// src/commands/uninstall.ts
|
|
4970
|
-
var CLI_VERSION = "1.
|
|
5035
|
+
var CLI_VERSION = "1.9.0";
|
|
4971
5036
|
function registerUninstallCommand(program2) {
|
|
4972
5037
|
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) => {
|
|
4973
5038
|
try {
|
|
@@ -5044,12 +5109,12 @@ function printUninstallSuccessBox(backupPath) {
|
|
|
5044
5109
|
lines.push(` ${chalk.dim("Backup:")} ${backupPath}`);
|
|
5045
5110
|
lines.push(` ${chalk.dim("Restore:")} ${chalk.cyan(`cp -r "${backupPath}"/* .`)}`);
|
|
5046
5111
|
}
|
|
5047
|
-
process.stdout.write(`${
|
|
5112
|
+
process.stdout.write(`${boxen8(lines.join("\n"), { padding: 1, borderStyle: "round" })}
|
|
5048
5113
|
`);
|
|
5049
5114
|
}
|
|
5050
5115
|
|
|
5051
5116
|
// src/index.ts
|
|
5052
|
-
var CLI_VERSION2 = "1.
|
|
5117
|
+
var CLI_VERSION2 = "1.9.0";
|
|
5053
5118
|
var program = new Command();
|
|
5054
5119
|
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(
|
|
5055
5120
|
"beforeAll",
|