@rheged-studio/changelog-core 1.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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +92 -0
  3. package/changelog-contract.md +129 -0
  4. package/config.json +9 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +106 -0
  8. package/dist/commands/add-links.d.ts +8 -0
  9. package/dist/commands/add-links.d.ts.map +1 -0
  10. package/dist/commands/add-links.js +258 -0
  11. package/dist/commands/backfill-commits.d.ts +19 -0
  12. package/dist/commands/backfill-commits.d.ts.map +1 -0
  13. package/dist/commands/backfill-commits.js +236 -0
  14. package/dist/commands/check-completeness.d.ts +13 -0
  15. package/dist/commands/check-completeness.d.ts.map +1 -0
  16. package/dist/commands/check-completeness.js +164 -0
  17. package/dist/commands/enrich.d.ts +17 -0
  18. package/dist/commands/enrich.d.ts.map +1 -0
  19. package/dist/commands/enrich.js +194 -0
  20. package/dist/commands/finalise.d.ts +25 -0
  21. package/dist/commands/finalise.d.ts.map +1 -0
  22. package/dist/commands/finalise.js +249 -0
  23. package/dist/commands/set-affected-packages.d.ts +13 -0
  24. package/dist/commands/set-affected-packages.d.ts.map +1 -0
  25. package/dist/commands/set-affected-packages.js +207 -0
  26. package/dist/commands/validate.d.ts +6 -0
  27. package/dist/commands/validate.d.ts.map +1 -0
  28. package/dist/commands/validate.js +293 -0
  29. package/dist/index.d.ts +23 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +24 -0
  32. package/dist/lib/blank.d.ts +5 -0
  33. package/dist/lib/blank.d.ts.map +1 -0
  34. package/dist/lib/blank.js +6 -0
  35. package/dist/lib/changelog.d.ts +6 -0
  36. package/dist/lib/changelog.d.ts.map +1 -0
  37. package/dist/lib/changelog.js +47 -0
  38. package/dist/lib/cli-entry.d.ts +10 -0
  39. package/dist/lib/cli-entry.d.ts.map +1 -0
  40. package/dist/lib/cli-entry.js +22 -0
  41. package/dist/lib/commit-count.d.ts +16 -0
  42. package/dist/lib/commit-count.d.ts.map +1 -0
  43. package/dist/lib/commit-count.js +72 -0
  44. package/dist/lib/config.d.ts +25 -0
  45. package/dist/lib/config.d.ts.map +1 -0
  46. package/dist/lib/config.js +156 -0
  47. package/dist/lib/derive-packages.d.ts +10 -0
  48. package/dist/lib/derive-packages.d.ts.map +1 -0
  49. package/dist/lib/derive-packages.js +42 -0
  50. package/dist/lib/enrich.d.ts +29 -0
  51. package/dist/lib/enrich.d.ts.map +1 -0
  52. package/dist/lib/enrich.js +54 -0
  53. package/dist/lib/frontmatter.d.ts +11 -0
  54. package/dist/lib/frontmatter.d.ts.map +1 -0
  55. package/dist/lib/frontmatter.js +355 -0
  56. package/dist/lib/stamp.d.ts +10 -0
  57. package/dist/lib/stamp.d.ts.map +1 -0
  58. package/dist/lib/stamp.js +35 -0
  59. package/dist/lib/vendor/issue-keys.d.ts +16 -0
  60. package/dist/lib/vendor/issue-keys.d.ts.map +1 -0
  61. package/dist/lib/vendor/issue-keys.js +29 -0
  62. package/package.json +124 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Stamp `version` onto an entry if it has none. Returns the rewritten markdown,
