@knpkv/jira-cli 0.1.1 → 1.0.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.
- package/CHANGELOG.md +67 -0
- package/README.md +66 -4
- package/dist/IssueService.d.ts +2 -2
- package/dist/IssueService.d.ts.map +1 -1
- package/dist/IssueService.js +3 -3
- package/dist/IssueService.js.map +1 -1
- package/dist/JiraAuth.d.ts +14 -14
- package/dist/JiraAuth.d.ts.map +1 -1
- package/dist/JiraAuth.js +18 -10
- package/dist/JiraAuth.js.map +1 -1
- package/dist/JiraCliError.d.ts +30 -0
- package/dist/JiraCliError.d.ts.map +1 -1
- package/dist/JiraCliError.js +14 -0
- package/dist/JiraCliError.js.map +1 -1
- package/dist/MarkdownWriter.d.ts +4 -4
- package/dist/MarkdownWriter.d.ts.map +1 -1
- package/dist/MarkdownWriter.js +6 -6
- package/dist/MarkdownWriter.js.map +1 -1
- package/dist/SyncWorkspace.d.ts +34 -0
- package/dist/SyncWorkspace.d.ts.map +1 -0
- package/dist/SyncWorkspace.js +105 -0
- package/dist/SyncWorkspace.js.map +1 -0
- package/dist/VersionService.d.ts +206 -0
- package/dist/VersionService.d.ts.map +1 -0
- package/dist/VersionService.js +426 -0
- package/dist/VersionService.js.map +1 -0
- package/dist/bin.js +29 -22
- package/dist/bin.js.map +1 -1
- package/dist/commands/auth.d.ts +2 -21
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +6 -6
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/get.d.ts +3 -8
- package/dist/commands/get.d.ts.map +1 -1
- package/dist/commands/get.js +4 -4
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/index.d.ts +2 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -2
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/issue.d.ts +8 -0
- package/dist/commands/issue.d.ts.map +1 -0
- package/dist/commands/issue.js +10 -0
- package/dist/commands/issue.js.map +1 -0
- package/dist/commands/layers.d.ts +6 -18
- package/dist/commands/layers.d.ts.map +1 -1
- package/dist/commands/layers.js +35 -24
- package/dist/commands/layers.js.map +1 -1
- package/dist/commands/search.d.ts +3 -8
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +8 -8
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/version.d.ts +12 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +179 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +14 -1
- package/dist/internal/frontmatter.js.map +1 -1
- package/dist/internal/oauthServer.d.ts +17 -5
- package/dist/internal/oauthServer.d.ts.map +1 -1
- package/dist/internal/oauthServer.js +23 -40
- package/dist/internal/oauthServer.js.map +1 -1
- package/dist/internal/openBrowser.d.ts +10 -0
- package/dist/internal/openBrowser.d.ts.map +1 -0
- package/dist/internal/openBrowser.js +17 -0
- package/dist/internal/openBrowser.js.map +1 -0
- package/dist/internal/sync/baseline.d.ts +11 -0
- package/dist/internal/sync/baseline.d.ts.map +1 -0
- package/dist/internal/sync/baseline.js +18 -0
- package/dist/internal/sync/baseline.js.map +1 -0
- package/dist/internal/sync/changes.d.ts +15 -0
- package/dist/internal/sync/changes.d.ts.map +1 -0
- package/dist/internal/sync/changes.js +72 -0
- package/dist/internal/sync/changes.js.map +1 -0
- package/dist/internal/sync/config.d.ts +12 -0
- package/dist/internal/sync/config.d.ts.map +1 -0
- package/dist/internal/sync/config.js +53 -0
- package/dist/internal/sync/config.js.map +1 -0
- package/dist/internal/sync/document.d.ts +9 -0
- package/dist/internal/sync/document.d.ts.map +1 -0
- package/dist/internal/sync/document.js +173 -0
- package/dist/internal/sync/document.js.map +1 -0
- package/dist/internal/sync/fieldValues.d.ts +30 -0
- package/dist/internal/sync/fieldValues.d.ts.map +1 -0
- package/dist/internal/sync/fieldValues.js +91 -0
- package/dist/internal/sync/fieldValues.js.map +1 -0
- package/dist/internal/sync/manifest.d.ts +12 -0
- package/dist/internal/sync/manifest.d.ts.map +1 -0
- package/dist/internal/sync/manifest.js +23 -0
- package/dist/internal/sync/manifest.js.map +1 -0
- package/dist/internal/sync/paths.d.ts +26 -0
- package/dist/internal/sync/paths.d.ts.map +1 -0
- package/dist/internal/sync/paths.js +22 -0
- package/dist/internal/sync/paths.js.map +1 -0
- package/dist/internal/sync/schemas.d.ts +128 -0
- package/dist/internal/sync/schemas.d.ts.map +1 -0
- package/dist/internal/sync/schemas.js +82 -0
- package/dist/internal/sync/schemas.js.map +1 -0
- package/dist/internal/sync/types.d.ts +144 -0
- package/dist/internal/sync/types.d.ts.map +1 -0
- package/dist/internal/sync/types.js +17 -0
- package/dist/internal/sync/types.js.map +1 -0
- package/package.json +13 -12
- package/skills/jira/SKILL.md +90 -0
- package/skills/jira/agents/openai.yaml +4 -0
- package/src/IssueService.ts +34 -28
- package/src/JiraAuth.ts +53 -39
- package/src/JiraCliError.ts +24 -0
- package/src/MarkdownWriter.ts +7 -11
- package/src/SyncWorkspace.ts +185 -0
- package/src/VersionService.ts +647 -0
- package/src/bin.ts +39 -29
- package/src/commands/auth.ts +6 -12
- package/src/commands/get.ts +4 -4
- package/src/commands/index.ts +2 -2
- package/src/commands/issue.ts +13 -0
- package/src/commands/layers.ts +44 -26
- package/src/commands/search.ts +8 -8
- package/src/commands/version.ts +267 -0
- package/src/internal/frontmatter.ts +15 -1
- package/src/internal/oauthServer.ts +43 -70
- package/src/internal/openBrowser.ts +31 -0
- package/src/internal/sync/baseline.ts +27 -0
- package/src/internal/sync/changes.ts +118 -0
- package/src/internal/sync/config.ts +76 -0
- package/src/internal/sync/document.ts +201 -0
- package/src/internal/sync/fieldValues.ts +145 -0
- package/src/internal/sync/manifest.ts +32 -0
- package/src/internal/sync/paths.ts +48 -0
- package/src/internal/sync/schemas.ts +103 -0
- package/src/internal/sync/types.ts +192 -0
- package/test/SyncWorkspace.test.ts +76 -0
- package/test/VersionService.test.ts +266 -0
- package/test/commandTree.test.ts +266 -0
- package/test/frontmatter.test.ts +69 -0
- package/test/integration.test.ts +187 -0
- package/test/syncChanges.test.ts +106 -0
- package/test/syncConfig.test.ts +138 -0
- package/test/syncDocument.test.ts +69 -0
- package/test/syncFieldValues.test.ts +101 -0
- package/vitest.config.integration.ts +17 -0
- package/vitest.config.ts +6 -0
package/dist/commands/get.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
* `jira get <key>` command — fetches a single issue and writes to Markdown.
|
|
3
|
-
*
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
import { Command } from "@effect/cli";
|
|
1
|
+
import { Command } from "effect/unstable/cli";
|
|
7
2
|
import { IssueService } from "../IssueService.js";
|
|
8
3
|
import { MarkdownWriter } from "../MarkdownWriter.js";
|
|
9
|
-
export declare const getCommand: Command.Command<"get",
|
|
4
|
+
export declare const getCommand: Command.Command<"get", {
|
|
10
5
|
readonly key: string;
|
|
11
6
|
readonly outputDir: string;
|
|
12
|
-
}>;
|
|
7
|
+
}, {}, import("../JiraCliError.js").JiraApiError | import("../JiraCliError.js").WriteError, IssueService | MarkdownWriter>;
|
|
13
8
|
//# sourceMappingURL=get.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAOA,OAAO,EAAoB,OAAO,EAAmB,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAYrD,eAAO,MAAM,UAAU;;;0HAoBqD,CAAA"}
|
package/dist/commands/get.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `jira get <key>` command — fetches a single issue and writes to Markdown.
|
|
2
|
+
* `jira issue get <key>` command — fetches a single issue and writes to Markdown.
|
|
3
3
|
*
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|
|
6
|
-
import { Args, Command, Options } from "@effect/cli";
|
|
7
6
|
import * as Console from "effect/Console";
|
|
8
7
|
import * as Effect from "effect/Effect";
|
|
8
|
+
import { Argument as Args, Command, Flag as Options } from "effect/unstable/cli";
|
|
9
9
|
import { IssueService } from "../IssueService.js";
|
|
10
10
|
import { MarkdownWriter } from "../MarkdownWriter.js";
|
|
11
|
-
const keyArg = Args.
|
|
11
|
+
const keyArg = Args.string("key").pipe(Args.withDescription("Issue key (e.g., PROJ-123)"));
|
|
12
12
|
const outputDirOption = Options.directory("output-dir").pipe(Options.withAlias("o"), Options.withDescription("Output directory for markdown file"), Options.withDefault("./jira-tickets"));
|
|
13
13
|
export const getCommand = Command.make("get", {
|
|
14
14
|
key: keyArg,
|
|
@@ -21,5 +21,5 @@ export const getCommand = Command.make("get", {
|
|
|
21
21
|
yield* Console.log(`Writing to ${outputDir}/${key}.md...`);
|
|
22
22
|
yield* writer.writeMulti([issue], outputDir);
|
|
23
23
|
yield* Console.log(`Done.`);
|
|
24
|
-
})).pipe(Command.withDescription("
|
|
24
|
+
})).pipe(Command.withDescription("Read-only: get a single Jira issue by key"));
|
|
25
25
|
//# sourceMappingURL=get.js.map
|
package/dist/commands/get.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACpC,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,2CAA2C,CAAC,CAAC,CAAA"}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { authCommand } from "./auth.js";
|
|
7
7
|
export { handleError } from "./errorHandler.js";
|
|
8
|
-
export {
|
|
8
|
+
export { issueCommand } from "./issue.js";
|
|
9
9
|
export { AppLayer, AuthOnlyLayer, getLayerType, MinimalLayer } from "./layers.js";
|
|
10
|
-
export {
|
|
10
|
+
export { versionCommand } from "./version.js";
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +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,
|
|
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,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/commands/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { authCommand } from "./auth.js";
|
|
7
7
|
export { handleError } from "./errorHandler.js";
|
|
8
|
-
export {
|
|
8
|
+
export { issueCommand } from "./issue.js";
|
|
9
9
|
export { AppLayer, AuthOnlyLayer, getLayerType, MinimalLayer } from "./layers.js";
|
|
10
|
-
export {
|
|
10
|
+
export { versionCommand } from "./version.js";
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +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,
|
|
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,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jira issue` command namespace.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "effect/unstable/cli";
|
|
7
|
+
export declare const issueCommand: Command.Command<"issue", {}, {}, import("../JiraCliError.js").JiraApiError | import("../JiraCliError.js").WriteError, never>;
|
|
8
|
+
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAI7C,eAAO,MAAM,YAAY,8HAGxB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jira issue` command namespace.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "effect/unstable/cli";
|
|
7
|
+
import { getCommand } from "./get.js";
|
|
8
|
+
import { searchCommand } from "./search.js";
|
|
9
|
+
export const issueCommand = Command.make("issue").pipe(Command.withDescription("Read-only Jira issue commands"), Command.withSubcommands([getCommand, searchCommand]));
|
|
10
|
+
//# sourceMappingURL=issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CACpD,OAAO,CAAC,eAAe,CAAC,+BAA+B,CAAC,EACxD,OAAO,CAAC,eAAe,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CACrD,CAAA"}
|
|
@@ -1,44 +1,32 @@
|
|
|
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";
|
|
1
|
+
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
15
2
|
import { JiraApiClient } from "@knpkv/jira-api-client";
|
|
16
3
|
import * as Layer from "effect/Layer";
|
|
17
4
|
import { IssueService, SiteUrl } from "../IssueService.js";
|
|
18
5
|
import { JiraAuth } from "../JiraAuth.js";
|
|
19
6
|
import { MarkdownWriter } from "../MarkdownWriter.js";
|
|
7
|
+
import { VersionService } from "../VersionService.js";
|
|
20
8
|
/**
|
|
21
9
|
* Full app layer with all services for search commands.
|
|
22
10
|
*
|
|
23
11
|
* @category Layers
|
|
24
12
|
*/
|
|
25
|
-
export declare const AppLayer: Layer.Layer<SiteUrl | IssueService | JiraApiClient | JiraAuth | import("
|
|
13
|
+
export declare const AppLayer: Layer.Layer<SiteUrl | IssueService | JiraApiClient | JiraAuth | import("effect/unstable/http/HttpClient").HttpClient | MarkdownWriter | VersionService | NodeServices.NodeServices, import("../JiraCliError.js").AuthMissingError | import("@knpkv/atlassian-common/auth").OAuthError | import("effect/PlatformError").PlatformError | import("@knpkv/atlassian-common/config").FileSystemError | import("@knpkv/atlassian-common/config").HomeDirectoryError, never>;
|
|
26
14
|
/**
|
|
27
15
|
* Auth-only layer for auth commands.
|
|
28
16
|
*
|
|
29
17
|
* @category Layers
|
|
30
18
|
*/
|
|
31
|
-
export declare const AuthOnlyLayer: Layer.Layer<IssueService | JiraAuth | import("
|
|
19
|
+
export declare const AuthOnlyLayer: Layer.Layer<IssueService | JiraAuth | import("effect/unstable/http/HttpClient").HttpClient | MarkdownWriter | VersionService | NodeServices.NodeServices, never, never>;
|
|
32
20
|
/**
|
|
33
21
|
* Minimal layer for help/version commands.
|
|
34
22
|
*
|
|
35
23
|
* @category Layers
|
|
36
24
|
*/
|
|
37
|
-
export declare const MinimalLayer: Layer.Layer<IssueService | JiraAuth | MarkdownWriter |
|
|
25
|
+
export declare const MinimalLayer: Layer.Layer<IssueService | JiraAuth | MarkdownWriter | VersionService | NodeServices.NodeServices, never, never>;
|
|
38
26
|
/**
|
|
39
27
|
* Determine which layer to use based on command.
|
|
40
28
|
*
|
|
41
29
|
* @category Utilities
|
|
42
30
|
*/
|
|
43
|
-
export declare const getLayerType: (
|
|
31
|
+
export declare const getLayerType: (args: ReadonlyArray<string>) => "full" | "auth" | "minimal";
|
|
44
32
|
//# sourceMappingURL=layers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,YAAY,MAAM,oCAAoC,CAAA;AAClE,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;AACnF,OAAO,EAAgC,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAiFnF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,ucAQpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,yKAMzB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,kHAKxB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,aAAa,CAAC,MAAM,CAAC,KAAG,MAAM,GAAG,MAAM,GAAG,SAY5E,CAAA"}
|
package/dist/commands/layers.js
CHANGED
|
@@ -3,47 +3,55 @@
|
|
|
3
3
|
*
|
|
4
4
|
* **Mental model**
|
|
5
5
|
*
|
|
6
|
-
* - **Lazy layer selection**: {@link getLayerType} inspects `
|
|
6
|
+
* - **Lazy layer selection**: {@link getLayerType} inspects CLI arguments from `Stdio` to pick
|
|
7
7
|
* the smallest layer needed — `"minimal"` for help/version, `"auth"` for auth commands,
|
|
8
|
-
* `"full"` for
|
|
9
|
-
* - **Dummy services**: Auth-only and minimal layers provide
|
|
8
|
+
* `"full"` for issue/version reads and writes.
|
|
9
|
+
* - **Dummy services**: Auth-only and minimal layers provide dying stubs
|
|
10
10
|
* for unused services to satisfy the type system without initialization cost.
|
|
11
11
|
*
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
|
-
import * as NodeContext from "@effect/platform-node/NodeContext";
|
|
15
14
|
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
|
|
15
|
+
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
16
16
|
import { JiraApiClient, JiraApiConfig } from "@knpkv/jira-api-client";
|
|
17
17
|
import * as Effect from "effect/Effect";
|
|
18
18
|
import * as Layer from "effect/Layer";
|
|
19
19
|
import { IssueService, layer as IssueServiceLayer, SiteUrl } from "../IssueService.js";
|
|
20
20
|
import { JiraAuth, layer as JiraAuthLayer } from "../JiraAuth.js";
|
|
21
21
|
import { layer as MarkdownWriterLayer, MarkdownWriter } from "../MarkdownWriter.js";
|
|
22
|
+
import { layer as VersionServiceLayer, VersionService } from "../VersionService.js";
|
|
22
23
|
// Dummy services for auth-only commands
|
|
23
24
|
const DummyIssueServiceLayer = Layer.succeed(IssueService, IssueService.of({
|
|
24
|
-
getByKey: () => Effect.
|
|
25
|
-
search: () => Effect.
|
|
26
|
-
searchAll: () => Effect.
|
|
25
|
+
getByKey: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
26
|
+
search: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
27
|
+
searchAll: () => Effect.die(new Error("Not configured - run 'jira auth login' first"))
|
|
27
28
|
}));
|
|
28
29
|
const DummyMarkdownWriterLayer = Layer.succeed(MarkdownWriter, MarkdownWriter.of({
|
|
29
|
-
writeMulti: () => Effect.
|
|
30
|
-
writeSingle: () => Effect.
|
|
30
|
+
writeMulti: () => Effect.die(new Error("Not configured")),
|
|
31
|
+
writeSingle: () => Effect.die(new Error("Not configured"))
|
|
32
|
+
}));
|
|
33
|
+
const DummyVersionServiceLayer = Layer.succeed(VersionService, VersionService.of({
|
|
34
|
+
listProjectVersions: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
35
|
+
getVersion: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
36
|
+
updateVersion: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
37
|
+
listRelatedWork: () => Effect.die(new Error("Not configured - run 'jira auth login' first")),
|
|
38
|
+
addRelatedWork: () => Effect.die(new Error("Not configured - run 'jira auth login' first"))
|
|
31
39
|
}));
|
|
32
40
|
const DummyJiraAuthLayer = Layer.succeed(JiraAuth, JiraAuth.of({
|
|
33
|
-
configure: () => Effect.
|
|
41
|
+
configure: () => Effect.die(new Error("Not configured")),
|
|
34
42
|
isConfigured: () => Effect.succeed(false),
|
|
35
|
-
login: () => Effect.
|
|
36
|
-
logout: () => Effect.
|
|
37
|
-
getAccessToken: () => Effect.
|
|
38
|
-
getCloudId: () => Effect.
|
|
39
|
-
getSiteUrl: () => Effect.
|
|
43
|
+
login: () => Effect.die(new Error("Not configured")),
|
|
44
|
+
logout: () => Effect.die(new Error("Not configured")),
|
|
45
|
+
getAccessToken: () => Effect.die(new Error("Not configured")),
|
|
46
|
+
getCloudId: () => Effect.die(new Error("Not configured")),
|
|
47
|
+
getSiteUrl: () => Effect.die(new Error("Not configured")),
|
|
40
48
|
getCurrentUser: () => Effect.succeed(null),
|
|
41
49
|
isLoggedIn: () => Effect.succeed(false)
|
|
42
50
|
}));
|
|
43
51
|
// Auth layer with HTTP client
|
|
44
|
-
const AuthLive = JiraAuthLayer.pipe(Layer.provide(NodeHttpClient.layer));
|
|
52
|
+
const AuthLive = JiraAuthLayer.pipe(Layer.provide(Layer.mergeAll(NodeHttpClient.layerUndici, NodeServices.layer)));
|
|
45
53
|
// Build Jira API config layer dynamically based on auth
|
|
46
|
-
const JiraConfigLive = Layer.
|
|
54
|
+
const JiraConfigLive = Layer.unwrap(Effect.gen(function* () {
|
|
47
55
|
const auth = yield* JiraAuth;
|
|
48
56
|
const accessToken = yield* auth.getAccessToken();
|
|
49
57
|
const cloudId = yield* auth.getCloudId();
|
|
@@ -59,7 +67,7 @@ const JiraConfigLive = Layer.unwrapEffect(Effect.gen(function* () {
|
|
|
59
67
|
// Build Jira API client layer with config (no HttpClient needed — uses openapi-fetch)
|
|
60
68
|
const JiraClientLive = JiraApiClient.layer.pipe(Layer.provide(JiraConfigLive));
|
|
61
69
|
// Build SiteUrl layer from auth
|
|
62
|
-
const SiteUrlLive = Layer.
|
|
70
|
+
const SiteUrlLive = Layer.unwrap(Effect.gen(function* () {
|
|
63
71
|
const auth = yield* JiraAuth;
|
|
64
72
|
const siteUrl = yield* auth.getSiteUrl();
|
|
65
73
|
return Layer.succeed(SiteUrl, siteUrl);
|
|
@@ -69,30 +77,33 @@ const SiteUrlLive = Layer.unwrapEffect(Effect.gen(function* () {
|
|
|
69
77
|
*
|
|
70
78
|
* @category Layers
|
|
71
79
|
*/
|
|
72
|
-
export const AppLayer = MarkdownWriterLayer.pipe(Layer.provideMerge(IssueServiceLayer), Layer.provideMerge(SiteUrlLive), Layer.provideMerge(JiraClientLive), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.
|
|
80
|
+
export const AppLayer = MarkdownWriterLayer.pipe(Layer.provideMerge(IssueServiceLayer), Layer.provideMerge(VersionServiceLayer), Layer.provideMerge(SiteUrlLive), Layer.provideMerge(JiraClientLive), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.layerUndici), Layer.provideMerge(NodeServices.layer));
|
|
73
81
|
/**
|
|
74
82
|
* Auth-only layer for auth commands.
|
|
75
83
|
*
|
|
76
84
|
* @category Layers
|
|
77
85
|
*/
|
|
78
|
-
export const AuthOnlyLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.
|
|
86
|
+
export const AuthOnlyLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(DummyVersionServiceLayer), Layer.provideMerge(AuthLive), Layer.provideMerge(NodeHttpClient.layerUndici), Layer.provideMerge(NodeServices.layer));
|
|
79
87
|
/**
|
|
80
88
|
* Minimal layer for help/version commands.
|
|
81
89
|
*
|
|
82
90
|
* @category Layers
|
|
83
91
|
*/
|
|
84
|
-
export const MinimalLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(DummyJiraAuthLayer), Layer.provideMerge(
|
|
92
|
+
export const MinimalLayer = DummyIssueServiceLayer.pipe(Layer.provideMerge(DummyMarkdownWriterLayer), Layer.provideMerge(DummyVersionServiceLayer), Layer.provideMerge(DummyJiraAuthLayer), Layer.provideMerge(NodeServices.layer));
|
|
85
93
|
/**
|
|
86
94
|
* Determine which layer to use based on command.
|
|
87
95
|
*
|
|
88
96
|
* @category Utilities
|
|
89
97
|
*/
|
|
90
|
-
export const getLayerType = (
|
|
91
|
-
const cmd =
|
|
98
|
+
export const getLayerType = (args) => {
|
|
99
|
+
const cmd = args[0];
|
|
100
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
101
|
+
return "minimal";
|
|
102
|
+
}
|
|
92
103
|
if (cmd === "auth") {
|
|
93
104
|
return "auth";
|
|
94
105
|
}
|
|
95
|
-
if (!cmd || cmd === "--help" || cmd === "-h" || cmd === "--version") {
|
|
106
|
+
if (!cmd || cmd === "skills" || cmd === "--help" || cmd === "-h" || cmd === "--version") {
|
|
96
107
|
return "minimal";
|
|
97
108
|
}
|
|
98
109
|
return "full";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/commands/layers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `jira search` command — JQL search with multi/single Markdown output.
|
|
3
|
-
*
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
import { Command } from "@effect/cli";
|
|
7
1
|
import * as Option from "effect/Option";
|
|
2
|
+
import { Command } from "effect/unstable/cli";
|
|
8
3
|
import { IssueService } from "../IssueService.js";
|
|
9
4
|
import { MarkdownWriter } from "../MarkdownWriter.js";
|
|
10
|
-
export declare const searchCommand: Command.Command<"search",
|
|
5
|
+
export declare const searchCommand: Command.Command<"search", {
|
|
11
6
|
readonly jql: Option.Option<string>;
|
|
12
7
|
readonly byVersion: Option.Option<string>;
|
|
13
8
|
readonly project: Option.Option<string>;
|
|
14
9
|
readonly outputDir: string;
|
|
15
10
|
readonly format: "multi" | "single";
|
|
16
11
|
readonly maxResults: number;
|
|
17
|
-
}>;
|
|
12
|
+
}, {}, import("../JiraCliError.js").JiraApiError | import("../JiraCliError.js").WriteError, IssueService | MarkdownWriter>;
|
|
18
13
|
//# sourceMappingURL=search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAoB,OAAO,EAAmB,MAAM,qBAAqB,CAAA;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAuCrD,eAAO,MAAM,aAAa;;;;;;;0HAmD6D,CAAA"}
|
package/dist/commands/search.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `jira search` command — JQL search with multi/single Markdown output.
|
|
2
|
+
* `jira issue search` command — JQL search with multi/single Markdown output.
|
|
3
3
|
*
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|
|
6
|
-
import { Args, Command, Options } from "@effect/cli";
|
|
7
6
|
import * as Console from "effect/Console";
|
|
8
7
|
import * as Effect from "effect/Effect";
|
|
9
8
|
import * as Option from "effect/Option";
|
|
9
|
+
import { Argument as Args, Command, Flag as Options } from "effect/unstable/cli";
|
|
10
10
|
import { buildByVersionJql } from "../internal/jqlBuilder.js";
|
|
11
11
|
import { IssueService } from "../IssueService.js";
|
|
12
12
|
import { MarkdownWriter } from "../MarkdownWriter.js";
|
|
13
13
|
// === Options ===
|
|
14
|
-
const jqlArg = Args.
|
|
15
|
-
const byVersionOption = Options.
|
|
16
|
-
const projectOption = Options.
|
|
14
|
+
const jqlArg = Args.string("jql").pipe(Args.withDescription("JQL query to search for issues"), Args.optional);
|
|
15
|
+
const byVersionOption = Options.string("by-version").pipe(Options.withAlias("v"), Options.withDescription("Search by fix version (pre-defined query)"), Options.optional);
|
|
16
|
+
const projectOption = Options.string("project").pipe(Options.withAlias("p"), Options.withDescription("Filter by project key"), Options.optional);
|
|
17
17
|
const outputDirOption = Options.directory("output-dir").pipe(Options.withAlias("o"), Options.withDescription("Output directory for markdown files"), Options.withDefault("./jira-tickets"));
|
|
18
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
19
|
const maxResultsOption = Options.integer("max-results").pipe(Options.withAlias("m"), Options.withDescription("Maximum number of results to fetch"), Options.withDefault(100));
|
|
@@ -40,8 +40,8 @@ export const searchCommand = Command.make("search", {
|
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
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>");
|
|
43
|
+
yield* Console.log("Usage: jira issue search <jql>");
|
|
44
|
+
yield* Console.log(" jira issue search --by-version <version>");
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
yield* Console.log(`Query: ${query}`);
|
|
@@ -60,5 +60,5 @@ export const searchCommand = Command.make("search", {
|
|
|
60
60
|
yield* writer.writeMulti(issues, outputDir);
|
|
61
61
|
yield* Console.log(`Exported ${issues.length} file(s) to ${outputDir}/`);
|
|
62
62
|
}
|
|
63
|
-
})).pipe(Command.withDescription("
|
|
63
|
+
})).pipe(Command.withDescription("Read-only: search Jira issues and export to markdown"));
|
|
64
64
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from "effect/unstable/cli";
|
|
2
|
+
import { JiraApiError } from "../JiraCliError.js";
|
|
3
|
+
import type { Version } from "../VersionService.js";
|
|
4
|
+
/**
|
|
5
|
+
* Return a copy of `version` with every resolved {@link Person.emailAddress}
|
|
6
|
+
* (PII) set to null — covering driver, contributors, approvers[].person and
|
|
7
|
+
* tickets[].assignee. Used to keep emails out of `--json` output unless the
|
|
8
|
+
* caller opts in with `--emails`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const stripEmails: (version: Version) => Version;
|
|
11
|
+
export declare const versionCommand: Command.Command<"version", {}, {}, JiraApiError, never>;
|
|
12
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAWA,OAAO,EAAoB,OAAO,EAAmB,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAG3D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,OAAO,KAAG,OAY9C,CAAA;AAqOD,eAAO,MAAM,cAAc,yDAG1B,CAAA"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jira version` command — list / get Jira project versions (releases) with
|
|
3
|
+
* Driver, Contributors and Approver fields resolved to display names, plus
|
|
4
|
+
* mutations: edit the description and manage "Related work" links (the
|
|
5
|
+
* Confluence pages surfaced on a release report).
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
import * as Console from "effect/Console";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as Option from "effect/Option";
|
|
12
|
+
import { Argument as Args, Command, Flag as Options } from "effect/unstable/cli";
|
|
13
|
+
import { JiraApiError } from "../JiraCliError.js";
|
|
14
|
+
import { VersionService } from "../VersionService.js";
|
|
15
|
+
/**
|
|
16
|
+
* Return a copy of `version` with every resolved {@link Person.emailAddress}
|
|
17
|
+
* (PII) set to null — covering driver, contributors, approvers[].person and
|
|
18
|
+
* tickets[].assignee. Used to keep emails out of `--json` output unless the
|
|
19
|
+
* caller opts in with `--emails`.
|
|
20
|
+
*/
|
|
21
|
+
export const stripEmails = (version) => {
|
|
22
|
+
const stripPerson = (person) => ({ ...person, emailAddress: null });
|
|
23
|
+
return {
|
|
24
|
+
...version,
|
|
25
|
+
driver: version.driver ? stripPerson(version.driver) : null,
|
|
26
|
+
contributors: version.contributors.map(stripPerson),
|
|
27
|
+
approvers: version.approvers.map((a) => ({ ...a, person: stripPerson(a.person) })),
|
|
28
|
+
tickets: version.tickets.map((t) => ({
|
|
29
|
+
...t,
|
|
30
|
+
assignee: t.assignee ? stripPerson(t.assignee) : null
|
|
31
|
+
}))
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Jira version ids are numeric (e.g. `10042`). Passing a name/key 404s with an
|
|
36
|
+
* opaque error, so validate early and emit a hint pointing at `version list`.
|
|
37
|
+
*/
|
|
38
|
+
const ensureNumericId = (id) => /^\d+$/.test(id)
|
|
39
|
+
? Effect.void
|
|
40
|
+
: Effect.fail(new JiraApiError({
|
|
41
|
+
message: `Invalid version id "${id}". The version id is numeric (e.g. 10042); ` +
|
|
42
|
+
`use 'jira version list --project <KEY>' to find it.`
|
|
43
|
+
}));
|
|
44
|
+
const projectOption = Options.string("project").pipe(Options.withAlias("p"), Options.withDescription("Jira project key (e.g. RPS)"));
|
|
45
|
+
const releasedOption = Options.boolean("released").pipe(Options.withDescription("Only list released versions"), Options.withDefault(false));
|
|
46
|
+
const unreleasedOption = Options.boolean("unreleased").pipe(Options.withDescription("Only list unreleased versions"), Options.withDefault(false));
|
|
47
|
+
const jsonOption = Options.boolean("json").pipe(Options.withDescription("Output as JSON"), Options.withDefault(false));
|
|
48
|
+
const emailsOption = Options.boolean("emails").pipe(Options.withDescription("Include resolved user email addresses in --json output"), Options.withDefault(false));
|
|
49
|
+
const customFieldOption = Options.string("custom-field").pipe(Options.withDescription("Custom field display name to include on each ticket (repeatable, e.g. " +
|
|
50
|
+
"--custom-field \"Security & Compliance Impact\"). Values are exposed in " +
|
|
51
|
+
"ticket.customFields[<name>]."), Options.atLeast(0));
|
|
52
|
+
const maxOption = Options.integer("max").pipe(Options.withAlias("m"), Options.withDescription("Maximum number of versions to fetch (default: all)"), Options.optional);
|
|
53
|
+
const idArg = Args.string("id").pipe(Args.withDescription("Version id (numeric)"));
|
|
54
|
+
const listCommand = Command.make("list", {
|
|
55
|
+
project: projectOption,
|
|
56
|
+
released: releasedOption,
|
|
57
|
+
unreleased: unreleasedOption,
|
|
58
|
+
customFields: customFieldOption,
|
|
59
|
+
max: maxOption,
|
|
60
|
+
json: jsonOption,
|
|
61
|
+
emails: emailsOption
|
|
62
|
+
}, ({ customFields, emails, json, max, project, released, unreleased }) => Effect.gen(function* () {
|
|
63
|
+
if (released && unreleased) {
|
|
64
|
+
return yield* Effect.fail(new JiraApiError({
|
|
65
|
+
message: "--released and --unreleased are mutually exclusive; pass at most one (omit both to list all)."
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
const service = yield* VersionService;
|
|
69
|
+
const versions = yield* service.listProjectVersions(project, {
|
|
70
|
+
released,
|
|
71
|
+
unreleased,
|
|
72
|
+
...(Option.isSome(max) ? { maxResults: max.value } : {}),
|
|
73
|
+
customFieldNames: customFields
|
|
74
|
+
});
|
|
75
|
+
if (json) {
|
|
76
|
+
const output = emails ? versions : versions.map(stripEmails);
|
|
77
|
+
yield* Console.log(JSON.stringify(output, null, 2));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const sep = " ";
|
|
81
|
+
yield* Console.log(["id", "name", "released", "releaseDate", "driver", "contributors", "approvers"].join(sep));
|
|
82
|
+
for (const v of versions) {
|
|
83
|
+
yield* Console.log([
|
|
84
|
+
v.id,
|
|
85
|
+
v.name,
|
|
86
|
+
String(v.released),
|
|
87
|
+
v.releaseDate ?? "-",
|
|
88
|
+
v.driver?.displayName ?? "-",
|
|
89
|
+
v.contributors.map((c) => c.displayName).join("|") || "-",
|
|
90
|
+
v.approvers.map((a) => `${a.person.displayName}:${a.status}`).join("|") || "-"
|
|
91
|
+
].join(sep));
|
|
92
|
+
}
|
|
93
|
+
})).pipe(Command.withDescription("Read-only: list versions for a Jira project"));
|
|
94
|
+
/** Cap on the number of ticket keys listed in the human `get` output. */
|
|
95
|
+
const TICKET_KEYS_LIMIT = 20;
|
|
96
|
+
const getCommand = Command.make("get", { id: idArg, json: jsonOption, emails: emailsOption }, ({ emails, id, json }) => Effect.gen(function* () {
|
|
97
|
+
yield* ensureNumericId(id);
|
|
98
|
+
const service = yield* VersionService;
|
|
99
|
+
const version = yield* service.getVersion(id);
|
|
100
|
+
if (json) {
|
|
101
|
+
const output = emails ? version : stripEmails(version);
|
|
102
|
+
yield* Console.log(JSON.stringify(output, null, 2));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
yield* Console.log(`# ${version.name} (${version.id})`);
|
|
106
|
+
yield* Console.log(`released: ${version.released}`);
|
|
107
|
+
yield* Console.log(`releaseDate: ${version.releaseDate ?? "-"}`);
|
|
108
|
+
yield* Console.log(`driver: ${version.driver?.displayName ?? "-"}`);
|
|
109
|
+
yield* Console.log(`contributors: ${version.contributors.map((c) => c.displayName).join(", ") || "-"}`);
|
|
110
|
+
yield* Console.log(`approvers: ${version.approvers.map((a) => `${a.person.displayName}:${a.status}`).join(", ") || "-"}`);
|
|
111
|
+
yield* Console.log(`tickets (${version.tickets.length}): ${formatTicketKeys(version.tickets)}`);
|
|
112
|
+
})).pipe(Command.withDescription("Read-only: get a single Jira version"));
|
|
113
|
+
/**
|
|
114
|
+
* Render a version's ticket keys for the human `get`: the first
|
|
115
|
+
* {@link TICKET_KEYS_LIMIT} keys, with a `(+M more)` suffix when truncated, or
|
|
116
|
+
* `-` when there are none.
|
|
117
|
+
*/
|
|
118
|
+
const formatTicketKeys = (tickets) => {
|
|
119
|
+
if (tickets.length === 0)
|
|
120
|
+
return "-";
|
|
121
|
+
const keys = tickets.map((t) => t.key);
|
|
122
|
+
const shown = keys.slice(0, TICKET_KEYS_LIMIT).join(", ");
|
|
123
|
+
const remaining = keys.length - TICKET_KEYS_LIMIT;
|
|
124
|
+
return remaining > 0 ? `${shown} (+${remaining} more)` : shown;
|
|
125
|
+
};
|
|
126
|
+
const descriptionOption = Options.string("description").pipe(Options.withAlias("d"), Options.withDescription("New version description"));
|
|
127
|
+
const updateCommand = Command.make("update", { id: idArg, description: descriptionOption, json: jsonOption }, ({ description, id, json }) => Effect.gen(function* () {
|
|
128
|
+
yield* ensureNumericId(id);
|
|
129
|
+
const service = yield* VersionService;
|
|
130
|
+
const version = yield* service.updateVersion(id, { description });
|
|
131
|
+
if (json) {
|
|
132
|
+
yield* Console.log(JSON.stringify(version, null, 2));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
yield* Console.log(`Updated version ${version.name} (${version.id})`);
|
|
136
|
+
yield* Console.log(`description: ${version.description ?? "-"}`);
|
|
137
|
+
})).pipe(Command.withDescription("Remote write: update a version's description (requires manage:jira-project scope)"));
|
|
138
|
+
// === related-work ===
|
|
139
|
+
const titleOption = Options.string("title").pipe(Options.withAlias("t"), Options.withDescription("Related-work link title (e.g. \"Release notes\")"));
|
|
140
|
+
const urlOption = Options.string("url").pipe(Options.withAlias("u"), Options.withDescription("Related-work link URL (e.g. a Confluence page)"));
|
|
141
|
+
const categoryOption = Options.string("category").pipe(Options.withAlias("c"), Options.withDescription("Related-work category (Jira groups by this; e.g. Communication, Testing, Design)"), Options.withDefault("Communication"));
|
|
142
|
+
const relatedWorkListCommand = Command.make("list", { id: idArg, json: jsonOption }, ({ id, json }) => Effect.gen(function* () {
|
|
143
|
+
yield* ensureNumericId(id);
|
|
144
|
+
const service = yield* VersionService;
|
|
145
|
+
const items = yield* service.listRelatedWork(id);
|
|
146
|
+
if (json) {
|
|
147
|
+
yield* Console.log(JSON.stringify(items, null, 2));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (items.length === 0) {
|
|
151
|
+
yield* Console.log("(no related work)");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const sep = " ";
|
|
155
|
+
yield* Console.log(["category", "title", "url"].join(sep));
|
|
156
|
+
for (const w of items) {
|
|
157
|
+
yield* Console.log([w.category || "-", w.title ?? "-", w.url ?? "-"].join(sep));
|
|
158
|
+
}
|
|
159
|
+
})).pipe(Command.withDescription("Read-only: list a version's related-work links"));
|
|
160
|
+
const relatedWorkAddCommand = Command.make("add", {
|
|
161
|
+
id: idArg,
|
|
162
|
+
title: titleOption,
|
|
163
|
+
url: urlOption,
|
|
164
|
+
category: categoryOption,
|
|
165
|
+
json: jsonOption
|
|
166
|
+
}, ({ category, id, json, title, url }) => Effect.gen(function* () {
|
|
167
|
+
yield* ensureNumericId(id);
|
|
168
|
+
const service = yield* VersionService;
|
|
169
|
+
const created = yield* service.addRelatedWork(id, { title, category, url });
|
|
170
|
+
if (json) {
|
|
171
|
+
yield* Console.log(JSON.stringify(created, null, 2));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
yield* Console.log(`Attached "${created.title ?? title}" (${created.category}) to version ${id}`);
|
|
175
|
+
yield* Console.log(`url: ${created.url ?? url}`);
|
|
176
|
+
})).pipe(Command.withDescription("Remote write: attach a related-work link (e.g. a Confluence page) to a version (requires manage:jira-project scope)"));
|
|
177
|
+
const relatedWorkCommand = Command.make("related-work").pipe(Command.withDescription("List or attach version related-work links (Confluence pages on the release report)"), Command.withSubcommands([relatedWorkListCommand, relatedWorkAddCommand]));
|
|
178
|
+
export const versionCommand = Command.make("version").pipe(Command.withDescription("Jira version commands"), Command.withSubcommands([listCommand, getCommand, updateCommand, relatedWorkCommand]));
|
|
179
|
+
//# sourceMappingURL=version.js.map
|