@zentao-hub/cli 0.1.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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/README.zh-CN.md +192 -0
  4. package/dist/agents.d.ts +62 -0
  5. package/dist/agents.js +202 -0
  6. package/dist/agents.js.map +1 -0
  7. package/dist/commands/init.d.ts +9 -0
  8. package/dist/commands/init.js +94 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/install-claude-md.d.ts +12 -0
  11. package/dist/commands/install-claude-md.js +25 -0
  12. package/dist/commands/install-claude-md.js.map +1 -0
  13. package/dist/commands/install-commands.d.ts +8 -0
  14. package/dist/commands/install-commands.js +27 -0
  15. package/dist/commands/install-commands.js.map +1 -0
  16. package/dist/commands/install-hooks.d.ts +7 -0
  17. package/dist/commands/install-hooks.js +31 -0
  18. package/dist/commands/install-hooks.js.map +1 -0
  19. package/dist/commands/install-mcp.d.ts +20 -0
  20. package/dist/commands/install-mcp.js +203 -0
  21. package/dist/commands/install-mcp.js.map +1 -0
  22. package/dist/commands/login.d.ts +17 -0
  23. package/dist/commands/login.js +110 -0
  24. package/dist/commands/login.js.map +1 -0
  25. package/dist/commands/logout.d.ts +7 -0
  26. package/dist/commands/logout.js +59 -0
  27. package/dist/commands/logout.js.map +1 -0
  28. package/dist/commands/profiles.d.ts +5 -0
  29. package/dist/commands/profiles.js +26 -0
  30. package/dist/commands/profiles.js.map +1 -0
  31. package/dist/commands/register.d.ts +12 -0
  32. package/dist/commands/register.js +26 -0
  33. package/dist/commands/register.js.map +1 -0
  34. package/dist/commands/repos.d.ts +8 -0
  35. package/dist/commands/repos.js +28 -0
  36. package/dist/commands/repos.js.map +1 -0
  37. package/dist/commands/uninstall-claude-md.d.ts +6 -0
  38. package/dist/commands/uninstall-claude-md.js +13 -0
  39. package/dist/commands/uninstall-claude-md.js.map +1 -0
  40. package/dist/commands/uninstall-commands.d.ts +7 -0
  41. package/dist/commands/uninstall-commands.js +21 -0
  42. package/dist/commands/uninstall-commands.js.map +1 -0
  43. package/dist/commands/uninstall-hooks.d.ts +6 -0
  44. package/dist/commands/uninstall-hooks.js +36 -0
  45. package/dist/commands/uninstall-hooks.js.map +1 -0
  46. package/dist/commands/uninstall-mcp.d.ts +8 -0
  47. package/dist/commands/uninstall-mcp.js +99 -0
  48. package/dist/commands/uninstall-mcp.js.map +1 -0
  49. package/dist/commands/uninstall.d.ts +14 -0
  50. package/dist/commands/uninstall.js +28 -0
  51. package/dist/commands/uninstall.js.map +1 -0
  52. package/dist/commands/use.d.ts +6 -0
  53. package/dist/commands/use.js +20 -0
  54. package/dist/commands/use.js.map +1 -0
  55. package/dist/commands/whoami.d.ts +6 -0
  56. package/dist/commands/whoami.js +48 -0
  57. package/dist/commands/whoami.js.map +1 -0
  58. package/dist/commands/workspace.d.ts +8 -0
  59. package/dist/commands/workspace.js +28 -0
  60. package/dist/commands/workspace.js.map +1 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +496 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/paths.d.ts +16 -0
  65. package/dist/paths.js +36 -0
  66. package/dist/paths.js.map +1 -0
  67. package/dist/prompt.d.ts +7 -0
  68. package/dist/prompt.js +43 -0
  69. package/dist/prompt.js.map +1 -0
  70. package/dist/registry.d.ts +16 -0
  71. package/dist/registry.js +42 -0
  72. package/dist/registry.js.map +1 -0
  73. package/dist/util.d.ts +27 -0
  74. package/dist/util.js +70 -0
  75. package/dist/util.js.map +1 -0
  76. package/package.json +57 -0
  77. package/templates/.claude/commands/bug-analyze.md +46 -0
  78. package/templates/.claude/commands/fix-bug.md +193 -0
  79. package/templates/.githooks/commit-msg +47 -0
  80. package/templates/CLAUDE.md +86 -0
  81. package/templates/repos.yaml.example +26 -0
