@knpkv/jira-cli 0.1.1

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 (87) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +141 -0
  4. package/dist/IssueService.d.ts +144 -0
  5. package/dist/IssueService.d.ts.map +1 -0
  6. package/dist/IssueService.js +250 -0
  7. package/dist/IssueService.js.map +1 -0
  8. package/dist/JiraAuth.d.ts +84 -0
  9. package/dist/JiraAuth.d.ts.map +1 -0
  10. package/dist/JiraAuth.js +246 -0
  11. package/dist/JiraAuth.js.map +1 -0
  12. package/dist/JiraCliError.d.ts +42 -0
  13. package/dist/JiraCliError.d.ts.map +1 -0
  14. package/dist/JiraCliError.js +35 -0
  15. package/dist/JiraCliError.js.map +1 -0
  16. package/dist/MarkdownWriter.d.ts +56 -0
  17. package/dist/MarkdownWriter.d.ts.map +1 -0
  18. package/dist/MarkdownWriter.js +66 -0
  19. package/dist/MarkdownWriter.js.map +1 -0
  20. package/dist/bin.d.ts +3 -0
  21. package/dist/bin.d.ts.map +1 -0
  22. package/dist/bin.js +39 -0
  23. package/dist/bin.js.map +1 -0
  24. package/dist/commands/auth.d.ts +22 -0
  25. package/dist/commands/auth.d.ts.map +1 -0
  26. package/dist/commands/auth.js +89 -0
  27. package/dist/commands/auth.js.map +1 -0
  28. package/dist/commands/errorHandler.d.ts +13 -0
  29. package/dist/commands/errorHandler.d.ts.map +1 -0
  30. package/dist/commands/errorHandler.js +13 -0
  31. package/dist/commands/errorHandler.js.map +1 -0
  32. package/dist/commands/get.d.ts +13 -0
  33. package/dist/commands/get.d.ts.map +1 -0
  34. package/dist/commands/get.js +25 -0
  35. package/dist/commands/get.js.map +1 -0
  36. package/dist/commands/index.d.ts +11 -0
  37. package/dist/commands/index.d.ts.map +1 -0
  38. package/dist/commands/index.js +11 -0
  39. package/dist/commands/index.js.map +1 -0
  40. package/dist/commands/layers.d.ts +44 -0
  41. package/dist/commands/layers.d.ts.map +1 -0
  42. package/dist/commands/layers.js +100 -0
  43. package/dist/commands/layers.js.map +1 -0
  44. package/dist/commands/search.d.ts +18 -0
  45. package/dist/commands/search.d.ts.map +1 -0
  46. package/dist/commands/search.js +64 -0
  47. package/dist/commands/search.js.map +1 -0
  48. package/dist/index.d.ts +10 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +10 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/internal/NodeLayers.d.ts +7 -0
  53. package/dist/internal/NodeLayers.d.ts.map +1 -0
  54. package/dist/internal/NodeLayers.js +15 -0
  55. package/dist/internal/NodeLayers.js.map +1 -0
  56. package/dist/internal/frontmatter.d.ts +60 -0
  57. package/dist/internal/frontmatter.d.ts.map +1 -0
  58. package/dist/internal/frontmatter.js +130 -0
  59. package/dist/internal/frontmatter.js.map +1 -0
  60. package/dist/internal/jqlBuilder.d.ts +39 -0
  61. package/dist/internal/jqlBuilder.d.ts.map +1 -0
  62. package/dist/internal/jqlBuilder.js +47 -0
  63. package/dist/internal/jqlBuilder.js.map +1 -0
  64. package/dist/internal/oauthServer.d.ts +55 -0
  65. package/dist/internal/oauthServer.d.ts.map +1 -0
  66. package/dist/internal/oauthServer.js +113 -0
  67. package/dist/internal/oauthServer.js.map +1 -0
  68. package/package.json +86 -0
  69. package/src/IssueService.ts +378 -0
  70. package/src/JiraAuth.ts +476 -0
  71. package/src/JiraCliError.ts +44 -0
  72. package/src/MarkdownWriter.ts +112 -0
  73. package/src/bin.ts +62 -0
  74. package/src/commands/auth.ts +124 -0
  75. package/src/commands/errorHandler.ts +14 -0
  76. package/src/commands/get.ts +42 -0
  77. package/src/commands/index.ts +11 -0
  78. package/src/commands/layers.ts +142 -0
  79. package/src/commands/search.ts +102 -0
  80. package/src/index.ts +26 -0
  81. package/src/internal/NodeLayers.ts +17 -0
  82. package/src/internal/frontmatter.ts +170 -0
  83. package/src/internal/jqlBuilder.ts +49 -0
  84. package/src/internal/oauthServer.ts +203 -0
  85. package/test/jqlBuilder.test.ts +45 -0
  86. package/tsconfig.json +32 -0
  87. package/vitest.config.ts +12 -0
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Auth subcommands: create, configure, login, logout, status.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - Each command is a standalone `Command.make` that yields into `JiraAuth` service methods.
7
+ * - `create` opens the Atlassian Developer Console; `configure` prompts for client ID/secret.
8
+ *
9
+ * @internal
10
+ */
11
+ import { Command, Options, Prompt } from "@effect/cli";
12
+ import * as PlatformCommand from "@effect/platform/Command";
13
+ import * as Console from "effect/Console";
14
+ import * as Effect from "effect/Effect";
15
+ import * as Option from "effect/Option";
16
+ import { JiraAuth } from "../JiraAuth.js";
17
+ // === Auth create command ===
18
+ const createCommand = Command.make("create", {}, () => Effect.gen(function* () {
19
+ yield* Console.log(`
20
+ Creating OAuth app in Atlassian Developer Console...
21
+
22
+ 1. Browser will open to create a new OAuth 2.0 (3LO) app
23
+ 2. Enter app name (e.g., "Jira CLI")
24
+ 3. After creation, go to "Permissions" and add:
25
+
26
+ Jira API:
27
+ - read:jira-work Search and read issues, comments, attachments
28
+ - read:jira-user Read user info for assignee/reporter fields
29
+
30
+ User Identity API:
31
+ - read:me Get your account ID and email for auth
32
+
33
+ 4. Go to "Authorization" and set callback URL:
34
+ http://localhost:8585/callback
35
+ 5. Go to "Settings" and copy Client ID and Secret
36
+ 6. Run: jira auth configure --client-id <ID> --client-secret <SECRET>
37
+ `);
38
+ const url = "https://developer.atlassian.com/console/myapps/create-3lo-app/";
39
+ yield* PlatformCommand.make("open", url).pipe(PlatformCommand.exitCode, Effect.catchAll(() => PlatformCommand.make("xdg-open", url).pipe(PlatformCommand.exitCode)), Effect.catchAll(() => PlatformCommand.make("cmd", "/c", "start", "", url).pipe(PlatformCommand.exitCode)), Effect.asVoid, Effect.catchAll(() => Effect.void));
40
+ })).pipe(Command.withDescription("Create OAuth app in Atlassian Developer Console"));
41
+ // === Auth configure command ===
42
+ const clientIdOption = Options.text("client-id").pipe(Options.withDescription("OAuth client ID from Atlassian Developer Console"), Options.optional);
43
+ const clientSecretOption = Options.text("client-secret").pipe(Options.withDescription("OAuth client secret"), Options.optional);
44
+ const configureCommand = Command.make("configure", { clientId: clientIdOption, clientSecret: clientSecretOption }, ({ clientId, clientSecret }) => Effect.gen(function* () {
45
+ const auth = yield* JiraAuth;
46
+ const rawClientId = Option.isSome(clientId)
47
+ ? clientId.value
48
+ : yield* Prompt.text({ message: "Enter OAuth client ID:" });
49
+ const rawClientSecret = Option.isSome(clientSecret)
50
+ ? clientSecret.value
51
+ : yield* Prompt.text({ message: "Enter OAuth client secret:" });
52
+ yield* auth.configure({ clientId: rawClientId, clientSecret: rawClientSecret });
53
+ yield* Console.log("OAuth configured. Run 'jira auth login' to authenticate.");
54
+ })).pipe(Command.withDescription("Configure OAuth client credentials"));
55
+ // === Auth login command ===
56
+ const siteOption = Options.text("site").pipe(Options.withDescription("Jira site URL to use (for accounts with multiple sites)"), Options.optional);
57
+ const loginCommand = Command.make("login", { site: siteOption }, ({ site }) => Effect.gen(function* () {
58
+ const auth = yield* JiraAuth;
59
+ const result = yield* auth.login(Option.isSome(site) ? { siteUrl: site.value } : undefined);
60
+ if (Array.isArray(result) && result.length > 0) {
61
+ yield* Console.log("\nRe-run with --site to select a specific site.");
62
+ }
63
+ })).pipe(Command.withDescription("Authenticate with Atlassian via OAuth"));
64
+ // === Auth logout command ===
65
+ const logoutCommand = Command.make("logout", {}, () => Effect.gen(function* () {
66
+ const auth = yield* JiraAuth;
67
+ yield* auth.logout();
68
+ yield* Console.log("Logged out");
69
+ })).pipe(Command.withDescription("Remove stored authentication"));
70
+ // === Auth status command ===
71
+ const statusCommand = Command.make("status", {}, () => Effect.gen(function* () {
72
+ const auth = yield* JiraAuth;
73
+ const user = yield* auth.getCurrentUser();
74
+ if (user) {
75
+ yield* Console.log(`Logged in as: ${user.name} (${user.email})`);
76
+ }
77
+ else {
78
+ yield* Console.log("Not logged in. Use 'jira auth login' to authenticate.");
79
+ }
80
+ })).pipe(Command.withDescription("Show authentication status"));
81
+ // === Auth command group ===
82
+ export const authCommand = Command.make("auth").pipe(Command.withDescription("Manage OAuth authentication"), Command.withSubcommands([
83
+ createCommand,
84
+ configureCommand,
85
+ loginCommand,
86
+ logoutCommand,
87
+ statusCommand
88
+ ]));
89
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Effect-idiomatic error handler — uses Cause.pretty for structured failure output.
3
+ *
4
+ * @internal
5
+ */
6
+ import * as Cause from "effect/Cause";
7
+ import type * as Effect from "effect/Effect";
8
+ /**
9
+ * Handle errors from CLI execution.
10
+ * Logs the pretty-printed cause to stderr via Console.error.
11
+ */
12
+ export declare const handleError: <E>(cause: Cause.Cause<E>) => Effect.Effect<void>;
13
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/commands/errorHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAE5C;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAuC,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Effect-idiomatic error handler — uses Cause.pretty for structured failure output.
3
+ *
4
+ * @internal
5
+ */
6
+ import * as Cause from "effect/Cause";
7
+ import * as Console from "effect/Console";
8
+ /**
9
+ * Handle errors from CLI execution.
10
+ * Logs the pretty-printed cause to stderr via Console.error.
11
+ */
12
+ export const handleError = (cause) => Console.error(Cause.pretty(cause));
13
+ //# sourceMappingURL=errorHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/commands/errorHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAGzC;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,KAAqB,EAAuB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `jira get <key>` command — fetches a single issue and writes to Markdown.
3
+ *
4
+ * @internal
5
+ */
6
+ import { Command } from "@effect/cli";
7
+ import { IssueService } from "../IssueService.js";
8
+ import { MarkdownWriter } from "../MarkdownWriter.js";
9
+ export declare const getCommand: Command.Command<"get", IssueService | MarkdownWriter, import("../JiraCliError.js").JiraApiError | import("../JiraCliError.js").WriteError, {
10
+ readonly key: string;
11
+ readonly outputDir: string;
12
+ }>;
13
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAQ,OAAO,EAAW,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAYrD,eAAO,MAAM,UAAU;;;EAoB0C,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `jira get <key>` command — fetches a single issue and writes to Markdown.
3
+ *
4
+ * @internal
5
+ */
6
+ import { Args, Command, Options } from "@effect/cli";
7
+ import * as Console from "effect/Console";
8
+ import * as Effect from "effect/Effect";
9
+ import { IssueService } from "../IssueService.js";
10
+ import { MarkdownWriter } from "../MarkdownWriter.js";
11
+ const keyArg = Args.text({ name: "key" }).pipe(Args.withDescription("Issue key (e.g., PROJ-123)"));
12
+ const outputDirOption = Options.directory("output-dir").pipe(Options.withAlias("o"), Options.withDescription("Output directory for markdown file"), Options.withDefault("./jira-tickets"));
13
+ export const getCommand = Command.make("get", {
14
+ key: keyArg,
15
+ outputDir: outputDirOption
16
+ }, ({ key, outputDir }) => Effect.gen(function* () {
17
+ const issueService = yield* IssueService;
18
+ const writer = yield* MarkdownWriter;
19
+ yield* Console.log(`Fetching ${key}...`);
20
+ const issue = yield* issueService.getByKey(key);
21
+ yield* Console.log(`Writing to ${outputDir}/${key}.md...`);
22
+ yield* writer.writeMulti([issue], outputDir);
23
+ yield* Console.log(`Done.`);
24
+ })).pipe(Command.withDescription("Get a single Jira issue by key"));
25
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAC5C,IAAI,CAAC,eAAe,CAAC,4BAA4B,CAAC,CACnD,CAAA;AAED,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAC1D,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,eAAe,CAAC,oCAAoC,CAAC,EAC7D,OAAO,CAAC,WAAW,CAAC,gBAAgB,CAAC,CACtC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CACpC,KAAK,EACL;IACE,GAAG,EAAE,MAAM;IACX,SAAS,EAAE,eAAe;CAC3B,EACD,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,CACrB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,YAAY,CAAA;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IAEpC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,CAAA;IAExC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAE/C,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,IAAI,GAAG,QAAQ,CAAC,CAAA;IAC1D,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAA;IAE5C,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC,CAAC,CACL,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,gCAAgC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Barrel export for CLI commands and layer definitions.
3
+ *
4
+ * @module
5
+ */
6
+ export { authCommand } from "./auth.js";
7
+ export { handleError } from "./errorHandler.js";
8
+ export { getCommand } from "./get.js";
9
+ export { AppLayer, AuthOnlyLayer, getLayerType, MinimalLayer } from "./layers.js";
10
+ export { searchCommand } from "./search.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Barrel export for CLI commands and layer definitions.
3
+ *
4
+ * @module
5
+ */
6
+ export { authCommand } from "./auth.js";
7
+ export { handleError } from "./errorHandler.js";
8
+ export { getCommand } from "./get.js";
9
+ export { AppLayer, AuthOnlyLayer, getLayerType, MinimalLayer } from "./layers.js";
10
+ export { searchCommand } from "./search.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Layer composition for CLI commands with three tiers: full, auth-only, minimal.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Lazy layer selection**: {@link getLayerType} inspects `process.argv[2]` to pick
7
+ * the smallest layer needed — `"minimal"` for help/version, `"auth"` for auth commands,
8
+ * `"full"` for search/get (which needs API client + issue service).
9
+ * - **Dummy services**: Auth-only and minimal layers provide `Effect.dieMessage` stubs
10
+ * for unused services to satisfy the type system without initialization cost.
11
+ *
12
+ * @internal
13
+ */
14
+ import * as NodeContext from "@effect/platform-node/NodeContext";
15
+ import { JiraApiClient } from "@knpkv/jira-api-client";
16
+ import * as Layer from "effect/Layer";
17
+ import { IssueService, SiteUrl } from "../IssueService.js";
18
+ import { JiraAuth } from "../JiraAuth.js";
19
+ import { MarkdownWriter } from "../MarkdownWriter.js";
20
+ /**
21
+ * Full app layer with all services for search commands.
22
+ *
23
+ * @category Layers
24
+ */
25
+ export declare const AppLayer: Layer.Layer<SiteUrl | IssueService | JiraApiClient | JiraAuth | import("@effect/platform/HttpClient").HttpClient | MarkdownWriter | NodeContext.NodeContext, import("../JiraCliError.js").AuthMissingError | import("@knpkv/atlassian-common/auth").OAuthError | import("@knpkv/atlassian-common/config").FileSystemError | import("@knpkv/atlassian-common/config").HomeDirectoryError | import("@effect/platform/Error").PlatformError, never>;
26
+ /**
27
+ * Auth-only layer for auth commands.
28
+ *
29
+ * @category Layers
30
+ */
31
+ export declare const AuthOnlyLayer: Layer.Layer<IssueService | JiraAuth | import("@effect/platform/HttpClient").HttpClient | MarkdownWriter | NodeContext.NodeContext, never, never>;
32
+ /**
33
+ * Minimal layer for help/version commands.
34
+ *
35
+ * @category Layers
36
+ */
37
+ export declare const MinimalLayer: Layer.Layer<IssueService | JiraAuth | MarkdownWriter | NodeContext.NodeContext, never, never>;
38
+ /**
39
+ * Determine which layer to use based on command.
40
+ *
41
+ * @category Utilities
42
+ */
43
+ export declare const getLayerType: (argv: ReadonlyArray<string>) => "full" | "auth" | "minimal";
44
+ //# sourceMappingURL=layers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,WAAW,MAAM,mCAAmC,CAAA;AAEhE,OAAO,EAAE,aAAa,EAAiB,MAAM,wBAAwB,CAAA;AAErE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,YAAY,EAA8B,OAAO,EAAE,MAAM,oBAAoB,CAAA;AACtF,OAAO,EAAE,QAAQ,EAA0B,MAAM,gBAAgB,CAAA;AACjE,OAAO,EAAgC,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAsEnF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,kbAOpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,kJAKzB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,+FAIxB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,aAAa,CAAC,MAAM,CAAC,KAAG,MAAM,GAAG,MAAM,GAAG,SAS5E,CAAA"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Layer composition for CLI commands with three tiers: full, auth-only, minimal.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **Lazy layer selection**: {@link getLayerType} inspects `process.argv[2]` to pick
7
+ * the smallest layer needed — `"minimal"` for help/version, `"auth"` for auth commands,
8
+ * `"full"` for search/get (which needs API client + issue service).
9
+ * - **Dummy services**: Auth-only and minimal layers provide `Effect.dieMessage` stubs
10
+ * for unused services to satisfy the type system without initialization cost.
11
+ *
12
+ * @internal
13
+ */
14
+ import * as NodeContext from "@effect/platform-node/NodeContext";
15
+ import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
16
+ import { JiraApiClient, JiraApiConfig } from "@knpkv/jira-api-client";
17
+ import * as Effect from "effect/Effect";
18
+ import * as Layer from "effect/Layer";
19
+ import { IssueService, layer as IssueServiceLayer, SiteUrl } from "../IssueService.js";
20
+ import { JiraAuth, layer as JiraAuthLayer } from "../JiraAuth.js";
21
+ import { layer as MarkdownWriterLayer, MarkdownWriter } from "../MarkdownWriter.js";
22
+ // Dummy services for auth-only commands
23
+ const DummyIssueServiceLayer = Layer.succeed(IssueService, IssueService.of({
24
+ getByKey: () => Effect.dieMessage("Not configured - run 'jira auth login' first"),
25
+ search: () => Effect.dieMessage("Not configured - run 'jira auth login' first"),
26
+ searchAll: () => Effect.dieMessage("Not configured - run 'jira auth login' first")
27
+ }));
28
+ const DummyMarkdownWriterLayer = Layer.succeed(MarkdownWriter, MarkdownWriter.of({
29
+ writeMulti: () => Effect.dieMessage("Not configured"),
30
+ writeSingle: () => Effect.dieMessage("Not configured")
31
+ }));
32
+ const DummyJiraAuthLayer = Layer.succeed(JiraAuth, JiraAuth.of({
33
+ configure: () => Effect.dieMessage("Not configured"),
34
+ isConfigured: () => Effect.succeed(false),
35
+ login: () => Effect.dieMessage("Not configured"),
36
+ logout: () => Effect.dieMessage("Not configured"),
37
+ getAccessToken: () => Effect.dieMessage("Not configured"),
38
+ getCloudId: () => Effect.dieMessage("Not configured"),
39
+ getSiteUrl: () => Effect.dieMessage("Not configured"),
40
+ getCurrentUser: () => Effect.succeed(null),
41
+ isLoggedIn: () => Effect.succeed(false)
42
+ }));
43
+ // Auth layer with HTTP client
44
+ const AuthLive = JiraAuthLayer.pipe(Layer.provide(NodeHttpClient.layer));
45
+ // Build Jira API config layer dynamically based on auth
46
+ const JiraConfigLive = Layer.unwrapEffect(Effect.gen(function* () {
47
+ const auth = yield* JiraAuth;
48
+ const accessToken = yield* auth.getAccessToken();
49
+ const cloudId = yield* auth.getCloudId();
50
+ return Layer.succeed(JiraApiConfig, {
51
+ baseUrl: "",
52
+ auth: {
53
+ type: "oauth2",
54
+ accessToken,
55
+ cloudId
56
+ }
57
+ });
58
+ }));
59
+ // Build Jira API client layer with config (no HttpClient needed — uses openapi-fetch)
60
+ const JiraClientLive = JiraApiClient.layer.pipe(Layer.provide(JiraConfigLive));
61
+ // Build SiteUrl layer from auth
62
+ const SiteUrlLive = Layer.unwrapEffect(Effect.gen(function* () {
63
+ const auth = yield* JiraAuth;
64
+ const siteUrl = yield* auth.getSiteUrl();
65
+ return Layer.succeed(SiteUrl, siteUrl);
66
+ }));
67
+ /**
68
+ * Full app layer with all services for search commands.
69
+ *
70
+ * @category Layers
71
+ */
72
+ export const AppLayer = MarkdownWriterLayer.pipe(Layer.provideMerge(IssueServiceLayer), Layer.provideMerge(SiteUrlLive), Layer.provideMerge(JiraClientLive), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.layer), Layer.provideMerge(NodeContext.layer));
73
+ /**
74
+ * Auth-only layer for auth commands.
75
+ *
76
+ * @category Layers
77
+ */
78
+ export const AuthOnlyLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.layer), Layer.provideMerge(NodeContext.layer));
79
+ /**
80
+ * Minimal layer for help/version commands.
81
+ *
82
+ * @category Layers
83
+ */
84
+ export const MinimalLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(DummyJiraAuthLayer), Layer.provideMerge(NodeContext.layer));
85
+ /**
86
+ * Determine which layer to use based on command.
87
+ *
88
+ * @category Utilities
89
+ */
90
+ export const getLayerType = (argv) => {
91
+ const cmd = argv[2];
92
+ if (cmd === "auth") {
93
+ return "auth";
94
+ }
95
+ if (!cmd || cmd === "--help" || cmd === "-h" || cmd === "--version") {
96
+ return "minimal";
97
+ }
98
+ return "full";
99
+ };
100
+ //# sourceMappingURL=layers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `jira search` command — JQL search with multi/single Markdown output.
3
+ *
4
+ * @internal
5
+ */
6
+ import { Command } from "@effect/cli";
7
+ import * as Option from "effect/Option";
8
+ import { IssueService } from "../IssueService.js";
9
+ import { MarkdownWriter } from "../MarkdownWriter.js";
10
+ export declare const searchCommand: Command.Command<"search", IssueService | MarkdownWriter, import("../JiraCliError.js").JiraApiError | import("../JiraCliError.js").WriteError, {
11
+ readonly jql: Option.Option<string>;
12
+ readonly byVersion: Option.Option<string>;
13
+ readonly project: Option.Option<string>;
14
+ readonly outputDir: string;
15
+ readonly format: "multi" | "single";
16
+ readonly maxResults: number;
17
+ }>;
18
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAQ,OAAO,EAAW,MAAM,aAAa,CAAA;AAGpD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAuCrD,eAAO,MAAM,aAAa;;;;;;;EAmDkD,CAAA"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * `jira search` command — JQL search with multi/single Markdown output.
3
+ *
4
+ * @internal
5
+ */
6
+ import { Args, Command, Options } from "@effect/cli";
7
+ import * as Console from "effect/Console";
8
+ import * as Effect from "effect/Effect";
9
+ import * as Option from "effect/Option";
10
+ import { buildByVersionJql } from "../internal/jqlBuilder.js";
11
+ import { IssueService } from "../IssueService.js";
12
+ import { MarkdownWriter } from "../MarkdownWriter.js";
13
+ // === Options ===
14
+ const jqlArg = Args.text({ name: "jql" }).pipe(Args.withDescription("JQL query to search for issues"), Args.optional);
15
+ const byVersionOption = Options.text("by-version").pipe(Options.withAlias("v"), Options.withDescription("Search by fix version (pre-defined query)"), Options.optional);
16
+ const projectOption = Options.text("project").pipe(Options.withAlias("p"), Options.withDescription("Filter by project key"), Options.optional);
17
+ const outputDirOption = Options.directory("output-dir").pipe(Options.withAlias("o"), Options.withDescription("Output directory for markdown files"), Options.withDefault("./jira-tickets"));
18
+ const formatOption = Options.choice("format", ["multi", "single"]).pipe(Options.withAlias("f"), Options.withDescription("Output format: multi (one file per issue) or single (combined file)"), Options.withDefault("multi"));
19
+ const maxResultsOption = Options.integer("max-results").pipe(Options.withAlias("m"), Options.withDescription("Maximum number of results to fetch"), Options.withDefault(100));
20
+ // === Search command ===
21
+ export const searchCommand = Command.make("search", {
22
+ jql: jqlArg,
23
+ byVersion: byVersionOption,
24
+ project: projectOption,
25
+ outputDir: outputDirOption,
26
+ format: formatOption,
27
+ maxResults: maxResultsOption
28
+ }, ({ byVersion, format, jql, maxResults, outputDir, project }) => Effect.gen(function* () {
29
+ const issueService = yield* IssueService;
30
+ const writer = yield* MarkdownWriter;
31
+ // Build JQL query
32
+ let query;
33
+ if (Option.isSome(byVersion)) {
34
+ const projectKey = Option.isSome(project) ? project.value : undefined;
35
+ query = buildByVersionJql(byVersion.value, projectKey);
36
+ yield* Console.log(`Searching by fix version: ${byVersion.value}`);
37
+ }
38
+ else if (Option.isSome(jql)) {
39
+ query = jql.value;
40
+ }
41
+ else {
42
+ yield* Console.log("Error: Either a JQL query or --by-version must be provided.");
43
+ yield* Console.log("Usage: jira search <jql>");
44
+ yield* Console.log(" jira search --by-version <version>");
45
+ return;
46
+ }
47
+ yield* Console.log(`Query: ${query}`);
48
+ yield* Console.log("Fetching issues...");
49
+ const issues = yield* issueService.searchAll(query, { maxResults });
50
+ if (issues.length === 0) {
51
+ yield* Console.log("No issues found.");
52
+ return;
53
+ }
54
+ yield* Console.log(`Found ${issues.length} issue(s). Writing to ${outputDir}...`);
55
+ if (format === "single") {
56
+ yield* writer.writeSingle(issues, outputDir, query);
57
+ yield* Console.log(`Exported to ${outputDir}/jira-export.md`);
58
+ }
59
+ else {
60
+ yield* writer.writeMulti(issues, outputDir);
61
+ yield* Console.log(`Exported ${issues.length} file(s) to ${outputDir}/`);
62
+ }
63
+ })).pipe(Command.withDescription("Search Jira issues and export to markdown"));
64
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Root barrel export for `@knpkv/jira-cli`.
3
+ *
4
+ * @module
5
+ */
6
+ export { type Attachment, type Comment, type Issue, IssueService, type IssueServiceShape, layer as IssueServiceLayer, type SearchOptions, type SearchResult, SiteUrl } from "./IssueService.js";
7
+ export { type AccessibleSite, JiraAuth, type JiraAuthService, layer as JiraAuthLayer, type LoginOptions } from "./JiraAuth.js";
8
+ export * from "./JiraCliError.js";
9
+ export { layer as MarkdownWriterLayer, MarkdownWriter, type MarkdownWriterShape } from "./MarkdownWriter.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;;;;GAIG;AAEH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,IAAI,iBAAiB,EAC1B,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,OAAO,EACR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,cAAc,EACnB,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,IAAI,aAAa,EACtB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAA;AACtB,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,KAAK,IAAI,mBAAmB,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Root barrel export for `@knpkv/jira-cli`.
3
+ *
4
+ * @module
5
+ */
6
+ export { IssueService, layer as IssueServiceLayer, SiteUrl } from "./IssueService.js";
7
+ export { JiraAuth, layer as JiraAuthLayer } from "./JiraAuth.js";
8
+ export * from "./JiraCliError.js";
9
+ export { layer as MarkdownWriterLayer, MarkdownWriter } from "./MarkdownWriter.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,YAAY,EAEZ,KAAK,IAAI,iBAAiB,EAG1B,OAAO,EACR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAEL,QAAQ,EAER,KAAK,IAAI,aAAa,EAEvB,MAAM,eAAe,CAAA;AACtB,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,KAAK,IAAI,mBAAmB,EAAE,cAAc,EAA4B,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * HTTP Server factory layer using Node.js http module.
3
+ *
4
+ * @category Layers
5
+ */
6
+ export declare const HttpServerFactoryLive: import("effect/Layer").Layer<import("./oauthServer.js").HttpServerFactoryTag, never, never>;
7
+ //# sourceMappingURL=NodeLayers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeLayers.d.ts","sourceRoot":"","sources":["../../src/internal/NodeLayers.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,6FAEjC,CAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Node.js-specific HTTP server factory — the only file importing `@effect/platform-node` server.
3
+ *
4
+ * @internal
5
+ */
6
+ import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
7
+ import { createServer } from "node:http";
8
+ import { makeHttpServerFactory } from "./oauthServer.js";
9
+ /**
10
+ * HTTP Server factory layer using Node.js http module.
11
+ *
12
+ * @category Layers
13
+ */
14
+ export const HttpServerFactoryLive = makeHttpServerFactory((port) => NodeHttpServer.layerServer(createServer, { port }));
15
+ //# sourceMappingURL=NodeLayers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeLayers.js","sourceRoot":"","sources":["../../src/internal/NodeLayers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CACxD,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAC7D,CAAA"}
@@ -0,0 +1,60 @@
1
+ import type { Issue } from "../IssueService.js";
2
+ /**
3
+ * Front-matter data for a Jira issue.
4
+ *
5
+ * @category Types
6
+ */
7
+ export interface IssueFrontMatter {
8
+ readonly key: string;
9
+ readonly id: string;
10
+ readonly summary: string;
11
+ readonly status: string;
12
+ readonly type: string;
13
+ readonly priority: string | null;
14
+ readonly assignee: string | null;
15
+ readonly reporter: string | null;
16
+ readonly created: string;
17
+ readonly updated: string;
18
+ readonly fixVersions: ReadonlyArray<string>;
19
+ readonly labels: ReadonlyArray<string>;
20
+ readonly components: ReadonlyArray<string>;
21
+ readonly url: string;
22
+ }
23
+ /**
24
+ * Extract front-matter data from an issue.
25
+ *
26
+ * @param issue - The issue to extract from
27
+ * @returns Front-matter object
28
+ *
29
+ * @category Utilities
30
+ */
31
+ export declare const extractFrontMatter: (issue: Issue) => IssueFrontMatter;
32
+ /**
33
+ * Serialize an issue to markdown with front-matter.
34
+ *
35
+ * @param issue - The issue to serialize
36
+ * @returns Markdown string with YAML front-matter
37
+ *
38
+ * @category Serialization
39
+ */
40
+ export declare const serializeIssue: (issue: Issue) => string;
41
+ /**
42
+ * Build markdown content for an issue (without front-matter).
43
+ *
44
+ * @param issue - The issue to build content for
45
+ * @returns Markdown content string
46
+ *
47
+ * @category Serialization
48
+ */
49
+ export declare const buildMarkdownContent: (issue: Issue) => string;
50
+ /**
51
+ * Build a combined markdown file for multiple issues.
52
+ *
53
+ * @param issues - The issues to include
54
+ * @param jql - The JQL query used (for header)
55
+ * @returns Combined markdown string
56
+ *
57
+ * @category Serialization
58
+ */
59
+ export declare const buildCombinedMarkdown: (issues: ReadonlyArray<Issue>, jql: string) => string;
60
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/internal/frontmatter.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE/C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,KAAK,KAAG,gBAehD,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,KAAG,MAI7C,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,KAAG,MAuCnD,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,KAAG,MAqCjF,CAAA"}