@hardlydifficult/ci-scripts 1.0.2 → 1.0.3

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/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # @hardlydifficult/ci-scripts
2
+
3
+ Reusable CI scripts exposed as CLI commands.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -D @hardlydifficult/ci-scripts
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ### `check-pinned-deps`
14
+
15
+ Validates that all dependencies in all `package.json` files use exact versions (no `^` or `~` prefixes). Exits with a non-zero code if any unpinned dependencies are found.
16
+
17
+ ```bash
18
+ npx check-pinned-deps
19
+ ```
20
+
21
+ ### `monorepo-publish`
22
+
23
+ Smart monorepo publisher. Auto-increments patch versions, publishes packages in dependency order, and transforms `file:` references to real versions before publishing.
24
+
25
+ ```bash
26
+ npx monorepo-publish
27
+ npx monorepo-publish --packages-dir libs
28
+ ```
29
+
30
+ The `--packages-dir` option specifies the directory containing packages. Defaults to `packages`.
31
+
32
+ ### `auto-commit-fixes`
33
+
34
+ Checks for uncommitted changes, commits them, and pushes with exponential backoff retry. Exits with code 1 after a successful commit to trigger a CI re-run so branch protection sees a clean pass. Does nothing if the working tree is clean.
35
+
36
+ Requires the `BRANCH` environment variable.
37
+
38
+ ```bash
39
+ BRANCH=my-feature npx auto-commit-fixes
40
+ ```
41
+
42
+ ### `sync-skills`
43
+
44
+ Pulls `.claude/` skills from GitHub repos listed in `packages/shared-config/skill-repos.json` using the GitHub REST API. Run from the monorepo root.
45
+
46
+ ```bash
47
+ npx sync-skills
48
+ ```
49
+
50
+ Set the `GITHUB_TOKEN` environment variable for private repos.
51
+
52
+ ### `log-local-skills`
53
+
54
+ Reports `.claude/` files that exist locally but are not in the shared-config package. Informational only, never fails.
55
+
56
+ ```bash
57
+ npx log-local-skills
58
+ ```
59
+
60
+ ## CI Workflow Integration
61
+
62
+ Typical GitHub Actions usage for auto-fix workflows:
63
+
64
+ ```yaml
65
+ - name: Auto-fix lint and format
66
+ run: npm run fix
67
+
68
+ - name: Log local .claude skills
69
+ run: npx log-local-skills
70
+
71
+ - name: Commit and push fixes
72
+ env:
73
+ BRANCH: ${{ github.head_ref || github.ref_name }}
74
+ run: npx auto-commit-fixes
75
+ ```
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=auto-commit-fixes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-commit-fixes.d.ts","sourceRoot":"","sources":["../src/auto-commit-fixes.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /* eslint-disable no-console */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ /**
6
+ * Auto-commits and pushes any uncommitted changes (e.g., from lint/format auto-fix or shared-config sync).
7
+ * Exits 0 if no changes. Exits 1 after successfully committing and pushing (to trigger CI re-run).
8
+ *
9
+ * Usage:
10
+ * npx auto-commit-fixes
11
+ *
12
+ * Environment:
13
+ * BRANCH - Required. The branch to push to (e.g., from github.head_ref || github.ref_name).
14
+ */
15
+ const child_process_1 = require("child_process");
16
+ function exec(command, ignoreError = false) {
17
+ console.log(`$ ${command}`);
18
+ try {
19
+ return (0, child_process_1.execSync)(command, { encoding: "utf-8", stdio: "pipe" }).trim();
20
+ }
21
+ catch (error) {
22
+ if (ignoreError) {
23
+ return "";
24
+ }
25
+ throw error;
26
+ }
27
+ }
28
+ function hasChanges() {
29
+ try {
30
+ (0, child_process_1.execSync)("git diff --exit-code", { stdio: "pipe" });
31
+ return false;
32
+ }
33
+ catch {
34
+ return true;
35
+ }
36
+ }
37
+ function sleep(ms) {
38
+ return new Promise((resolve) => {
39
+ setTimeout(resolve, ms);
40
+ });
41
+ }
42
+ async function pushWithRetry(branch) {
43
+ for (let attempt = 1; attempt <= 4; attempt++) {
44
+ exec(`git pull --rebase origin ${branch}`, true);
45
+ try {
46
+ exec(`git push origin HEAD:${branch}`);
47
+ return;
48
+ }
49
+ catch {
50
+ if (attempt === 4) {
51
+ throw new Error("Failed to push after 4 attempts");
52
+ }
53
+ const delay = Math.pow(2, attempt) * 1000;
54
+ console.log(`Push failed, retrying in ${String(delay / 1000)}s...`);
55
+ await sleep(delay);
56
+ }
57
+ }
58
+ }
59
+ async function main() {
60
+ const branch = process.env.BRANCH;
61
+ if (branch === undefined || branch === "") {
62
+ console.error("Error: BRANCH environment variable is required.");
63
+ /* eslint-disable no-template-curly-in-string */
64
+ console.error("Set it in your CI workflow: BRANCH: ${{ github.head_ref || github.ref_name }}");
65
+ /* eslint-enable no-template-curly-in-string */
66
+ process.exit(1);
67
+ }
68
+ if (!hasChanges()) {
69
+ console.log("No changes detected. Nothing to commit.");
70
+ return;
71
+ }
72
+ console.log("Changes detected. Committing auto-fixes...");
73
+ exec('git config --local user.email "github-actions[bot]@users.noreply.github.com"');
74
+ exec('git config --local user.name "github-actions[bot]"');
75
+ // Stash, pull latest, reapply
76
+ exec("git stash");
77
+ exec(`git pull --rebase origin ${branch}`, true);
78
+ exec("git stash pop", true);
79
+ exec("git add -A");
80
+ exec('git commit -m "style: auto-fix linting issues"');
81
+ await pushWithRetry(branch);
82
+ console.log("");
83
+ console.log("Auto-fix commit pushed successfully.");
84
+ console.log("This build will fail so the next CI run validates the fixes.");
85
+ process.exit(1);
86
+ }
87
+ main().catch((err) => {
88
+ console.error("auto-commit-fixes failed:", err);
89
+ process.exit(1);
90
+ });
91
+ //# sourceMappingURL=auto-commit-fixes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-commit-fixes.js","sourceRoot":"","sources":["../src/auto-commit-fixes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=log-local-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-local-skills.d.ts","sourceRoot":"","sources":["../src/log-local-skills.ts"],"names":[],"mappings":""}
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /* eslint-disable no-console */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ /**
6
+ * Logs .claude/ files that exist locally but not in the shared-config package.
7
+ * Informational only - never fails. Helps identify skills that could be promoted to shared.
8
+ *
9
+ * Usage:
10
+ * npx log-local-skills
11
+ */
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ function listFilesRecursive(dir) {
15
+ const results = [];
16
+ if (!(0, fs_1.existsSync)(dir)) {
17
+ return results;
18
+ }
19
+ for (const entry of (0, fs_1.readdirSync)(dir)) {
20
+ if (entry === ".gitkeep") {
21
+ continue;
22
+ }
23
+ const fullPath = (0, path_1.join)(dir, entry);
24
+ const stat = (0, fs_1.statSync)(fullPath);
25
+ if (stat.isDirectory()) {
26
+ results.push(...listFilesRecursive(fullPath));
27
+ }
28
+ else {
29
+ results.push(fullPath);
30
+ }
31
+ }
32
+ return results;
33
+ }
34
+ function findSharedConfigFiles() {
35
+ // Try to find shared-config package in node_modules
36
+ try {
37
+ const sharedConfigBase = (0, path_1.join)(process.cwd(), "node_modules", "@hardlydifficult", "shared-config", "files", ".claude");
38
+ if ((0, fs_1.existsSync)(sharedConfigBase)) {
39
+ return sharedConfigBase;
40
+ }
41
+ }
42
+ catch {
43
+ // Ignore
44
+ }
45
+ // Try monorepo path
46
+ const monoRepoPath = (0, path_1.join)(process.cwd(), "packages", "shared-config", "files", ".claude");
47
+ if ((0, fs_1.existsSync)(monoRepoPath)) {
48
+ return monoRepoPath;
49
+ }
50
+ return null;
51
+ }
52
+ function main() {
53
+ const localClaudeDir = (0, path_1.join)(process.cwd(), ".claude");
54
+ if (!(0, fs_1.existsSync)(localClaudeDir)) {
55
+ console.log("No .claude/ directory found in repo root.");
56
+ return;
57
+ }
58
+ const sharedClaudeDir = findSharedConfigFiles();
59
+ if (sharedClaudeDir === null) {
60
+ console.log("Could not find shared-config package. Listing all .claude/ files as local:");
61
+ const allFiles = listFilesRecursive(localClaudeDir);
62
+ for (const file of allFiles) {
63
+ console.log(` LOCAL: ${(0, path_1.relative)(process.cwd(), file)}`);
64
+ }
65
+ return;
66
+ }
67
+ const localFiles = listFilesRecursive(localClaudeDir);
68
+ const sharedFiles = new Set(listFilesRecursive(sharedClaudeDir).map((f) => (0, path_1.relative)(sharedClaudeDir, f)));
69
+ const localOnly = [];
70
+ for (const file of localFiles) {
71
+ const relPath = (0, path_1.relative)(localClaudeDir, file);
72
+ if (!sharedFiles.has(relPath)) {
73
+ localOnly.push(relPath);
74
+ }
75
+ }
76
+ if (localOnly.length === 0) {
77
+ console.log("All .claude/ files are from shared-config. No local-only files.");
78
+ }
79
+ else {
80
+ console.log(`Found ${String(localOnly.length)} local-only .claude/ file(s):`);
81
+ for (const file of localOnly) {
82
+ console.log(` LOCAL: .claude/${file}`);
83
+ }
84
+ console.log("\nConsider promoting these to shared-config if they should be shared across repos.");
85
+ }
86
+ }
87
+ main();
88
+ //# sourceMappingURL=log-local-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-local-skills.js","sourceRoot":"","sources":["../src/log-local-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=sync-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-skills.d.ts","sourceRoot":"","sources":["../src/sync-skills.ts"],"names":[],"mappings":""}
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /* eslint-disable no-console */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ /**
6
+ * Syncs .claude/ skills from external GitHub repositories into the shared-config package.
7
+ * Reads skill-repos.json for the list of repos (owner/repo format).
8
+ * Uses the GitHub REST API with native fetch().
9
+ *
10
+ * Usage:
11
+ * npx sync-skills
12
+ *
13
+ * Environment:
14
+ * GITHUB_TOKEN - Optional. Required for private repos. Auto-available in GitHub Actions.
15
+ */
16
+ const fs_1 = require("fs");
17
+ const path_1 = require("path");
18
+ const GITHUB_API = "https://api.github.com";
19
+ function getHeaders() {
20
+ const headers = {
21
+ Accept: "application/vnd.github.v3+json",
22
+ "User-Agent": "hardlydifficult-sync-skills",
23
+ };
24
+ const token = process.env.GITHUB_TOKEN;
25
+ if (token !== undefined && token !== "") {
26
+ headers.Authorization = `token ${token}`;
27
+ }
28
+ return headers;
29
+ }
30
+ async function fetchContents(repo, path) {
31
+ const url = `${GITHUB_API}/repos/${repo}/contents/${path}`;
32
+ const response = await fetch(url, { headers: getHeaders() });
33
+ if (response.status === 404) {
34
+ console.log(` No ${path} directory found in ${repo}, skipping`);
35
+ return [];
36
+ }
37
+ if (!response.ok) {
38
+ throw new Error(`GitHub API error ${String(response.status)}: ${await response.text()}`);
39
+ }
40
+ const data = await response.json();
41
+ if (!Array.isArray(data)) {
42
+ // Single file, not a directory
43
+ return [data];
44
+ }
45
+ return data;
46
+ }
47
+ async function downloadFile(downloadUrl) {
48
+ const response = await fetch(downloadUrl, { headers: getHeaders() });
49
+ if (!response.ok) {
50
+ throw new Error(`Failed to download ${downloadUrl}: ${String(response.status)}`);
51
+ }
52
+ return response.text();
53
+ }
54
+ async function syncDirectory(repo, remotePath, localDir) {
55
+ const contents = await fetchContents(repo, remotePath);
56
+ for (const item of contents) {
57
+ const localPath = (0, path_1.join)(localDir, item.name);
58
+ if (item.type === "dir") {
59
+ (0, fs_1.mkdirSync)(localPath, { recursive: true });
60
+ await syncDirectory(repo, item.path, localPath);
61
+ }
62
+ else if (item.download_url !== null) {
63
+ const content = await downloadFile(item.download_url);
64
+ const parentDir = (0, path_1.dirname)(localPath);
65
+ if (!(0, fs_1.existsSync)(parentDir)) {
66
+ (0, fs_1.mkdirSync)(parentDir, { recursive: true });
67
+ }
68
+ (0, fs_1.writeFileSync)(localPath, content);
69
+ console.log(` Synced: ${item.path}`);
70
+ }
71
+ }
72
+ }
73
+ async function main() {
74
+ // Find skill-repos.json relative to this monorepo
75
+ const sharedConfigDir = (0, path_1.join)(process.cwd(), "packages", "shared-config");
76
+ const skillReposPath = (0, path_1.join)(sharedConfigDir, "skill-repos.json");
77
+ if (!(0, fs_1.existsSync)(skillReposPath)) {
78
+ console.error("Error: packages/shared-config/skill-repos.json not found");
79
+ console.error("Run this command from the monorepo root.");
80
+ process.exit(1);
81
+ }
82
+ const skillRepos = JSON.parse((0, fs_1.readFileSync)(skillReposPath, "utf-8"));
83
+ if (skillRepos.length === 0) {
84
+ console.log("No skill repos configured in skill-repos.json");
85
+ return;
86
+ }
87
+ const targetDir = (0, path_1.join)(sharedConfigDir, "files", ".claude");
88
+ // Clean and recreate the target .claude directory
89
+ if ((0, fs_1.existsSync)(targetDir)) {
90
+ (0, fs_1.rmSync)(targetDir, { recursive: true });
91
+ }
92
+ (0, fs_1.mkdirSync)(targetDir, { recursive: true });
93
+ for (const repo of skillRepos) {
94
+ console.log(`Syncing skills from ${repo}...`);
95
+ await syncDirectory(repo, ".claude", targetDir);
96
+ }
97
+ console.log("Skill sync complete.");
98
+ }
99
+ main().catch((err) => {
100
+ console.error("Skill sync failed:", err);
101
+ process.exit(1);
102
+ });
103
+ //# sourceMappingURL=sync-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-skills.js","sourceRoot":"","sources":["../src/sync-skills.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@hardlydifficult/ci-scripts",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Reusable CI scripts",
5
5
  "bin": {
6
6
  "check-pinned-deps": "./dist/check-pinned-deps.js",
7
- "monorepo-publish": "./dist/publish.js"
7
+ "monorepo-publish": "./dist/publish.js",
8
+ "sync-skills": "./dist/sync-skills.js",
9
+ "log-local-skills": "./dist/log-local-skills.js",
10
+ "auto-commit-fixes": "./dist/auto-commit-fixes.js"
8
11
  },
9
12
  "files": [
10
13
  "dist"