argustack 0.1.5 → 0.1.7

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 (128) hide show
  1. package/README.md +25 -12
  2. package/dist/adapters/csv/mapper.d.ts.map +1 -1
  3. package/dist/adapters/csv/mapper.js +53 -21
  4. package/dist/adapters/csv/mapper.js.map +1 -1
  5. package/dist/adapters/git/mapper.d.ts +1 -1
  6. package/dist/adapters/git/mapper.js +1 -1
  7. package/dist/adapters/git/provider.d.ts.map +1 -1
  8. package/dist/adapters/git/provider.js +1 -3
  9. package/dist/adapters/git/provider.js.map +1 -1
  10. package/dist/adapters/github/mapper.d.ts +1 -1
  11. package/dist/adapters/github/mapper.js +1 -1
  12. package/dist/adapters/jira/mapper.d.ts.map +1 -1
  13. package/dist/adapters/jira/mapper.js +19 -2
  14. package/dist/adapters/jira/mapper.js.map +1 -1
  15. package/dist/adapters/jira/provider.d.ts.map +1 -1
  16. package/dist/adapters/jira/provider.js +0 -4
  17. package/dist/adapters/jira/provider.js.map +1 -1
  18. package/dist/adapters/postgres/schema.d.ts.map +1 -1
  19. package/dist/adapters/postgres/schema.js +14 -5
  20. package/dist/adapters/postgres/schema.js.map +1 -1
  21. package/dist/adapters/postgres/storage.d.ts.map +1 -1
  22. package/dist/adapters/postgres/storage.js +15 -14
  23. package/dist/adapters/postgres/storage.js.map +1 -1
  24. package/dist/cli/index.js +0 -6
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/init/generators.d.ts +6 -0
  27. package/dist/cli/init/generators.d.ts.map +1 -0
  28. package/dist/cli/init/generators.js +153 -0
  29. package/dist/cli/init/generators.js.map +1 -0
  30. package/dist/cli/init/index.d.ts +4 -0
  31. package/dist/cli/init/index.d.ts.map +1 -0
  32. package/dist/cli/init/index.js +254 -0
  33. package/dist/cli/init/index.js.map +1 -0
  34. package/dist/cli/init/setup-csv.d.ts +4 -0
  35. package/dist/cli/init/setup-csv.d.ts.map +1 -0
  36. package/dist/cli/init/setup-csv.js +52 -0
  37. package/dist/cli/init/setup-csv.js.map +1 -0
  38. package/dist/cli/init/setup-db.d.ts +4 -0
  39. package/dist/cli/init/setup-db.d.ts.map +1 -0
  40. package/dist/cli/init/setup-db.js +33 -0
  41. package/dist/cli/init/setup-db.js.map +1 -0
  42. package/dist/cli/init/setup-git.d.ts +4 -0
  43. package/dist/cli/init/setup-git.d.ts.map +1 -0
  44. package/dist/cli/init/setup-git.js +244 -0
  45. package/dist/cli/init/setup-git.js.map +1 -0
  46. package/dist/cli/init/setup-github.d.ts +4 -0
  47. package/dist/cli/init/setup-github.d.ts.map +1 -0
  48. package/dist/cli/init/setup-github.js +102 -0
  49. package/dist/cli/init/setup-github.js.map +1 -0
  50. package/dist/cli/init/setup-jira.d.ts +4 -0
  51. package/dist/cli/init/setup-jira.d.ts.map +1 -0
  52. package/dist/cli/init/setup-jira.js +124 -0
  53. package/dist/cli/init/setup-jira.js.map +1 -0
  54. package/dist/cli/init/types.d.ts +59 -0
  55. package/dist/cli/init/types.d.ts.map +1 -0
  56. package/dist/cli/init/types.js +31 -0
  57. package/dist/cli/init/types.js.map +1 -0
  58. package/dist/cli/init.d.ts.map +1 -1
  59. package/dist/cli/init.js +29 -38
  60. package/dist/cli/init.js.map +1 -1
  61. package/dist/cli/mcp-install.d.ts.map +1 -1
  62. package/dist/cli/mcp-install.js +0 -21
  63. package/dist/cli/mcp-install.js.map +1 -1
  64. package/dist/cli/sources.d.ts.map +1 -1
  65. package/dist/cli/sources.js +0 -5
  66. package/dist/cli/sources.js.map +1 -1
  67. package/dist/cli/status.d.ts.map +1 -1
  68. package/dist/cli/status.js +1 -4
  69. package/dist/cli/status.js.map +1 -1
  70. package/dist/cli/sync.d.ts.map +1 -1
  71. package/dist/cli/sync.js +0 -3
  72. package/dist/cli/sync.js.map +1 -1
  73. package/dist/core/types/config.js +1 -1
  74. package/dist/core/types/config.js.map +1 -1
  75. package/dist/core/types/issue.d.ts +5 -0
  76. package/dist/core/types/issue.d.ts.map +1 -1
  77. package/dist/mcp/helpers.d.ts +24 -0
  78. package/dist/mcp/helpers.d.ts.map +1 -0
  79. package/dist/mcp/helpers.js +73 -0
  80. package/dist/mcp/helpers.js.map +1 -0
  81. package/dist/mcp/server.d.ts +2 -3
  82. package/dist/mcp/server.d.ts.map +1 -1
  83. package/dist/mcp/server.js +12 -1411
  84. package/dist/mcp/server.js.map +1 -1
  85. package/dist/mcp/tools/estimate.d.ts +3 -0
  86. package/dist/mcp/tools/estimate.d.ts.map +1 -0
  87. package/dist/mcp/tools/estimate.js +478 -0
  88. package/dist/mcp/tools/estimate.js.map +1 -0
  89. package/dist/mcp/tools/issue.d.ts +3 -0
  90. package/dist/mcp/tools/issue.d.ts.map +1 -0
  91. package/dist/mcp/tools/issue.js +468 -0
  92. package/dist/mcp/tools/issue.js.map +1 -0
  93. package/dist/mcp/tools/query.d.ts +3 -0
  94. package/dist/mcp/tools/query.d.ts.map +1 -0
  95. package/dist/mcp/tools/query.js +319 -0
  96. package/dist/mcp/tools/query.js.map +1 -0
  97. package/dist/mcp/tools/search.d.ts +3 -0
  98. package/dist/mcp/tools/search.d.ts.map +1 -0
  99. package/dist/mcp/tools/search.js +61 -0
  100. package/dist/mcp/tools/search.js.map +1 -0
  101. package/dist/mcp/tools/workspace.d.ts +3 -0
  102. package/dist/mcp/tools/workspace.d.ts.map +1 -0
  103. package/dist/mcp/tools/workspace.js +86 -0
  104. package/dist/mcp/tools/workspace.js.map +1 -0
  105. package/dist/mcp/types.d.ts +157 -0
  106. package/dist/mcp/types.d.ts.map +1 -0
  107. package/dist/mcp/types.js +2 -0
  108. package/dist/mcp/types.js.map +1 -0
  109. package/dist/use-cases/embed.d.ts.map +1 -1
  110. package/dist/use-cases/embed.js +1 -3
  111. package/dist/use-cases/embed.js.map +1 -1
  112. package/dist/use-cases/pull-git.d.ts.map +1 -1
  113. package/dist/use-cases/pull-git.js +2 -6
  114. package/dist/use-cases/pull-git.js.map +1 -1
  115. package/dist/use-cases/pull-github.d.ts.map +1 -1
  116. package/dist/use-cases/pull-github.js +2 -6
  117. package/dist/use-cases/pull-github.js.map +1 -1
  118. package/dist/use-cases/pull.d.ts.map +1 -1
  119. package/dist/use-cases/pull.js +2 -13
  120. package/dist/use-cases/pull.js.map +1 -1
  121. package/dist/workspace/config.d.ts.map +1 -1
  122. package/dist/workspace/config.js +0 -3
  123. package/dist/workspace/config.js.map +1 -1
  124. package/dist/workspace/resolver.d.ts.map +1 -1
  125. package/dist/workspace/resolver.js +0 -1
  126. package/dist/workspace/resolver.js.map +1 -1
  127. package/package.json +1 -1
  128. package/templates/init.sql +5 -0
