thumbgate 1.27.8 → 1.27.10

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.
Files changed (117) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.well-known/llms.txt +1 -2
  3. package/.well-known/mcp/server-card.json +1 -1
  4. package/README.md +4 -2
  5. package/adapters/claude/.mcp.json +2 -2
  6. package/adapters/mcp/server-stdio.js +1 -1
  7. package/adapters/opencode/opencode.json +1 -1
  8. package/bin/cli.js +259 -78
  9. package/config/gate-templates.json +228 -0
  10. package/config/gates/claim-verification.json +18 -0
  11. package/package.json +14 -21
  12. package/public/blog.html +30 -0
  13. package/public/compare/adopt-ai.html +219 -0
  14. package/public/compare/agentix-labs.html +197 -0
  15. package/public/compare/ai-experience-orchestration.html +216 -0
  16. package/public/compare/anthropic-claude-for-legal.html +260 -0
  17. package/public/compare/anthropic-containment.html +280 -0
  18. package/public/compare/arcade.html +175 -0
  19. package/public/compare/arcjet.html +239 -0
  20. package/public/compare/bumblebee.html +307 -0
  21. package/public/compare/claude-code-hooks.html +294 -0
  22. package/public/compare/databricks-unity-ai-gateway.html +215 -0
  23. package/public/compare/fallow.html +351 -0
  24. package/public/compare/heidi.html +233 -0
  25. package/public/compare/mem0.html +342 -0
  26. package/public/compare/oak-and-sparrow-gatekeeper.html +289 -0
  27. package/public/compare/rein.html +236 -0
  28. package/public/compare/sigmashake.html +256 -0
  29. package/public/compare/speclock.html +342 -0
  30. package/public/compare.html +2 -0
  31. package/public/guides/agent-harness-optimization.html +342 -0
  32. package/public/guides/agentic-web-governance.html +406 -0
  33. package/public/guides/ai-agent-governance-sprint.html +415 -0
  34. package/public/guides/ai-agent-pre-action-approval-gates.html +401 -0
  35. package/public/guides/ai-agent-workflow-migration-checklist.html +392 -0
  36. package/public/guides/ai-deployment-readiness.html +415 -0
  37. package/public/guides/ai-mode-ads-agent-governance.html +401 -0
  38. package/public/guides/ai-search-topical-presence.html +342 -0
  39. package/public/guides/autoresearch-agent-safety.html +342 -0
  40. package/public/guides/background-agent-governance.html +358 -0
  41. package/public/guides/best-tools-stop-ai-agents-breaking-production.html +363 -0
  42. package/public/guides/browser-automation-safety.html +342 -0
  43. package/public/guides/chatgpt-ads-trust.html +353 -0
  44. package/public/guides/claude-code-feedback.html +339 -0
  45. package/public/guides/claude-code-prevent-repeated-mistakes.html +161 -0
  46. package/public/guides/claude-code-skills-guardrails.html +343 -0
  47. package/public/guides/claude-desktop.html +356 -0
  48. package/public/guides/code-knowledge-graph-guardrails.html +365 -0
  49. package/public/guides/codex-cli-guardrails.html +339 -0
  50. package/public/guides/cursor-agent-guardrails.html +339 -0
  51. package/public/guides/cursor-prevent-repeated-mistakes.html +161 -0
  52. package/public/guides/database-agent-safety.html +406 -0
  53. package/public/guides/deepseek-v4-runtime-guardrails.html +346 -0
  54. package/public/guides/developer-machine-supply-chain-guardrails.html +358 -0
  55. package/public/guides/gcp-mcp-guardrails.html +147 -0
  56. package/public/guides/gemini-cli-feedback-memory.html +339 -0
  57. package/public/guides/gpt-5-5-model-evaluation.html +358 -0
  58. package/public/guides/internal-ai-engineering-stack-guardrails.html +348 -0
  59. package/public/guides/long-running-agent-context-management.html +346 -0
  60. package/public/guides/mcp-tool-governance.html +401 -0
  61. package/public/guides/multica-thumbgate-setup.html +134 -0
  62. package/public/guides/native-messaging-host-security.html +342 -0
  63. package/public/guides/policy-engine-pre-action-gates.html +346 -0
  64. package/public/guides/pre-action-checks.html +342 -0
  65. package/public/guides/pretooluse-hooks-vs-advisory-prompt-rules.html +342 -0
  66. package/public/guides/prompt-tricks-to-workflow-rules.html +365 -0
  67. package/public/guides/proxy-pointer-rag-guardrails.html +352 -0
  68. package/public/guides/rag-precision-tuning-guardrails.html +352 -0
  69. package/public/guides/reasoning-compression-guardrails.html +346 -0
  70. package/public/guides/relational-knowledge-ai-recommendations.html +342 -0
  71. package/public/guides/roo-code-alternative-cline.html +339 -0
  72. package/public/guides/semantic-programmatic-seo-guardrails.html +352 -0
  73. package/public/guides/seo-agent-skills-guardrails.html +344 -0
  74. package/public/guides/stop-repeated-ai-agent-mistakes.html +342 -0
  75. package/public/index.html +192 -50
  76. package/public/learn/ac-dc-runtime-enforcement.html +277 -0
  77. package/public/learn/agent-harness-pattern.html +181 -0
  78. package/public/learn/agent-identity-connector-governance.html +146 -0
  79. package/public/learn/agent-swarms-shared-gates.html +173 -0
  80. package/public/learn/agentic-enterprise-context-brain.html +117 -0
  81. package/public/learn/agentic-os-team-governance.html +146 -0
  82. package/public/learn/ai-agent-governance.html +158 -0
  83. package/public/learn/ai-agent-persistent-memory.html +211 -0
  84. package/public/learn/anthropomorphic-claim-gates.html +180 -0
  85. package/public/learn/background-agent-control-layer.html +184 -0
  86. package/public/learn/claude-code-goal-with-rubrics.html +205 -0
  87. package/public/learn/codex-role-plugins-need-governance.html +125 -0
  88. package/public/learn/cost-aware-agent-gate-routing.html +173 -0
  89. package/public/learn/databricks-unity-ai-gateway-runtime-governance.html +157 -0
  90. package/public/learn/deterministic-agent-workflows.html +185 -0
  91. package/public/learn/feedback-loop-vs-decision-layer.html +283 -0
  92. package/public/learn/from-prototype-to-production.html +223 -0
  93. package/public/learn/learn.css +51 -0
  94. package/public/learn/mcp-pre-action-checks-explained.html +172 -0
  95. package/public/learn/pretix-stripe-connect-marketplaces.html +161 -0
  96. package/public/learn/regulated-agent-execution-boundary.html +196 -0
  97. package/public/learn/spec-driven-development.html +168 -0
  98. package/public/learn/stop-ai-agent-force-push.html +134 -0
  99. package/public/learn/vibe-coding-safety-net.html +142 -0
  100. package/public/learn.html +34 -50
  101. package/public/numbers.html +2 -2
  102. package/public/pro.html +6 -6
  103. package/scripts/cli-schema.js +10 -22
  104. package/scripts/dashboard-chat.js +1 -2
  105. package/scripts/document-intake.js +49 -1
  106. package/scripts/gemini-embedding-policy.js +1 -2
  107. package/scripts/hook-stop-anti-claim.js +103 -42
  108. package/scripts/hosted-config.js +12 -0
  109. package/scripts/plausible-domain-config.js +1 -3
  110. package/scripts/reddit-browser-notification-watch.js +230 -0
  111. package/scripts/seo-gsd.js +0 -239
  112. package/scripts/tool-registry.js +2 -2
  113. package/scripts/vector-store.js +0 -44
  114. package/scripts/workspace-evolver.js +2 -62
  115. package/src/api/server.js +126 -335
  116. package/adapters/policy-engine/ethicore-guardian-client.js +0 -68
  117. package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +0 -260
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
3
3
  "description": "One 👎 becomes a hard rule the agent cannot bypass. Captures thumbs-down feedback, distills it into PreToolUse Pre-Action Checks, enforced across every future Claude Code session.",
