ctxloom-pro 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.
@@ -0,0 +1,18 @@
1
+ import {
2
+ __resetTelemetryWarnFlagsForTests,
3
+ appendEvent,
4
+ diskSink,
5
+ filenameForDate,
6
+ readEvents,
7
+ telemetryDir
8
+ } from "./chunk-5I6CJITG.js";
9
+ import "./chunk-TYDMSHV7.js";
10
+ export {
11
+ __resetTelemetryWarnFlagsForTests,
12
+ appendEvent,
13
+ diskSink,
14
+ filenameForDate,
15
+ readEvents,
16
+ telemetryDir
17
+ };
18
+ //# sourceMappingURL=eventCollector-QSRBVUDF.js.map
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ import {
49
49
  validateDefaultRoot,
50
50
  wrapWithIndexingEnvelope,
51
51
  writeCODEOWNERS
52
- } from "./chunk-Q2KTZNNU.js";
52
+ } from "./chunk-7GZVGIQL.js";
53
53
  import {
54
54
  VectorStore
55
55
  } from "./chunk-DVI2RWJR.js";
@@ -57,6 +57,7 @@ import {
57
57
  generateEmbedding,
58
58
  indexDirectory
59
59
  } from "./chunk-UVR65QBJ.js";
60
+ import "./chunk-5I6CJITG.js";
60
61
  import {
61
62
  logger
62
63
  } from "./chunk-TYDMSHV7.js";
@@ -1018,7 +1019,7 @@ try {
1018
1019
  } catch {
1019
1020
  }
1020
1021
  var args = process.argv.slice(2);
1021
- var ctxloomVersion = "1.3.0".length > 0 ? "1.3.0" : "dev";
1022
+ var ctxloomVersion = "1.4.0".length > 0 ? "1.4.0" : "dev";
1022
1023
  if (args.includes("--version") || args.includes("-v")) {
1023
1024
  process.stdout.write(`ctxloom ${ctxloomVersion}
1024
1025
  `);
@@ -1086,12 +1087,12 @@ function buildActivityFromOverlay(store) {
1086
1087
  lastCommitTimestamp
1087
1088
  }));
1088
1089
  }