3
+ * or null when the entry already has a version (no write needed).
4
+ */
5
+ export declare function stampVersion(raw: string, version: string): null | string;
6
+ /**
7
+ * Read the `version` field from a package.json string.
8
+ */
9
+ export declare function readPackageVersion(packageJsonRaw: string): string;
10
+ //# sourceMappingURL=stamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamp.d.ts","sourceRoot":"","sources":["../../src/lib/stamp.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CASxE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAajE"}
@@ -0,0 +1,35 @@
1
+ // Pure helpers for release-time version stamping: set `version` on an entry
2
+ // that doesn't have one, and read the version from package.json.
3
+ //
4
+ // Library module (no CLI): the release-time orchestrator finalise composes
5
+ // these. Kept pure so they're trivially unit-testable. Zero-dep — uses the
6
+ // package's frontmatter parser.
7
+ import { blank } from "./blank.js";
8
+ import { parseFrontmatter, stringifyFrontmatter } from "./frontmatter.js";
9
+ /**
10
+ * Stamp `version` onto an entry if it has none. Returns the rewritten markdown,
11
+ * or null when the entry already has a version (no write needed).
12
+ */
13
+ export function stampVersion(raw, version) {
14
+ const parsed = parseFrontmatter(raw);
15
+ const fm = { ...parsed.data };
16
+ if (!blank(fm.version)) {
17
+ return null;
18
+ }
19
+ fm.version = version;
20
+ return stringifyFrontmatter(parsed.content, fm);
21
+ }
22
+ /**
23
+ * Read the `version` field from a package.json string.
24
+ */
25
+ export function readPackageVersion(packageJsonRaw) {
26
+ const pkg = JSON.parse(packageJsonRaw);
27
+ if (!pkg ||
28
+ typeof pkg !== "object" ||
29
+ Array.isArray(pkg) ||
30
+ typeof pkg.version !== "string" ||
31
+ pkg.version.length === 0) {
32
+ throw new Error("package.json is missing a string `version`");
33
+ }
34
+ return pkg.version;
35
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Escape regex metacharacters so a configured key such as `C++` or `MY.KEY`
3
+ * can't throw at construction or silently widen the match.
4
+ */
5
+ export declare function escapeRegex(source: string): string;
6
+ /**
7
+ * Build the `\b(?:KEY|…)-\d+\b` matcher (global flag) from configured issue keys.
8
+ *
9
+ * Returns `null` when no keys are configured: an empty alternation would match
10
+ * the empty string before every `-<digits>` and inject bogus links (e.g. `-2`).
11
+ * A single key needs no `(?:…)` wrapper — only wrap when there's an alternation,
12
+ * because the naive join `\bA|B-\d+\b` parses as `\bA` *or* `B-\d+\b` (matching a
13
+ * bare `A` and missing `A-7`).
14
+ */
15
+ export declare function buildIssueRe(keys: string[]): null | RegExp;
16
+ //# sourceMappingURL=issue-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-keys.d.ts","sourceRoot":"","sources":["../../../src/lib/vendor/issue-keys.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CAQ1D"}
@@ -0,0 +1,29 @@
1
+ // Canonical issue-key helpers — the single source of truth for deriving a
2
+ // Linear issue-key regex from a branch name or prose.
3
+ //
4
+ // Pure and zero-dependency by design: the host loads its own config and
5
+ // passes the configured keys in.
6
+ /**
7
+ * Escape regex metacharacters so a configured key such as `C++` or `MY.KEY`
8
+ * can't throw at construction or silently widen the match.
9
+ */
10
+ export function escapeRegex(source) {
11
+ return source.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
12
+ }
13
+ /**
14
+ * Build the `\b(?:KEY|…)-\d+\b` matcher (global flag) from configured issue keys.
15
+ *
16
+ * Returns `null` when no keys are configured: an empty alternation would match
17
+ * the empty string before every `-<digits>` and inject bogus links (e.g. `-2`).
18
+ * A single key needs no `(?:…)` wrapper — only wrap when there's an alternation,
19
+ * because the naive join `\bA|B-\d+\b` parses as `\bA` *or* `B-\d+\b` (matching a
20
+ * bare `A` and missing `A-7`).
21
+ */
22
+ export function buildIssueRe(keys) {
23
+ if (!Array.isArray(keys) || keys.length === 0) {
24
+ return null;
25
+ }
26
+ const alternation = keys.map(escapeRegex).join("|");
27
+ const group = keys.length > 1 ? `(?:${alternation})` : alternation;
28
+ return new RegExp(`\\b${group}-\\d+\\b`, "g");
29
+ }
package/package.json ADDED
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "@rheged-studio/changelog-core",
3
+ "version": "1.1.1",
4
+ "description": "Shared changelog contract and dual-runtime CLI for Acme Skunkworks — validate, enrich, and finalise dated changelog entries.",
5
+ "keywords": [
6
+ "changelog",
7
+ "release-notes",
8
+ "validate",
9
+ "enrich",
10
+ "finalise"
11
+ ],
12
+ "homepage": "https://github.com/rheged-studio/changelog-core#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/rheged-studio/changelog-core/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/rheged-studio/changelog-core.git"
19
+ },
20
+ "license": "MIT",
21
+ "author": {
22
+ "name": "Rob Easthope",
23
+ "url": "https://github.com/RobEasthope"
24
+ },
25
+ "type": "module",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "./contract": "./changelog-contract.md"
33
+ },
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "bin": {
38
+ "changelog-core": "dist/cli.js"
39
+ },
40
+ "files": [
41
+ "changelog-contract.md",
42
+ "config.json",
43
+ "dist"
44
+ ],
45
+ "scripts": {
46
+ "act:ci": "act pull_request -W .github/workflows/ci.yml --eventpath .github/act-events/pull_request.json",
47
+ "act:list": "act --list",
48
+ "act:release:dry": "act push -W .github/workflows/pkg-release.yml",
49
+ "build": "tsc",
50
+ "changelog:enrich": "tsx src/cli.ts --config config.json enrich",
51
+ "changelog:finalise": "tsx src/cli.ts --config config.json finalise",
52
+ "ci:list": "gh run list --limit 10",
53
+ "ci:view": "gh run view",
54
+ "ci:watch": "gh run watch $(gh run list -L 1 --json databaseId -q '.[0].databaseId // empty')",
55
+ "clean": "rimraf node_modules dist",
56
+ "format": "prettier --write .",
57
+ "lint": "eslint 'src/**/*.ts' 'tests/**/*.ts' --cache --cache-location ./.eslintcache",
58
+ "lint:fix": "eslint 'src/**/*.ts' 'tests/**/*.ts' --fix --cache --cache-location ./.eslintcache",
59
+ "lint:md": "markdownlint-cli2 '**/*.{md,mdx}' '!**/node_modules/**' '!**/dist/**' '!**/.turbo/**' '!**/.astro/**' '!**/.claude/skills/**' '!**/.agents/skills/**'",
60
+ "lint:md:fix": "markdownlint-cli2 --fix '**/*.{md,mdx}' '!**/node_modules/**' '!**/dist/**' '!**/.turbo/**' '!**/.astro/**' '!**/.claude/skills/**' '!**/.agents/skills/**'",
61
+ "lint:sh": "bash -c 'if command -v shellcheck >/dev/null 2>&1; then shellcheck infrastructure/scripts/*.sh .husky/pre-commit .husky/pre-push .husky/commit-msg; elif [ \"$(uname -s)\" = \"Darwin\" ]; then echo \"⚠️ shellcheck not installed — skipping. Install: brew install shellcheck\"; else echo \"⚠️ shellcheck not installed — skipping. Install: apt-get install shellcheck\"; fi'",
62
+ "lint:workflows": "actionlint",
63
+ "lint:yaml": "yamllint .",
64
+ "prepare": "husky",
65
+ "prepublishOnly": "pnpm run build",
66
+ "release:manual": "pnpm run build && npm publish --access public --provenance=false",
67
+ "release:manual:dry": "pnpm run build && npm publish --access public --provenance=false --dry-run",
68
+ "sort-pkg-json": "sort-package-json",
69
+ "test": "vitest run",
70
+ "test:sh": "bash -c 'if command -v bats >/dev/null 2>&1; then bats infrastructure/tests/*.bats; elif [ \"$(uname -s)\" = \"Darwin\" ]; then echo \"⚠️ bats not installed — skipping. Install: brew install bats-core\"; else echo \"⚠️ bats not installed — skipping. Install: apt-get install bats\"; fi'",
71
+ "test:watch": "vitest",
72
+ "tsc": "tsc --noEmit && tsc -p tsconfig.tools.json",
73
+ "validate:changelog": "tsx src/cli.ts --config config.json validate"
74
+ },
75
+ "lint-staged": {
76
+ "**/*": [
77
+ "prettier --write --ignore-unknown"
78
+ ],
79
+ "**/*.{ts,tsx,js,mjs,cjs}": [
80
+ "bash -c 'pnpm exec eslint --fix --cache --cache-location ./.eslintcache \"$@\" || true' --"
81
+ ],
82
+ "**/package.json": [
83
+ "bash -c 'sort-package-json \"$@\" || true' --",
84
+ "bash -c 'pnpm exec eslint --fix --cache --cache-location ./.eslintcache \"$@\" || true' --"
85
+ ],
86
+ "**/*.{md,mdx}": [
87
+ "bash -c 'markdownlint-cli2 --fix --config ./.markdownlint-cli2.jsonc \"$@\" || true' --"
88
+ ],
89
+ "**/*.{yml,yaml}": [
90
+ "bash -c 'if command -v yamllint >/dev/null 2>&1; then yamllint \"$@\"; elif [ \"$(uname -s)\" = \"Darwin\" ]; then echo \"⚠️ yamllint not installed — skipping. Install with: brew install yamllint\"; else echo \"⚠️ yamllint not installed — skipping. Install with: pip install --user yamllint==1.37.1\"; fi' --"
91
+ ],
92
+ ".github/workflows/*.{yml,yaml}": [
93
+ "bash -c 'if command -v actionlint >/dev/null 2>&1; then actionlint \"$@\"; elif [ \"$(uname -s)\" = \"Darwin\" ]; then echo \"⚠️ actionlint not installed — skipping. Install with: brew install actionlint\"; else echo \"⚠️ actionlint not installed — skipping. Install via: bash <(curl -fsSL https://raw.githubusercontent.com/rhysd/actionlint/v1.7.5/scripts/download-actionlint.bash)\"; fi' --"
94
+ ]
95
+ },
96
+ "devDependencies": {
97
+ "@acme-skunkworks/commitlint-config": "^1.0.1",
98
+ "@acme-skunkworks/eslint-config": "^1.1.3",
99
+ "@acme-skunkworks/markdownlint-config": "^3.0.0",
100
+ "@commitlint/cli": "^21.2.1",
101
+ "@types/node": "^25.6.0",
102
+ "bats": "1.13.0",
103
+ "eslint": "^9.0.0",
104
+ "husky": "^9.1.7",
105
+ "jiti": "^2.7.0",
106
+ "lint-staged": "^16.3.2",
107
+ "markdownlint-cli2": "^0.18.1",
108
+ "prettier": "^3.0.0",
109
+ "prettier-plugin-tailwindcss": "^0.8.0",
110
+ "rimraf": "^6.0.1",
111
+ "sort-package-json": "^3.6.1",
112
+ "tsx": "^4.21.1",
113
+ "typescript": "^6.0.3",
114
+ "vitest": "^4.1.6"
115
+ },
116
+ "packageManager": "pnpm@10.33.0",
117
+ "engines": {
118
+ "node": ">=22"
119
+ },
120
+ "publishConfig": {
121
+ "access": "public",
122
+ "provenance": true
123
+ }
124
+ }