codebrief 1.3.0 → 1.4.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/README.md +25 -5
- package/dist/index.js +30 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -279,7 +279,8 @@ npx codebrief [directory] [options]
|
|
|
279
279
|
| `--dry-run` | Preview what would be generated |
|
|
280
280
|
| `--refresh-snapshot` | Re-scan source files and update just the code snapshot |
|
|
281
281
|
| `--reconfigure` | Re-prompt even if `.codebrief.json` exists |
|
|
282
|
-
| `--check` | Check if the snapshot is stale (exit 0 = fresh, 1 = stale) |
|
|
282
|
+
| `--check` | Check if the snapshot is stale via hash comparison (exit 0 = fresh, 1 = stale) |
|
|
283
|
+
| `--check=timestamp` | Timestamp-only staleness check — instant, no file hashing (for shell hooks) |
|
|
283
284
|
| `--max-tokens=N` | Set the token budget for the code snapshot |
|
|
284
285
|
| `--generate-skills` | Generate Claude Code skill files |
|
|
285
286
|
| `-v, --verbose` | Show detailed progress output |
|
|
@@ -296,7 +297,7 @@ This finds the `<!-- CODE SNAPSHOT -->` markers in your context file, re-scans s
|
|
|
296
297
|
|
|
297
298
|
## Shell Integration
|
|
298
299
|
|
|
299
|
-
Automatically detect stale snapshots when you `cd` into a project:
|
|
300
|
+
Automatically detect stale snapshots when you `cd` into a project. These hooks run in pure shell (no Node.js boot), so they add zero latency to your prompt:
|
|
300
301
|
|
|
301
302
|
<details>
|
|
302
303
|
<summary><strong>zsh</strong></summary>
|
|
@@ -305,7 +306,13 @@ Automatically detect stale snapshots when you `cd` into a project:
|
|
|
305
306
|
# Add to ~/.zshrc
|
|
306
307
|
chpwd() {
|
|
307
308
|
if [[ -f .codebrief.json ]]; then
|
|
308
|
-
|
|
309
|
+
local ts days stale_days
|
|
310
|
+
ts=$(command grep -o '"snapshotGeneratedAt":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*$')
|
|
311
|
+
[[ -z "$ts" ]] && return
|
|
312
|
+
stale_days=$(command grep -o '"staleDays":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*$')
|
|
313
|
+
: "${stale_days:=7}"
|
|
314
|
+
days=$(( ($(date +%s) - ts / 1000) / 86400 ))
|
|
315
|
+
(( days > stale_days )) && echo "codebrief: snapshot is ${days}d old. Run: npx codebrief --refresh-snapshot"
|
|
309
316
|
fi
|
|
310
317
|
}
|
|
311
318
|
```
|
|
@@ -320,7 +327,13 @@ chpwd() {
|
|
|
320
327
|
cd() {
|
|
321
328
|
builtin cd "$@" || return
|
|
322
329
|
if [[ -f .codebrief.json ]]; then
|
|
323
|
-
|
|
330
|
+
local ts days stale_days
|
|
331
|
+
ts=$(command grep -o '"snapshotGeneratedAt":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*$')
|
|
332
|
+
[[ -z "$ts" ]] && return
|
|
333
|
+
stale_days=$(command grep -o '"staleDays":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*$')
|
|
334
|
+
: "${stale_days:=7}"
|
|
335
|
+
days=$(( ($(date +%s) - ts / 1000) / 86400 ))
|
|
336
|
+
(( days > stale_days )) && echo "codebrief: snapshot is ${days}d old. Run: npx codebrief --refresh-snapshot"
|
|
324
337
|
fi
|
|
325
338
|
}
|
|
326
339
|
```
|
|
@@ -334,13 +347,20 @@ cd() {
|
|
|
334
347
|
# Add to ~/.config/fish/conf.d/codebrief.fish
|
|
335
348
|
function __codebrief_check --on-variable PWD
|
|
336
349
|
if test -f .codebrief.json
|
|
337
|
-
|
|
350
|
+
set -l ts (command grep -o '"snapshotGeneratedAt":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*\$')
|
|
351
|
+
test -z "$ts"; and return
|
|
352
|
+
set -l stale_days (command grep -o '"staleDays":[0-9]*' .codebrief.json 2>/dev/null | command grep -o '[0-9]*\$')
|
|
353
|
+
test -z "$stale_days"; and set stale_days 7
|
|
354
|
+
set -l days (math "( "(date +%s)" - $ts / 1000) / 86400")
|
|
355
|
+
test $days -gt $stale_days; and echo "codebrief: snapshot is "$days"d old. Run: npx codebrief --refresh-snapshot"
|
|
338
356
|
end
|
|
339
357
|
end
|
|
340
358
|
```
|
|
341
359
|
|
|
342
360
|
</details>
|
|
343
361
|
|
|
362
|
+
> **Tip:** Set `"staleDays": 14` in `.codebrief.json` to customize the threshold. For CI/pre-commit use the hash-based `--check` instead.
|
|
363
|
+
|
|
344
364
|
## Config File
|
|
345
365
|
|
|
346
366
|
On first run, codebrief saves your answers to `.codebrief.json`:
|
package/dist/index.js
CHANGED
|
@@ -3411,11 +3411,13 @@ async function loadConfig(rootDir) {
|
|
|
3411
3411
|
generatePerPackage: cfg.generatePerPackage ?? false,
|
|
3412
3412
|
snapshotHash: cfg.snapshotHash,
|
|
3413
3413
|
snapshotGeneratedAt: cfg.snapshotGeneratedAt,
|
|
3414
|
-
language: cfg.language
|
|
3414
|
+
language: cfg.language,
|
|
3415
|
+
staleDays: cfg.staleDays
|
|
3415
3416
|
};
|
|
3416
3417
|
}
|
|
3417
3418
|
async function saveConfig(rootDir, answers, snapshotHash, language) {
|
|
3418
3419
|
const configPath = path6.join(rootDir, CONFIG_FILENAME);
|
|
3420
|
+
const existing = await readJsonFile(configPath);
|
|
3419
3421
|
const cfg = {
|
|
3420
3422
|
_version: CONFIG_VERSION,
|
|
3421
3423
|
ides: answers.ides,
|
|
@@ -3427,7 +3429,8 @@ async function saveConfig(rootDir, answers, snapshotHash, language) {
|
|
|
3427
3429
|
stackCorrections: answers.stackCorrections,
|
|
3428
3430
|
generatePerPackage: answers.generatePerPackage,
|
|
3429
3431
|
...snapshotHash ? { snapshotHash, snapshotGeneratedAt: Date.now() } : {},
|
|
3430
|
-
...language ? { language } : {}
|
|
3432
|
+
...language ? { language } : {},
|
|
3433
|
+
...existing?.staleDays != null ? { staleDays: existing.staleDays } : {}
|
|
3431
3434
|
};
|
|
3432
3435
|
await writeFileSafe(configPath, JSON.stringify(cfg, null, 2) + "\n");
|
|
3433
3436
|
}
|
|
@@ -3585,6 +3588,11 @@ async function refreshSnapshot(rootDir) {
|
|
|
3585
3588
|
updated = content.slice(0, startIdx) + newBlock + content.slice(endIdx);
|
|
3586
3589
|
}
|
|
3587
3590
|
await writeFileSafe(absPath, updated);
|
|
3591
|
+
if (config) {
|
|
3592
|
+
const answers = configToAnswers(config);
|
|
3593
|
+
const newHash = await computeSnapshotHash(rootDir, config.language ?? detected.language);
|
|
3594
|
+
await saveConfig(rootDir, answers, newHash, config.language ?? detected.language);
|
|
3595
|
+
}
|
|
3588
3596
|
p3.log.success(`Updated snapshot in ${theme.accent(found.path)}`);
|
|
3589
3597
|
}
|
|
3590
3598
|
|
|
@@ -3773,7 +3781,7 @@ async function animateCommunities(communityCount) {
|
|
|
3773
3781
|
}
|
|
3774
3782
|
|
|
3775
3783
|
// src/index.ts
|
|
3776
|
-
var VERSION = true ? "1.
|
|
3784
|
+
var VERSION = true ? "1.4.0" : "0.0.0-dev";
|
|
3777
3785
|
var NAME = true ? "codebrief" : "codebrief";
|
|
3778
3786
|
var DESCRIPTION = true ? "Bootstrap optimized AI context files for any project. Auto-detect stack, generate code snapshots, produce config for Claude Code, Cursor, Copilot, Windsurf, Cline, Continue, Aider, and more." : "";
|
|
3779
3787
|
function printHelp() {
|
|
@@ -3790,7 +3798,8 @@ function printHelp() {
|
|
|
3790
3798
|
console.log(` ${theme.accent("--dry-run")} Preview what would be generated`);
|
|
3791
3799
|
console.log(` ${theme.accent("--reconfigure")} Re-prompt even if .codebrief.json exists`);
|
|
3792
3800
|
console.log(` ${theme.accent("--refresh-snapshot")} Re-scan source files, update code snapshot only`);
|
|
3793
|
-
console.log(` ${theme.accent("--check")} Exit 0 if snapshot is fresh, 1 if stale`);
|
|
3801
|
+
console.log(` ${theme.accent("--check")} Exit 0 if snapshot is fresh, 1 if stale (hash-based)`);
|
|
3802
|
+
console.log(` ${theme.accent("--check=timestamp")} Exit 0/1 based on age only (no Node.js needed in shell hooks)`);
|
|
3794
3803
|
console.log(` ${theme.accent("--max-tokens=N")} Set the token budget for the code snapshot`);
|
|
3795
3804
|
console.log(` ${theme.accent("--generate-skills")} Generate Claude Code skill files`);
|
|
3796
3805
|
console.log(` ${theme.accent("-v, --verbose")} Show detailed progress output`);
|
|
@@ -3817,7 +3826,9 @@ async function main() {
|
|
|
3817
3826
|
const dryRun = args.includes("--dry-run");
|
|
3818
3827
|
const refresh = args.includes("--refresh-snapshot");
|
|
3819
3828
|
const reconfigure = args.includes("--reconfigure");
|
|
3820
|
-
const
|
|
3829
|
+
const checkArg = args.find((a) => a === "--check" || a.startsWith("--check="));
|
|
3830
|
+
const check = !!checkArg;
|
|
3831
|
+
const checkTimestamp = checkArg === "--check=timestamp";
|
|
3821
3832
|
const verbose = args.includes("--verbose") || args.includes("-v");
|
|
3822
3833
|
const generateSkills = args.includes("--generate-skills");
|
|
3823
3834
|
const maxTokensArg = args.find((a) => a.startsWith("--max-tokens="));
|
|
@@ -3842,6 +3853,20 @@ async function main() {
|
|
|
3842
3853
|
};
|
|
3843
3854
|
if (check) {
|
|
3844
3855
|
const config = await loadConfig(rootDir);
|
|
3856
|
+
if (checkTimestamp) {
|
|
3857
|
+
if (!config?.snapshotGeneratedAt) {
|
|
3858
|
+
process.exit(0);
|
|
3859
|
+
}
|
|
3860
|
+
const staleDays = config.staleDays ?? 7;
|
|
3861
|
+
const daysSince = Math.floor(
|
|
3862
|
+
(Date.now() - config.snapshotGeneratedAt) / (1e3 * 60 * 60 * 24)
|
|
3863
|
+
);
|
|
3864
|
+
if (daysSince > staleDays) {
|
|
3865
|
+
console.log(`codebrief: snapshot is ${daysSince}d old. Run: npx codebrief --refresh-snapshot`);
|
|
3866
|
+
process.exit(1);
|
|
3867
|
+
}
|
|
3868
|
+
process.exit(0);
|
|
3869
|
+
}
|
|
3845
3870
|
if (!config?.snapshotHash) {
|
|
3846
3871
|
process.exit(0);
|
|
3847
3872
|
}
|