@kitschpatrol/chagent 0.1.0 → 0.2.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/dist/bin/cli.js +6 -6
- package/dist/lib/bumpp.d.ts +1 -1
- package/dist/lib/bumpp.js +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -2
- package/dist/{lib-CXMRRbJf.js → lib-DTp3sA-Q.js} +1 -1
- package/dist/{review-LYSADnul.js → review-BwgeC2dB.js} +26 -16
- package/dist/{types-Cms1Tu5k.d.ts → types-COQP1I5w.d.ts} +1 -1
- package/package.json +2 -2
- package/readme.md +7 -3
package/dist/bin/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as version, S as
|
|
3
|
-
import { n as assertAmendable, t as amendRelease } from "../lib-
|
|
2
|
+
import { C as version, S as maxTimeoutMinutes, b as defaultModels, i as generateChangelog, l as agentNames, n as previewChangelog, r as reviewChangelog, s as writeChangelog, t as assertReviewTerminal, u as efforts, x as defaults, y as setLogger } from "../review-BwgeC2dB.js";
|
|
3
|
+
import { n as assertAmendable, t as amendRelease } from "../lib-DTp3sA-Q.js";
|
|
4
4
|
import { t as createProgressLine } from "../progress-DQtRnH1N.js";
|
|
5
5
|
import { createLogger } from "lognow";
|
|
6
6
|
import path from "node:path";
|
|
@@ -122,15 +122,15 @@ try {
|
|
|
122
122
|
description: "Configuration file path",
|
|
123
123
|
type: "string"
|
|
124
124
|
}).option("timeout", {
|
|
125
|
-
defaultDescription: String(defaults.
|
|
126
|
-
description: "Agent timeout in
|
|
125
|
+
defaultDescription: String(defaults.timeout),
|
|
126
|
+
description: "Agent timeout in minutes",
|
|
127
127
|
type: "number"
|
|
128
128
|
}).option("verbose", {
|
|
129
129
|
default: false,
|
|
130
130
|
description: "Log commands, cache decisions, and session details to stderr",
|
|
131
131
|
type: "boolean"
|
|
132
132
|
}).check((args) => {
|
|
133
|
-
if (args.timeout !== void 0 && (!Number.isFinite(args.timeout) || args.timeout <= 0 || args.timeout
|
|
133
|
+
if (args.timeout !== void 0 && (!Number.isFinite(args.timeout) || args.timeout <= 0 || args.timeout > 35791.39411666667)) throw new Error(`--timeout must be a positive number of minutes, up to ${Math.floor(maxTimeoutMinutes)}.`);
|
|
134
134
|
return true;
|
|
135
135
|
}), async (args) => {
|
|
136
136
|
if (!args.dryRun && args.interactive) assertReviewTerminal();
|
|
@@ -149,7 +149,7 @@ try {
|
|
|
149
149
|
},
|
|
150
150
|
rebuild: args.rebuild,
|
|
151
151
|
signal: controller.signal,
|
|
152
|
-
|
|
152
|
+
timeout: args.timeout
|
|
153
153
|
}));
|
|
154
154
|
try {
|
|
155
155
|
if (args.dryRun) {
|
package/dist/lib/bumpp.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as GenerateOptions } from "../types-
|
|
1
|
+
import { u as GenerateOptions } from "../types-COQP1I5w.js";
|
|
2
2
|
import { VersionBumpOptions } from "bumpp";
|
|
3
3
|
type ExecuteHook = Exclude<NonNullable<VersionBumpOptions['execute']>, string>;
|
|
4
4
|
export type BumppHookOptions = Omit<GenerateOptions, 'cwd' | 'release'> & {
|
package/dist/lib/bumpp.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as git, i as generateChangelog, m as localDate, r as reviewChangelog, s as writeChangelog, t as assertReviewTerminal } from "../review-
|
|
1
|
+
import { g as git, i as generateChangelog, m as localDate, r as reviewChangelog, s as writeChangelog, t as assertReviewTerminal } from "../review-BwgeC2dB.js";
|
|
2
2
|
import { t as createProgressLine } from "../progress-DQtRnH1N.js";
|
|
3
3
|
|
|
4
4
|
// src/lib/bumpp.ts
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as Config, a as ChangeSet, c as Evidence, d as GenerationRequest, f as GenerationResponse, g as RunSettings, h as ReleaseSummary, i as Change, l as FileEdit, m as ReleaseRequest, n as AgentName, o as ChangelogPlan, p as ReleaseContext, r as Category, s as Effort, t as AgentAdapter, u as GenerateOptions, v as defineConfig, y as loadConfig } from "../types-
|
|
1
|
+
import { _ as Config, a as ChangeSet, c as Evidence, d as GenerationRequest, f as GenerationResponse, g as RunSettings, h as ReleaseSummary, i as Change, l as FileEdit, m as ReleaseRequest, n as AgentName, o as ChangelogPlan, p as ReleaseContext, r as Category, s as Effort, t as AgentAdapter, u as GenerateOptions, v as defineConfig, y as loadConfig } from "../types-COQP1I5w.js";
|
|
2
2
|
import { ILogBasic, ILogLayer } from "lognow";
|
|
3
3
|
/** Create an adapter for an installed CLI using its existing authentication. */
|
|
4
4
|
export declare function createAgent(name: AgentName): AgentAdapter;
|
package/dist/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as defineConfig, c as createAgent, i as generateChangelog, n as previewChangelog, o as loadConfig, r as reviewChangelog, s as writeChangelog, y as setLogger } from "../review-
|
|
2
|
-
import { t as amendRelease } from "../lib-
|
|
1
|
+
import { a as defineConfig, c as createAgent, i as generateChangelog, n as previewChangelog, o as loadConfig, r as reviewChangelog, s as writeChangelog, y as setLogger } from "../review-BwgeC2dB.js";
|
|
2
|
+
import { t as amendRelease } from "../lib-DTp3sA-Q.js";
|
|
3
3
|
|
|
4
4
|
export { amendRelease, createAgent, defineConfig, generateChangelog, loadConfig, previewChangelog, reviewChangelog, setLogger, writeChangelog };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as isAncestor, d as LOCKFILE_PATH, f as inspectRepository, g as git, h as manifestAt, p as isVersionOnlyChange, s as writeChangelog, v as runCommand } from "./review-
|
|
1
|
+
import { _ as isAncestor, d as LOCKFILE_PATH, f as inspectRepository, g as git, h as manifestAt, p as isVersionOnlyChange, s as writeChangelog, v as runCommand } from "./review-BwgeC2dB.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { realpath } from "node:fs/promises";
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ import { isCancel, select } from "@clack/prompts";
|
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
17
|
var name = "@kitschpatrol/chagent";
|
|
18
|
-
var version = "0.
|
|
18
|
+
var version = "0.2.0";
|
|
19
19
|
var engines = { "node": "^24.16.0 || >=26.3.0" };
|
|
20
20
|
|
|
21
21
|
// src/lib/defaults.ts
|
|
@@ -25,14 +25,14 @@ const defaults = {
|
|
|
25
25
|
effort: "xhigh",
|
|
26
26
|
github: true,
|
|
27
27
|
maxInputChars: 8e4,
|
|
28
|
-
|
|
28
|
+
timeout: 20
|
|
29
29
|
};
|
|
30
30
|
const defaultModels = {
|
|
31
31
|
claude: "claude-opus-5-5",
|
|
32
32
|
codex: "gpt-6.1-sol"
|
|
33
33
|
};
|
|
34
34
|
/** Node.js timers fire immediately when given a longer delay. */
|
|
35
|
-
const
|
|
35
|
+
const maxTimeoutMinutes = 2147483647 / 6e4;
|
|
36
36
|
|
|
37
37
|
// src/lib/log.ts
|
|
38
38
|
/**
|
|
@@ -119,7 +119,8 @@ async function runCommand(command, args, options = {}) {
|
|
|
119
119
|
detached,
|
|
120
120
|
env: options.env ?? process.env,
|
|
121
121
|
stdio: options.inherit === true ? "inherit" : "pipe",
|
|
122
|
-
windowsHide: true
|
|
122
|
+
windowsHide: true,
|
|
123
|
+
windowsVerbatimArguments: options.windowsVerbatimArguments
|
|
123
124
|
});
|
|
124
125
|
const group = detached ? child.pid : void 0;
|
|
125
126
|
if (group !== void 0) trackGroup(group);
|
|
@@ -1055,7 +1056,8 @@ const configSchema = z.strictObject({
|
|
|
1055
1056
|
packages: z.array(z.string()).optional(),
|
|
1056
1057
|
/** Templates containing {version} and optionally {name}. */
|
|
1057
1058
|
tagPatterns: z.array(z.string().includes("{version}")).optional(),
|
|
1058
|
-
|
|
1059
|
+
/** Minutes each agent session may run. */
|
|
1060
|
+
timeout: z.number().positive().max(maxTimeoutMinutes).optional()
|
|
1059
1061
|
});
|
|
1060
1062
|
const resolvedConfigSchema = configSchema.required({
|
|
1061
1063
|
agent: true,
|
|
@@ -1063,8 +1065,11 @@ const resolvedConfigSchema = configSchema.required({
|
|
|
1063
1065
|
effort: true,
|
|
1064
1066
|
github: true,
|
|
1065
1067
|
maxInputChars: true,
|
|
1066
|
-
|
|
1067
|
-
})
|
|
1068
|
+
timeout: true
|
|
1069
|
+
}).transform(({ timeout, ...config }) => ({
|
|
1070
|
+
...config,
|
|
1071
|
+
timeoutMs: timeout * 6e4
|
|
1072
|
+
}));
|
|
1068
1073
|
function invalidConfig(source, error) {
|
|
1069
1074
|
return new Error(`Invalid options in ${source}:\n${z.prettifyError(error)}`, { cause: error });
|
|
1070
1075
|
}
|
|
@@ -1827,7 +1832,7 @@ function releaseContext(options, pkg) {
|
|
|
1827
1832
|
return pkg.directory === options.releaseDirectory ? options.release : void 0;
|
|
1828
1833
|
}
|
|
1829
1834
|
/** Resolve a package's releases and prepare requests for those it still needs. */
|
|
1830
|
-
async function preparePackage(context, pkg, aggregateHistory = false,
|
|
1835
|
+
async function preparePackage(context, pkg, aggregateHistory = false, recordedAtRoot) {
|
|
1831
1836
|
const { repository } = context;
|
|
1832
1837
|
const file = await findChangelog(path.join(repository.root, pkg.directory));
|
|
1833
1838
|
const content = context.options.rebuild ? void 0 : file.content;
|
|
@@ -1854,7 +1859,7 @@ async function preparePackage(context, pkg, aggregateHistory = false, aggregateC
|
|
|
1854
1859
|
version: release.version
|
|
1855
1860
|
};
|
|
1856
1861
|
summaries.push(summary);
|
|
1857
|
-
if (!shouldWrite &&
|
|
1862
|
+
if (!shouldWrite && recordedAtRoot?.(summary) === true) continue;
|
|
1858
1863
|
const existingBody = (draftPromoted ? release === newest : release.version === "Unreleased") ? draft?.body : void 0;
|
|
1859
1864
|
const from = existingBody === void 0 ? void 0 : await incrementalBase(context, file.path, content, release);
|
|
1860
1865
|
const request = await prepareRelease(context, pkg, release, existingBody ?? "", mode, from);
|
|
@@ -2078,9 +2083,12 @@ async function generateWorkspace(context) {
|
|
|
2078
2083
|
const rootReleases = await resolveReleases(repository, repository.rootPackage, options, releaseContext(options, repository.rootPackage));
|
|
2079
2084
|
const shared = rootReleases.some((release) => release.version !== "Unreleased");
|
|
2080
2085
|
const rootFile = await findChangelog(repository.root);
|
|
2081
|
-
const
|
|
2086
|
+
const rootContent = options.rebuild ? void 0 : rootFile.content;
|
|
2087
|
+
const rootMissing = shared ? new Set(missingReleases(rootReleases, rootContent).map((release) => release.version)) : void 0;
|
|
2088
|
+
const needsPackageHistory = rootMissing === void 0 || rootMissing.values().some((version) => version !== "Unreleased");
|
|
2089
|
+
const recordedAtRoot = (summary) => rootMissing === void 0 ? rootContent !== void 0 && missingPackageSummaries([summary], rootContent).length === 0 : !rootMissing.has(summary.version);
|
|
2082
2090
|
const packages = [];
|
|
2083
|
-
for (const pkg of repository.packages) packages.push(await preparePackage(context, pkg, needsPackageHistory,
|
|
2091
|
+
for (const pkg of repository.packages) packages.push(await preparePackage(context, pkg, needsPackageHistory, recordedAtRoot));
|
|
2084
2092
|
const root = shared ? await preparePackage(context, repository.rootPackage) : void 0;
|
|
2085
2093
|
const independent = shared ? void 0 : await prepareIndependent(context, packages.flatMap((pkg) => pkg.summaries));
|
|
2086
2094
|
const requests = [...packages, ...root === void 0 ? [] : [root]].flatMap((pkg) => pkg.work.map((item) => item.request));
|
|
@@ -2231,21 +2239,23 @@ function changelogProblem(plan) {
|
|
|
2231
2239
|
}
|
|
2232
2240
|
}
|
|
2233
2241
|
async function openEditor(editor, file, cwd) {
|
|
2234
|
-
const
|
|
2242
|
+
const windows = process.platform === "win32";
|
|
2243
|
+
const args = windows ? [
|
|
2235
2244
|
"/d",
|
|
2236
2245
|
"/s",
|
|
2237
2246
|
"/c",
|
|
2238
|
-
|
|
2247
|
+
`"${editor} "${file}""`
|
|
2239
2248
|
] : [
|
|
2240
2249
|
"-c",
|
|
2241
2250
|
`${editor} "$1"`,
|
|
2242
2251
|
"chagent-editor",
|
|
2243
2252
|
file
|
|
2244
2253
|
];
|
|
2245
|
-
await runCommand(
|
|
2254
|
+
await runCommand(windows ? "cmd.exe" : "sh", args, {
|
|
2246
2255
|
cwd,
|
|
2247
2256
|
inherit: true,
|
|
2248
|
-
timeoutMs: 864e5
|
|
2257
|
+
timeoutMs: 864e5,
|
|
2258
|
+
windowsVerbatimArguments: windows
|
|
2249
2259
|
});
|
|
2250
2260
|
}
|
|
2251
2261
|
/**
|
|
@@ -2307,4 +2317,4 @@ async function reviewChangelog(plan, options = {}) {
|
|
|
2307
2317
|
}
|
|
2308
2318
|
}
|
|
2309
2319
|
|
|
2310
|
-
export { version as C,
|
|
2320
|
+
export { version as C, maxTimeoutMinutes as S, isAncestor as _, defineConfig as a, defaultModels as b, createAgent as c, LOCKFILE_PATH as d, inspectRepository as f, git as g, manifestAt as h, generateChangelog as i, agentNames as l, localDate as m, previewChangelog as n, loadConfig as o, isVersionOnlyChange as p, reviewChangelog as r, writeChangelog as s, assertReviewTerminal as t, efforts as u, runCommand as v, defaults as x, setLogger as y };
|
|
@@ -18,7 +18,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
18
18
|
model: z.ZodOptional<z.ZodString>;
|
|
19
19
|
packages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
20
20
|
tagPatterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
|
-
|
|
21
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
22
22
|
}, z.core.$strict>;
|
|
23
23
|
type Config = z.infer<typeof configSchema>;
|
|
24
24
|
/** Define optional repository configuration with TypeScript completion. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitschpatrol/chagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Changelog agent. CLI tool and TypeScript library to generate and update changelogs with a little help from your LLMs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"changelog",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"clean-deep": "shx rm -f pnpm-lock.yaml && git clean -fdX",
|
|
91
91
|
"fix": "pnpm build && ksc fix",
|
|
92
92
|
"lint": "pnpm build && ksc lint",
|
|
93
|
-
"release": "bumpp --all --commit 'Release: %s' --execute 'node dist/bin/cli.js' && pnpm build && pnpm publish --otp $(op item get npm --otp) && brewpub --tap kitschpatrol/tap --description 'Generate and update changelogs from Git history with Codex or Claude'",
|
|
93
|
+
"release": "pnpm build && bumpp --all --commit 'Release: %s' --execute 'node dist/bin/cli.js' && pnpm build && pnpm publish --otp $(op item get npm --otp) && brewpub --tap kitschpatrol/tap --description 'Generate and update changelogs from Git history with Codex or Claude'",
|
|
94
94
|
"test": "pnpm build && vitest run"
|
|
95
95
|
}
|
|
96
96
|
}
|
package/readme.md
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
<!-- /short-description -->
|
|
17
17
|
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
>
|
|
20
|
+
> **This project is under development. It should not be considered suitable for general use until a 1.0 release.**
|
|
21
|
+
|
|
18
22
|
## Overview
|
|
19
23
|
|
|
20
24
|
Run `chagent` in a Git repository to either create a changelog where none previously existed, or update an existing changelog to capture recent changes.
|
|
@@ -142,7 +146,7 @@ chagent
|
|
|
142
146
|
| `--github` | Enrich Git evidence using gh when available; disable with --no-github | `boolean` | `true` |
|
|
143
147
|
| `--cache` | Cache drafts and incremental state; disable with --no-cache | `boolean` | `true` |
|
|
144
148
|
| `--config` | Configuration file path | `string` | auto-detected from repository root |
|
|
145
|
-
| `--timeout` | Agent timeout in
|
|
149
|
+
| `--timeout` | Agent timeout in minutes | `number` | `20` |
|
|
146
150
|
| `--verbose` | Log commands, cache decisions, and session details to stderr | `boolean` | `false` |
|
|
147
151
|
| `--help`<br>`-h` | Show help | `boolean` | |
|
|
148
152
|
| `--version`<br>`-v` | Show version number | `boolean` | |
|
|
@@ -262,7 +266,7 @@ export default defineConfig({
|
|
|
262
266
|
github: true,
|
|
263
267
|
maxInputChars: 80_000,
|
|
264
268
|
model: 'gpt-6.1-sol',
|
|
265
|
-
|
|
269
|
+
timeout: 20,
|
|
266
270
|
})
|
|
267
271
|
```
|
|
268
272
|
|
|
@@ -280,7 +284,7 @@ Chagent reads reachable version tags and commit history regardless of the projec
|
|
|
280
284
|
|
|
281
285
|
GitHub enrichment uses release dates and commit-associated PR information. PR lookups batch unique commits across all requested releases and packages; each release receives only its associated PRs. **GitHub release-note bodies are never generation inputs.** Changelog files and generated build output are excluded from source evidence. Existing changelog prose is supplied only to preserve edits and avoid duplicate entries.
|
|
282
286
|
|
|
283
|
-
The agent chooses which historical source files, public interfaces, documentation, and build configuration to inspect. It reads Git snapshots at the supplied release refs instead of treating current or uncommitted files as historical evidence. `maxInputChars` bounds the starting context supplied to agents; it does not restrict which repository files they can investigate. Requests prioritize release boundaries and existing human entries, then fit optional starting evidence into the remaining budget. An individual release's existing entries are never truncated. `
|
|
287
|
+
The agent chooses which historical source files, public interfaces, documentation, and build configuration to inspect. It reads Git snapshots at the supplied release refs instead of treating current or uncommitted files as historical evidence. `maxInputChars` bounds the starting context supplied to agents; it does not restrict which repository files they can investigate. Requests prioritize release boundaries and existing human entries, then fit optional starting evidence into the remaining budget. An individual release's existing entries are never truncated. `timeout` sets the minutes each agent session may run. Lockfile maintenance retains its commit intent, while pure npm version-bump bookkeeping is excluded.
|
|
284
288
|
|
|
285
289
|
Agents return structured changes with evidence references. Stray whitespace and list markers in descriptions are normalized. A response that still fails validation gets one correction request; a second failure stops the run before anything is written or cached. Application code owns the header, release boundaries, Markdown insertion, and Git writes. Agents run in the repository: Codex uses a read-only sandbox with approval requests disabled; Claude exposes read/search and Bash tools in [`dontAsk` mode](https://code.claude.com/docs/en/permissions), which allows read-only commands and denies actions requiring permission. Customizations are disabled for these invocations. Only chagent writes the reviewed changelog. Repository content is sent to the selected agent service using your existing account.
|
|
286
290
|
|