4
- "version": "1.27.8",
4
+ "version": "1.27.7",
5
5
  "author": {
6
6
  "name": "Igor Ganapolsky",
7
7
  "email": "ig5973700@gmail.com",
@@ -64,11 +64,10 @@ npx thumbgate init --agent claude-code
64
64
  - Agent discovery: https://thumbgate.ai/.well-known/mcp.json
65
65
  - Progressive tool index: https://thumbgate.ai/.well-known/mcp/tools.json
66
66
  - Context footprint report: https://thumbgate.ai/.well-known/mcp/footprint.json
67
- - Headroom context compression guardrails: https://thumbgate.ai/guides/headroom-context-compression-guardrails
68
- - Sovereign coding model guardrails: https://thumbgate.ai/guides/sovereign-coding-model-guardrails
69
67
  - Agentic web governance: https://thumbgate.ai/guides/agentic-web-governance
70
68
  - AI Mode ads and agent governance: https://thumbgate.ai/guides/ai-mode-ads-agent-governance
71
69
  - MCP tool governance: https://thumbgate.ai/guides/mcp-tool-governance
70
+ - Policy engines need pre-action gates: https://thumbgate.ai/guides/policy-engine-pre-action-gates
72
71
  - AI agent pre-action approval gates: https://thumbgate.ai/guides/ai-agent-pre-action-approval-gates
73
72
  - Agent skills: https://thumbgate.ai/.well-known/mcp/skills.json
74
73
  - MCP applications: https://thumbgate.ai/.well-known/mcp/applications.json
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.27.8",
3
+ "version": "1.27.7",
4
4
  "description": "ThumbGate — 👍👎 feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
5
5
  "homepage": "https://thumbgate.ai",
6
6
  "transport": "stdio",
package/README.md CHANGED
@@ -16,6 +16,10 @@ The product is a self-improving enforcement layer: thumbs-down feedback, prompt
16
16
  <img src="docs/media/thumbgate-demo.gif" alt="ThumbGate blocking an AI agent's dangerous commands (rm -rf, force-push, chmod 777) in real time, while letting safe commands through" width="820" />
17
17
  </p>
18
18
 
19
+ <p align="center">
20
+ <img src="docs/diagrams/pre-action-gate-loop.svg" alt="ThumbGate pre-action gate loop: agent intent, PreToolUse gate, block or allow with audit receipt" width="920" />
21
+ </p>
22
+
19
23
  ```
20
24
  Agent tries: rm -rf tests/
21
25
  ThumbGate: ⛔ BLOCKED — "Never delete test directories"
@@ -384,8 +388,6 @@ npx thumbgate model-candidates --workload=dashboard-analysis --provider=openai -
384
388
  npx thumbgate native-messaging-audit # inspect local browser bridges and extension hosts
385
389
  npx thumbgate dashboard --open # open local project-scoped dashboard in browser
386
390
  thumbgate-dashboard # standalone browser dashboard shortcut (run '/project:thumbgate-dashboard' in Claude/Grok)
387
- npx thumbgate check-update # check if a new version is available on npm/GitHub
388
- npx thumbgate self-update # update ThumbGate to the latest version globally
389
391
  npx thumbgate serve # start MCP server on stdio
390
392
  npx thumbgate bench # run reliability benchmark
391
393
  npx thumbgate bench --programbench-smoke # include cleanroom whole-repo proof lane
@@ -2,13 +2,13 @@
2
2
  "mcpServers": {
3
3
  "thumbgate": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "thumbgate@1.27.8", "thumbgate", "serve"]
5
+ "args": ["--yes", "--package", "thumbgate@1.27.7", "thumbgate", "serve"]
6
6
  }
7
7
  },
8
8
  "hooks": {
9
9
  "preToolUse": {
10
10
  "command": "npx",
11
- "args": ["--yes", "--package", "thumbgate@1.27.8", "thumbgate", "gate-check"]
11
+ "args": ["--yes", "--package", "thumbgate@1.27.7", "thumbgate", "gate-check"]
12
12
  }
13
13
  }
14
14
  }
@@ -231,7 +231,7 @@ const {
231
231
  finalizeSession: finalizeFeedbackSession,
232
232
  } = require('../../scripts/feedback-session');
233
233
 
234
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.27.8' };
234
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.27.7' };
235
235
  const COMMERCE_CATEGORIES = [
236
236
  'product_recommendation',
237
237
  'brand_compliance',
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.27.8",
10
+ "thumbgate@1.27.7",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
package/bin/cli.js CHANGED
@@ -2188,26 +2188,6 @@ function pulse() {
2188
2188
  });
2189
2189
  }
2190
2190
 
2191
- function checkUpdateCmd() {
2192
- const { checkUpdate } = require(path.join(PKG_ROOT, 'scripts', 'check-update'));
2193
- const args = parseArgs(process.argv.slice(3));
2194
- checkUpdate({ verbose: !args.json, force: args.force }).then((res) => {
2195
- if (args.json) {
2196
- console.log(JSON.stringify(res, null, 2));
2197
- }
2198
- process.exit(0);
2199
- }).catch((err) => {
2200
- console.error(err && err.message ? err.message : err);
2201
- process.exit(1);
2202
- });
2203
- }
2204
-
2205
- function selfUpdateCmd() {
2206
- const { selfUpdate } = require(path.join(PKG_ROOT, 'scripts', 'check-update'));
2207
- const success = selfUpdate();
2208
- process.exit(success ? 0 : 1);
2209
- }
2210
-
2211
2191
  function dispatchBrief() {
2212
2192
  const args = parseArgs(process.argv.slice(3));
2213
2193
  const {
@@ -3171,7 +3151,6 @@ const SUBCOMMAND_HELP = {
3171
3151
  lessons: 'Usage: npx thumbgate lessons [--query="..."] [--limit=N]\n\nSearch the lesson database (Pro feature).',
3172
3152
  search: 'Usage: npx thumbgate search <query>\n\nSearch ThumbGate knowledge base (Pro feature).',
3173
3153
  'gate-check': 'Usage: npx thumbgate gate-check\n\nPreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict.',
3174
- 'hermes-gate': 'Usage: npx thumbgate hermes-gate\n\nNous Research Hermes Agent pre_tool_call shell hook: reads Hermes tool-call JSON from stdin, runs the ThumbGate gate pipeline (strict by default), and outputs {"decision":"block","reason":...} to veto or {} to allow. Gates terminal/patch/skill_manage etc. See adapters/hermes/config.yaml.',
3175
3154
  'break-glass': 'Usage: npx thumbgate break-glass --reason="why" [--ttl=5m] [--json]\n\nShort-lived recovery path for over-firing gates. Allows hook settings edits and satisfies PR-create/thread-check gates without disabling core destructive-action protections.',
3176
3155
  serve: 'Usage: npx thumbgate serve\n\nStart the MCP stdio server. This is for agent runtimes, not the local HTTP dashboard.',
3177
3156
  mcp: 'Usage: npx thumbgate mcp\n\nAlias for `thumbgate serve`.',
@@ -3189,6 +3168,11 @@ const SUBCOMMAND_HELP = {
3189
3168
  'ai-inventory': 'Usage: npx thumbgate ai-inventory [--root <dir>] [--format=summary|json|cyclonedx] [--output <path>] [--max-files=N]\n\nScan source/manifests/model artifacts for AI, ML, agent-framework, vector DB, Vertex, Gemini, and Dialogflow CX components. Use --format=cyclonedx to produce exportable ML-BOM evidence for enterprise reviews.',
3190
3169
  brain: 'Usage: npx thumbgate brain [--write] [--json] [--limit=N]\n\nBuild the agent-readable "context brain" — a single artifact consolidating this\nrepo\'s lessons, prevention rules, active gates, and project context for a coding\nagent to read BEFORE acting. --write saves it to .thumbgate/BRAIN.md (versioned,\ndeterministic). --json emits the structured model. --limit caps lessons (default 15).',
3191
3170
  'team-sync': 'Usage: npx thumbgate team-sync\n\nSynchronize prevention rules and context brain with your team\'s git repository (git pull --rebase & git push), then auto-rebuild the local brain.',
3171
+ dream: 'Usage: npx thumbgate dream [--min=N] [--feedback-dir=DIR] [--json]\n\nConsolidate raw history and lessons ("Silicon Dreaming"), merge duplicates, promote recurring failures to gates, and rebuild prevention rules + BRAIN.md.',
3172
+ consolidate: 'Usage: npx thumbgate consolidate\n\nAlias for npx thumbgate dream.',
3173
+ triage: 'Usage: npx thumbgate triage [--schedule="daily 9:00"] [--json]\n\nRun git updates, test verification, and memory consolidation, or schedule it on a cron.',
3174
+ hygiene: 'Usage: npx thumbgate hygiene\n\nAlias for npx thumbgate triage.',
3175
+ community: 'Usage: npx thumbgate community query <error> | share <rule-id>\n\nQuery or share verified prevention rules with the community knowledge registry.',
3192
3176
  };
3193
3177
 
3194
3178
  if (_wantsHelp && COMMAND && SUBCOMMAND_HELP[COMMAND]) {
@@ -3291,6 +3275,31 @@ function renderBrainMarkdown(model) {
3291
3275
  return out.join('\n');
3292
3276
  }
3293
3277
 
3278
+ function autoWireInstructionFile(fileName) {
3279
+ const filePath = path.join(CWD, fileName);
3280
+ if (!fs.existsSync(filePath)) return;
3281
+ try {
3282
+ let content = fs.readFileSync(filePath, 'utf8');
3283
+ const blockStart = '<!-- ThumbGate -->';
3284
+ const blockEnd = '<!-- End ThumbGate -->';
3285
+ const block = `${blockStart}\nIMPORTANT: Read .thumbgate/BRAIN.md first for lessons, prevention rules, and active gates in this repo.\n${blockEnd}\n`;
3286
+
3287
+ if (content.includes(blockStart)) {
3288
+ const startIdx = content.indexOf(blockStart);
3289
+ const endIdx = content.indexOf(blockEnd);
3290
+ if (endIdx !== -1) {
3291
+ content = content.slice(0, startIdx) + block + content.slice(endIdx + blockEnd.length).replace(/^\n+/, '');
3292
+ }
3293
+ } else {
3294
+ content = block + '\n' + content;
3295
+ }
3296
+ fs.writeFileSync(filePath, content);
3297
+ console.error(` Auto-wired agent pointer into ${fileName}`);
3298
+ } catch (err) {
3299
+ console.warn(`⚠️ Failed to auto-wire agent pointer in ${fileName}: ${err.message}`);
3300
+ }
3301
+ }
3302
+
3294
3303
  function cmdBrain(args = {}) {
3295
3304
  const model = buildBrainModel({ limit: args.limit });
3296
3305
  if (args.json) { console.log(JSON.stringify(model, null, 2)); return 0; }
@@ -3310,14 +3319,120 @@ function cmdBrain(args = {}) {
3310
3319
  const lt = (model.lessons && model.lessons.total) || 0;
3311
3320
  const rt = (model.rules && model.rules.total) || 0;
3312
3321
  const gt = (model.gates && model.gates.total) || 0;
3313
- console.log(`\u{1f9e0} Wrote context brain to .thumbgate/BRAIN.md (${lt} lessons · ${rt} rules · ${gt} gates).`);
3314
- console.log(' Point your agent at it: add "Read .thumbgate/BRAIN.md first" to CLAUDE.md / AGENTS.md.');
3322
+ console.error(`\u{1f9e0} Wrote context brain to .thumbgate/BRAIN.md (${lt} lessons · ${rt} rules · ${gt} gates).`);
3323
+
3324
+ // Auto-inject pointer block into CLAUDE.md / AGENTS.md
3325
+ autoWireInstructionFile('CLAUDE.md');
3326
+ autoWireInstructionFile('AGENTS.md');
3327
+
3315
3328
  return 0;
3316
3329
  }
3317
3330
  process.stdout.write(md);
3318
3331
  return 0;
3319
3332
  }
3320
3333
 
3334
+ function brain() {
3335
+ const args = parseArgs(process.argv.slice(3));
3336
+ const subcommand = process.argv.slice(3).find((arg) => !arg.startsWith('--')) || 'status';
3337
+ const {
3338
+ buildContextPack,
3339
+ checkNeverDo,
3340
+ cleanupReport,
3341
+ ensureBrain,
3342
+ formatContextPack,
3343
+ recordMemory,
3344
+ refreshNeverDoGates,
3345
+ } = require(path.join(PKG_ROOT, 'scripts', 'brain'));
3346
+
3347
+ if (subcommand === 'init' || subcommand === 'status') {
3348
+ const result = ensureBrain(CWD);
3349
+ const gates = refreshNeverDoGates(CWD);
3350
+ const payload = { ...result, gateCount: gates.gateCount };
3351
+ if (args.json) {
3352
+ console.log(JSON.stringify(payload, null, 2));
3353
+ return;
3354
+ }
3355
+ console.log('ThumbGate brain');
3356
+ console.log('='.repeat(15));
3357
+ console.log(`Brain dir : ${path.relative(CWD, result.brainDir)}`);
3358
+ console.log(`Created : ${result.created.length}`);
3359
+ console.log(`Soul files: ${result.soulFiles.length}`);
3360
+ console.log(`Memory dirs: ${result.memoryDirs.length}`);
3361
+ console.log(`Never-do gates: ${gates.gateCount}`);
3362
+ return;
3363
+ }
3364
+
3365
+ if (subcommand === 'context') {
3366
+ const task = args.task || process.argv.slice(4).find((arg) => !arg.startsWith('--')) || '';
3367
+ const pack = buildContextPack(CWD, { task });
3368
+ if (args.json) {
3369
+ console.log(JSON.stringify(pack, null, 2));
3370
+ return;
3371
+ }
3372
+ process.stdout.write(formatContextPack(pack));
3373
+ return;
3374
+ }
3375
+
3376
+ if (subcommand === 'remember') {
3377
+ const title = args.title || process.argv.slice(4).find((arg) => !arg.startsWith('--')) || '';
3378
+ const result = recordMemory(CWD, {
3379
+ type: args.type,
3380
+ title,
3381
+ content: args.content || title,
3382
+ reason: args.reason,
3383
+ source: args.source,
3384
+ tags: args.tags,
3385
+ date: args.date,
3386
+ });
3387
+ if (args.json) {
3388
+ console.log(JSON.stringify(result, null, 2));
3389
+ return;
3390
+ }
3391
+ if (!result.ok) {
3392
+ console.error(result.error);
3393
+ process.exit(1);
3394
+ }
3395
+ console.log(`Stored brain memory: ${result.path}`);
3396
+ return;
3397
+ }
3398
+
3399
+ if (subcommand === 'check') {
3400
+ const text = args.text || args.action || readStdinText();
3401
+ const result = checkNeverDo(CWD, { text });
3402
+ if (args.json) {
3403
+ console.log(JSON.stringify(result, null, 2));
3404
+ if (!result.ok) process.exit(2);
3405
+ return;
3406
+ }
3407
+ console.log(`ThumbGate brain decision: ${result.decision.toUpperCase()}`);
3408
+ for (const rule of result.blocked) console.log(`- ${rule.text}`);
3409
+ if (!result.ok) process.exit(2);
3410
+ return;
3411
+ }
3412
+
3413
+ if (subcommand === 'cleanup') {
3414
+ const report = cleanupReport(CWD, args);
3415
+ if (args.json) {
3416
+ console.log(JSON.stringify(report, null, 2));
3417
+ return;
3418
+ }
3419
+ console.log('ThumbGate brain cleanup report');
3420
+ console.log('='.repeat(31));
3421
+ console.log(`Memory files: ${report.total}`);
3422
+ console.log(`Unsourced : ${report.unsourced.length}`);
3423
+ console.log(`Stale : ${report.stale.length}`);
3424
+ console.log(`Duplicates : ${report.duplicates.length}`);
3425
+ if (report.unsourced.length) {
3426
+ console.log('\nUnsourced files:');
3427
+ for (const filePath of report.unsourced) console.log(`- ${filePath}`);
3428
+ }
3429
+ return;
3430
+ }
3431
+
3432
+ console.error('Usage: npx thumbgate brain init|context|remember|check|cleanup [--json]');
3433
+ process.exit(1);
3434
+ }
3435
+
3321
3436
  async function teamSync() {
3322
3437
  const { execSync } = require('child_process');
3323
3438
 
@@ -3496,6 +3611,127 @@ switch (COMMAND) {
3496
3611
  }
3497
3612
  break;
3498
3613
  }
3614
+ case 'dream':
3615
+ case 'consolidate': {
3616
+ const args = parseArgs(process.argv.slice(3));
3617
+ const { dream } = require(path.join(PKG_ROOT, 'scripts', 'dream-consolidation'));
3618
+ dream({
3619
+ pkgRoot: PKG_ROOT,
3620
+ feedbackDir: args['feedback-dir'] || args.feedbackDir || CWD,
3621
+ rulesPath: args.output || path.join(CWD, '.thumbgate', 'prevention-rules.md'),
3622
+ minOccurrences: args.min || 2,
3623
+ }).then(async (result) => {
3624
+ try {
3625
+ await cmdBrain({ write: true });
3626
+ } catch (brainErr) {
3627
+ console.warn(`⚠️ Failed to rebuild context brain: ${brainErr.message}`);
3628
+ }
3629
+ if (args.json) {
3630
+ console.log(JSON.stringify(result, null, 2));
3631
+ } else {
3632
+ console.log(`✨ [Dreaming] Consolidation complete! Merged ${result.consolidated} duplicate(s) into ${result.lessonsCount} lessons.`);
3633
+ }
3634
+ process.exit(0);
3635
+ }).catch((err) => {
3636
+ console.error('❌ Error during memory consolidation:', err && err.message ? err.message : err);
3637
+ process.exit(1);
3638
+ });
3639
+ break;
3640
+ }
3641
+ case 'triage':
3642
+ case 'hygiene': {
3643
+ const args = parseArgs(process.argv.slice(3));
3644
+ const { runTriageLoop } = require(path.join(PKG_ROOT, 'scripts', 'triage-loop'));
3645
+
3646
+ if (args.schedule) {
3647
+ const { createSchedule } = require(path.join(PKG_ROOT, 'scripts', 'schedule-manager'));
3648
+ const scheduleResult = createSchedule({
3649
+ id: 'thumbgate-triage-hygiene',
3650
+ name: 'ThumbGate Triage & Hygiene Loop',
3651
+ description: 'Run autonomous git checks, test suite verification, and Silicon Dreaming memory consolidation.',
3652
+ schedule: args.schedule,
3653
+ command: `const { runTriageLoop } = require('${path.join(PKG_ROOT, 'scripts', 'triage-loop')}'); runTriageLoop({ cwd: '${CWD}', pkgRoot: '${PKG_ROOT}' }).catch(console.error);`,
3654
+ workingDirectory: CWD,
3655
+ });
3656
+ if (args.json) {
3657
+ console.log(JSON.stringify(scheduleResult, null, 2));
3658
+ } else {
3659
+ if (scheduleResult.success) {
3660
+ console.log(`✅ [Triage] Scheduled triage hygiene loop: ${scheduleResult.message}`);
3661
+ } else {
3662
+ console.error(`❌ [Triage] Failed to schedule: ${scheduleResult.error}`);
3663
+ process.exit(1);
3664
+ }
3665
+ }
3666
+ break;
3667
+ }
3668
+
3669
+ runTriageLoop({
3670
+ cwd: CWD,
3671
+ pkgRoot: PKG_ROOT,
3672
+ }).then(async (result) => {
3673
+ try {
3674
+ await cmdBrain({ write: true });
3675
+ } catch (brainErr) {
3676
+ console.warn(`⚠️ Failed to rebuild context brain: ${brainErr.message}`);
3677
+ }
3678
+ if (args.json) {
3679
+ console.log(JSON.stringify(result, null, 2));
3680
+ } else {
3681
+ console.log(result.log);
3682
+ }
3683
+ process.exit(0);
3684
+ }).catch((err) => {
3685
+ console.error('❌ Error during triage loop execution:', err && err.message ? err.message : err);
3686
+ process.exit(1);
3687
+ });
3688
+ break;
3689
+ }
3690
+ case 'community': {
3691
+ const args = parseArgs(process.argv.slice(3));
3692
+ const sub = process.argv.slice(3).find((arg) => !arg.startsWith('--'));
3693
+ const { queryCommunity, shareRule } = require(path.join(PKG_ROOT, 'scripts', 'community-knowledge'));
3694
+
3695
+ if (sub === 'query') {
3696
+ const queryIdx = process.argv.indexOf('query');
3697
+ const queryText = process.argv.slice(queryIdx + 1).filter(arg => !arg.startsWith('--')).join(' ');
3698
+ const result = queryCommunity(queryText, { remote: args.remote });
3699
+ if (args.json) {
3700
+ console.log(JSON.stringify(result, null, 2));
3701
+ } else {
3702
+ console.log(`🔍 Found ${result.resultsCount} community rule(s) matching "${result.query}":`);
3703
+ for (const r of result.results) {
3704
+ console.log(`\n- [${r.id}] ${r.rule}`);
3705
+ console.log(` Remedy: ${r.remedy}`);
3706
+ console.log(` Explanation: ${r.explanation}`);
3707
+ }
3708
+ }
3709
+ process.exit(0);
3710
+ } else if (sub === 'share') {
3711
+ const shareIdx = process.argv.indexOf('share');
3712
+ const ruleId = process.argv.slice(shareIdx + 1).find(arg => !arg.startsWith('--'));
3713
+ if (!ruleId) {
3714
+ console.error('❌ Error: rule ID is required for share subcommand.');
3715
+ process.exit(1);
3716
+ }
3717
+ const result = shareRule(ruleId, { feedbackDir: CWD });
3718
+ if (args.json) {
3719
+ console.log(JSON.stringify(result, null, 2));
3720
+ } else {
3721
+ if (result.ok) {
3722
+ console.log(`✨ Successfully shared rule "${ruleId}" to community registry.`);
3723
+ } else {
3724
+ console.error(`❌ Failed to share rule: ${result.error}`);
3725
+ process.exit(1);
3726
+ }
3727
+ }
3728
+ process.exit(0);
3729
+ } else {
3730
+ console.error('Usage: npx thumbgate community query <error> | share <rule-id> [--json]');
3731
+ process.exit(1);
3732
+ }
3733
+ break;
3734
+ }
3499
3735
  case 'billing:setup':
3500
3736
  require(path.join(PKG_ROOT, 'scripts', 'billing-setup'));
3501
3737
  break;
@@ -3863,14 +4099,6 @@ switch (COMMAND) {
3863
4099
  case 'pulse':
3864
4100
  pulse();
3865
4101
  break;
3866
- case 'check-update':
3867
- case 'upgrade-check':
3868
- checkUpdateCmd();
3869
- break;
3870
- case 'self-update':
3871
- case 'upgrade-cli':
3872
- selfUpdateCmd();
3873
- break;
3874
4102
  case 'dispatch':
3875
4103
  case 'dispatch-brief':
3876
4104
  dispatchBrief();
@@ -3896,53 +4124,6 @@ switch (COMMAND) {
3896
4124
  });
3897
4125
  break;
3898
4126
  }
3899
- case 'hermes-gate': {
3900
- // Nous Research Hermes Agent `pre_tool_call` shell hook.
3901
- // Hermes pipes each pending tool call as JSON to stdin and reads a decision from stdout;
3902
- // {"decision":"block","reason":...} vetoes the call. We reuse the SAME gate pipeline as
3903
- // `gate-check` (runAsync → secret guard, security scan, force-push / skill_manage / learned
3904
- // prevention rules) and translate the verdict into Hermes's format.
3905
- //
3906
- // Hermes `pre_tool_call` is binary (block or allow) with no warn channel, and the whole point
3907
- // of wiring it is to gate, so we run STRICT enforcement by default — otherwise ThumbGate's
3908
- // warn-by-default posture would pass every deny through and the hook would block nothing.
3909
- // Opt out with THUMBGATE_HERMES_WARN_ONLY=1; THUMBGATE_HOTFIX_BYPASS=1 still disables checks.
3910
- // Wire it in ~/.hermes/config.yaml — see adapters/hermes/config.yaml.
3911
- if (process.env.THUMBGATE_HERMES_WARN_ONLY !== '1' && process.env.THUMBGATE_HOTFIX_BYPASS !== '1') {
3912
- process.env.THUMBGATE_STRICT_ENFORCEMENT = '1';
3913
- }
3914
- const { runAsync: hermesGateRun } = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
3915
- let hermesStdin = '';
3916
- process.stdin.setEncoding('utf8');
3917
- process.stdin.on('data', (chunk) => { hermesStdin += chunk; });
3918
- process.stdin.on('end', async () => {
3919
- try {
3920
- const payload = JSON.parse(hermesStdin);
3921
- // Hermes sends snake_case tool_name/tool_input — gates-engine reads these directly.
3922
- const verdict = await hermesGateRun({ tool_name: payload.tool_name, tool_input: payload.tool_input });
3923
- let parsed = {};
3924
- try { parsed = JSON.parse(verdict); } catch (_e) { parsed = {}; }
3925
- const hso = parsed.hookSpecificOutput || {};
3926
- if (hso.permissionDecision === 'deny') {
3927
- process.stdout.write(JSON.stringify({
3928
- decision: 'block',
3929
- reason: hso.permissionDecisionReason || 'Blocked by ThumbGate prevention rule.',
3930
- }) + '\n');
3931
- } else {
3932
- // warn / no match → allow. The gate engine already logged the decision.
3933
- process.stdout.write(JSON.stringify({}) + '\n');
3934
- }
3935
- process.exit(0);
3936
- } catch (err) {
3937
- // Hermes hooks fail OPEN on error/timeout — emit an explicit allow so a gate fault
3938
- // never wedges the agent (reliability ≈ enforcement; keep this fast).
3939
- process.stderr.write(`hermes-gate error: ${err.message}\n`);
3940
- process.stdout.write(JSON.stringify({}) + '\n');
3941
- process.exit(0);
3942
- }
3943
- });
3944
- break;
3945
- }
3946
4127
  case 'gate-stats':
3947
4128
  gateStats();
3948
4129
  break;