Perform code optimization and document cleanup (#1)
## Summary - add repository-wide quality tooling and verification scaffolding, including CI workflows, pnpm workspace setup, ESLint/Prettier/markdown checks, and generated-output verification helpers - reorganize skill sources and generation flow by introducing canonical `_source` variants, generator/manifests, reusable helper abstractions, and shared web-automation/browser utilities - clean up and expand documentation so the root README flows into docs and skill docs, with clearer development, reviewer, installer, and workflow guidance ## Notable changes - docs flow and consistency cleanup across `README.md`, `docs/README.md`, and related docs - new scripts for `check`, docs verification, generated-file verification, shell portability, and safe directory replacement - refactors in Atlassian and web-automation skill runtimes to reduce duplication and centralize reusable code - changelog, development documentation, and CI surface updates ## Test Plan - [ ] `pnpm run check` - [ ] review generated/manifests and skill sync outputs - [ ] smoke-check docs flow from `README.md` to `docs/README.md` to skill docs ## Notes - this branch currently includes tracked `skills/web-automation/shared/node_modules` content that should be reviewed carefully as potentially noisy/accidental committed artifacts Co-authored-by: Stefano Fiorini <stefano.fiorini@firsthorizon.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"$schema": "https://ai-coding-skills.dev/schemas/generated-manifest/v1.json",
|
||||
"generator": "scripts/generate-skills.mjs",
|
||||
"generatedRoot": "skills/atlassian/claude-code",
|
||||
"files": [
|
||||
{
|
||||
"path": "scripts/package.json",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "4030a6965cd5b29674beedd2b5b1bce08b9bd8a7304dfc22d68ca9c0cdd0f6a3"
|
||||
},
|
||||
{
|
||||
"path": "scripts/pnpm-lock.yaml",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "15556a6f53e68bb8d92d2710aae0836bc80af7f29be9d63aa1b87fcbd33732c6"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/adf.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "c7c3b4a78ccd8fb5a8ab99c82e0eab67a0a0d656b3985c1f56817bda199ad20f"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/cli.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "90dcc029adf0625b86c5eec44c5c1fd11bbf95ffe1185016d139c8a6982d54ff"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/command-helpers.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "aa03d8d288c8c00485ea10d3b3a60804c1b9ee23ef265004e7912f3242dbcee7"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/config.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "700dcdce96afab5294426e09f539135ae5432632370260190d6292071422eb3f"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/confluence.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "28f65f280cd9b6119ce7eab583d0083231525ad6dc04b73389cb5dcbab5bf095"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/files.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "16296eaa3ae41a4d7c694773036f9bb4bd2baa2db6a9c318078532b713678dba"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/health.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "1db4b49e05b16a095b7e7ca31cdc4e22ebda19e20e05c40baaaac648eaec0d08"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/http.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "66444b777d4d9b14d9793eb051c586eb811d2b36815b1018dd9d7517666c7eb2"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/jira.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "bec0e81a0424dd412c36988cef42c01a95f044ee8346ba626e7eb8bd79379f07"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/output.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "38e99818582a4962c09a83175634cba2bfead6acf33bd5f43cdca5caed7100a0"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/raw.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "48fd54bd0cdb421badb58f9be2933a039fe3b9350bbe6191070c9f7bb0054670"
|
||||
},
|
||||
{
|
||||
"path": "scripts/src/types.ts",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "9f92d27ab68604d5abfd0f5dc9552b96fed6d1f9fc7dc6eb30190d8b617628bf"
|
||||
},
|
||||
{
|
||||
"path": "scripts/tsconfig.json",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "3c2eb7ba5c95a16cada153de4787ca7a4bf179609bf3848e12ff15b1b7927a68"
|
||||
},
|
||||
{
|
||||
"path": "SKILL.md",
|
||||
"kind": "file",
|
||||
"mode": "644",
|
||||
"sha256": "96b660983b82a4060d5e3d91f916aa683f584a7b26f74c3145b3e23994030b71"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,6 +3,8 @@ name: atlassian
|
||||
description: Interact with Atlassian Cloud Jira and Confluence through a portable task-oriented CLI for search, issue/page edits, comments, transitions, and bounded raw requests.
|
||||
---
|
||||
|
||||
<!-- ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/_source/claude-code/SKILL.md and run `pnpm run sync:pi`. -->
|
||||
|
||||
# Atlassian (Claude Code)
|
||||
|
||||
Portable Atlassian workflows for Claude Code using a shared TypeScript CLI.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "atlassian-skill-scripts",
|
||||
"name": "@ai-coding-skills/atlassian-claude-code",
|
||||
"version": "1.0.0",
|
||||
"description": "Shared runtime for the Atlassian skill",
|
||||
"type": "module",
|
||||
@@ -16,5 +16,6 @@
|
||||
"tsx": "^4.20.5",
|
||||
"typescript": "^5.9.2"
|
||||
},
|
||||
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34"
|
||||
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34",
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
const TEXT_NODE = "text";
|
||||
|
||||
function textNode(text: string) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
import process from "node:process";
|
||||
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";
|
||||
@@ -10,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;
|
||||
@@ -20,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,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
import path from "node:path";
|
||||
|
||||
import { config as loadDotEnv } from "dotenv";
|
||||
|
||||
@@ -1,3 +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";
|
||||
|
||||
@@ -177,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,
|
||||
@@ -223,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,
|
||||
@@ -266,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,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
import { readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
import { createJsonHeaders, createStatusError } from "./http.js";
|
||||
import type { AtlassianConfig, CommandOutput, FetchLike } from "./types.js";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
import { createBasicAuthHeader } from "./config.js";
|
||||
import type { AtlassianConfig, FetchLike } from "./types.js";
|
||||
|
||||
|
||||
@@ -1,4 +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";
|
||||
|
||||
@@ -161,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 };
|
||||
@@ -192,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 {
|
||||
@@ -215,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 {
|
||||
@@ -242,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,3 +1,4 @@
|
||||
// ⚠️ 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, Writer } from "./types.js";
|
||||
|
||||
function renderText(payload: CommandOutput<unknown>) {
|
||||
|
||||
@@ -1,3 +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";
|
||||
@@ -61,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,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ⚠️ GENERATED FILE – do not edit directly. Edit the canonical source in skills/atlassian/shared/scripts/ and run `pnpm run sync:pi`.
|
||||
export type AtlassianConfig = {
|
||||
baseUrl: string;
|
||||
jiraBaseUrl: string;
|
||||
|
||||
Reference in New Issue
Block a user