package/dist/index.js ADDED
@@ -0,0 +1,496 @@
1
+ #!/usr/bin/env node
2
+ import { CliError } from "./util.js";
3
+ import { installCommands } from "./commands/install-commands.js";
4
+ import { installHooks } from "./commands/install-hooks.js";
5
+ import { installClaudeMd } from "./commands/install-claude-md.js";
6
+ import { installMcp } from "./commands/install-mcp.js";
7
+ import { uninstall } from "./commands/uninstall.js";
8
+ import { uninstallCommands } from "./commands/uninstall-commands.js";
9
+ import { uninstallHooks } from "./commands/uninstall-hooks.js";
10
+ import { uninstallClaudeMd } from "./commands/uninstall-claude-md.js";
11
+ import { uninstallMcp } from "./commands/uninstall-mcp.js";
12
+ import { init } from "./commands/init.js";
13
+ import { register } from "./commands/register.js";
14
+ import { repos } from "./commands/repos.js";
15
+ import { workspace } from "./commands/workspace.js";
16
+ import { login } from "./commands/login.js";
17
+ import { logout } from "./commands/logout.js";
18
+ import { whoami } from "./commands/whoami.js";
19
+ import { profiles } from "./commands/profiles.js";
20
+ import { use } from "./commands/use.js";
21
+ const HELP = `zentao-hub — helper CLI for zentao-hub-mcp
22
+
23
+ Usage:
24
+ zentao-hub <command> [options]
25
+
26
+ Commands:
27
+ login Log in to ZenTao, cache the token, and (when a system
28
+ keychain is available) cache the password so the MCP
29
+ server can auto-refresh expired tokens. Supports
30
+ multiple named profiles for several ZenTao instances.
31
+ Reads URL/username/password from flags or stdin;
32
+ password input is hidden. Token is stored at
33
+ ~/.zentao-hub/credentials.json (mode 0600); password
34
+ goes to the OS keychain (macOS Keychain / libsecret
35
+ on Linux / Credential Manager on Windows).
36
+ --profile <name> Profile name (default: 'default'). Re-using a name
37
+ overwrites that profile.
38
+ --set-default Make this profile the default after login.
39
+ --url <url> ZenTao base URL, e.g. https://zentao.example.com
40
+ --username <user> Account name.
41
+ --password <pass> Password (omit to be prompted without echo).
42
+ --credentials <path> Override credentials file location.
43
+ --no-save-password Don't cache the password; auto-refresh is disabled.
44
+ --save-password Require keychain availability; fail if missing.
45
+
46
+ logout Remove a profile from the credentials file and clear
47
+ its cached password from the keychain. Deletes the
48
+ file when no profiles remain.
49
+ --profile <name> Which profile to log out (default: current default).
50
+ --all Remove every profile and delete the credentials file.
51
+ --credentials <path> Override credentials file location.
52
+
53
+ whoami Print a profile's cached login (URL, username, masked
54
+ token) and whether auto-refresh is enabled.
55
+ --profile <name> Which profile to inspect (default: current default).
56
+ --credentials <path> Override credentials file location.
57
+
58
+ profiles List all configured profiles, marking the default.
59
+ --credentials <path> Override credentials file location.
60
+
61
+ use <name> Switch the default profile.
62
+ --credentials <path> Override credentials file location.
63
+
64
+ install <target> Install one of the integration pieces. Targets:
65
+ commands slash commands / prompts (fix-bug,
66
+ bug-analyze) for the chosen AI agent
67
+ hooks commit-msg hook (AI-signature blocker
68
+ + Conventional Commits check)
69
+ claude-md AI-collaboration instructions file
70
+ (CLAUDE.md / AGENTS.md / etc.)
71
+ mcp zentao-hub MCP server entry in the
72
+ agent's config
73
+
74
+ install commands --agent <id> claude | copilot | copilot-cli | codex
75
+ Claude → ~/.claude/commands/*.md
76
+ Codex → ~/.codex/prompts/*.md
77
+ Copilot → <repo>/.github/prompts/*.prompt.md
78
+ Copilot CLI → ~/.copilot/agents/*.agent.md
79
+ --repo <dir> Repo root (Copilot scope; default: cwd).
80
+ --dest <dir> Override target dir.
81
+ --force Overwrite existing files.
82
+
83
+ install hooks --repo <dir> Repo root (default: cwd).
84
+ --force Overwrite existing hook.
85
+ --no-set-hooks-path
86
+ Skip 'git config core.hooksPath .githooks'.
87
+
88
+ install claude-md --agent <id> Target agent (prompts when omitted).
89
+ claude → CLAUDE.md, codex → AGENTS.md,
90
+ copilot → .github/copilot-instructions.md.
91
+ --repo <dir> Repo root (default: cwd).
92
+ --force Overwrite existing file.
93
+
94
+ install mcp --agent <id> Target agent: claude | copilot |
95
+ copilot-cli | codex.
96
+ claude → ~/.claude.json or <repo>/.mcp.json
97
+ copilot → User/mcp.json or <repo>/.vscode/mcp.json
98
+ copilot-cli → ~/.copilot/mcp-config.json (user) or
99
+ <repo>/.mcp.json (workspace, shared
100
+ with Claude Code)
101
+ codex → ~/.codex/config.toml (user-only)
102
+ --scope <where>
103
+ 'user' (default) or 'workspace'
104
+ (claude+copilot only).
105
+ --repo <dir> Repo root for workspace scope (default: cwd).
106
+ --name <name> MCP server name (default: zentao-hub).
107
+ --command <bin>
108
+ Override binary used to spawn the server
109
+ (default: zentao-hub-mcp).
110
+ --profile <name>
111
+ Bind a specific credentials profile via
112
+ ZENTAO_PROFILE (default: active default).
113
+ --no-profile Don't write ZENTAO_PROFILE — server falls
114
+ back to the credentials file's default.
115
+ --force Overwrite an existing entry with the
116
+ same --name.
117
+ --credentials <path>
118
+ Override credentials file location.
119
+
120
+ uninstall [target] Reverse one — or all — install steps. Targets are
121
+ the same as 'install'; omit for a one-shot revert of
122
+ commands + hooks + claude-md (mcp is not removed by
123
+ the one-shot — call 'uninstall mcp' explicitly).
124
+ Leaves credentials and workspaces alone; use
125
+ 'logout --all' / 'rm -rf <workspace>' for those.
126
+
127
+ uninstall (no target) one-shot revert. Options:
128
+ --agent <id> Target agent (prompts when omitted).
129
+ --repo <dir> Repo root for hooks / instructions
130
+ (default: cwd).
131
+ --dest <dir> Override slash-commands dir.
132
+ --keep-hooks-path
133
+ Don't unset 'git config core.hooksPath'.
134
+
135
+ uninstall commands --agent <id> Target agent (prompts when omitted).
136
+ --repo <dir> Repo root (Copilot scope; default: cwd).
137
+ --dest <dir> Override target dir.
138
+
139
+ uninstall hooks --repo <dir> Repo root (default: cwd).
140
+ --keep-hooks-path
141
+ Leave 'git config core.hooksPath' alone.
142
+
143
+ uninstall claude-md --agent <id> Target agent (prompts when omitted).
144
+ --repo <dir> Repo root (default: cwd).
145
+
146
+ uninstall mcp --agent <id> Target agent (prompts when omitted).
147
+ --scope <where>
148
+ 'user' (default) or 'workspace'.
149
+ --repo <dir> Repo root for workspace scope.
150
+ --name <name> MCP server name to remove
151
+ (default: zentao-hub).
152
+
153
+ init Create the bug-context workspace for a profile at
154
+ <ZENTAO_HUB or ~/.zentao-hub>/<profile>/ with
155
+ bugs/, repos.yaml, repos.yaml.example.
156
+ --profile <name> Profile name (default: current default profile).
157
+ --workspace <dir> Override workspace path (bypasses per-profile layout).
158
+ --force Overwrite existing repos.yaml.
159
+ --migrate-legacy Move legacy ~/.zentao-hub/{bugs,repos.yaml} into the
160
+ default profile's workspace (default profile only).
161
+ --credentials <path> Override credentials file location.
162
+
163
+ register <productId> <repoPath>
164
+ Add a repo to the active profile's repos.yaml under
165
+ <productId>.
166
+ --name <name>
167
+ --tag <tag> Repeatable.
168
+ --profile <name> Profile to register against (default: current default).
169
+ --workspace <dir> Override workspace path.
170
+ --credentials <path> Override credentials file location.
171
+ --skip-git-check Allow non-git directories.
172
+
173
+ repos [productId] Print the active profile's registry (optionally
174
+ filtered by productId).
175
+ --profile <name> Profile to read (default: current default).
176
+ --workspace <dir> Override workspace path.
177
+ --credentials <path> Override credentials file location.
178
+
179
+ workspace, ws Show the resolved workspace for a profile.
180
+ --profile <name> Profile to inspect (default: current default).
181
+ --workspace <dir> Override workspace path.
182
+ --print-path Print only the workspace path (for slash commands).
183
+ --credentials <path> Override credentials file location.
184
+
185
+ help Show this help.
186
+
187
+ Environment:
188
+ ZENTAO_HUB Hub *root* used by slash commands and CLI. The active
189
+ workspace is always <root>/<profile>/. Defaults to
190
+ ~/.zentao-hub.
191
+ ZENTAO_HUB_CREDENTIALS Default credentials file path
192
+ (default: ~/.zentao-hub/credentials.json).
193
+ ZENTAO_PROFILE (Used by zentao-hub-mcp.) Picks which profile from the
194
+ credentials file the MCP server should authenticate
195
+ as. Defaults to the file's 'default' profile, or to
196
+ the sole profile if only one is configured.
197
+ `;
198
+ function parseArgs(argv, multi = new Set()) {
199
+ const positional = [];
200
+ const options = {};
201
+ for (let i = 0; i < argv.length; i++) {
202
+ const a = argv[i];
203
+ if (a === "--") {
204
+ positional.push(...argv.slice(i + 1));
205
+ break;
206
+ }
207
+ if (a.startsWith("--")) {
208
+ const eq = a.indexOf("=");
209
+ const key = (eq === -1 ? a.slice(2) : a.slice(2, eq));
210
+ const explicit = eq === -1 ? undefined : a.slice(eq + 1);
211
+ // booleans: --no-foo, or flag without value followed by another flag/end
212
+ if (key.startsWith("no-") && explicit === undefined) {
213
+ options[key.slice(3)] = false;
214
+ continue;
215
+ }
216
+ const next = argv[i + 1];
217
+ const value = explicit ?? (next !== undefined && !next.startsWith("--") ? (i++, next) : true);
218
+ if (multi.has(key)) {
219
+ const prev = options[key];
220
+ if (Array.isArray(prev))
221
+ prev.push(String(value));
222
+ else
223
+ options[key] = [String(value)];
224
+ }
225
+ else {
226
+ options[key] = value;
227
+ }
228
+ }
229
+ else {
230
+ positional.push(a);
231
+ }
232
+ }
233
+ return { positional, options };
234
+ }
235
+ function asString(v) {
236
+ return typeof v === "string" ? v : undefined;
237
+ }
238
+ function asBool(v) {
239
+ return typeof v === "boolean" ? v : undefined;
240
+ }
241
+ function asStringArray(v) {
242
+ return Array.isArray(v) ? v.filter((x) => typeof x === "string") : undefined;
243
+ }
244
+ const INSTALL_TARGETS = ["commands", "hooks", "claude-md", "mcp"];
245
+ const UNINSTALL_TARGETS = INSTALL_TARGETS;
246
+ async function runInstall(target, rest) {
247
+ switch (target) {
248
+ case "commands": {
249
+ const { options } = parseArgs(rest);
250
+ await installCommands({
251
+ agent: asString(options.agent),
252
+ dest: asString(options.dest),
253
+ repo: asString(options.repo),
254
+ force: asBool(options.force) ?? false,
255
+ });
256
+ return;
257
+ }
258
+ case "hooks": {
259
+ const { options } = parseArgs(rest);
260
+ await installHooks({
261
+ repo: asString(options.repo),
262
+ force: asBool(options.force) ?? false,
263
+ setHooksPath: asBool(options["set-hooks-path"]),
264
+ });
265
+ return;
266
+ }
267
+ case "claude-md": {
268
+ const { options } = parseArgs(rest);
269
+ await installClaudeMd({
270
+ agent: asString(options.agent),
271
+ repo: asString(options.repo),
272
+ force: asBool(options.force) ?? false,
273
+ });
274
+ return;
275
+ }
276
+ case "mcp": {
277
+ const { options } = parseArgs(rest);
278
+ await installMcp({
279
+ agent: asString(options.agent),
280
+ scope: asString(options.scope),
281
+ repo: asString(options.repo),
282
+ name: asString(options.name),
283
+ command: asString(options.command),
284
+ profile: asString(options.profile),
285
+ noProfile: asBool(options.profile) === false ? true : undefined,
286
+ force: asBool(options.force) ?? false,
287
+ credentials: asString(options.credentials),
288
+ });
289
+ return;
290
+ }
291
+ default:
292
+ throw new CliError(`unknown install target: ${target}\nusage: zentao-hub install <${INSTALL_TARGETS.join("|")}>`);
293
+ }
294
+ }
295
+ async function runUninstall(target, rest) {
296
+ if (!target) {
297
+ const { options } = parseArgs(rest);
298
+ await uninstall({
299
+ agent: asString(options.agent),
300
+ repo: asString(options.repo),
301
+ dest: asString(options.dest),
302
+ keepHooksPath: asBool(options["keep-hooks-path"]) ?? false,
303
+ });
304
+ return;
305
+ }
306
+ switch (target) {
307
+ case "commands": {
308
+ const { options } = parseArgs(rest);
309
+ await uninstallCommands({
310
+ agent: asString(options.agent),
311
+ dest: asString(options.dest),
312
+ repo: asString(options.repo),
313
+ });
314
+ return;
315
+ }
316
+ case "hooks": {
317
+ const { options } = parseArgs(rest);
318
+ await uninstallHooks({
319
+ repo: asString(options.repo),
320
+ keepHooksPath: asBool(options["keep-hooks-path"]) ?? false,
321
+ });
322
+ return;
323
+ }
324
+ case "claude-md": {
325
+ const { options } = parseArgs(rest);
326
+ await uninstallClaudeMd({
327
+ agent: asString(options.agent),
328
+ repo: asString(options.repo),
329
+ });
330
+ return;
331
+ }
332
+ case "mcp": {
333
+ const { options } = parseArgs(rest);
334
+ await uninstallMcp({
335
+ agent: asString(options.agent),
336
+ scope: asString(options.scope),
337
+ repo: asString(options.repo),
338
+ name: asString(options.name),
339
+ });
340
+ return;
341
+ }
342
+ default:
343
+ throw new CliError(`unknown uninstall target: ${target}\nusage: zentao-hub uninstall [${UNINSTALL_TARGETS.join("|")}]`);
344
+ }
345
+ }
346
+ async function main() {
347
+ const [, , cmd, ...rest] = process.argv;
348
+ if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
349
+ process.stdout.write(HELP);
350
+ return;
351
+ }
352
+ if (cmd === "--version" || cmd === "-v") {
353
+ const fs = await import("node:fs/promises");
354
+ const path = await import("node:path");
355
+ const { fileURLToPath } = await import("node:url");
356
+ const here = path.dirname(fileURLToPath(import.meta.url));
357
+ const text = await fs.readFile(path.resolve(here, "..", "package.json"), "utf8");
358
+ const { version } = JSON.parse(text);
359
+ process.stdout.write(`${version}\n`);
360
+ return;
361
+ }
362
+ switch (cmd) {
363
+ case "login": {
364
+ const { options } = parseArgs(rest);
365
+ await login({
366
+ url: asString(options.url),
367
+ username: asString(options.username),
368
+ password: asString(options.password),
369
+ profile: asString(options.profile),
370
+ setDefault: asBool(options["set-default"]) ?? false,
371
+ credentials: asString(options.credentials),
372
+ savePassword: asBool(options["save-password"]),
373
+ });
374
+ return;
375
+ }
376
+ case "logout": {
377
+ const { options } = parseArgs(rest);
378
+ await logout({
379
+ profile: asString(options.profile),
380
+ all: asBool(options.all) ?? false,
381
+ credentials: asString(options.credentials),
382
+ });
383
+ return;
384
+ }
385
+ case "whoami": {
386
+ const { options } = parseArgs(rest);
387
+ await whoami({
388
+ profile: asString(options.profile),
389
+ credentials: asString(options.credentials),
390
+ });
391
+ return;
392
+ }
393
+ case "profiles": {
394
+ const { options } = parseArgs(rest);
395
+ await profiles({ credentials: asString(options.credentials) });
396
+ return;
397
+ }
398
+ case "use": {
399
+ const { positional, options } = parseArgs(rest);
400
+ const name = positional[0];
401
+ if (!name) {
402
+ throw new CliError("usage: zentao-hub use <profile> [--credentials <path>]");
403
+ }
404
+ await use({ profile: name, credentials: asString(options.credentials) });
405
+ return;
406
+ }
407
+ case "install": {
408
+ const target = rest[0];
409
+ if (!target || target.startsWith("--")) {
410
+ throw new CliError(`usage: zentao-hub install <${INSTALL_TARGETS.join("|")}> [options]`);
411
+ }
412
+ await runInstall(target, rest.slice(1));
413
+ return;
414
+ }
415
+ case "uninstall": {
416
+ const first = rest[0];
417
+ if (!first || first.startsWith("--")) {
418
+ await runUninstall(undefined, rest);
419
+ }
420
+ else {
421
+ await runUninstall(first, rest.slice(1));
422
+ }
423
+ return;
424
+ }
425
+ case "init": {
426
+ const { options } = parseArgs(rest);
427
+ await init({
428
+ workspace: asString(options.workspace),
429
+ profile: asString(options.profile),
430
+ credentials: asString(options.credentials),
431
+ force: asBool(options.force) ?? false,
432
+ migrateLegacy: asBool(options["migrate-legacy"]) ?? false,
433
+ });
434
+ return;
435
+ }
436
+ case "register": {
437
+ const { positional, options } = parseArgs(rest, new Set(["tag"]));
438
+ const [pidStr, repoPath] = positional;
439
+ if (!pidStr || !repoPath) {
440
+ throw new CliError("usage: zentao-hub register <productId> <repoPath> [--name n] [--tag t]... [--profile p]");
441
+ }
442
+ const productId = Number(pidStr);
443
+ if (!Number.isInteger(productId) || productId <= 0) {
444
+ throw new CliError(`productId must be a positive integer, got ${pidStr}`);
445
+ }
446
+ await register({
447
+ productId,
448
+ repoPath,
449
+ name: asString(options.name),
450
+ tags: asStringArray(options.tag),
451
+ workspace: asString(options.workspace),
452
+ profile: asString(options.profile),
453
+ credentials: asString(options.credentials),
454
+ skipGitCheck: asBool(options["skip-git-check"]) ?? false,
455
+ });
456
+ return;
457
+ }
458
+ case "repos": {
459
+ const { positional, options } = parseArgs(rest);
460
+ const pidStr = positional[0];
461
+ const productId = pidStr ? Number(pidStr) : undefined;
462
+ if (pidStr && (!Number.isInteger(productId) || productId <= 0)) {
463
+ throw new CliError(`productId must be a positive integer, got ${pidStr}`);
464
+ }
465
+ await repos({
466
+ productId,
467
+ workspace: asString(options.workspace),
468
+ profile: asString(options.profile),
469
+ credentials: asString(options.credentials),
470
+ });
471
+ return;
472
+ }
473
+ case "workspace":
474
+ case "ws": {
475
+ const { options } = parseArgs(rest);
476
+ await workspace({
477
+ workspace: asString(options.workspace),
478
+ profile: asString(options.profile),
479
+ credentials: asString(options.credentials),
480
+ printPath: asBool(options["print-path"]) ?? false,
481
+ });
482
+ return;
483
+ }
484
+ default:
485
+ throw new CliError(`unknown command: ${cmd}\nRun 'zentao-hub help' for usage.`);
486
+ }
487
+ }
488
+ main().catch((err) => {
489
+ if (err instanceof CliError) {
490
+ process.stderr.write(`${err.message}\n`);
491
+ process.exit(err.exitCode);
492
+ }
493
+ process.stderr.write(`zentao-hub failed: ${err.stack ?? String(err)}\n`);
494
+ process.exit(1);
495
+ });
496
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare const TEMPLATES_DIR: string;
2
+ /**
3
+ * Root that holds all per-profile workspaces and the credentials file.
4
+ * Override with $ZENTAO_HUB; defaults to ~/.zentao-hub.
5
+ */
6
+ export declare function resolveHubRoot(explicit?: string): string;
7
+ /**
8
+ * Per-profile workspace: `<root>/<profile>/`. This is the directory that
9
+ * holds `bugs/`, `repos.yaml`, `repos.yaml.example`.
10
+ *
11
+ * When `explicit` is given, it is returned verbatim — that keeps the
12
+ * `--workspace <dir>` escape hatch working when callers want to bypass
13
+ * the per-profile layout.
14
+ */
15
+ export declare function resolveWorkspace(profile: string, explicit?: string): string;
16
+ export declare function resolveClaudeCommandsDir(explicit?: string): string;
package/dist/paths.js ADDED
@@ -0,0 +1,36 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ const here = path.dirname(fileURLToPath(import.meta.url));
5
+ // dist/ lives next to templates/ inside the package.
6
+ export const TEMPLATES_DIR = path.resolve(here, "..", "templates");
7
+ /**
8
+ * Root that holds all per-profile workspaces and the credentials file.
9
+ * Override with $ZENTAO_HUB; defaults to ~/.zentao-hub.
10
+ */
11
+ export function resolveHubRoot(explicit) {
12
+ if (explicit)
13
+ return path.resolve(explicit);
14
+ if (process.env.ZENTAO_HUB)
15
+ return path.resolve(process.env.ZENTAO_HUB);
16
+ return path.join(os.homedir(), ".zentao-hub");
17
+ }
18
+ /**
19
+ * Per-profile workspace: `<root>/<profile>/`. This is the directory that
20
+ * holds `bugs/`, `repos.yaml`, `repos.yaml.example`.
21
+ *
22
+ * When `explicit` is given, it is returned verbatim — that keeps the
23
+ * `--workspace <dir>` escape hatch working when callers want to bypass
24
+ * the per-profile layout.
25
+ */
26
+ export function resolveWorkspace(profile, explicit) {
27
+ if (explicit)
28
+ return path.resolve(explicit);
29
+ return path.join(resolveHubRoot(), profile);
30
+ }
31
+ export function resolveClaudeCommandsDir(explicit) {
32
+ if (explicit)
33
+ return path.resolve(explicit);
34
+ return path.join(os.homedir(), ".claude", "commands");
35
+ }
36
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,qDAAqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAEnE;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAiB;IAC9C,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,QAAiB;IACjE,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAiB;IACxD,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function promptLine(question: string): Promise<string>;
2
+ /**
3
+ * Prompt for a secret without echoing it to the terminal. Implementation
4
+ * trick: override readline's _writeToOutput so keystrokes don't reach stdout,
5
+ * while still emitting the prompt itself.
6
+ */
7
+ export declare function promptSecret(question: string): Promise<string>;
package/dist/prompt.js ADDED
@@ -0,0 +1,43 @@
1
+ import readline from "node:readline";
2
+ export async function promptLine(question) {
3
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
4
+ try {
5
+ return await new Promise((resolve) => {
6
+ rl.question(question, (answer) => resolve(answer));
7
+ });
8
+ }
9
+ finally {
10
+ rl.close();
11
+ }
12
+ }
13
+ /**
14
+ * Prompt for a secret without echoing it to the terminal. Implementation
15
+ * trick: override readline's _writeToOutput so keystrokes don't reach stdout,
16
+ * while still emitting the prompt itself.
17
+ */
18
+ export async function promptSecret(question) {
19
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
20
+ // readline doesn't expose this in its types; cast to reach the hook.
21
+ const r = rl;
22
+ const original = r._writeToOutput.bind(rl);
23
+ let prompted = false;
24
+ r._writeToOutput = (s) => {
25
+ if (!prompted) {
26
+ original(s);
27
+ prompted = true;
28
+ }
29
+ // swallow subsequent writes (the typed characters)
30
+ };
31
+ try {
32
+ return await new Promise((resolve) => {
33
+ rl.question(question, (answer) => {
34
+ process.stdout.write("\n");
35
+ resolve(answer);
36
+ });
37
+ });
38
+ }
39
+ finally {
40
+ rl.close();
41
+ }
42
+ }
43
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAC3C,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,qEAAqE;IACrE,MAAM,CAAC,GAAG,EAAwD,CAAC;IACnE,MAAM,QAAQ,GAAG,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,CAAC,CAAC,cAAc,GAAG,CAAC,CAAS,EAAE,EAAE;QAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,CAAC,CAAC,CAAC;YACZ,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,mDAAmD;IACrD,CAAC,CAAC;IACF,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAC3C,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface RepoEntry {
2
+ path: string;
3
+ name?: string;
4
+ tags?: string[];
5
+ }
6
+ export interface Registry {
7
+ products: Record<string, RepoEntry[]>;
8
+ }
9
+ export declare function registryPath(profile: string, workspace?: string): string;
10
+ export declare function loadRegistry(profile: string, workspace?: string): Promise<Registry>;
11
+ export declare function saveRegistry(reg: Registry, profile: string, workspace?: string): Promise<void>;
12
+ export declare function listEntries(reg: Registry, productId: number | string): RepoEntry[];
13
+ export declare function addEntry(reg: Registry, productId: number | string, entry: RepoEntry): {
14
+ added: boolean;
15
+ entries: RepoEntry[];
16
+ };