1089
- var LICENSE_GATE_BYPASS_COMMANDS = /* @__PURE__ */ new Set(["trial", "activate", "deactivate", "status", "--help"]);
1090
+ var LICENSE_GATE_BYPASS_COMMANDS = /* @__PURE__ */ new Set(["trial", "activate", "deactivate", "status", "budget-stats", "--help"]);
1090
1091
  async function checkLicense() {
1091
1092
  if (command !== void 0 && LICENSE_GATE_BYPASS_COMMANDS.has(command)) return;
1092
1093
  const ciKey = process.env["CTXLOOM_LICENSE_KEY"];
1093
1094
  if (ciKey) {
1094
- const { ApiClient } = await import("./src-HNXOOOWF.js");
1095
+ const { ApiClient } = await import("./src-CH2OSHKF.js");
1095
1096
  const client = new ApiClient(process.env["CTXLOOM_API_BASE"]);
1096
1097
  try {
1097
1098
  const result = await client.validate(ciKey, "ci-ephemeral");
@@ -1443,6 +1444,9 @@ async function main() {
1443
1444
  process.stdout.write(` ${style.dim("Root:")} ${initRoot}
1444
1445
 
1445
1446
  `);
1447
+ const skipHarness = process.argv.includes("--skip-harness");
1448
+ const dryRun = process.argv.includes("--dry-run");
1449
+ const force = process.argv.includes("--force");
1446
1450
  try {
1447
1451
  const result = runInit(initRoot);
1448
1452
  const mcpLabel = result.mcpJson.created ? `${style.bold("Created")} ${result.mcpJson.path}` : result.mcpJson.merged ? `${style.bold("Merged ctxloom entry into")} ${result.mcpJson.path}` : `${style.dim("Already up to date:")} ${result.mcpJson.path}`;
@@ -1455,10 +1459,33 @@ async function main() {
1455
1459
  process.stdout.write(` ${warn(w)}
1456
1460
  `);
1457
1461
  }
1462
+ if (!skipHarness) {
1463
+ process.stdout.write("\n");
1464
+ const { installHarness } = await import("./src-CH2OSHKF.js");
1465
+ const h = installHarness({ cwd: initRoot, dryRun, force });
1466
+ const harnessFiles = [
1467
+ h.claudeMd,
1468
+ h.agentsMd,
1469
+ h.geminiMd,
1470
+ h.hooksJson,
1471
+ h.sessionStartSh,
1472
+ ...h.skills
1473
+ ];
1474
+ for (const fr of harnessFiles) {
1475
+ const rel = path4.relative(initRoot, fr.path);
1476
+ const label = fr.alreadyCorrect ? `${style.dim("Already up to date:")} ${rel}` : fr.created ? `${style.bold(dryRun ? "Would create" : "Created")} ${rel}` : `${style.bold(dryRun ? "Would update" : "Updated")} ${rel}`;
1477
+ process.stdout.write(` ${success(label)}
1478
+ `);
1479
+ }
1480
+ for (const w of h.warnings) {
1481
+ process.stdout.write(` ${warn(w)}
1482
+ `);
1483
+ }
1484
+ }
1458
1485
  process.stdout.write("\n");
1459
1486
  process.stdout.write(nextStep("Build the index", "ctxloom index"));
1460
1487
  process.stdout.write(
1461
- ` ${style.dim("Then reopen your AI tool in this directory to pick up the new .mcp.json.")}
1488
+ ` ${style.dim("Then reopen your AI tool in this directory to pick up the new .mcp.json + hooks.")}
1462
1489
 
1463
1490
  `
1464
1491
  );
@@ -1496,7 +1523,7 @@ async function main() {
1496
1523
  process.exit(1);
1497
1524
  }
1498
1525
  if (alias !== void 0) {
1499
- const { validateAlias } = await import("./src-HNXOOOWF.js");
1526
+ const { validateAlias } = await import("./src-CH2OSHKF.js");
1500
1527
  const v = validateAlias(alias);
1501
1528
  if (!v.ok) {
1502
1529
  console.error(`[ctxloom] Invalid alias: ${v.reason}`);
@@ -1569,6 +1596,23 @@ async function main() {
1569
1596
  }
1570
1597
  break;
1571
1598
  }
1599
+ case "budget-stats": {
1600
+ const windowArg = args.find((a) => a.startsWith("--window="))?.split("=")[1] ?? "14d";
1601
+ const toolArg = args.find((a) => a.startsWith("--tool="))?.split("=")[1];
1602
+ const days = parseInt(windowArg.replace(/d$/, ""), 10);
1603
+ if (!Number.isFinite(days) || days <= 0) {
1604
+ console.error(`[ctxloom] Invalid --window=${windowArg} \u2014 expected an integer day count like 14d`);
1605
+ process.exit(1);
1606
+ }
1607
+ const until = /* @__PURE__ */ new Date();
1608
+ const since = new Date(until.getTime() - days * 24 * 60 * 60 * 1e3);
1609
+ const { readEvents } = await import("./eventCollector-QSRBVUDF.js");
1610
+ const { summarize, renderSummary } = await import("./budgetStats-TURA232F.js");
1611
+ const events = readEvents({ since, until, tool: toolArg });
1612
+ const summary = summarize(events, since, until);
1613
+ console.log(renderSummary(summary));
1614
+ break;
1615
+ }
1572
1616
  case "dashboard": {
1573
1617
  const port = Number(
1574
1618
  args.find((a) => a.startsWith("--port="))?.split("=")[1] ?? "7842"
@@ -1743,7 +1787,7 @@ Suggested reviewers for ${files.length} file(s):`);
1743
1787
  process.stderr.write("[ctxloom] --limit must be a non-negative integer (0 for unlimited)\n");
1744
1788
  process.exit(2);
1745
1789
  }
1746
- const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-HNXOOOWF.js");
1790
+ const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-CH2OSHKF.js");
1747
1791
  let config;
1748
1792
  try {
1749
1793
  config = await loadRulesConfig(root);
@@ -1767,7 +1811,7 @@ Suggested reviewers for ${files.length} file(s):`);
1767
1811
  }
1768
1812
  let graph;
1769
1813
  if (useSnapshot) {
1770
- const { DependencyGraph: DG } = await import("./src-HNXOOOWF.js");
1814
+ const { DependencyGraph: DG } = await import("./src-CH2OSHKF.js");
1771
1815
  graph = new DG();
1772
1816
  const loaded = await graph.loadSnapshotOnly(root);
1773
1817
  if (!loaded) {
@@ -1776,7 +1820,7 @@ Suggested reviewers for ${files.length} file(s):`);
1776
1820
  }
1777
1821
  } else {
1778
1822
  process.stderr.write("[ctxloom] Building dependency graph...\n");
1779
- const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-HNXOOOWF.js");
1823
+ const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-CH2OSHKF.js");
1780
1824
  let parser;
1781
1825
  try {
1782
1826
  parser = new ASTParser2();
@@ -1828,6 +1872,9 @@ Usage:
1828
1872
  ctxloom dashboard Start the web dashboard (port 7842)
1829
1873
  ctxloom dashboard --port=N Start on custom port
1830
1874
  ctxloom dashboard --open Open browser automatically
1875
+ ctxloom budget-stats Aggregate Phase B budget events (per-tool p50/p75/p95)
1876
+ ctxloom budget-stats --window=Nd Lookback window in days (default: 14)
1877
+ ctxloom budget-stats --tool=NAME Restrict to one tool
1831
1878
  ctxloom review-suggest [files] Suggest reviewers from ownership index
1832
1879
  ctxloom authors-sync Map git emails to GitHub handles (needs GITHUB_TOKEN)
1833
1880
  ctxloom rules check Check architecture rules (.ctxloom/rules.yml)
@@ -3,10 +3,13 @@ import {
3
3
  ApiClient,
4
4
  AuthorResolver,
5
5
  BAND_PCT,
6
+ CTXLOOM_HOOK_ENTRIES,
7
+ CTXLOOM_SKILLS,
6
8
  CallGraphIndex,
7
9
  ChurnIndex,
8
10
  CoChangeIndex,
9
11
  CommunityDetector,
12
+ DEFAULT_HMAC_KEY,
10
13
  DEFAULT_REVIEW_CONFIG,
11
14
  DependencyGraph,
12
15
  EmailAlreadyUsedError,
@@ -30,11 +33,14 @@ import {
30
33
  PathValidator,
31
34
  ProjectStateManager,
32
35
  RISK_WEIGHTS,
36
+ RULES_BLOCK_CONTENT,
37
+ RULES_BLOCK_NAME,
33
38
  RepoRegistry,
34
39
  RuleManager,
35
40
  RulesChecker,
36
41
  RulesConfigError,
37
42
  SCORE_FLOOR,
43
+ SESSION_START_FULL,
38
44
  SILO_BUS_FACTOR,
39
45
  SeatLimitError,
40
46
  Skeletonizer,
@@ -48,6 +54,7 @@ import {
48
54
  buildBlastRadiusXml,
49
55
  buildCodeownersBlock,
50
56
  captureError,
57
+ computeBlockHmac,
51
58
  computeRiskBreakdown,
52
59
  computeRiskCaps,
53
60
  createProjectState,
@@ -56,6 +63,7 @@ import {
56
63
  detectChanges,
57
64
  disposeProjectState,
58
65
  ensureVectorsInitialized,
66
+ extractBlock,
59
67
  extractImports,
60
68
  extractNotebookLanguage,
61
69
  extractNotebookPythonSource,
@@ -70,6 +78,7 @@ import {
70
78
  getOrCreateDistinctId,
71
79
  getTelemetryLevel,
72
80
  hashProjectRoot,
81
+ installHarness,
73
82
  isActive,
74
83
  isSiloed,
75
84
  listNamedSnapshots,
@@ -87,6 +96,7 @@ import {
87
96
  recordTrendSnapshot,
88
97
  renderStatusXml,
89
98
  requireActive,
99
+ resolveHmacKey,
90
100
  resolveImport,
91
101
  resolveProjectRoot,
92
102
  resolveViaGitHubApi,
@@ -97,13 +107,17 @@ import {
97
107
  shouldEmitFirstReviewRun,
98
108
  shouldEmitInstallCompleted,
99
109
  shouldShowTelemetryNotice,
110
+ skillFilePath,
100
111
  startTrial,
101
112
  track,
113
+ upsertBlock,
102
114
  validateAlias,
103
115
  validateDefaultRoot,
116
+ verifyBlock,
117
+ wrapBlock,
104
118
  wrapWithIndexingEnvelope,
105
119
  writeCODEOWNERS
106
- } from "./chunk-Q2KTZNNU.js";
120
+ } from "./chunk-7GZVGIQL.js";
107
121
  import {
108
122
  VectorStore
109
123
  } from "./chunk-DVI2RWJR.js";
@@ -113,6 +127,7 @@ import {
113
127
  generateEmbedding,
114
128
  indexDirectory
115
129
  } from "./chunk-UVR65QBJ.js";
130
+ import "./chunk-5I6CJITG.js";
116
131
  import {
117
132
  logger
118
133
  } from "./chunk-TYDMSHV7.js";
@@ -121,10 +136,13 @@ export {
121
136
  ApiClient,
122
137
  AuthorResolver,
123
138
  BAND_PCT,
139
+ CTXLOOM_HOOK_ENTRIES,
140
+ CTXLOOM_SKILLS,
124
141
  CallGraphIndex,
125
142
  ChurnIndex,
126
143
  CoChangeIndex,
127
144
  CommunityDetector,
145
+ DEFAULT_HMAC_KEY,
128
146
  DEFAULT_REVIEW_CONFIG,
129
147
  DependencyGraph,
130
148
  EMBEDDING_DIMENSION,
@@ -149,11 +167,14 @@ export {
149
167
  PathValidator,
150
168
  ProjectStateManager,
151
169
  RISK_WEIGHTS,
170
+ RULES_BLOCK_CONTENT,
171
+ RULES_BLOCK_NAME,
152
172
  RepoRegistry,
153
173
  RuleManager,
154
174
  RulesChecker,
155
175
  RulesConfigError,
156
176
  SCORE_FLOOR,
177
+ SESSION_START_FULL,
157
178
  SILO_BUS_FACTOR,
158
179
  SeatLimitError,
159
180
  Skeletonizer,
@@ -169,6 +190,7 @@ export {
169
190
  buildCodeownersBlock,
170
191
  captureError,
171
192
  collectFiles,
193
+ computeBlockHmac,
172
194
  computeRiskBreakdown,
173
195
  computeRiskCaps,
174
196
  createProjectState,
@@ -177,6 +199,7 @@ export {
177
199
  detectChanges,
178
200
  disposeProjectState,
179
201
  ensureVectorsInitialized,
202
+ extractBlock,
180
203
  extractImports,
181
204
  extractNotebookLanguage,
182
205
  extractNotebookPythonSource,
@@ -193,6 +216,7 @@ export {
193
216
  getTelemetryLevel,
194
217
  hashProjectRoot,
195
218
  indexDirectory,
219
+ installHarness,
196
220
  isActive,
197
221
  isSiloed,
198
222
  listNamedSnapshots,
@@ -211,6 +235,7 @@ export {
211
235
  recordTrendSnapshot,
212
236
  renderStatusXml,
213
237
  requireActive,
238
+ resolveHmacKey,
214
239
  resolveImport,
215
240
  resolveProjectRoot,
216
241
  resolveViaGitHubApi,
@@ -221,11 +246,15 @@ export {
221
246
  shouldEmitFirstReviewRun,
222
247
  shouldEmitInstallCompleted,
223
248
  shouldShowTelemetryNotice,
249
+ skillFilePath,
224
250
  startTrial,
225
251
  track,
252
+ upsertBlock,
226
253
  validateAlias,
227
254
  validateDefaultRoot,
255
+ verifyBlock,
256
+ wrapBlock,
228
257
  wrapWithIndexingEnvelope,
229
258
  writeCODEOWNERS
230
259
  };
231
- //# sourceMappingURL=src-HNXOOOWF.js.map
260
+ //# sourceMappingURL=src-CH2OSHKF.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ctxloom-pro",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "ctxloom — The Universal Code Context Engine. A local-first MCP server providing intelligent code context via hybrid Vector + AST + Graph search with Skeletonization (92% token reduction).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",