brainclaw 1.12.0 → 1.13.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 +32 -0
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli.js +9 -2
- package/dist/commands/claim-resource.js +1 -0
- package/dist/commands/estimation-report.js +1 -1
- package/dist/commands/harvest.js +30 -22
- package/dist/commands/mcp.js +279 -44
- package/dist/commands/release-claim.js +21 -1
- package/dist/core/agent-capability.js +15 -4
- package/dist/core/agent-registry.js +7 -1
- package/dist/core/claims.js +160 -1
- package/dist/core/context.js +11 -4
- package/dist/core/dispatch-status.js +113 -7
- package/dist/core/entity-operations.js +51 -3
- package/dist/core/loops/store.js +33 -0
- package/dist/core/reputation.js +18 -0
- package/dist/core/schema.js +7 -0
- package/dist/core/worktree.js +146 -22
- package/dist/facts.js +36 -3
- package/dist/facts.json +35 -2
- package/docs/mcp-schema-changelog.md +7 -2
- package/package.json +6 -4
package/dist/core/worktree.js
CHANGED
|
@@ -582,6 +582,16 @@ export function createWorktree(mainWorktreePath, branchName, options = {}) {
|
|
|
582
582
|
if (fs.existsSync(mainGitignorePath)) {
|
|
583
583
|
fs.copyFileSync(mainGitignorePath, targetGitignorePath);
|
|
584
584
|
}
|
|
585
|
+
// trp#926 — record the RESOLVED base ref SHA at creation time. base_ref is
|
|
586
|
+
// usually "HEAD" or a branch name, both of which drift after creation and
|
|
587
|
+
// are useless for later "how many commits did the worker add?" comparisons.
|
|
588
|
+
// The resolved SHA is the stable anchor: `${base_ref_sha}..HEAD` on the lane
|
|
589
|
+
// deterministically counts the worker's contribution even as master advances.
|
|
590
|
+
// Best-effort — an unresolvable base_ref simply omits the field.
|
|
591
|
+
const baseRefSha = (() => {
|
|
592
|
+
const rev = runGit(['rev-parse', baseRef], mainWorktreePath);
|
|
593
|
+
return rev.ok ? rev.stdout.trim() : undefined;
|
|
594
|
+
})();
|
|
585
595
|
// Write brainclaw metadata sidecar inside the worktree
|
|
586
596
|
const meta = {
|
|
587
597
|
session_id: options.sessionId,
|
|
@@ -590,6 +600,7 @@ export function createWorktree(mainWorktreePath, branchName, options = {}) {
|
|
|
590
600
|
created_at: new Date().toISOString(),
|
|
591
601
|
main_worktree_path: mainWorktreePath,
|
|
592
602
|
base_ref: baseRef,
|
|
603
|
+
...(baseRefSha ? { base_ref_sha: baseRefSha } : {}),
|
|
593
604
|
reset_existing_branch: options.resetExistingBranch === true,
|
|
594
605
|
git_advice: 'git add ONLY specific files, NEVER git add -A.',
|
|
595
606
|
// pln#523: surface any shared-path link failures (e.g. node_modules junction
|
|
@@ -827,25 +838,63 @@ export function safeRemoveWorktreeDir(dirPath) {
|
|
|
827
838
|
catch { /* best effort */ }
|
|
828
839
|
}
|
|
829
840
|
/**
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
*
|
|
841
|
+
* Depth cap for detachWorktreeJunctions' recursive walk. 8 covers realistic
|
|
842
|
+
* monorepo trees (apps/<pkg>/packages/<pkg>/node_modules, pnpm nested links)
|
|
843
|
+
* while keeping the walk bounded on pathological structures. Hitting the cap
|
|
844
|
+
* is a hard failure: continuing to `git worktree remove` after an incomplete
|
|
845
|
+
* scan would re-open the junction-follow wipe class. .git is skipped outright
|
|
846
|
+
* — it never contains user junctions and can be very deep.
|
|
847
|
+
*/
|
|
848
|
+
const JUNCTION_SCAN_MAX_DEPTH = 8;
|
|
849
|
+
/**
|
|
850
|
+
* pln#498 + trp#926 (2026-07-03 incident) — Detach ALL symlinks/junctions from
|
|
851
|
+
* a worktree before any recursive removal. On Windows, `git worktree remove`
|
|
852
|
+
* performs its own recursive rm and historically (git ≤ 2.38) followed NTFS
|
|
853
|
+
* junctions into the main repo, wiping `node_modules`. Unlinking every
|
|
854
|
+
* junction entry first leaves git only regular files/dirs to walk.
|
|
835
855
|
*
|
|
836
|
-
*
|
|
837
|
-
*
|
|
856
|
+
* Historically this only inspected top-level entries — that covered the
|
|
857
|
+
* classic single-stack shared `node_modules` case but MISSED:
|
|
858
|
+
* - monorepo per-package junctions created by pln#523
|
|
859
|
+
* (apps/<pkg>/node_modules, packages/<pkg>/node_modules);
|
|
860
|
+
* - operator- or worker-created manual junctions at nested paths.
|
|
861
|
+
* The 2026-07-03 incident (node_modules racine rasé via the auto-junction)
|
|
862
|
+
* was a recurrence of the pln#498 class, extended one level of nesting.
|
|
863
|
+
*
|
|
864
|
+
* The recursion NEVER descends into a symlink (lstat + unlink at the entry
|
|
865
|
+
* itself), so it cannot follow a junction into the main repo. `.git/` is
|
|
866
|
+
* skipped entirely — git manages its own state and it never holds user
|
|
867
|
+
* junctions. Depth is capped defensively at JUNCTION_SCAN_MAX_DEPTH; hitting
|
|
868
|
+
* the cap aborts removal rather than silently leaving deeper links in place.
|
|
838
869
|
*/
|
|
839
870
|
export function detachWorktreeJunctions(worktreePath) {
|
|
871
|
+
if (!fs.existsSync(worktreePath))
|
|
872
|
+
return;
|
|
873
|
+
const failures = [];
|
|
874
|
+
detachJunctionsRecursively(worktreePath, 0, failures);
|
|
875
|
+
if (failures.length > 0) {
|
|
876
|
+
throw new Error(`could not safely detach worktree junctions: ${failures.join('; ')}`);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
function detachJunctionsRecursively(dir, depth, failures) {
|
|
880
|
+
if (depth > JUNCTION_SCAN_MAX_DEPTH) {
|
|
881
|
+
failures.push(`scan depth exceeded at ${dir}`);
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
840
884
|
let entries;
|
|
841
885
|
try {
|
|
842
|
-
entries = fs.readdirSync(
|
|
886
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
843
887
|
}
|
|
844
|
-
catch {
|
|
845
|
-
|
|
888
|
+
catch (err) {
|
|
889
|
+
failures.push(`could not read ${dir}: ${err.message}`);
|
|
890
|
+
return;
|
|
846
891
|
}
|
|
847
892
|
for (const entry of entries) {
|
|
848
|
-
|
|
893
|
+
// `.git` is a file (linked worktree pointer) at the worktree root or a
|
|
894
|
+
// real dir in the main repo — either way, do not walk it.
|
|
895
|
+
if (entry.name === '.git')
|
|
896
|
+
continue;
|
|
897
|
+
const child = path.join(dir, entry.name);
|
|
849
898
|
let stat;
|
|
850
899
|
try {
|
|
851
900
|
stat = fs.lstatSync(child);
|
|
@@ -853,16 +902,24 @@ export function detachWorktreeJunctions(worktreePath) {
|
|
|
853
902
|
catch {
|
|
854
903
|
continue;
|
|
855
904
|
}
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
fs.unlinkSync(child);
|
|
860
|
-
}
|
|
861
|
-
catch {
|
|
905
|
+
if (stat.isSymbolicLink()) {
|
|
906
|
+
// Unlink the junction. Do NOT descend into it (that would follow the
|
|
907
|
+
// link back into the main repo — the exact class we're preventing).
|
|
862
908
|
try {
|
|
863
|
-
fs.
|
|
909
|
+
fs.unlinkSync(child);
|
|
864
910
|
}
|
|
865
|
-
catch {
|
|
911
|
+
catch (unlinkErr) {
|
|
912
|
+
try {
|
|
913
|
+
fs.rmdirSync(child);
|
|
914
|
+
}
|
|
915
|
+
catch (rmdirErr) {
|
|
916
|
+
failures.push(`could not detach link ${child}: unlink=${unlinkErr.message}; rmdir=${rmdirErr.message}`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
if (stat.isDirectory()) {
|
|
922
|
+
detachJunctionsRecursively(child, depth + 1, failures);
|
|
866
923
|
}
|
|
867
924
|
}
|
|
868
925
|
}
|
|
@@ -924,6 +981,57 @@ export function worktreeHasOnlyBirthNoise(statusZStdout) {
|
|
|
924
981
|
|| isSystemDirtyPath(norm);
|
|
925
982
|
});
|
|
926
983
|
}
|
|
984
|
+
/**
|
|
985
|
+
* trp#926 (squash-aware GC) — True when every commit on `branch` that is not
|
|
986
|
+
* an ancestor of `baseRef` has a patch-equivalent commit ALREADY on `baseRef`.
|
|
987
|
+
*
|
|
988
|
+
* `git branch --merged HEAD` and `merge-base --is-ancestor` are ancestry-only:
|
|
989
|
+
* a squash-merge on GitHub creates a NEW commit on master whose ancestry does
|
|
990
|
+
* not include the lane commits, so an ancestry probe returns "not merged" and
|
|
991
|
+
* the GC keeps the worktree forever. `git cherry <base> <branch>` uses
|
|
992
|
+
* patch-id equivalence — the same signal GitHub itself uses to say "this PR is
|
|
993
|
+
* merged". Output is one line per commit in `base..branch`:
|
|
994
|
+
* `+ <sha>` = patch NOT yet on base (a real un-integrated commit)
|
|
995
|
+
* `- <sha>` = patch already on base (via squash / cherry-pick / rebase)
|
|
996
|
+
* The branch is "merged by content" iff there are no `+` lines. An empty
|
|
997
|
+
* output (no commits ahead of base) is also merged.
|
|
998
|
+
*
|
|
999
|
+
* Returns `false` on any git failure — a probe that cannot prove merged must
|
|
1000
|
+
* NEVER lie "yes" and cause a keep-me worktree to be GC'd. Callers combine
|
|
1001
|
+
* this with ancestry ('git branch --merged') so both signals contribute.
|
|
1002
|
+
*/
|
|
1003
|
+
export function isBranchMergedByContent(mainWorktreePath, branchName, baseRef = 'HEAD') {
|
|
1004
|
+
const cherry = runGit(['cherry', baseRef, branchName], mainWorktreePath);
|
|
1005
|
+
if (!cherry.ok)
|
|
1006
|
+
return false;
|
|
1007
|
+
const lines = cherry.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
1008
|
+
if (lines.length === 0)
|
|
1009
|
+
return true; // no commits ahead of base → fully merged
|
|
1010
|
+
// A `+` line means "patch not on base" — one is enough to disqualify.
|
|
1011
|
+
if (!lines.some((l) => l.startsWith('+ ')))
|
|
1012
|
+
return true;
|
|
1013
|
+
// Multi-commit squash merges often do not produce per-commit patch-id
|
|
1014
|
+
// matches: the squash commit's aggregate patch differs from each individual
|
|
1015
|
+
// branch commit. As a second, still content-only signal, compare the final
|
|
1016
|
+
// content of files changed by the branch. If every branch-touched path now
|
|
1017
|
+
// matches baseRef, removing the worktree cannot drop unique file content.
|
|
1018
|
+
const mergeBase = runGit(['merge-base', baseRef, branchName], mainWorktreePath);
|
|
1019
|
+
if (!mergeBase.ok || !mergeBase.stdout.trim())
|
|
1020
|
+
return false;
|
|
1021
|
+
const changed = runGit(['diff', '--name-only', '-z', mergeBase.stdout.trim(), branchName], mainWorktreePath);
|
|
1022
|
+
if (!changed.ok)
|
|
1023
|
+
return false;
|
|
1024
|
+
const paths = changed.stdout.split('\0').filter(Boolean);
|
|
1025
|
+
if (paths.length === 0)
|
|
1026
|
+
return true;
|
|
1027
|
+
for (let i = 0; i < paths.length; i += 100) {
|
|
1028
|
+
const chunk = paths.slice(i, i + 100);
|
|
1029
|
+
const diff = runGit(['diff', '--quiet', branchName, baseRef, '--', ...chunk], mainWorktreePath);
|
|
1030
|
+
if (!diff.ok)
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
return true;
|
|
1034
|
+
}
|
|
927
1035
|
/**
|
|
928
1036
|
* Removes worktrees whose branch has been fully merged into the current branch
|
|
929
1037
|
* (typically master/main after a merge). Also removes brainclaw-managed
|
|
@@ -931,6 +1039,12 @@ export function worktreeHasOnlyBirthNoise(statusZStdout) {
|
|
|
931
1039
|
* (orphan dirs left behind by force-deleted branches).
|
|
932
1040
|
*
|
|
933
1041
|
* Safe by default: skips worktrees with uncommitted changes unless `force` is set.
|
|
1042
|
+
*
|
|
1043
|
+
* trp#926 — Merged detection is a UNION of two signals:
|
|
1044
|
+
* - ancestry (`git branch --merged HEAD`): catches fast-forward / merge-commit;
|
|
1045
|
+
* - content (`git cherry HEAD <branch>`, patch-id): catches squash merges,
|
|
1046
|
+
* which is GitHub's default merge strategy on this repo and previously left
|
|
1047
|
+
* every squashed lane un-GC-able forever.
|
|
934
1048
|
*/
|
|
935
1049
|
export function cleanMergedWorktrees(mainWorktreePath, options = {}) {
|
|
936
1050
|
const result = { removed: [], skipped: [], pruned: false };
|
|
@@ -949,7 +1063,12 @@ export function cleanMergedWorktrees(mainWorktreePath, options = {}) {
|
|
|
949
1063
|
for (const wt of worktrees) {
|
|
950
1064
|
if (wt.is_main)
|
|
951
1065
|
continue;
|
|
952
|
-
|
|
1066
|
+
// trp#926 — a lane's branch is "merged" if EITHER git says its commits are
|
|
1067
|
+
// ancestors of HEAD (fast-forward / merge-commit) OR every commit's patch
|
|
1068
|
+
// is already on HEAD (squash-merge, catching GitHub's default strategy).
|
|
1069
|
+
// Without the content probe, squashed lanes accumulate forever.
|
|
1070
|
+
const isMerged = mergedBranches.has(wt.branch)
|
|
1071
|
+
|| isBranchMergedByContent(mainWorktreePath, wt.branch, 'HEAD');
|
|
953
1072
|
if (!isMerged) {
|
|
954
1073
|
continue;
|
|
955
1074
|
}
|
|
@@ -1054,9 +1173,14 @@ export function gcWorktreeIfHarvested(mainWorktreePath, worktreePath, options =
|
|
|
1054
1173
|
}
|
|
1055
1174
|
const ancestor = runGit(['merge-base', '--is-ancestor', laneHead.stdout.trim(), mainHead.stdout.trim()], mainWorktreePath);
|
|
1056
1175
|
// exit 0 = ancestor (safe). Non-zero = not an ancestor OR a git error — both
|
|
1057
|
-
// mean "cannot prove integrated"
|
|
1058
|
-
|
|
1176
|
+
// mean "cannot prove integrated via ancestry". trp#926 — fall back to the
|
|
1177
|
+
// content probe (patch-id): a squash-merged lane is not an ancestor but is
|
|
1178
|
+
// fully integrated, and previously the GC kept it forever. Ancestry OR
|
|
1179
|
+
// content, either signal is enough; a failed content probe still keeps the
|
|
1180
|
+
// worktree (isBranchMergedByContent returns false on git failure).
|
|
1181
|
+
if (!ancestor.ok && branch && !isBranchMergedByContent(mainWorktreePath, branch, mainHead.stdout.trim())) {
|
|
1059
1182
|
return out(false, 'lane branch has un-integrated commits (or unverifiable)', branch);
|
|
1183
|
+
}
|
|
1060
1184
|
}
|
|
1061
1185
|
try {
|
|
1062
1186
|
removeWorktree(mainWorktreePath, worktreePath, { force: true });
|
package/dist/facts.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by scripts/emit-site-facts.mjs at build time. Do not edit manually.
|
|
2
|
-
// Source: brainclaw v1.
|
|
2
|
+
// Source: brainclaw v1.13.0 on 2026-07-04T20:40:39.712Z
|
|
3
3
|
export const FACTS = {
|
|
4
|
-
"version": "1.
|
|
5
|
-
"generated_at": "2026-
|
|
4
|
+
"version": "1.13.0",
|
|
5
|
+
"generated_at": "2026-07-04T20:40:39.712Z",
|
|
6
6
|
"tools": {
|
|
7
7
|
"count": 67,
|
|
8
8
|
"published_count": 66,
|
|
@@ -469,6 +469,39 @@ export const FACTS = {
|
|
|
469
469
|
"max_concurrent_tasks": 1
|
|
470
470
|
}
|
|
471
471
|
]
|
|
472
|
+
},
|
|
473
|
+
"bench": {
|
|
474
|
+
"schema": "brainclaw.bench.v1",
|
|
475
|
+
"generated_at": "2026-07-04T20:40:37.627Z",
|
|
476
|
+
"node_version": "v24.18.0",
|
|
477
|
+
"platform": "linux-x64",
|
|
478
|
+
"repeats": 3,
|
|
479
|
+
"scenarios": [
|
|
480
|
+
{
|
|
481
|
+
"name": "cold_onboard",
|
|
482
|
+
"volume": "empty",
|
|
483
|
+
"description": "fresh machine → init → first useful context. Baseline for time-to-first-value.",
|
|
484
|
+
"duration_ms_median": 78,
|
|
485
|
+
"payload_chars_median": 1650,
|
|
486
|
+
"payload_tokens_est_median": 413
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"name": "warm_work",
|
|
490
|
+
"volume": "medium",
|
|
491
|
+
"description": "bclaw_work consult over a real-shaped store (~200 plans / 500 handoffs / 450 claims).",
|
|
492
|
+
"duration_ms_median": 130,
|
|
493
|
+
"payload_chars_median": 2626,
|
|
494
|
+
"payload_tokens_est_median": 657
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
"name": "first_edit",
|
|
498
|
+
"volume": "medium",
|
|
499
|
+
"description": "code_find + code_brief on the fresh-agent path (missing index, first touch).",
|
|
500
|
+
"duration_ms_median": 8,
|
|
501
|
+
"payload_chars_median": 442,
|
|
502
|
+
"payload_tokens_est_median": 111
|
|
503
|
+
}
|
|
504
|
+
]
|
|
472
505
|
}
|
|
473
506
|
}
|
|
474
507
|
export default FACTS
|
package/dist/facts.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"generated_at": "2026-
|
|
2
|
+
"version": "1.13.0",
|
|
3
|
+
"generated_at": "2026-07-04T20:40:39.712Z",
|
|
4
4
|
"tools": {
|
|
5
5
|
"count": 67,
|
|
6
6
|
"published_count": 66,
|
|
@@ -467,5 +467,38 @@
|
|
|
467
467
|
"max_concurrent_tasks": 1
|
|
468
468
|
}
|
|
469
469
|
]
|
|
470
|
+
},
|
|
471
|
+
"bench": {
|
|
472
|
+
"schema": "brainclaw.bench.v1",
|
|
473
|
+
"generated_at": "2026-07-04T20:40:37.627Z",
|
|
474
|
+
"node_version": "v24.18.0",
|
|
475
|
+
"platform": "linux-x64",
|
|
476
|
+
"repeats": 3,
|
|
477
|
+
"scenarios": [
|
|
478
|
+
{
|
|
479
|
+
"name": "cold_onboard",
|
|
480
|
+
"volume": "empty",
|
|
481
|
+
"description": "fresh machine → init → first useful context. Baseline for time-to-first-value.",
|
|
482
|
+
"duration_ms_median": 78,
|
|
483
|
+
"payload_chars_median": 1650,
|
|
484
|
+
"payload_tokens_est_median": 413
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"name": "warm_work",
|
|
488
|
+
"volume": "medium",
|
|
489
|
+
"description": "bclaw_work consult over a real-shaped store (~200 plans / 500 handoffs / 450 claims).",
|
|
490
|
+
"duration_ms_median": 130,
|
|
491
|
+
"payload_chars_median": 2626,
|
|
492
|
+
"payload_tokens_est_median": 657
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
"name": "first_edit",
|
|
496
|
+
"volume": "medium",
|
|
497
|
+
"description": "code_find + code_brief on the fresh-agent path (missing index, first touch).",
|
|
498
|
+
"duration_ms_median": 8,
|
|
499
|
+
"payload_chars_median": 442,
|
|
500
|
+
"payload_tokens_est_median": 111
|
|
501
|
+
}
|
|
502
|
+
]
|
|
470
503
|
}
|
|
471
504
|
}
|
|
@@ -122,8 +122,13 @@ will still succeed. A follow-up PR will strip the dead handler code.
|
|
|
122
122
|
changelog records the published MCP surface fingerprint. When a tool
|
|
123
123
|
name, tier, category, or input schema changes, the test fails until
|
|
124
124
|
this section is updated.
|
|
125
|
-
- MCP public surface fingerprint: `sha256:
|
|
126
|
-
(updated 2026-
|
|
125
|
+
- MCP public surface fingerprint: `sha256:2b0dfbd62acd71b7`
|
|
126
|
+
(updated 2026-07-04 for trp#928: explicit `coordinator_override` boolean added
|
|
127
|
+
to `bclaw_release_claim` and `bclaw_transition` input schemas — the coordinator
|
|
128
|
+
path to release/stale a non-owned claim is now opt-in and audited rather than
|
|
129
|
+
auto-derived from trust level. Additive: no tool added, removed, or renamed; no
|
|
130
|
+
required argument changed. Previous: `sha256:188d2eba8828e4fe`
|
|
131
|
+
updated 2026-06-24 for 1.11.0: `bclaw_move` added (pln#595) AND a `cascade`
|
|
127
132
|
boolean added to `bclaw_code_refresh` / `bclaw_code_status` (DGX Finding 2).
|
|
128
133
|
Additive: one new tool; nothing removed or renamed; no required argument changed.
|
|
129
134
|
Supersedes the per-branch interim hashes sha256:dffcc868ae90e013 and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brainclaw",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Shared project memory for humans and coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"clean:dist-test": "node scripts/clean-build.mjs dist-test",
|
|
43
43
|
"build": "npm run build:cli && node scripts/build-vsix.mjs --optional",
|
|
44
44
|
"build:cli": "npm run clean:dist && tsc && node scripts/copy-default-profiles.mjs && node scripts/copy-code-map-wasm.mjs",
|
|
45
|
-
"build:release": "npm run
|
|
46
|
-
"emit:facts": "npm run
|
|
45
|
+
"build:release": "npm run emit:facts && node scripts/build-vsix.mjs",
|
|
46
|
+
"emit:facts": "npm run bench && node scripts/emit-site-facts.mjs",
|
|
47
47
|
"dev": "npm run clean:dist && tsc && node scripts/copy-default-profiles.mjs && node dist/cli.js",
|
|
48
48
|
"dev:mcp": "tsc && node scripts/copy-default-profiles.mjs",
|
|
49
49
|
"build:mcp-schemas": "npm run clean:dist && tsc && node scripts/build-mcp-schemas.mjs",
|
|
@@ -60,6 +60,8 @@
|
|
|
60
60
|
"test:cross": "npm run build:test && node scripts/test-cross.mjs default",
|
|
61
61
|
"test:coverage": "npm run build:test && c8 --all --src dist-test/src --reporter=text-summary --reporter=lcov --exclude=dist-test/tests/** --exclude=dist-test/scripts/** node scripts/run-tests.mjs default",
|
|
62
62
|
"test:coverage:check": "npm run build:test && c8 --all --check-coverage --lines 55 --functions 60 --branches 65 --statements 55 --src dist-test/src --reporter=text-summary --exclude=dist-test/tests/** --exclude=dist-test/scripts/** node scripts/run-tests.mjs default",
|
|
63
|
+
"bench": "npm run build:test && node scripts/bench.mjs",
|
|
64
|
+
"bench:check": "node scripts/bench-check.mjs",
|
|
63
65
|
"prepublishOnly": "npm run build:release && npm run pack:check"
|
|
64
66
|
},
|
|
65
67
|
"keywords": [
|
|
@@ -79,7 +81,7 @@
|
|
|
79
81
|
},
|
|
80
82
|
"devDependencies": {
|
|
81
83
|
"@eslint/js": "^10.0.1",
|
|
82
|
-
"@types/node": "^
|
|
84
|
+
"@types/node": "^26.0.1",
|
|
83
85
|
"ajv": "^8.20.0",
|
|
84
86
|
"c8": "^11.0.0",
|
|
85
87
|
"eslint": "^10.5.0",
|