@hiveai/cli 0.24.0 → 0.25.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/index.js CHANGED
@@ -2253,6 +2253,7 @@ import path11 from "path";
2253
2253
  import {
2254
2254
  buildFrontmatter,
2255
2255
  loadMemoriesFromDir as loadMemoriesFromDir5,
2256
+ meetsSeedQualityFloor,
2256
2257
  memoryFilePath,
2257
2258
  serializeMemory as serializeMemory2,
2258
2259
  STACK_PACK_TAG
@@ -2293,7 +2294,12 @@ app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: t
2293
2294
  body: `Controllers must never import Prisma/TypeORM directly \u2014 that belongs in Services.
2294
2295
 
2295
2296
  Controller \u2192 Service \u2192 Repository (or direct ORM) is the required layering.
2296
- Direct ORM usage in controllers makes testing impossible and couples transport to persistence.`
2297
+ Direct ORM usage in controllers makes testing impossible and couples transport to persistence.`,
2298
+ sensor: {
2299
+ pattern: "@prisma/client|PrismaClient|getRepository\\(|createQueryBuilder\\(",
2300
+ paths: ["**/*.controller.ts"],
2301
+ message: "ORM/Prisma used directly in a controller \u2014 move persistence into a Service (Controller \u2192 Service \u2192 Repository)."
2302
+ }
2297
2303
  },
2298
2304
  {
2299
2305
  slug: "nestjs-exception-filter-for-prisma",
@@ -2478,7 +2484,11 @@ Routes without schema accept any body and bypass Fastify's fast-json-stringify s
2478
2484
 
2479
2485
  Calling $disconnect() after each request wastes the warm connection pool.
2480
2486
  Create one PrismaClient per process (module-level singleton), not per request.
2481
- Disconnecting is only needed when the process is shutting down.`
2487
+ Disconnecting is only needed when the process is shutting down.`,
2488
+ sensor: {
2489
+ pattern: "\\$disconnect\\(\\)",
2490
+ message: "prisma.$disconnect() per request drains the warm connection pool in serverless \u2014 use a module-level PrismaClient singleton and only disconnect on shutdown."
2491
+ }
2482
2492
  },
2483
2493
  {
2484
2494
  slug: "prisma-migrations-never-modify",
@@ -2534,7 +2544,11 @@ const store = useStore();
2534
2544
  const count = useStore((s) => s.count);
2535
2545
  \`\`\`
2536
2546
 
2537
- Subscribing to the whole store is the single most common Zustand performance mistake.`
2547
+ Subscribing to the whole store is the single most common Zustand performance mistake.`,
2548
+ sensor: {
2549
+ pattern: "use[A-Z]\\w*Store\\(\\s*\\)",
2550
+ message: "A Zustand store hook called with no selector subscribes to the WHOLE store (re-renders on any change) \u2014 pass a slice selector: useStore(s => s.field)."
2551
+ }
2538
2552
  },
2539
2553
  {
2540
2554
  slug: "zustand-devtools-wrap-dev-only",
@@ -2755,7 +2769,8 @@ const users = await User.find({});
2755
2769
  const users = await User.find({}).lean();
2756
2770
  \`\`\`
2757
2771
 
2758
- Never use .lean() when you need to call .save() or Mongoose instance methods.`
2772
+ \`.lean()\` skips hydration into a Mongoose \`Document\`, so getters, virtuals, \`toObject()\` and
2773
+ instance methods are gone. Never use \`.lean()\` when you then call \`.save()\` or instance methods.`
2759
2774
  },
2760
2775
  {
2761
2776
  slug: "mongoose-index-frequently-queried-fields",
@@ -2974,7 +2989,11 @@ A committed key lets anyone forge sessions and CSRF tokens.`
2974
2989
  db.execute(f"SELECT * FROM users WHERE id = {uid}")
2975
2990
  # \u2705
2976
2991
  db.execute("SELECT * FROM users WHERE id = %s", (uid,))
2977
- \`\`\``
2992
+ \`\`\``,
2993
+ sensor: {
2994
+ pattern: `execute\\(\\s*f["']`,
2995
+ message: 'SQL built with an f-string inside execute() \u2014 SQL injection risk; use a parameterized query: execute("\u2026 %s \u2026", (params,)).'
2996
+ }
2978
2997
  }
2979
2998
  ],
2980
2999
  vue: [
@@ -3342,6 +3361,7 @@ async function seedStackPack(haivePaths, stack) {
3342
3361
  let memCount = 0;
3343
3362
  let sensorCount = 0;
3344
3363
  for (const mem of memories) {
3364
+ if (!meetsSeedQualityFloor(mem.body, Boolean(mem.sensor))) continue;
3345
3365
  const sensor = mem.sensor ? {
3346
3366
  kind: "regex",
3347
3367
  pattern: mem.sensor.pattern,
@@ -3390,7 +3410,7 @@ ${SEED_FOOTER(stack)}` });
3390
3410
 
3391
3411
  // src/commands/init.ts
3392
3412
  var execFileAsync = promisify2(execFile2);
3393
- var HAIVE_GITHUB_ACTION_REF = `v${"0.24.0"}`;
3413
+ var HAIVE_GITHUB_ACTION_REF = `v${"0.25.0"}`;
3394
3414
  var PROJECT_CONTEXT_TEMPLATE = `# Project context
3395
3415
 
3396
3416
  > Generated by \`haive init\`. Run \`haive init --bootstrap\` to auto-fill from your codebase,
@@ -8676,7 +8696,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
8676
8696
  };
8677
8697
  }
8678
8698
  var SERVER_NAME = "haive";
8679
- var SERVER_VERSION = "0.24.0";
8699
+ var SERVER_VERSION = "0.25.0";
8680
8700
  function jsonResult(data) {
8681
8701
  return {
8682
8702
  content: [
@@ -14453,7 +14473,7 @@ function registerDoctor(program2) {
14453
14473
  fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
14454
14474
  });
14455
14475
  }
14456
- findings.push(...await collectInstallFindings(root, "0.24.0"));
14476
+ findings.push(...await collectInstallFindings(root, "0.25.0"));
14457
14477
  findings.push(...await collectToolchainFindings(root));
14458
14478
  try {
14459
14479
  const legacyRaw = execSync3("haive-mcp --version", {
@@ -14461,7 +14481,7 @@ function registerDoctor(program2) {
14461
14481
  timeout: 3e3,
14462
14482
  stdio: ["ignore", "pipe", "ignore"]
14463
14483
  }).trim();
14464
- const cliVersion = "0.24.0";
14484
+ const cliVersion = "0.25.0";
14465
14485
  if (legacyRaw && legacyRaw !== cliVersion) {
14466
14486
  findings.push({
14467
14487
  severity: "warn",
@@ -16165,7 +16185,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
16165
16185
  findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
16166
16186
  });
16167
16187
  }
16168
- findings.push(...await inspectIntegrationVersions(root, "0.24.0"));
16188
+ findings.push(...await inspectIntegrationVersions(root, "0.25.0"));
16169
16189
  if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
16170
16190
  const hasBriefing = await hasRecentBriefingMarker2(paths, sessionId);
16171
16191
  findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
@@ -18324,7 +18344,7 @@ function registerBridges(program2) {
18324
18344
 
18325
18345
  // src/index.ts
18326
18346
  var program = new Command64();
18327
- program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.24.0").option("--advanced", "show maintenance and experimental commands in help");
18347
+ program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.25.0").option("--advanced", "show maintenance and experimental commands in help");
18328
18348
  registerInit(program);
18329
18349
  registerWelcome(program);
18330
18350
  registerResolveProject(program);