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,173 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { dirname, join } from 'path';
4
+ import TOML from '@iarna/toml';
5
+ import { getToken } from './credentials.js';
6
+ import { parseConfig } from './configSchema.js';
7
+ export function resolveConfigPath() {
8
+ const xdg = process.env.XDG_CONFIG_HOME;
9
+ if (xdg)
10
+ return join(xdg, 'jirallm', 'config.toml');
11
+ return join(homedir(), '.config', 'jirallm', 'config.toml');
12
+ }
13
+ function expandTilde(value) {
14
+ if (!value)
15
+ return value;
16
+ if (value === '~')
17
+ return homedir();
18
+ if (value.startsWith('~/'))
19
+ return join(homedir(), value.slice(2));
20
+ return value;
21
+ }
22
+ export function readConfig(path = resolveConfigPath()) {
23
+ if (!existsSync(path))
24
+ return {};
25
+ const raw = readFileSync(path, 'utf-8');
26
+ const parsed = TOML.parse(raw);
27
+ return parseConfig(parsed, path);
28
+ }
29
+ export function writeConfig(config, path = resolveConfigPath()) {
30
+ mkdirSync(dirname(path), { recursive: true });
31
+ writeFileSync(path, TOML.stringify(config), 'utf-8');
32
+ }
33
+ function buildOrg(name, raw) {
34
+ const orgs = raw.orgs ?? {};
35
+ const r = orgs[name];
36
+ if (!r) {
37
+ const known = Object.keys(orgs).join(', ') || '(none)';
38
+ throw new Error(`Organization "${name}" not found in config. Known orgs: ${known}`);
39
+ }
40
+ const projects = {};
41
+ for (const [key, p] of Object.entries(r.projects ?? {})) {
42
+ projects[key] = { key, outputDir: expandTilde(p.output_dir) };
43
+ }
44
+ return {
45
+ name,
46
+ baseUrl: r.base_url,
47
+ userEmail: r.user_email,
48
+ includeSubtasks: r.include_subtasks,
49
+ videoFrames: r.video_frames
50
+ ? {
51
+ enabled: r.video_frames.enabled,
52
+ fps: r.video_frames.fps,
53
+ quality: r.video_frames.quality,
54
+ maxFrames: r.video_frames.max_frames,
55
+ similarityThreshold: r.video_frames.similarity_threshold,
56
+ }
57
+ : undefined,
58
+ projects,
59
+ };
60
+ }
61
+ function pickProject(org, projectKey) {
62
+ if (!projectKey) {
63
+ const keys = Object.keys(org.projects).join(', ') || '(none)';
64
+ throw new Error(`No project specified for org "${org.name}". Available projects: ${keys}`);
65
+ }
66
+ const project = org.projects[projectKey];
67
+ if (!project) {
68
+ const keys = Object.keys(org.projects).join(', ') || '(none)';
69
+ throw new Error(`Project "${projectKey}" not found in org "${org.name}". Available projects: ${keys}`);
70
+ }
71
+ return project;
72
+ }
73
+ export function listOrgs(raw = readConfig()) {
74
+ return Object.keys(raw.orgs ?? {});
75
+ }
76
+ export function findOrgsByProjectKey(projectKey, raw = readConfig()) {
77
+ const matches = [];
78
+ for (const [name, org] of Object.entries(raw.orgs ?? {})) {
79
+ if (org.projects && projectKey in org.projects)
80
+ matches.push(name);
81
+ }
82
+ return matches;
83
+ }
84
+ export async function loadProfile(opts = {}) {
85
+ const path = opts.configPath ?? resolveConfigPath();
86
+ const raw = readConfig(path);
87
+ const orgName = opts.org;
88
+ if (!orgName) {
89
+ throw new Error('No --org provided and the issue key prefix did not match a configured project. ' +
90
+ 'Pass --org or run `jirallm init`.');
91
+ }
92
+ const org = buildOrg(orgName, raw);
93
+ const project = pickProject(org, opts.project);
94
+ const apiToken = await getToken(orgName);
95
+ if (!apiToken) {
96
+ throw new Error(`No API token found for org "${orgName}". Run \`jirallm auth set --org ${orgName}\`.`);
97
+ }
98
+ return {
99
+ org,
100
+ project,
101
+ apiToken,
102
+ config: {
103
+ baseUrl: org.baseUrl,
104
+ userEmail: org.userEmail,
105
+ projectKey: project.key,
106
+ },
107
+ };
108
+ }
109
+ function orgToRaw(org) {
110
+ const raw = {
111
+ base_url: org.baseUrl,
112
+ user_email: org.userEmail,
113
+ };
114
+ if (org.includeSubtasks !== undefined)
115
+ raw.include_subtasks = org.includeSubtasks;
116
+ if (org.videoFrames) {
117
+ raw.video_frames = {
118
+ enabled: org.videoFrames.enabled,
119
+ fps: org.videoFrames.fps,
120
+ quality: org.videoFrames.quality,
121
+ max_frames: org.videoFrames.maxFrames,
122
+ similarity_threshold: org.videoFrames.similarityThreshold,
123
+ };
124
+ }
125
+ const projects = {};
126
+ for (const [key, p] of Object.entries(org.projects)) {
127
+ const rp = {};
128
+ if (p.outputDir)
129
+ rp.output_dir = p.outputDir;
130
+ projects[key] = rp;
131
+ }
132
+ raw.projects = projects;
133
+ return raw;
134
+ }
135
+ export function upsertOrg(org, configPath = resolveConfigPath()) {
136
+ const raw = readConfig(configPath);
137
+ raw.orgs = raw.orgs ?? {};
138
+ raw.orgs[org.name] = orgToRaw(org);
139
+ writeConfig(raw, configPath);
140
+ }
141
+ export function upsertProject(orgName, project, configPath = resolveConfigPath()) {
142
+ const raw = readConfig(configPath);
143
+ if (!raw.orgs?.[orgName]) {
144
+ throw new Error(`Organization "${orgName}" not found. Create it first via \`jirallm init\`.`);
145
+ }
146
+ const orgRaw = raw.orgs[orgName];
147
+ orgRaw.projects = orgRaw.projects ?? {};
148
+ const rp = {};
149
+ if (project.outputDir)
150
+ rp.output_dir = project.outputDir;
151
+ orgRaw.projects[project.key] = rp;
152
+ writeConfig(raw, configPath);
153
+ }
154
+ export function removeOrg(name, configPath = resolveConfigPath()) {
155
+ const raw = readConfig(configPath);
156
+ if (!raw.orgs?.[name])
157
+ return { removed: false };
158
+ delete raw.orgs[name];
159
+ writeConfig(raw, configPath);
160
+ return { removed: true };
161
+ }
162
+ export function removeProject(orgName, projectKey, configPath = resolveConfigPath()) {
163
+ const raw = readConfig(configPath);
164
+ const orgRaw = raw.orgs?.[orgName];
165
+ if (!orgRaw)
166
+ return { removed: false };
167
+ if (!orgRaw.projects?.[projectKey])
168
+ return { removed: false };
169
+ delete orgRaw.projects[projectKey];
170
+ writeConfig(raw, configPath);
171
+ return { removed: true };
172
+ }
173
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'fs';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
+ vi.mock('./credentials.js', () => ({
6
+ getToken: vi.fn(async (_name) => 'fake-token'),
7
+ }));
8
+ import { findOrgsByProjectKey, loadProfile, readConfig, upsertOrg, upsertProject, } from './config.js';
9
+ import { getToken } from './credentials.js';
10
+ const mockedGetToken = vi.mocked(getToken);
11
+ let tmpDir;
12
+ let configPath;
13
+ beforeEach(() => {
14
+ tmpDir = mkdtempSync(join(tmpdir(), 'jirallm-cfg-'));
15
+ configPath = join(tmpDir, 'config.toml');
16
+ });
17
+ afterEach(() => {
18
+ rmSync(tmpDir, { recursive: true, force: true });
19
+ });
20
+ const SAMPLE_CONFIG = `[orgs.widgets]
21
+ base_url = "https://widgets.atlassian.net"
22
+ user_email = "user@widgets.example"
23
+
24
+ [orgs.widgets.projects.WID]
25
+ output_dir = "~/jira/widgets"
26
+
27
+ [orgs.acme]
28
+ base_url = "https://acme.atlassian.net"
29
+ user_email = "user@acme.example"
30
+
31
+ [orgs.acme.projects.PROJ]
32
+ output_dir = "~/jira/acme/proj"
33
+
34
+ [orgs.acme.projects.CORE]
35
+ output_dir = "~/jira/acme/core"
36
+
37
+ [orgs.acme.projects.LIB]
38
+ `;
39
+ describe('loadProfile', () => {
40
+ it('throws helpful error when nothing is configured', async () => {
41
+ await expect(loadProfile({ configPath })).rejects.toThrow(/--org/);
42
+ });
43
+ it('resolves org and project selectors', async () => {
44
+ writeFileSync(configPath, SAMPLE_CONFIG);
45
+ const r = await loadProfile({ org: 'acme', project: 'CORE', configPath });
46
+ expect(r.org.name).toBe('acme');
47
+ expect(r.project.key).toBe('CORE');
48
+ expect(r.config.projectKey).toBe('CORE');
49
+ expect(r.config.baseUrl).toBe('https://acme.atlassian.net');
50
+ expect(r.project.outputDir).toMatch(/jira\/acme\/core$/);
51
+ expect(r.project.outputDir?.startsWith('~')).toBe(false);
52
+ });
53
+ it('errors when no project is provided', async () => {
54
+ writeFileSync(configPath, SAMPLE_CONFIG);
55
+ await expect(loadProfile({ org: 'widgets', configPath })).rejects.toThrow(/No project specified/);
56
+ });
57
+ it('errors when no org is provided', async () => {
58
+ writeFileSync(configPath, SAMPLE_CONFIG);
59
+ await expect(loadProfile({ configPath })).rejects.toThrow(/--org/);
60
+ });
61
+ it('errors when org has no token', async () => {
62
+ writeFileSync(configPath, SAMPLE_CONFIG);
63
+ mockedGetToken.mockResolvedValueOnce(undefined);
64
+ await expect(loadProfile({ org: 'acme', project: 'PROJ', configPath })).rejects.toThrow(/No API token/);
65
+ });
66
+ it('errors on missing org', async () => {
67
+ writeFileSync(configPath, SAMPLE_CONFIG);
68
+ await expect(loadProfile({ org: 'nope', project: 'PROJ', configPath })).rejects.toThrow(/not found/);
69
+ });
70
+ it('errors on missing project under known org', async () => {
71
+ writeFileSync(configPath, SAMPLE_CONFIG);
72
+ await expect(loadProfile({ org: 'acme', project: 'NOPE', configPath })).rejects.toThrow(/not found in org/);
73
+ });
74
+ });
75
+ describe('upsertOrg + upsertProject', () => {
76
+ it('writes and round-trips an org with projects', () => {
77
+ upsertOrg({
78
+ name: 'fresh',
79
+ baseUrl: 'https://fresh.example',
80
+ userEmail: 'f@x.example',
81
+ videoFrames: { enabled: true, fps: 7, maxFrames: 20 },
82
+ projects: {},
83
+ }, configPath);
84
+ upsertProject('fresh', { key: 'FR', outputDir: '/tmp/fr' }, configPath);
85
+ upsertProject('fresh', { key: 'FR2' }, configPath);
86
+ const raw = readConfig(configPath);
87
+ expect(raw.orgs?.fresh.base_url).toBe('https://fresh.example');
88
+ expect(raw.orgs?.fresh.video_frames?.fps).toBe(7);
89
+ expect(raw.orgs?.fresh.projects?.FR.output_dir).toBe('/tmp/fr');
90
+ expect(raw.orgs?.fresh.projects?.FR2).toBeDefined();
91
+ });
92
+ it('upsertProject errors if org missing', () => {
93
+ expect(() => upsertProject('nope', { key: 'X' }, configPath)).toThrow(/not found/);
94
+ });
95
+ });
96
+ describe('findOrgsByProjectKey', () => {
97
+ it('returns empty when no match', () => {
98
+ writeFileSync(configPath, SAMPLE_CONFIG);
99
+ expect(findOrgsByProjectKey('NOPE', readConfig(configPath))).toEqual([]);
100
+ });
101
+ it('returns the single org when only one matches', () => {
102
+ writeFileSync(configPath, SAMPLE_CONFIG);
103
+ expect(findOrgsByProjectKey('WID', readConfig(configPath))).toEqual(['widgets']);
104
+ });
105
+ it('returns multiple orgs when several share the project key', () => {
106
+ writeFileSync(configPath, `${SAMPLE_CONFIG}\n[orgs.widgets.projects.PROJ]\noutput_dir = "~/jira/widgets/proj"\n`);
107
+ const matches = findOrgsByProjectKey('PROJ', readConfig(configPath));
108
+ expect(matches.sort()).toEqual(['acme', 'widgets']);
109
+ });
110
+ });
111
+ describe('config validation (Zod)', () => {
112
+ it('rejects missing base_url with field path', () => {
113
+ writeFileSync(configPath, `[orgs.acme]\nuser_email = "u@x.example"\n`);
114
+ expect(() => readConfig(configPath)).toThrow(/orgs\.acme\.base_url/);
115
+ });
116
+ it('rejects wrong type for video_frames.fps', () => {
117
+ writeFileSync(configPath, `[orgs.acme]\nbase_url = "https://x.example"\nuser_email = "u@x.example"\n[orgs.acme.video_frames]\nfps = "five"\n`);
118
+ expect(() => readConfig(configPath)).toThrow(/orgs\.acme\.video_frames\.fps/);
119
+ });
120
+ it('rejects unknown keys at the org level', () => {
121
+ writeFileSync(configPath, `[orgs.acme]\nbase_url = "https://x.example"\nuser_email = "u@x.example"\nbasee_url = "typo"\n`);
122
+ expect(() => readConfig(configPath)).toThrow(/orgs\.acme/);
123
+ });
124
+ it('accepts an empty file', () => {
125
+ writeFileSync(configPath, '');
126
+ expect(() => readConfig(configPath)).not.toThrow();
127
+ expect(readConfig(configPath)).toEqual({});
128
+ });
129
+ });
130
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ declare const projectRawSchema: z.ZodObject<{
3
+ output_dir: z.ZodOptional<z.ZodString>;
4
+ }, z.core.$strict>;
5
+ declare const orgRawSchema: z.ZodObject<{
6
+ base_url: z.ZodURL;
7
+ user_email: z.ZodEmail;
8
+ include_subtasks: z.ZodOptional<z.ZodBoolean>;
9
+ video_frames: z.ZodOptional<z.ZodObject<{
10
+ enabled: z.ZodOptional<z.ZodBoolean>;
11
+ fps: z.ZodOptional<z.ZodNumber>;
12
+ quality: z.ZodOptional<z.ZodNumber>;
13
+ max_frames: z.ZodOptional<z.ZodNumber>;
14
+ similarity_threshold: z.ZodOptional<z.ZodNumber>;
15
+ }, z.core.$strict>>;
16
+ projects: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
17
+ output_dir: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strict>>>;
19
+ }, z.core.$strict>;
20
+ declare const configRawSchema: z.ZodObject<{
21
+ orgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
22
+ base_url: z.ZodURL;
23
+ user_email: z.ZodEmail;
24
+ include_subtasks: z.ZodOptional<z.ZodBoolean>;
25
+ video_frames: z.ZodOptional<z.ZodObject<{
26
+ enabled: z.ZodOptional<z.ZodBoolean>;
27
+ fps: z.ZodOptional<z.ZodNumber>;
28
+ quality: z.ZodOptional<z.ZodNumber>;
29
+ max_frames: z.ZodOptional<z.ZodNumber>;
30
+ similarity_threshold: z.ZodOptional<z.ZodNumber>;
31
+ }, z.core.$strict>>;
32
+ projects: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
33
+ output_dir: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strict>>>;
35
+ }, z.core.$strict>>>;
36
+ }, z.core.$strict>;
37
+ export type RawProject = z.infer<typeof projectRawSchema>;
38
+ export type RawOrg = z.infer<typeof orgRawSchema>;
39
+ export type RawConfig = z.infer<typeof configRawSchema>;
40
+ export declare function parseConfig(input: unknown, sourcePath?: string): RawConfig;
41
+ export {};
42
+ //# sourceMappingURL=configSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configSchema.d.ts","sourceRoot":"","sources":["../../src/lib/configSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,QAAA,MAAM,gBAAgB;;kBAIX,CAAC;AAEZ,QAAA,MAAM,YAAY;;;;;;;;;;;;;;kBAQP,CAAC;AAEZ,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;kBAIV,CAAC;AAEZ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAU1E"}
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ const videoFramesRawSchema = z
3
+ .object({
4
+ enabled: z.boolean().optional(),
5
+ fps: z.number().optional(),
6
+ quality: z.number().optional(),
7
+ max_frames: z.number().optional(),
8
+ similarity_threshold: z.number().optional(),
9
+ })
10
+ .strict();
11
+ const projectRawSchema = z
12
+ .object({
13
+ output_dir: z.string().optional(),
14
+ })
15
+ .strict();
16
+ const orgRawSchema = z
17
+ .object({
18
+ base_url: z.url(),
19
+ user_email: z.email(),
20
+ include_subtasks: z.boolean().optional(),
21
+ video_frames: videoFramesRawSchema.optional(),
22
+ projects: z.record(z.string(), projectRawSchema).optional(),
23
+ })
24
+ .strict();
25
+ const configRawSchema = z
26
+ .object({
27
+ orgs: z.record(z.string(), orgRawSchema).optional(),
28
+ })
29
+ .strict();
30
+ export function parseConfig(input, sourcePath) {
31
+ const result = configRawSchema.safeParse(input);
32
+ if (result.success)
33
+ return result.data;
34
+ const lines = result.error.issues.map((issue) => {
35
+ const path = issue.path.length > 0 ? issue.path.join('.') : '(root)';
36
+ return ` ${path}: ${issue.message}`;
37
+ });
38
+ const where = sourcePath ? ` at ${sourcePath}` : '';
39
+ throw new Error(`Invalid jirallm config${where}:\n${lines.join('\n')}`);
40
+ }
41
+ //# sourceMappingURL=configSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../../src/lib/configSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE;IACjB,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE;IACrB,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC,YAAY,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAC7C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,QAAQ,EAAE;CAC5D,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,eAAe,GAAG,CAAC;KACtB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,QAAQ,EAAE;CACpD,CAAC;KACD,MAAM,EAAE,CAAC;AAMZ,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,UAAmB;IAC7D,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IAEvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,OAAO,KAAK,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function getToken(orgName: string): Promise<string | undefined>;
2
+ export declare function setToken(orgName: string, token: string): Promise<void>;
3
+ export declare function removeToken(orgName: string): Promise<boolean>;
4
+ export declare function hasStoredToken(orgName: string): Promise<boolean>;
5
+ export declare const __test: {
6
+ resetKeytarCache: () => void;
7
+ };
8
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAyBA,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS3E;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5E;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAInE;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAStE;AAED,eAAO,MAAM,MAAM;;CAKlB,CAAC"}
@@ -0,0 +1,62 @@
1
+ const SERVICE = 'jirallm';
2
+ let keytarLoadPromise;
3
+ let cachedKeytar;
4
+ async function loadKeytar() {
5
+ if (keytarLoadPromise)
6
+ return keytarLoadPromise;
7
+ keytarLoadPromise = (async () => {
8
+ try {
9
+ const mod = (await import('keytar'));
10
+ cachedKeytar = (mod.default ?? mod);
11
+ }
12
+ catch {
13
+ cachedKeytar = undefined;
14
+ }
15
+ return cachedKeytar;
16
+ })();
17
+ return keytarLoadPromise;
18
+ }
19
+ export async function getToken(orgName) {
20
+ const keytar = await loadKeytar();
21
+ if (!keytar)
22
+ return undefined;
23
+ try {
24
+ const t = await keytar.getPassword(SERVICE, `${orgName}:api_token`);
25
+ return t ?? undefined;
26
+ }
27
+ catch {
28
+ return undefined;
29
+ }
30
+ }
31
+ export async function setToken(orgName, token) {
32
+ const keytar = await loadKeytar();
33
+ if (!keytar) {
34
+ throw new Error('OS keychain (keytar) is unavailable. Run `pnpm rebuild keytar` after `pnpm approve-builds`.');
35
+ }
36
+ await keytar.setPassword(SERVICE, `${orgName}:api_token`, token);
37
+ }
38
+ export async function removeToken(orgName) {
39
+ const keytar = await loadKeytar();
40
+ if (!keytar)
41
+ return false;
42
+ return keytar.deletePassword(SERVICE, `${orgName}:api_token`);
43
+ }
44
+ export async function hasStoredToken(orgName) {
45
+ const keytar = await loadKeytar();
46
+ if (!keytar)
47
+ return false;
48
+ try {
49
+ const t = await keytar.getPassword(SERVICE, `${orgName}:api_token`);
50
+ return Boolean(t);
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ export const __test = {
57
+ resetKeytarCache: () => {
58
+ keytarLoadPromise = undefined;
59
+ cachedKeytar = undefined;
60
+ },
61
+ };
62
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,SAAS,CAAC;AAQ1B,IAAI,iBAA0D,CAAC;AAC/D,IAAI,YAAgC,CAAC;AAErC,KAAK,UAAU,UAAU;IACvB,IAAI,iBAAiB;QAAE,OAAO,iBAAiB,CAAC;IAChD,iBAAiB,GAAG,CAAC,KAAK,IAAI,EAAE;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAA2C,CAAC;YAC/E,YAAY,GAAG,CAAC,GAAG,CAAC,OAAO,IAAK,GAAyB,CAAkB,CAAC;QAC9E,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,GAAG,SAAS,CAAC;QAC3B,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC,CAAC,EAAE,CAAC;IACL,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAe;IAC5C,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,OAAO,YAAY,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,SAAS,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAe,EAAE,KAAa;IAC3D,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,OAAO,YAAY,EAAE,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,OAAO,YAAY,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,OAAO,YAAY,CAAC,CAAC;QACpE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gBAAgB,EAAE,GAAG,EAAE;QACrB,iBAAiB,GAAG,SAAS,CAAC;QAC9B,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=credentials.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.test.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ const store = new Map();
3
+ vi.mock('keytar', () => {
4
+ const k = (s, a) => `${s}::${a}`;
5
+ return {
6
+ default: {
7
+ getPassword: vi.fn(async (s, a) => store.get(k(s, a)) ?? null),
8
+ setPassword: vi.fn(async (s, a, p) => {
9
+ store.set(k(s, a), p);
10
+ }),
11
+ deletePassword: vi.fn(async (s, a) => store.delete(k(s, a))),
12
+ },
13
+ };
14
+ });
15
+ import { getToken, setToken, removeToken, hasStoredToken, __test } from './credentials.js';
16
+ beforeEach(() => {
17
+ store.clear();
18
+ __test.resetKeytarCache();
19
+ });
20
+ afterEach(() => {
21
+ store.clear();
22
+ });
23
+ describe('credentials', () => {
24
+ it('round-trips token via keychain', async () => {
25
+ await setToken('work', 'tok-1');
26
+ expect(await hasStoredToken('work')).toBe(true);
27
+ expect(await getToken('work')).toBe('tok-1');
28
+ expect(await removeToken('work')).toBe(true);
29
+ expect(await getToken('work')).toBeUndefined();
30
+ });
31
+ it('returns undefined when no keychain entry exists', async () => {
32
+ expect(await getToken('anything')).toBeUndefined();
33
+ });
34
+ });
35
+ //# sourceMappingURL=credentials.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.test.js","sourceRoot":"","sources":["../../src/lib/credentials.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEzE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;IACrB,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACjD,OAAO;QACL,OAAO,EAAE;YACP,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAC9E,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE;gBAC3D,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,CAAC,CAAC;YACF,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SAC7E;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE3F,UAAU,CAAC,GAAG,EAAE;IACd,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,MAAM,CAAC,gBAAgB,EAAE,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,CAAC,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type JiraConfig } from './jiraClient.js';
2
+ export type ExportOptions = {
3
+ outputDir: string;
4
+ includeSubtasks?: boolean;
5
+ includeParentEpic?: boolean;
6
+ videoFrames?: {
7
+ enabled: boolean;
8
+ fps?: number;
9
+ quality?: number;
10
+ maxFrames?: number;
11
+ similarityThreshold?: number;
12
+ };
13
+ };
14
+ export type ExportResult = {
15
+ imported: string[];
16
+ updated: string[];
17
+ failed: Array<{
18
+ key: string;
19
+ error: string;
20
+ }>;
21
+ };
22
+ export declare class JiraExporter {
23
+ private client;
24
+ constructor(config: JiraConfig, apiToken: string);
25
+ exportIssue(issueKey: string, options: ExportOptions): Promise<string>;
26
+ exportIssues(issueKeys: string[], options: ExportOptions): Promise<ExportResult>;
27
+ }
28
+ //# sourceMappingURL=exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../src/lib/exporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,UAAU,EAAqB,MAAM,iBAAiB,CAAC;AAGjF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/C,CAAC;AAoEF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;IAI1C,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IA0EtE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAuBvF"}