@@ -0,0 +1,4 @@
1
+ import type { InitFlags, CsvSetupResult } from './types.js';
2
+ export declare function setupCsvInteractive(): Promise<CsvSetupResult>;
3
+ export declare function setupCsvFromFlags(flags: InitFlags): CsvSetupResult | null;
4
+ //# sourceMappingURL=setup-csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-csv.d.ts","sourceRoot":"","sources":["../../../src/cli/init/setup-csv.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgB5D,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,CAAC,CA+BnE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,cAAc,GAAG,IAAI,CAKzE"}
@@ -0,0 +1,52 @@
1
+ import { input } from '@inquirer/prompts';
2
+ import { readdirSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import chalk from 'chalk';
5
+ import { resolvePath } from './types.js';
6
+ async function promptCsvPath() {
7
+ const raw = await input({
8
+ message: 'Path to Jira CSV file:',
9
+ validate: (val) => {
10
+ if (!val.trim()) {
11
+ return 'CSV file path is required';
12
+ }
13
+ return true;
14
+ },
15
+ });
16
+ return resolvePath(raw);
17
+ }
18
+ export async function setupCsvInteractive() {
19
+ console.log('');
20
+ console.log(chalk.bold(' Jira CSV Import setup'));
21
+ console.log(chalk.dim(' Import issues from a Jira CSV export file.\n'));
22
+ const cwd = process.cwd();
23
+ const csvFiles = readdirSync(cwd).filter((f) => f.toLowerCase().endsWith('.csv'));
24
+ let csvFilePath;
25
+ if (csvFiles.length > 0) {
26
+ const { select } = await import('@inquirer/prompts');
27
+ const MANUAL_ENTRY = '__manual__';
28
+ const selected = await select({
29
+ message: csvFiles.length === 1
30
+ ? `Found CSV file in current directory:`
31
+ : `Found ${csvFiles.length} CSV files in current directory:`,
32
+ choices: [
33
+ ...csvFiles.map((f) => ({ value: join(cwd, f), name: f })),
34
+ { value: MANUAL_ENTRY, name: 'Enter path manually…' },
35
+ ],
36
+ });
37
+ csvFilePath = selected === MANUAL_ENTRY ? await promptCsvPath() : selected;
38
+ }
39
+ else {
40
+ csvFilePath = await promptCsvPath();
41
+ }
42
+ const resolved = resolve(csvFilePath);
43
+ console.log(chalk.green(` CSV file: ${resolved}`));
44
+ return { csvFilePath: resolved };
45
+ }
46
+ export function setupCsvFromFlags(flags) {
47
+ if (!flags.csvFile) {
48
+ throw new Error('CSV requires: --csv-file');
49
+ }
50
+ return { csvFilePath: flags.csvFile };
51
+ }
52
+ //# sourceMappingURL=setup-csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-csv.js","sourceRoot":"","sources":["../../../src/cli/init/setup-csv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,KAAK,UAAU,aAAa;IAC1B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC;QACtB,OAAO,EAAE,wBAAwB;QACjC,QAAQ,EAAE,CAAC,GAAG,EAAiB,EAAE;YAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChB,OAAO,2BAA2B,CAAC;YACrC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;IACH,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAEzE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAElF,IAAI,WAAmB,CAAC;IAExB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,YAAY,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAS;YACpC,OAAO,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAC5B,CAAC,CAAC,sCAAsC;gBACxC,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,kCAAkC;YAC9D,OAAO,EAAE;gBACP,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC1D,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,sBAAsB,EAAE;aACtD;SACF,CAAC,CAAC;QACH,WAAW,GAAG,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC,CAAC;IAEpD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { InitFlags, DbSetupResult } from './types.js';
2
+ export declare function setupDbInteractive(): Promise<DbSetupResult | null>;
3
+ export declare function setupDbFromFlags(flags: InitFlags): DbSetupResult | null;
4
+ //# sourceMappingURL=setup-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-db.d.ts","sourceRoot":"","sources":["../../../src/cli/init/setup-db.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3D,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAmBxE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,IAAI,CAWvE"}
@@ -0,0 +1,33 @@
1
+ import { input, password } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import { validatePort } from './types.js';
4
+ export async function setupDbInteractive() {
5
+ console.log('');
6
+ console.log(chalk.bold(' Database setup'));
7
+ console.log(chalk.dim(' Connect to the project database you want to analyze.\n'));
8
+ console.log(chalk.dim(' (This is the TARGET database, not Argustack internal DB)\n'));
9
+ const targetDbHost = await input({ message: 'DB Host:', default: 'localhost' });
10
+ const targetDbPortStr = await input({
11
+ message: 'DB Port:', default: '5432',
12
+ validate: (val) => validatePort(val),
13
+ });
14
+ const targetDbUser = await input({ message: 'DB User:' });
15
+ const targetDbPassword = await password({ message: 'DB Password:' });
16
+ const targetDbName = await input({ message: 'DB Name:' });
17
+ const targetDbPort = parseInt(targetDbPortStr, 10);
18
+ console.log(chalk.green(` Database configured: ${targetDbUser}@${targetDbHost}:${targetDbPort}/${targetDbName}`));
19
+ return { targetDbHost, targetDbPort, targetDbUser, targetDbPassword, targetDbName };
20
+ }
21
+ export function setupDbFromFlags(flags) {
22
+ if (!flags.targetDbHost || !flags.targetDbUser || !flags.targetDbName) {
23
+ throw new Error('Database requires: --target-db-host, --target-db-user, --target-db-name');
24
+ }
25
+ return {
26
+ targetDbHost: flags.targetDbHost,
27
+ targetDbPort: parseInt(flags.targetDbPort ?? '5432', 10),
28
+ targetDbUser: flags.targetDbUser,
29
+ targetDbPassword: flags.targetDbPassword ?? '',
30
+ targetDbName: flags.targetDbName,
31
+ };
32
+ }
33
+ //# sourceMappingURL=setup-db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-db.js","sourceRoot":"","sources":["../../../src/cli/init/setup-db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;IAEvF,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAChF,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC;QAClC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM;QACpC,QAAQ,EAAE,CAAC,GAAG,EAAiB,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC;KACpD,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,YAAY,IAAI,YAAY,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC;IAEnH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAgB;IAC/C,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY,IAAI,MAAM,EAAE,EAAE,CAAC;QACxD,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,EAAE;QAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { InitFlags, GitSetupResult } from './types.js';
2
+ export declare function setupGitInteractive(): Promise<GitSetupResult | null>;
3
+ export declare function setupGitFromFlags(flags: InitFlags): GitSetupResult | null;
4
+ //# sourceMappingURL=setup-git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-git.d.ts","sourceRoot":"","sources":["../../../src/cli/init/setup-git.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0K5D,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqF1E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,cAAc,GAAG,IAAI,CAMzE"}
@@ -0,0 +1,244 @@
1
+ import { input, confirm, checkbox } from '@inquirer/prompts';
2
+ import { password } from '@inquirer/prompts';
3
+ import { existsSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ import { spawn } from 'node:child_process';
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ import { resolvePath, getErrorMsg } from './types.js';
9
+ function gitCloneWithProgress(url, targetPath, spinner) {
10
+ return new Promise((res, rej) => {
11
+ const proc = spawn('git', ['clone', '--progress', url, targetPath], {
12
+ stdio: ['pipe', 'pipe', 'pipe'],
13
+ cwd: process.env['HOME'],
14
+ });
15
+ const repoName = url.split('/').pop()?.replace(/\.git$/, '') ?? 'repo';
16
+ proc.stderr.on('data', (data) => {
17
+ const line = data.toString().trim();
18
+ const match = /(\w[\w\s]+?):\s+(\d+)%\s+\((\d+)\/(\d+)\)/.exec(line);
19
+ if (match) {
20
+ const [, phase, pct] = match;
21
+ spinner.text = `Cloning ${repoName}: ${phase?.trim()} ${pct}%`;
22
+ }
23
+ });
24
+ proc.on('close', (code) => {
25
+ if (code === 0) {
26
+ res();
27
+ }
28
+ else {
29
+ rej(new Error(`git clone exited with code ${String(code)}`));
30
+ }
31
+ });
32
+ proc.on('error', rej);
33
+ });
34
+ }
35
+ async function collectGitRepoLocal() {
36
+ const rawPath = await input({
37
+ message: 'Path to local repo:',
38
+ validate: (val) => {
39
+ const trimmed = val.trim();
40
+ if (!trimmed) {
41
+ return 'Path is required';
42
+ }
43
+ const resolved = resolvePath(trimmed);
44
+ if (!existsSync(join(resolved, '.git'))) {
45
+ return `Not a git repository: ${resolved} (no .git/ directory)`;
46
+ }
47
+ return true;
48
+ },
49
+ });
50
+ return resolvePath(rawPath);
51
+ }
52
+ async function collectGitRepoGithub() {
53
+ const githubToken = await password({
54
+ message: 'GitHub token (PAT):',
55
+ mask: '*',
56
+ validate: (val) => {
57
+ if (!val.trim()) {
58
+ return 'Token is required';
59
+ }
60
+ return true;
61
+ },
62
+ });
63
+ const spinner = ora('Fetching accessible repositories...').start();
64
+ let repos;
65
+ try {
66
+ const { Octokit } = await import('octokit');
67
+ const octokit = new Octokit({ auth: githubToken.trim() });
68
+ const result = await octokit.rest.repos.listForAuthenticatedUser({
69
+ per_page: 100,
70
+ sort: 'updated',
71
+ direction: 'desc',
72
+ });
73
+ repos = result.data.map((r) => ({
74
+ full_name: r.full_name,
75
+ clone_url: r.clone_url,
76
+ isPrivate: r.private,
77
+ description: r.description,
78
+ }));
79
+ spinner.succeed(`Found ${repos.length} repositories`);
80
+ }
81
+ catch (err) {
82
+ spinner.fail('Failed to fetch repositories');
83
+ console.log(chalk.red(` Error: ${getErrorMsg(err)}`));
84
+ return { paths: [], token: githubToken.trim(), repos: [] };
85
+ }
86
+ if (repos.length === 0) {
87
+ console.log(chalk.yellow(' No repositories accessible with this token.'));
88
+ return { paths: [], token: githubToken.trim(), repos: [] };
89
+ }
90
+ const selectedRepos = await checkbox({
91
+ message: 'Select repositories to clone:',
92
+ choices: repos.map((r) => ({
93
+ value: { cloneUrl: r.clone_url, fullName: r.full_name },
94
+ name: `${r.full_name} ${r.isPrivate ? '(private)' : '(public)'}`,
95
+ ...(r.description ? { description: r.description } : {}),
96
+ })),
97
+ });
98
+ if (selectedRepos.length === 0) {
99
+ console.log(chalk.yellow(' No repositories selected.'));
100
+ return { paths: [], token: githubToken.trim(), repos: [] };
101
+ }
102
+ const clonedPaths = [];
103
+ const clonedRepos = [];
104
+ for (const { cloneUrl, fullName } of selectedRepos) {
105
+ const repoName = cloneUrl.split('/').pop()?.replace(/\.git$/, '') ?? 'repo';
106
+ const defaultPath = resolve(repoName);
107
+ const cloneDir = await input({
108
+ message: `Clone ${repoName} into directory:`,
109
+ default: defaultPath,
110
+ });
111
+ const targetPath = resolvePath(cloneDir);
112
+ const cloneSpinner = ora(`Cloning ${repoName}...`).start();
113
+ try {
114
+ await gitCloneWithProgress(cloneUrl, targetPath, cloneSpinner);
115
+ cloneSpinner.succeed(`Cloned to ${targetPath}`);
116
+ clonedPaths.push(targetPath);
117
+ clonedRepos.push(fullName);
118
+ }
119
+ catch (err) {
120
+ cloneSpinner.fail(`Failed to clone ${repoName}`);
121
+ console.log(chalk.red(` Error: ${getErrorMsg(err)}`));
122
+ }
123
+ }
124
+ return { paths: clonedPaths, token: githubToken.trim(), repos: clonedRepos };
125
+ }
126
+ async function collectGitRepoUrl() {
127
+ const repoUrl = await input({
128
+ message: 'Repository URL (HTTPS):',
129
+ validate: (val) => {
130
+ const trimmed = val.trim();
131
+ if (!trimmed) {
132
+ return 'URL is required';
133
+ }
134
+ if (!trimmed.startsWith('https://') && !trimmed.startsWith('git@')) {
135
+ return 'Must start with https:// or git@';
136
+ }
137
+ return true;
138
+ },
139
+ });
140
+ const defaultDir = repoUrl.trim().split('/').pop()?.replace(/\.git$/, '') ?? 'repo';
141
+ const defaultPath = resolve(defaultDir);
142
+ const cloneDir = await input({
143
+ message: 'Clone into directory:',
144
+ default: defaultPath,
145
+ });
146
+ const targetPath = resolvePath(cloneDir);
147
+ const spinner = ora(`Cloning ${repoUrl.trim()}...`).start();
148
+ try {
149
+ await gitCloneWithProgress(repoUrl.trim(), targetPath, spinner);
150
+ spinner.succeed(`Cloned to ${targetPath}`);
151
+ return targetPath;
152
+ }
153
+ catch (err) {
154
+ spinner.fail('Clone failed');
155
+ console.log(chalk.red(` Error: ${getErrorMsg(err)}`));
156
+ console.log(chalk.dim(' Check URL and network. Make sure git is installed.'));
157
+ return null;
158
+ }
159
+ }
160
+ export async function setupGitInteractive() {
161
+ console.log('');
162
+ console.log(chalk.bold(' Git setup'));
163
+ console.log(chalk.dim(' Connect to Git repositories.\n'));
164
+ const { select } = await import('@inquirer/prompts');
165
+ const gitRepoPaths = [];
166
+ let savedGithubToken;
167
+ const savedGithubRepos = [];
168
+ let addMore = true;
169
+ while (addMore) {
170
+ const mode = await select({
171
+ message: gitRepoPaths.length === 0
172
+ ? 'Where is your Git repository?'
173
+ : 'Add another Git repository:',
174
+ choices: [
175
+ {
176
+ value: 'local',
177
+ name: 'Local path',
178
+ description: 'The repo is already downloaded to your computer. ' +
179
+ 'You just point to the folder where it lives (e.g. ~/projects/my-app). ' +
180
+ 'Nothing is downloaded — Argustack reads commit history directly from disk',
181
+ },
182
+ {
183
+ value: 'github',
184
+ name: 'Clone from GitHub',
185
+ description: 'You have a GitHub account with access to the repo. ' +
186
+ 'Enter your GitHub token — Argustack will show all repos you have access to, ' +
187
+ 'you pick the ones you need, and they download automatically',
188
+ },
189
+ {
190
+ value: 'clone',
191
+ name: 'Clone from URL',
192
+ description: 'You have a direct link to the repo (from GitHub, GitLab, Bitbucket, or any git server). ' +
193
+ 'Paste the URL and Argustack will download the repo for you. ' +
194
+ 'Use this if your repo is not on GitHub or you prefer to paste the link manually',
195
+ },
196
+ ],
197
+ });
198
+ if (mode === 'local') {
199
+ const path = await collectGitRepoLocal();
200
+ if (path) {
201
+ gitRepoPaths.push(path);
202
+ }
203
+ }
204
+ else if (mode === 'github') {
205
+ const result = await collectGitRepoGithub();
206
+ gitRepoPaths.push(...result.paths);
207
+ savedGithubToken = result.token;
208
+ savedGithubRepos.push(...result.repos);
209
+ }
210
+ else {
211
+ const path = await collectGitRepoUrl();
212
+ if (path) {
213
+ gitRepoPaths.push(path);
214
+ }
215
+ }
216
+ if (gitRepoPaths.length === 0) {
217
+ const skip = await confirm({ message: 'Skip Git for now?', default: true });
218
+ if (skip) {
219
+ return null;
220
+ }
221
+ continue;
222
+ }
223
+ addMore = await confirm({ message: 'Add another Git repository?', default: false });
224
+ }
225
+ if (gitRepoPaths.length === 0) {
226
+ return null;
227
+ }
228
+ for (const p of gitRepoPaths) {
229
+ console.log(chalk.green(` Git source configured: ${p}`));
230
+ }
231
+ return {
232
+ gitRepoPaths,
233
+ ...(savedGithubToken ? { githubToken: savedGithubToken } : {}),
234
+ ...(savedGithubRepos.length > 0 ? { githubRepos: savedGithubRepos } : {}),
235
+ };
236
+ }
237
+ export function setupGitFromFlags(flags) {
238
+ if (!flags.gitRepo) {
239
+ throw new Error('Git requires: --git-repo');
240
+ }
241
+ const paths = flags.gitRepo.split(',').map((p) => p.trim()).filter(Boolean);
242
+ return { gitRepoPaths: paths };
243
+ }
244
+ //# sourceMappingURL=setup-git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-git.js","sourceRoot":"","sources":["../../../src/cli/init/setup-git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { InitFlags, GitHubSetupResult } from './types.js';
2
+ export declare function setupGithubInteractive(existingToken?: string, existingRepos?: string[]): Promise<GitHubSetupResult | null>;
3
+ export declare function setupGithubFromFlags(flags: InitFlags): GitHubSetupResult | null;
4
+ //# sourceMappingURL=setup-github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-github.d.ts","sourceRoot":"","sources":["../../../src/cli/init/setup-github.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/D,wBAAsB,sBAAsB,CAC1C,aAAa,CAAC,EAAE,MAAM,EACtB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA+FnC;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,iBAAiB,GAAG,IAAI,CAS/E"}
@@ -0,0 +1,102 @@
1
+ import { confirm, password } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { getErrorMsg } from './types.js';
5
+ export async function setupGithubInteractive(existingToken, existingRepos) {
6
+ console.log('');
7
+ console.log(chalk.bold(' GitHub setup'));
8
+ console.log(chalk.dim(' Connect to GitHub API for PRs, reviews, and releases.\n'));
9
+ if (existingToken && existingRepos && existingRepos.length > 0) {
10
+ const repoToUse = existingRepos[0] ?? '';
11
+ const [owner = '', repo = ''] = repoToUse.split('/');
12
+ if (existingRepos.length === 1) {
13
+ console.log(chalk.green(` Auto-configured from Git step: ${repoToUse}`));
14
+ }
15
+ else {
16
+ console.log(chalk.dim(` Repos from Git step: ${existingRepos.join(', ')}`));
17
+ console.log(chalk.green(` Using first repo for GitHub PRs: ${repoToUse}`));
18
+ }
19
+ return {
20
+ githubToken: existingToken.trim(),
21
+ githubOwner: owner,
22
+ githubRepo: repo,
23
+ };
24
+ }
25
+ let githubToken;
26
+ if (existingToken) {
27
+ console.log(chalk.green(' Using GitHub token from Git clone step.'));
28
+ githubToken = existingToken;
29
+ }
30
+ else {
31
+ console.log(chalk.dim(' Generate token: Settings → Developer settings → Personal access tokens'));
32
+ githubToken = await password({
33
+ message: 'GitHub token (PAT):',
34
+ mask: '*',
35
+ validate: (val) => {
36
+ if (!val.trim()) {
37
+ return 'Token is required';
38
+ }
39
+ return true;
40
+ },
41
+ });
42
+ }
43
+ const spinner = ora('Fetching accessible repositories...').start();
44
+ let repos;
45
+ try {
46
+ const { Octokit } = await import('octokit');
47
+ const octokit = new Octokit({ auth: githubToken.trim() });
48
+ const result = await octokit.rest.repos.listForAuthenticatedUser({
49
+ per_page: 100,
50
+ sort: 'updated',
51
+ direction: 'desc',
52
+ });
53
+ repos = result.data.map((r) => ({
54
+ full_name: r.full_name,
55
+ isPrivate: r.private,
56
+ description: r.description,
57
+ }));
58
+ spinner.succeed(`Found ${repos.length} accessible repositories`);
59
+ }
60
+ catch (err) {
61
+ spinner.fail('Failed to fetch repositories');
62
+ console.log(chalk.red(` Error: ${getErrorMsg(err)}`));
63
+ console.log(chalk.dim(' You can add GitHub token to .env later.'));
64
+ const skip = await confirm({ message: 'Skip GitHub for now?', default: true });
65
+ if (skip) {
66
+ return null;
67
+ }
68
+ return setupGithubInteractive(existingToken);
69
+ }
70
+ if (repos.length === 0) {
71
+ console.log(chalk.yellow(' No repositories accessible with this token.'));
72
+ console.log(chalk.dim(' Make sure the token has access to at least one repository.'));
73
+ return null;
74
+ }
75
+ const { select } = await import('@inquirer/prompts');
76
+ const selectedRepo = await select({
77
+ message: 'Select repository:',
78
+ choices: repos.map((r) => ({
79
+ value: r.full_name,
80
+ name: `${r.full_name} ${r.isPrivate ? '(private)' : '(public)'}`,
81
+ ...(r.description ? { description: r.description } : {}),
82
+ })),
83
+ });
84
+ const [owner = '', repo = ''] = selectedRepo.split('/');
85
+ console.log(chalk.green(` GitHub configured: ${selectedRepo}`));
86
+ return {
87
+ githubToken: githubToken.trim(),
88
+ githubOwner: owner,
89
+ githubRepo: repo,
90
+ };
91
+ }
92
+ export function setupGithubFromFlags(flags) {
93
+ if (!flags.githubToken || !flags.githubOwner || !flags.githubRepo) {
94
+ throw new Error('GitHub requires: --github-token, --github-owner, --github-repo');
95
+ }
96
+ return {
97
+ githubToken: flags.githubToken,
98
+ githubOwner: flags.githubOwner,
99
+ githubRepo: flags.githubRepo,
100
+ };
101
+ }
102
+ //# sourceMappingURL=setup-github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-github.js","sourceRoot":"","sources":["../../../src/cli/init/setup-github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { InitFlags, JiraSetupResult } from './types.js';
2
+ export declare function setupJiraInteractive(): Promise<JiraSetupResult | null>;
3
+ export declare function setupJiraFromFlags(flags: InitFlags): Promise<JiraSetupResult | null>;
4
+ //# sourceMappingURL=setup-jira.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-jira.d.ts","sourceRoot":"","sources":["../../../src/cli/init/setup-jira.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAe7D,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAgG5E;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAgC1F"}
@@ -0,0 +1,124 @@
1
+ import { input, confirm, password, checkbox } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { extractJiraBaseUrl, getErrorMsg } from './types.js';
5
+ async function testJiraConnection(url, email, token) {
6
+ const { Version3Client } = await import('jira.js');
7
+ const client = new Version3Client({
8
+ host: url,
9
+ authentication: { basic: { email, apiToken: token } },
10
+ });
11
+ const result = await client.projects.searchProjects({ maxResults: 200 });
12
+ return result.values.map((p) => p.key);
13
+ }
14
+ export async function setupJiraInteractive() {
15
+ console.log('');
16
+ console.log(chalk.bold(' Jira setup'));
17
+ console.log(chalk.dim(' Connect to your Jira instance.\n'));
18
+ const jiraUrlRaw = await input({
19
+ message: 'Jira URL:',
20
+ default: 'https://your-team.atlassian.net',
21
+ validate: (val) => {
22
+ if (!val.startsWith('https://')) {
23
+ return 'Must start with https://';
24
+ }
25
+ return true;
26
+ },
27
+ });
28
+ const jiraUrl = extractJiraBaseUrl(jiraUrlRaw);
29
+ const jiraEmail = await input({
30
+ message: 'Email:',
31
+ validate: (val) => {
32
+ if (!val.includes('@')) {
33
+ return 'Must be a valid email';
34
+ }
35
+ return true;
36
+ },
37
+ });
38
+ let jiraToken;
39
+ let availableProjects;
40
+ for (;;) {
41
+ jiraToken = await password({
42
+ message: 'API Token:',
43
+ mask: '*',
44
+ validate: (val) => {
45
+ if (!val.trim()) {
46
+ return 'Token is required';
47
+ }
48
+ return true;
49
+ },
50
+ });
51
+ const spinner = ora('Testing Jira connection...').start();
52
+ try {
53
+ availableProjects = await testJiraConnection(jiraUrl, jiraEmail, jiraToken);
54
+ }
55
+ catch (err) {
56
+ spinner.fail('Connection failed');
57
+ console.log(chalk.red(` Error: ${getErrorMsg(err)}`));
58
+ console.log(chalk.dim(' Check URL, email, token. Generate token:'));
59
+ console.log(chalk.dim(' https://id.atlassian.com/manage-profile/security/api-tokens'));
60
+ const retry = await confirm({ message: 'Try again?', default: true });
61
+ if (retry) {
62
+ continue;
63
+ }
64
+ const skip = await confirm({ message: 'Skip Jira for now?', default: false });
65
+ if (skip) {
66
+ return null;
67
+ }
68
+ return setupJiraInteractive();
69
+ }
70
+ if (availableProjects.length === 0) {
71
+ spinner.warn('Connected, but found 0 projects. Token may have limited permissions.');
72
+ console.log(chalk.yellow(' Your token works but has no project access.'));
73
+ console.log(chalk.dim(' This usually means the token was pasted incorrectly or has restricted scopes.'));
74
+ const retry = await confirm({ message: 'Re-enter token?', default: true });
75
+ if (retry) {
76
+ continue;
77
+ }
78
+ }
79
+ else {
80
+ spinner.succeed(`Connected! Found ${availableProjects.length} projects: ${availableProjects.join(', ')}`);
81
+ }
82
+ break;
83
+ }
84
+ const jiraProjects = await checkbox({
85
+ message: 'Select projects to pull:',
86
+ choices: availableProjects.map((key) => ({
87
+ value: key,
88
+ name: key,
89
+ })),
90
+ });
91
+ if (jiraProjects.length === 0) {
92
+ console.log(chalk.yellow(' No projects selected.'));
93
+ return null;
94
+ }
95
+ return { jiraUrl, jiraEmail, jiraToken, jiraProjects };
96
+ }
97
+ export async function setupJiraFromFlags(flags) {
98
+ if (!flags.jiraUrl || !flags.jiraEmail || !flags.jiraToken) {
99
+ throw new Error('Jira requires: --jira-url, --jira-email, --jira-token');
100
+ }
101
+ const spinner = ora('Testing Jira connection...').start();
102
+ try {
103
+ const availableProjects = await testJiraConnection(extractJiraBaseUrl(flags.jiraUrl), flags.jiraEmail, flags.jiraToken);
104
+ spinner.succeed(`Connected! Found ${availableProjects.length} projects: ${availableProjects.join(', ')}`);
105
+ let jiraProjects;
106
+ if (!flags.jiraProjects || flags.jiraProjects.toLowerCase() === 'all') {
107
+ jiraProjects = availableProjects;
108
+ }
109
+ else {
110
+ jiraProjects = flags.jiraProjects.split(',').map((p) => p.trim().toUpperCase());
111
+ }
112
+ return {
113
+ jiraUrl: flags.jiraUrl,
114
+ jiraEmail: flags.jiraEmail,
115
+ jiraToken: flags.jiraToken,
116
+ jiraProjects,
117
+ };
118
+ }
119
+ catch (err) {
120
+ spinner.fail('Connection failed');
121
+ throw new Error(`Jira connection failed: ${getErrorMsg(err)}`, { cause: err });
122
+ }
123
+ }
124
+ //# sourceMappingURL=setup-jira.js.map