jirallm 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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/dist/cli/commands/auth.d.ts +7 -0
  4. package/dist/cli/commands/auth.d.ts.map +1 -0
  5. package/dist/cli/commands/auth.js +69 -0
  6. package/dist/cli/commands/auth.js.map +1 -0
  7. package/dist/cli/commands/doctor.d.ts +5 -0
  8. package/dist/cli/commands/doctor.d.ts.map +1 -0
  9. package/dist/cli/commands/doctor.js +191 -0
  10. package/dist/cli/commands/doctor.js.map +1 -0
  11. package/dist/cli/commands/init.d.ts +2 -0
  12. package/dist/cli/commands/init.d.ts.map +1 -0
  13. package/dist/cli/commands/init.js +198 -0
  14. package/dist/cli/commands/init.js.map +1 -0
  15. package/dist/cli/commands/orgs.d.ts +8 -0
  16. package/dist/cli/commands/orgs.d.ts.map +1 -0
  17. package/dist/cli/commands/orgs.js +81 -0
  18. package/dist/cli/commands/orgs.js.map +1 -0
  19. package/dist/cli/commands/profiles.d.ts +2 -0
  20. package/dist/cli/commands/profiles.d.ts.map +1 -0
  21. package/dist/cli/commands/profiles.js +20 -0
  22. package/dist/cli/commands/profiles.js.map +1 -0
  23. package/dist/cli/commands/setup.d.ts +7 -0
  24. package/dist/cli/commands/setup.d.ts.map +1 -0
  25. package/dist/cli/commands/setup.js +130 -0
  26. package/dist/cli/commands/setup.js.map +1 -0
  27. package/dist/cli/index.d.ts +3 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +267 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/cli/issueKey.d.ts +13 -0
  32. package/dist/cli/issueKey.d.ts.map +1 -0
  33. package/dist/cli/issueKey.js +50 -0
  34. package/dist/cli/issueKey.js.map +1 -0
  35. package/dist/cli/issueKey.test.d.ts +2 -0
  36. package/dist/cli/issueKey.test.d.ts.map +1 -0
  37. package/dist/cli/issueKey.test.js +48 -0
  38. package/dist/cli/issueKey.test.js.map +1 -0
  39. package/dist/index.d.ts +10 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +6 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/lib/config.d.ts +49 -0
  44. package/dist/lib/config.d.ts.map +1 -0
  45. package/dist/lib/config.js +173 -0
  46. package/dist/lib/config.js.map +1 -0
  47. package/dist/lib/config.test.d.ts +2 -0
  48. package/dist/lib/config.test.d.ts.map +1 -0
  49. package/dist/lib/config.test.js +130 -0
  50. package/dist/lib/config.test.js.map +1 -0
  51. package/dist/lib/configSchema.d.ts +42 -0
  52. package/dist/lib/configSchema.d.ts.map +1 -0
  53. package/dist/lib/configSchema.js +41 -0
  54. package/dist/lib/configSchema.js.map +1 -0
  55. package/dist/lib/credentials.d.ts +8 -0
  56. package/dist/lib/credentials.d.ts.map +1 -0
  57. package/dist/lib/credentials.js +62 -0
  58. package/dist/lib/credentials.js.map +1 -0
  59. package/dist/lib/credentials.test.d.ts +2 -0
  60. package/dist/lib/credentials.test.d.ts.map +1 -0
  61. package/dist/lib/credentials.test.js +35 -0
  62. package/dist/lib/credentials.test.js.map +1 -0
  63. package/dist/lib/exporter.d.ts +28 -0
  64. package/dist/lib/exporter.d.ts.map +1 -0
  65. package/dist/lib/exporter.js +149 -0
  66. package/dist/lib/exporter.js.map +1 -0
  67. package/dist/lib/jiraClient.d.ts +129 -0
  68. package/dist/lib/jiraClient.d.ts.map +1 -0
  69. package/dist/lib/jiraClient.js +308 -0
  70. package/dist/lib/jiraClient.js.map +1 -0
  71. package/dist/lib/platform.d.ts +9 -0
  72. package/dist/lib/platform.d.ts.map +1 -0
  73. package/dist/lib/platform.js +82 -0
  74. package/dist/lib/platform.js.map +1 -0
  75. package/dist/lib/runCommand.d.ts +7 -0
  76. package/dist/lib/runCommand.d.ts.map +1 -0
  77. package/dist/lib/runCommand.js +26 -0
  78. package/dist/lib/runCommand.js.map +1 -0
  79. package/dist/lib/videoFrameExtractor.d.ts +22 -0
  80. package/dist/lib/videoFrameExtractor.d.ts.map +1 -0
  81. package/dist/lib/videoFrameExtractor.js +234 -0
  82. package/dist/lib/videoFrameExtractor.js.map +1 -0
  83. package/package.json +57 -0
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { select, isCancel, cancel } from '@clack/prompts';
4
+ import { JiraExporter } from '../lib/exporter.js';
5
+ import { findOrgsByProjectKey, loadProfile, readConfig } from '../lib/config.js';
6
+ import { parseIssueKeyArgs } from './issueKey.js';
7
+ import { runInit } from './commands/init.js';
8
+ import { runAuthSet, runAuthRm, runAuthList, runAuthStatus } from './commands/auth.js';
9
+ import { runOrgsList, runOrgsRemove, runProjectRemove } from './commands/orgs.js';
10
+ import { runDoctor } from './commands/doctor.js';
11
+ import { runSetup } from './commands/setup.js';
12
+ async function pickOrgInteractively(candidates, projectKey) {
13
+ const raw = readConfig();
14
+ const choice = await select({
15
+ message: `Multiple orgs have a "${projectKey}" project. Which one?`,
16
+ options: candidates.map((name) => ({
17
+ value: name,
18
+ label: name,
19
+ hint: raw.orgs?.[name]?.base_url,
20
+ })),
21
+ });
22
+ if (isCancel(choice)) {
23
+ cancel('Cancelled.');
24
+ process.exit(0);
25
+ }
26
+ return choice;
27
+ }
28
+ async function resolveOrgAndKeys(rawArgs, flags) {
29
+ const parsed = parseIssueKeyArgs(rawArgs);
30
+ const keys = parsed.keys;
31
+ if (flags.org && parsed.org && flags.org !== parsed.org) {
32
+ throw new Error(`--org "${flags.org}" conflicts with the org/ prefix "${parsed.org}/" in the issue keys.`);
33
+ }
34
+ const projectKey = flags.project ?? parsed.projectKey;
35
+ const explicitOrg = flags.org ?? parsed.org;
36
+ if (explicitOrg)
37
+ return { org: explicitOrg, projectKey, keys };
38
+ const matches = findOrgsByProjectKey(parsed.projectKey);
39
+ if (matches.length === 0) {
40
+ throw new Error(`Project "${parsed.projectKey}" not found in any configured org. ` +
41
+ 'Run `jirallm init` to add it, or pass --org explicitly.');
42
+ }
43
+ if (matches.length === 1)
44
+ return { org: matches[0], projectKey, keys };
45
+ if (!process.stdin.isTTY) {
46
+ throw new Error(`Project "${parsed.projectKey}" exists in multiple orgs (${matches.join(', ')}). ` +
47
+ `Pass --org or use the org/${parsed.projectKey}-N syntax.`);
48
+ }
49
+ const org = await pickOrgInteractively(matches, parsed.projectKey);
50
+ return { org, projectKey, keys };
51
+ }
52
+ async function runExport(rawArgs, flags) {
53
+ if (rawArgs.length === 0) {
54
+ await runInit();
55
+ process.exit(0);
56
+ }
57
+ let baseUrl = flags.baseUrl;
58
+ let userEmail = flags.userEmail;
59
+ let projectKey = flags.project;
60
+ let apiToken = flags.apiToken;
61
+ let outputDir = flags.outputDir ?? './jira-export';
62
+ let includeSubtasks = flags.includeSubtasks ?? false;
63
+ let videoEnabled = flags.videoFrames;
64
+ let fps = flags.fps ? parseInt(flags.fps, 10) : 5;
65
+ let maxFrames = flags.maxFrames ? parseInt(flags.maxFrames, 10) : 10;
66
+ let keys;
67
+ let org = flags.org;
68
+ try {
69
+ const resolved = await resolveOrgAndKeys(rawArgs, flags);
70
+ org = resolved.org;
71
+ projectKey = resolved.projectKey;
72
+ keys = resolved.keys;
73
+ }
74
+ catch (err) {
75
+ console.error(err.message);
76
+ process.exit(1);
77
+ }
78
+ if (!(baseUrl && userEmail && apiToken)) {
79
+ try {
80
+ const resolved = await loadProfile({ org, project: projectKey });
81
+ baseUrl = baseUrl ?? resolved.config.baseUrl;
82
+ userEmail = userEmail ?? resolved.config.userEmail;
83
+ projectKey = projectKey ?? resolved.project.key;
84
+ apiToken = apiToken ?? resolved.apiToken;
85
+ if (!flags.outputDir && resolved.project.outputDir) {
86
+ outputDir = resolved.project.outputDir;
87
+ }
88
+ if (flags.includeSubtasks === undefined && resolved.org.includeSubtasks !== undefined) {
89
+ includeSubtasks = resolved.org.includeSubtasks;
90
+ }
91
+ if (resolved.org.videoFrames) {
92
+ if (resolved.org.videoFrames.enabled === false && flags.videoFrames !== false) {
93
+ videoEnabled = false;
94
+ }
95
+ if (!flags.fps && resolved.org.videoFrames.fps !== undefined) {
96
+ fps = resolved.org.videoFrames.fps;
97
+ }
98
+ if (!flags.maxFrames && resolved.org.videoFrames.maxFrames !== undefined) {
99
+ maxFrames = resolved.org.videoFrames.maxFrames;
100
+ }
101
+ }
102
+ }
103
+ catch (err) {
104
+ console.error(err.message);
105
+ process.exit(1);
106
+ }
107
+ }
108
+ const exporter = new JiraExporter({ baseUrl: baseUrl, projectKey: projectKey, userEmail: userEmail }, apiToken);
109
+ console.log(`Exporting ${keys.length} issue(s) to ${outputDir}...`);
110
+ const result = await exporter.exportIssues(keys, {
111
+ outputDir,
112
+ includeSubtasks,
113
+ videoFrames: { enabled: videoEnabled, fps, maxFrames },
114
+ });
115
+ console.log('\nExport summary:');
116
+ if (result.imported.length > 0) {
117
+ console.log(` Imported (${result.imported.length}): ${result.imported.join(', ')}`);
118
+ }
119
+ if (result.updated.length > 0) {
120
+ console.log(` Updated (${result.updated.length}): ${result.updated.join(', ')}`);
121
+ }
122
+ if (result.failed.length > 0) {
123
+ console.log(` Failed (${result.failed.length}):`);
124
+ for (const { key, error } of result.failed)
125
+ console.log(` - ${key}: ${error}`);
126
+ process.exit(1);
127
+ }
128
+ }
129
+ const program = new Command();
130
+ program.enablePositionalOptions();
131
+ program
132
+ .name('jirallm')
133
+ .description('Export Jira issues as LLM-ready context bundles')
134
+ .version('0.1.0');
135
+ program
136
+ .argument('[issue-keys...]', 'Jira issue keys, e.g. PROJ-123 or acme/PROJ-123')
137
+ .option('-o, --org <name>', 'Organization name from config (auto-resolved from issue prefix if unique)')
138
+ .option('-P, --project <key>', 'Project key override')
139
+ .option('--output-dir <path>', 'Output directory (default: ./jira-export)')
140
+ .option('--base-url <url>', 'Jira base URL (overrides config)')
141
+ .option('--user-email <email>', 'Jira user email (overrides config)')
142
+ .option('--api-token <token>', 'Jira API token (overrides keychain)')
143
+ .option('--no-video-frames', 'Disable video frame extraction')
144
+ .option('--fps <n>', 'Frame extraction FPS')
145
+ .option('--max-frames <n>', 'Max frames kept per video')
146
+ .option('--include-subtasks', 'Fetch and include subtask metadata')
147
+ .action(async (keys, flags) => {
148
+ await runExport(keys, flags);
149
+ })
150
+ .addHelpText('after', `
151
+ Examples:
152
+ $ jirallm init
153
+ $ jirallm PROJ-123 # auto-resolves org from PROJ prefix
154
+ $ jirallm acme/PROJ-123 # disambiguate when multiple orgs have PROJ
155
+ $ jirallm PROJ-123 PROJ-124 --output-dir ./context
156
+ $ jirallm PROJ-123 --no-video-frames
157
+ $ jirallm PROJ-123 --fps 2 --max-frames 6
158
+ $ jirallm PROJ-123 --include-subtasks
159
+ $ jirallm --org acme PROJ-123
160
+ $ jirallm doctor --org acme
161
+ $ jirallm setup
162
+ $ jirallm orgs list
163
+
164
+ Run \`jirallm <command> --help\` for command-specific options.
165
+ `);
166
+ program
167
+ .command('init')
168
+ .description('Interactive setup wizard — creates an org or adds a project, and stores the API token in your OS keychain')
169
+ .action(async () => {
170
+ await runInit();
171
+ })
172
+ .addHelpText('after', '\nExample:\n $ jirallm init\n');
173
+ const auth = program.command('auth').description('Manage stored API tokens (per organization)');
174
+ auth
175
+ .command('set')
176
+ .description('Store/replace the API token for an organization')
177
+ .requiredOption('-o, --org <name>', 'Organization name')
178
+ .action(async (opts) => {
179
+ await runAuthSet(opts.org);
180
+ });
181
+ auth
182
+ .command('rm')
183
+ .description('Remove the stored API token for an organization')
184
+ .requiredOption('-o, --org <name>', 'Organization name')
185
+ .option('-y, --yes', 'Skip confirmation prompt')
186
+ .action(async (opts) => {
187
+ await runAuthRm(opts.org, { yes: opts.yes });
188
+ });
189
+ auth
190
+ .command('list')
191
+ .description('List all orgs and the resolved state of their API tokens')
192
+ .action(async () => {
193
+ await runAuthList();
194
+ });
195
+ auth
196
+ .command('status')
197
+ .description('Show whether a token is resolvable for an org (exits non-zero if missing)')
198
+ .requiredOption('-o, --org <name>', 'Organization name')
199
+ .action(async (opts) => {
200
+ await runAuthStatus(opts.org);
201
+ });
202
+ auth.addHelpText('after', `
203
+ Examples:
204
+ $ jirallm auth list
205
+ $ jirallm auth status --org acme
206
+ $ jirallm auth set --org acme
207
+ $ jirallm auth rm --org acme --yes
208
+ `);
209
+ const orgs = program.command('orgs').description('Inspect or modify organizations and their projects');
210
+ orgs
211
+ .command('list')
212
+ .description('List all configured organizations and projects')
213
+ .action(async () => {
214
+ await runOrgsList();
215
+ });
216
+ orgs
217
+ .command('rm')
218
+ .description('Remove an organization (and its keychain token) along with all its projects')
219
+ .requiredOption('-o, --org <name>', 'Organization name')
220
+ .option('-y, --yes', 'Skip confirmation prompt')
221
+ .action(async (opts) => {
222
+ await runOrgsRemove(opts.org, { yes: opts.yes });
223
+ });
224
+ const orgProject = orgs.command('project').description('Manage projects within an organization');
225
+ orgProject
226
+ .command('rm')
227
+ .description('Remove a project from an organization')
228
+ .requiredOption('-o, --org <name>', 'Organization name')
229
+ .requiredOption('-k, --key <key>', 'Project key')
230
+ .option('-y, --yes', 'Skip confirmation prompt')
231
+ .action(async (opts) => {
232
+ await runProjectRemove(opts.org, opts.key, { yes: opts.yes });
233
+ });
234
+ orgs.addHelpText('after', `
235
+ Examples:
236
+ $ jirallm orgs list
237
+ $ jirallm orgs rm --org acme
238
+ $ jirallm orgs project rm --org acme --key PROJ
239
+ `);
240
+ program
241
+ .command('doctor')
242
+ .description('Check that everything jirallm needs is installed and reachable')
243
+ .option('-o, --org <name>', 'Organization to use for the Jira reachability check')
244
+ .option('-P, --project <key>', 'Project key to use for the Jira reachability check')
245
+ .action(async (opts) => {
246
+ await runDoctor({ org: opts.org, project: opts.project });
247
+ })
248
+ .addHelpText('after', '\nExample:\n $ jirallm doctor --org acme\n');
249
+ program
250
+ .command('setup')
251
+ .description('Install missing system dependencies (currently: ffmpeg) with cascading consent')
252
+ .option('--bundled', 'Install ffmpeg-static globally instead of system ffmpeg')
253
+ .option('-y, --yes', 'Auto-confirm package-manager install (does NOT auto-confirm Homebrew install)')
254
+ .action(async (opts) => {
255
+ await runSetup({ bundled: opts.bundled, yes: opts.yes });
256
+ })
257
+ .addHelpText('after', `
258
+ Examples:
259
+ $ jirallm setup
260
+ $ jirallm setup --yes
261
+ $ jirallm setup --bundled
262
+ `);
263
+ program.parseAsync(process.argv).catch((error) => {
264
+ console.error('Unexpected error:', error);
265
+ process.exit(1);
266
+ });
267
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type ParsedIssueKey = {
2
+ org?: string;
3
+ key: string;
4
+ projectKey: string;
5
+ };
6
+ export declare function parseIssueKey(input: string): ParsedIssueKey;
7
+ export type ResolvedKeys = {
8
+ org?: string;
9
+ projectKey: string;
10
+ keys: string[];
11
+ };
12
+ export declare function parseIssueKeyArgs(inputs: string[]): ResolvedKeys;
13
+ //# sourceMappingURL=issueKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issueKey.d.ts","sourceRoot":"","sources":["../../src/cli/issueKey.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAmB3D;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAoChE"}
@@ -0,0 +1,50 @@
1
+ const ISSUE_KEY_RE = /^([A-Z][A-Z0-9_]*)-\d+$/;
2
+ const ORG_PART_RE = /^[a-zA-Z0-9_.-]+$/;
3
+ export function parseIssueKey(input) {
4
+ const slashIdx = input.indexOf('/');
5
+ let org;
6
+ let rest = input;
7
+ if (slashIdx !== -1) {
8
+ org = input.slice(0, slashIdx);
9
+ rest = input.slice(slashIdx + 1);
10
+ if (!org || !ORG_PART_RE.test(org)) {
11
+ throw new Error(`Invalid org prefix in "${input}". Use letters, digits, _, ., -.`);
12
+ }
13
+ }
14
+ const upperRest = rest.toUpperCase();
15
+ const match = ISSUE_KEY_RE.exec(upperRest);
16
+ if (!match) {
17
+ throw new Error(`Invalid issue key "${input}". Expected PROJECT-123 or org/PROJECT-123.`);
18
+ }
19
+ return { org, key: upperRest, projectKey: match[1] };
20
+ }
21
+ export function parseIssueKeyArgs(inputs) {
22
+ if (inputs.length === 0)
23
+ throw new Error('No issue keys provided.');
24
+ const parsed = inputs.map(parseIssueKey);
25
+ const projectKey = parsed[0].projectKey;
26
+ for (const p of parsed) {
27
+ if (p.projectKey !== projectKey) {
28
+ throw new Error(`All issue keys must share the same project prefix. Got "${parsed[0].key}" and "${p.key}". ` +
29
+ 'Run jirallm separately for each project, or pass --org/--project explicitly.');
30
+ }
31
+ }
32
+ const orgs = parsed
33
+ .map((p) => p.org)
34
+ .filter((o) => o !== undefined);
35
+ let org;
36
+ if (orgs.length > 0) {
37
+ const first = orgs[0];
38
+ for (const o of orgs) {
39
+ if (o !== first) {
40
+ throw new Error(`Mixed org prefixes in issue keys ("${first}" vs "${o}"). All keys must share the same org/.`);
41
+ }
42
+ }
43
+ if (orgs.length !== parsed.length) {
44
+ throw new Error('When using the org/KEY syntax, all issue keys must include the same org/ prefix.');
45
+ }
46
+ org = first;
47
+ }
48
+ return { org, projectKey, keys: parsed.map((p) => p.key) };
49
+ }
50
+ //# sourceMappingURL=issueKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issueKey.js","sourceRoot":"","sources":["../../src/cli/issueKey.ts"],"names":[],"mappings":"AAMA,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAC/C,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,GAAuB,CAAC;IAC5B,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/B,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,kCAAkC,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,6CAA6C,CACzE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAQD,MAAM,UAAU,iBAAiB,CAAC,MAAgB;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,2DAA2D,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,KAAK;gBAC1F,8EAA8E,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;SACjB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/C,IAAI,GAAuB,CAAC;IAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CACb,sCAAsC,KAAK,SAAS,CAAC,wCAAwC,CAC9F,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;QACJ,CAAC;QACD,GAAG,GAAG,KAAK,CAAC;IACd,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=issueKey.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issueKey.test.d.ts","sourceRoot":"","sources":["../../src/cli/issueKey.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { parseIssueKey, parseIssueKeyArgs } from './issueKey.js';
3
+ describe('parseIssueKey', () => {
4
+ it('parses a bare issue key', () => {
5
+ expect(parseIssueKey('PROJ-123')).toEqual({ org: undefined, key: 'PROJ-123', projectKey: 'PROJ' });
6
+ });
7
+ it('uppercases lowercase input', () => {
8
+ expect(parseIssueKey('proj-123')).toEqual({ org: undefined, key: 'PROJ-123', projectKey: 'PROJ' });
9
+ });
10
+ it('parses an org-qualified key', () => {
11
+ expect(parseIssueKey('acme/PROJ-123')).toEqual({
12
+ org: 'acme',
13
+ key: 'PROJ-123',
14
+ projectKey: 'PROJ',
15
+ });
16
+ });
17
+ it('rejects garbage', () => {
18
+ expect(() => parseIssueKey('not-an-issue')).toThrow(/Invalid issue key/);
19
+ expect(() => parseIssueKey('123')).toThrow(/Invalid issue key/);
20
+ expect(() => parseIssueKey('/PROJ-1')).toThrow(/Invalid org prefix/);
21
+ });
22
+ });
23
+ describe('parseIssueKeyArgs', () => {
24
+ it('happy path with bare keys', () => {
25
+ expect(parseIssueKeyArgs(['PROJ-1', 'PROJ-2'])).toEqual({
26
+ org: undefined,
27
+ projectKey: 'PROJ',
28
+ keys: ['PROJ-1', 'PROJ-2'],
29
+ });
30
+ });
31
+ it('happy path with consistent org/ prefix', () => {
32
+ expect(parseIssueKeyArgs(['acme/PROJ-1', 'acme/PROJ-2'])).toEqual({
33
+ org: 'acme',
34
+ projectKey: 'PROJ',
35
+ keys: ['PROJ-1', 'PROJ-2'],
36
+ });
37
+ });
38
+ it('rejects mixed project prefixes', () => {
39
+ expect(() => parseIssueKeyArgs(['PROJ-1', 'CORE-2'])).toThrow(/same project prefix/);
40
+ });
41
+ it('rejects mixed org prefixes', () => {
42
+ expect(() => parseIssueKeyArgs(['acme/PROJ-1', 'globex/PROJ-2'])).toThrow(/Mixed org prefixes/);
43
+ });
44
+ it('rejects partial org/ qualification', () => {
45
+ expect(() => parseIssueKeyArgs(['acme/PROJ-1', 'PROJ-2'])).toThrow(/all issue keys must include/i);
46
+ });
47
+ });
48
+ //# sourceMappingURL=issueKey.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issueKey.test.js","sourceRoot":"","sources":["../../src/cli/issueKey.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { JiraClient } from './lib/jiraClient.js';
2
+ export type { JiraConfig, JiraTaskData, JiraTaskSummary } from './lib/jiraClient.js';
3
+ export { JiraExporter } from './lib/exporter.js';
4
+ export type { ExportOptions, ExportResult } from './lib/exporter.js';
5
+ export { extractAndDeduplicateFrames, checkFFmpegInstalled, isVideoFile, } from './lib/videoFrameExtractor.js';
6
+ export type { ExtractionOptions, ExtractionResult } from './lib/videoFrameExtractor.js';
7
+ export { loadProfile, resolveConfigPath, readConfig, writeConfig, upsertOrg, upsertProject, listOrgs, findOrgsByProjectKey, } from './lib/config.js';
8
+ export type { Organization, Project, ResolvedProfile, LoadProfileOptions, VideoFramesConfig, } from './lib/config.js';
9
+ export { getToken, setToken, removeToken, hasStoredToken } from './lib/credentials.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACxF,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,QAAQ,EACR,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { JiraClient } from './lib/jiraClient.js';
2
+ export { JiraExporter } from './lib/exporter.js';
3
+ export { extractAndDeduplicateFrames, checkFFmpegInstalled, isVideoFile, } from './lib/videoFrameExtractor.js';
4
+ export { loadProfile, resolveConfigPath, readConfig, writeConfig, upsertOrg, upsertProject, listOrgs, findOrgsByProjectKey, } from './lib/config.js';
5
+ export { getToken, setToken, removeToken, hasStoredToken } from './lib/credentials.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,QAAQ,EACR,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { JiraConfig } from './jiraClient.js';
2
+ import { type RawConfig } from './configSchema.js';
3
+ export type VideoFramesConfig = {
4
+ enabled?: boolean;
5
+ fps?: number;
6
+ quality?: number;
7
+ maxFrames?: number;
8
+ similarityThreshold?: number;
9
+ };
10
+ export type Project = {
11
+ key: string;
12
+ outputDir?: string;
13
+ };
14
+ export type Organization = {
15
+ name: string;
16
+ baseUrl: string;
17
+ userEmail: string;
18
+ includeSubtasks?: boolean;
19
+ videoFrames?: VideoFramesConfig;
20
+ projects: Record<string, Project>;
21
+ };
22
+ export type ResolvedProfile = {
23
+ config: JiraConfig;
24
+ org: Organization;
25
+ project: Project;
26
+ apiToken: string;
27
+ };
28
+ export type LoadProfileOptions = {
29
+ org?: string;
30
+ project?: string;
31
+ configPath?: string;
32
+ };
33
+ export declare function resolveConfigPath(): string;
34
+ export declare function readConfig(path?: string): RawConfig;
35
+ export declare function writeConfig(config: RawConfig, path?: string): void;
36
+ export declare function listOrgs(raw?: RawConfig): string[];
37
+ export declare function findOrgsByProjectKey(projectKey: string, raw?: RawConfig): string[];
38
+ export declare function loadProfile(opts?: LoadProfileOptions): Promise<ResolvedProfile>;
39
+ export declare function upsertOrg(org: Organization, configPath?: string): void;
40
+ export declare function upsertProject(orgName: string, project: Project, configPath?: string): void;
41
+ export type RemoveOrgResult = {
42
+ removed: boolean;
43
+ };
44
+ export declare function removeOrg(name: string, configPath?: string): RemoveOrgResult;
45
+ export type RemoveProjectResult = {
46
+ removed: boolean;
47
+ };
48
+ export declare function removeProject(orgName: string, projectKey: string, configPath?: string): RemoveProjectResult;
49
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAe,KAAK,SAAS,EAAgC,MAAM,mBAAmB,CAAC;AAE9F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,iBAAiB,IAAI,MAAM,CAI1C;AASD,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAA4B,GAAG,SAAS,CAKxE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,GAAE,MAA4B,GAAG,IAAI,CAGvF;AAkDD,wBAAgB,QAAQ,CAAC,GAAG,GAAE,SAAwB,GAAG,MAAM,EAAE,CAEhE;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,SAAwB,GAC5B,MAAM,EAAE,CAMV;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8BzF;AA2BD,wBAAgB,SAAS,CACvB,GAAG,EAAE,YAAY,EACjB,UAAU,GAAE,MAA4B,GACvC,IAAI,CAKN;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,UAAU,GAAE,MAA4B,GACvC,IAAI,CAWN;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnD,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAA4B,GACvC,eAAe,CAMjB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAA4B,GACvC,mBAAmB,CAQrB"}