feat(M4): Reusable code abstractions and dead-code removal

This commit is contained in:
Stefano Fiorini
2026-05-03 21:45:49 -05:00
parent 86ad783f82
commit 7495020a9c
98 changed files with 1696 additions and 950 deletions
@@ -25,7 +25,13 @@
"path": "scripts/src/cli.ts",
"kind": "file",
"mode": "644",
"sha256": "5c4f4db76817fa9dbdae0fd0c75be302248d4b87fc0a53f6bd3c90407a75ae98"
"sha256": "90dcc029adf0625b86c5eec44c5c1fd11bbf95ffe1185016d139c8a6982d54ff"
},
{
"path": "scripts/src/command-helpers.ts",
"kind": "file",
"mode": "644",
"sha256": "aa03d8d288c8c00485ea10d3b3a60804c1b9ee23ef265004e7912f3242dbcee7"
},
{
"path": "scripts/src/config.ts",
@@ -37,7 +43,7 @@
"path": "scripts/src/confluence.ts",
"kind": "file",
"mode": "644",
"sha256": "709d5d61fdb14e37aa4eaa7175eb7f17f0ec661376c96071020fbc9574ddbb73"
"sha256": "28f65f280cd9b6119ce7eab583d0083231525ad6dc04b73389cb5dcbab5bf095"
},
{
"path": "scripts/src/files.ts",
@@ -61,7 +67,7 @@
"path": "scripts/src/jira.ts",
"kind": "file",
"mode": "644",
"sha256": "485d8d618fe04eb1ce546c1694eadf15d867bc83c2a6f7df994688ab0335ea4f"
"sha256": "bec0e81a0424dd412c36988cef42c01a95f044ee8346ba626e7eb8bd79379f07"
},
{
"path": "scripts/src/output.ts",
@@ -73,7 +79,7 @@
"path": "scripts/src/raw.ts",
"kind": "file",
"mode": "644",
"sha256": "2309c96dd45a03509df204803de9ecf0b5ff82fd488730f55ac5dd6a23b81dd8"
"sha256": "48fd54bd0cdb421badb58f9be2933a039fe3b9350bbe6191070c9f7bb0054670"
},
{
"path": "scripts/src/types.ts",
@@ -4,6 +4,7 @@ import { pathToFileURL } from "node:url";
import { Command } from "commander";
import { resolveFormat } from "./command-helpers.js";
import { createConfluenceClient } from "./confluence.js";
import { loadConfig } from "./config.js";
import { readWorkspaceFile } from "./files.js";
@@ -11,7 +12,7 @@ import { runHealthCheck } from "./health.js";
import { createJiraClient } from "./jira.js";
import { writeOutput } from "./output.js";
import { runRawCommand } from "./raw.js";
import type { FetchLike, OutputFormat, Writer } from "./types.js";
import type { FetchLike, Writer } from "./types.js";
type CliContext = {
cwd?: string;
@@ -21,10 +22,6 @@ type CliContext = {
stderr?: Writer;
};
function resolveFormat(format: string | undefined): OutputFormat {
return format === "text" ? "text" : "json";
}
function createRuntime(context: CliContext) {
const cwd = context.cwd ?? process.cwd();
const env = context.env ?? process.env;
@@ -0,0 +1,25 @@
// ⚠️ GENERATED FILE do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
import type { CommandOutput, OutputFormat } from "./types.js";
/**
* Produce the standard dry-run response payload for write operations.
*
* Use this when `--dry-run` is passed to skip the actual API call and
* echo the pending request back to the caller.
*
* @example
* if (input.dryRun) return dryRunResponse(request);
*/
export function dryRunResponse<T>(data: T): CommandOutput<T> {
return { ok: true, dryRun: true, data };
}
/**
* Resolve the `--format` CLI option to a typed OutputFormat.
*
* Returns `"text"` only for the exact string `"text"`;
* all other values (including `undefined`) fall back to `"json"`.
*/
export function resolveFormat(format: string | undefined): OutputFormat {
return format === "text" ? "text" : "json";
}
@@ -1,4 +1,5 @@
// ⚠️ GENERATED FILE do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
import { dryRunResponse } from "./command-helpers.js";
import { sendJsonRequest } from "./http.js";
import type { AtlassianConfig, CommandOutput, FetchLike } from "./types.js";
@@ -178,13 +179,7 @@ export function createConfluenceClient(options: ConfluenceClientOptions) {
},
};
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const raw = await sendJsonRequest({
config,
@@ -224,13 +219,7 @@ export function createConfluenceClient(options: ConfluenceClientOptions) {
},
};
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const raw = await sendJsonRequest({
config,
@@ -267,13 +256,7 @@ export function createConfluenceClient(options: ConfluenceClientOptions) {
},
};
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const raw = await sendJsonRequest({
config,
@@ -1,5 +1,6 @@
// ⚠️ GENERATED FILE do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
import { markdownToAdf } from "./adf.js";
import { dryRunResponse } from "./command-helpers.js";
import { sendJsonRequest } from "./http.js";
import type { AtlassianConfig, CommandOutput, FetchLike, JiraIssueSummary } from "./types.js";
@@ -162,13 +163,7 @@ export function createJiraClient(options: JiraClientOptions) {
},
});
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const raw = await send("POST", "/rest/api/3/issue", request.body);
return { ok: true, data: raw };
@@ -193,13 +188,7 @@ export function createJiraClient(options: JiraClientOptions) {
fields,
});
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
await send("PUT", `/rest/api/3/issue/${input.issue}`, request.body);
return {
@@ -216,13 +205,7 @@ export function createJiraClient(options: JiraClientOptions) {
body: markdownToAdf(input.body),
});
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const raw = await send("POST", `/rest/api/3/issue/${input.issue}/comment`, request.body);
return {
@@ -243,13 +226,7 @@ export function createJiraClient(options: JiraClientOptions) {
},
);
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
await send("POST", `/rest/api/3/issue/${input.issue}/transitions`, request.body);
return {
@@ -1,4 +1,5 @@
// ⚠️ GENERATED FILE do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
import { dryRunResponse } from "./command-helpers.js";
import { readWorkspaceFile } from "./files.js";
import { sendJsonRequest } from "./http.js";
import type { AtlassianConfig, CommandOutput, FetchLike } from "./types.js";
@@ -62,13 +63,7 @@ export async function runRawCommand(
...(body === undefined ? {} : { body }),
};
if (input.dryRun) {
return {
ok: true,
dryRun: true,
data: request,
};
}
if (input.dryRun) return dryRunResponse(request);
const data = await sendJsonRequest({
config,