thumbgate 0.9.13 → 1.0.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.
Files changed (70) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.well-known/mcp/server-card.json +1 -1
  4. package/README.md +6 -3
  5. package/adapters/README.md +1 -1
  6. package/adapters/chatgpt/openapi.yaml +105 -0
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/codex/config.toml +2 -2
  9. package/adapters/forge/forge.yaml +28 -0
  10. package/adapters/mcp/server-stdio.js +32 -1
  11. package/adapters/opencode/opencode.json +1 -1
  12. package/bin/cli.js +53 -3
  13. package/config/mcp-allowlists.json +10 -0
  14. package/openapi/openapi.yaml +105 -0
  15. package/package.json +4 -4
  16. package/plugins/amp-skill/INSTALL.md +3 -4
  17. package/plugins/amp-skill/SKILL.md +0 -1
  18. package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +1 -1
  19. package/plugins/claude-codex-bridge/.mcp.json +1 -1
  20. package/plugins/claude-skill/INSTALL.md +1 -2
  21. package/plugins/codex-profile/.codex-plugin/plugin.json +1 -1
  22. package/plugins/codex-profile/.mcp.json +1 -1
  23. package/plugins/codex-profile/INSTALL.md +1 -1
  24. package/plugins/codex-profile/README.md +1 -1
  25. package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +1 -1
  26. package/plugins/opencode-profile/INSTALL.md +1 -1
  27. package/public/blog.html +1 -0
  28. package/public/dashboard.html +1 -1
  29. package/public/guide.html +1 -1
  30. package/public/index.html +29 -5
  31. package/public/learn/agent-harness-pattern.html +1 -1
  32. package/public/learn/ai-agent-persistent-memory.html +1 -1
  33. package/public/learn/mcp-pre-action-gates-explained.html +1 -1
  34. package/public/learn/stop-ai-agent-force-push.html +1 -1
  35. package/public/learn/vibe-coding-safety-net.html +1 -1
  36. package/public/learn.html +62 -1
  37. package/public/lessons.html +1 -1
  38. package/public/pro.html +1 -1
  39. package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
  40. package/scripts/agent-security-hardening.js +4 -4
  41. package/scripts/async-job-runner.js +84 -24
  42. package/scripts/auto-wire-hooks.js +59 -1
  43. package/scripts/context-manager.js +330 -0
  44. package/scripts/dashboard.js +1 -1
  45. package/scripts/distribution-surfaces.js +12 -0
  46. package/scripts/ensure-repo-bootstrap.js +15 -14
  47. package/scripts/feedback-history-distiller.js +7 -1
  48. package/scripts/feedback-loop.js +10 -4
  49. package/scripts/feedback-paths.js +142 -10
  50. package/scripts/feedback-root-consolidator.js +18 -4
  51. package/scripts/gates-engine.js +96 -10
  52. package/scripts/hook-auto-capture.sh +1 -1
  53. package/scripts/hosted-job-launcher.js +260 -0
  54. package/scripts/managed-dpo-export.js +91 -0
  55. package/scripts/obsidian-export.js +0 -1
  56. package/scripts/operational-integrity.js +50 -7
  57. package/scripts/post-everywhere.js +10 -0
  58. package/scripts/prove-lancedb.js +62 -4
  59. package/scripts/publish-decision.js +16 -0
  60. package/scripts/self-healing-check.js +6 -1
  61. package/scripts/seo-gsd.js +217 -4
  62. package/scripts/social-analytics/load-env.js +33 -2
  63. package/scripts/social-analytics/store.js +200 -2
  64. package/scripts/statusline-cache-path.js +9 -6
  65. package/scripts/sync-version.js +18 -11
  66. package/scripts/tool-registry.js +37 -0
  67. package/scripts/train_from_feedback.py +0 -4
  68. package/scripts/workflow-sentinel.js +793 -0
  69. package/src/api/server.js +297 -38
  70. /package/scripts/{rlhf_session_start.sh → thumbgate_session_start.sh} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "0.9.13",
3
+ "version": "1.0.0",
4
4
  "plugins": [
5
5
  {
6
6
  "name": "thumbgate",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
3
3
  "description": "Pre-action gates that block AI coding agents from repeating known mistakes. Captures feedback, auto-promotes failures into prevention rules, and enforces them via PreToolUse hooks.",
4
- "version": "0.9.13",
4
+ "version": "1.0.0",
5
5
  "author": {
6
6
  "name": "Igor Ganapolsky"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "0.9.13",
3
+ "version": "1.0.0",
4
4
  "description": "ThumbGate — 👍👎 feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
5
5
  "homepage": "https://github.com/IgorGanapolsky/thumbgate",
6
6
  "transport": "stdio",
package/README.md CHANGED
@@ -7,7 +7,9 @@ Make your AI coding agent self-improving. One thumbs-down creates a gate that pe
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
8
8
  [![Try Free](https://img.shields.io/badge/Pro-Try%20Free%20→-635bff?style=for-the-badge&logo=stripe&logoColor=white)](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=badge_cta)
9
9
 
10
- **[Pro Page](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page)** · **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Pricing](https://thumbgate-production.up.railway.app/#pricing?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Setup Guide](https://thumbgate-production.up.railway.app/guide?utm_source=github&utm_medium=readme&utm_campaign=top_cta)**
10
+ **[Pro Page](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page)** · **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Pricing](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=top_cta#pricing)** · **[Setup Guide](https://thumbgate-production.up.railway.app/guide?utm_source=github&utm_medium=readme&utm_campaign=top_cta)**
11
+
12
+ **Popular buyer questions:** **[How to stop repeated AI agent mistakes](https://thumbgate-production.up.railway.app/guides/stop-repeated-ai-agent-mistakes?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Cursor guardrails](https://thumbgate-production.up.railway.app/guides/cursor-agent-guardrails?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Codex CLI guardrails](https://thumbgate-production.up.railway.app/guides/codex-cli-guardrails?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Gemini CLI memory + enforcement](https://thumbgate-production.up.railway.app/guides/gemini-cli-feedback-memory?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)**
11
13
 
12
14
  ### Get Started
13
15
 
@@ -15,7 +17,7 @@ Make your AI coding agent self-improving. One thumbs-down creates a gate that pe
15
17
 
16
18
  [![Sign up for ThumbGate Pro](https://img.shields.io/badge/>>%20Start%20Free%20→%20ThumbGate%20Pro-635bff?style=for-the-badge)](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=get_started)
17
19
 
18
- Free for individual developers. Pro adds team dashboards, DPO export, and unlimited lesson search. [See pricing →](https://thumbgate-production.up.railway.app/#pricing?utm_source=github&utm_medium=readme&utm_campaign=pricing_link)
20
+ Free for individual developers. Pro adds team dashboards, DPO export, and unlimited lesson search. [See pricing →](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=pricing_link#pricing)
19
21
 
20
22
  **Paid path for individual operators:** [ThumbGate Pro](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page) is the buyer-ready page for the personal local dashboard, DPO export, and review-ready evidence. It makes the paid upgrade legible before checkout while the self-hosted path below stays optimized for open source evaluation.
21
23
 
@@ -142,7 +144,7 @@ Free includes unlimited feedback captures, 5 daily lesson searches, unlimited re
142
144
 
143
145
  It does not update model weights. It's context engineering — enforcement that gets smarter every session.
144
146
 
145
- **[Get Pro](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)** | **[Start Team Rollout](https://thumbgate-production.up.railway.app/#workflow-sprint-intake?utm_source=github&utm_medium=readme&utm_campaign=team_rollout)** | **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)**
147
+ **[Get Pro](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)** | **[Start Team Rollout](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=team_rollout#workflow-sprint-intake)** | **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)**
146
148
 
147
149
  ## Tech Stack
148
150
 
@@ -167,6 +169,7 @@ It does not update model weights. It's context engineering — enforcement that
167
169
  ## Docs
168
170
 
169
171
  - [Commercial Truth](docs/COMMERCIAL_TRUTH.md) — pricing, claims, what we don't say
172
+ - [SemVer Policy](docs/SEMVER_POLICY.md) — stable vs prerelease channel rules
170
173
  - [Verification Evidence](docs/VERIFICATION_EVIDENCE.md) — proof artifacts
171
174
  - [WORKFLOW.md](WORKFLOW.md) — agent-run contract (scope, hard stops, proof commands)
172
175
  - [ready-for-agent issue template](.github/ISSUE_TEMPLATE/ready-for-agent.yml) — intake for agent tasks
@@ -3,7 +3,7 @@
3
3
  - `chatgpt/openapi.yaml`: import into GPT Actions.
4
4
  - `gemini/function-declarations.json`: Gemini function-calling definitions.
5
5
  - `mcp/server-stdio.js`: underlying local MCP stdio server implementation.
6
- - `claude/.mcp.json`: example Claude Code MCP config using `npx --yes --package thumbgate@0.9.13 thumbgate serve`.
6
+ - `claude/.mcp.json`: example Claude Code MCP config using `npx --yes --package thumbgate@1.0.0 thumbgate serve`.
7
7
  - `codex/config.toml`: example Codex MCP profile section using the same version-pinned portable launcher.
8
8
  - `amp/skills/thumbgate-feedback/SKILL.md`: Amp skill template.
9
9
  - `opencode/opencode.json`: portable OpenCode MCP profile using the same version-pinned portable launcher.
@@ -1101,11 +1101,116 @@ paths:
1101
1101
  type: string
1102
1102
  outputPath:
1103
1103
  type: string
1104
+ async:
1105
+ type: boolean
1106
+ mode:
1107
+ type: string
1108
+ enum: [sync, async]
1109
+ jobId:
1110
+ type: string
1104
1111
  responses:
1105
1112
  '200':
1106
1113
  description: DPO export completed
1114
+ '202':
1115
+ description: DPO export accepted as a hosted background job
1116
+ '401':
1117
+ description: Unauthorized
1118
+ /v1/jobs:
1119
+ get:
1120
+ operationId: listHostedJobs
1121
+ parameters:
1122
+ - in: query
1123
+ name: limit
1124
+ schema:
1125
+ type: integer
1126
+ default: 20
1127
+ - in: query
1128
+ name: status
1129
+ schema:
1130
+ type: string
1131
+ description: Optional comma-separated list of job statuses to filter.
1132
+ responses:
1133
+ '200':
1134
+ description: Hosted job states
1135
+ '401':
1136
+ description: Unauthorized
1137
+ /v1/jobs/harness:
1138
+ post:
1139
+ operationId: launchHostedHarness
1140
+ requestBody:
1141
+ required: true
1142
+ content:
1143
+ application/json:
1144
+ schema:
1145
+ type: object
1146
+ required: [harness]
1147
+ properties:
1148
+ harness:
1149
+ type: string
1150
+ harnessId:
1151
+ type: string
1152
+ jobId:
1153
+ type: string
1154
+ skill:
1155
+ type: string
1156
+ partnerProfile:
1157
+ type: string
1158
+ autoImprove:
1159
+ type: boolean
1160
+ inputs:
1161
+ type: object
1162
+ responses:
1163
+ '202':
1164
+ description: Hosted harness accepted
1165
+ '401':
1166
+ description: Unauthorized
1167
+ /v1/jobs/{jobId}:
1168
+ get:
1169
+ operationId: getHostedJob
1170
+ parameters:
1171
+ - in: path
1172
+ name: jobId
1173
+ required: true
1174
+ schema:
1175
+ type: string
1176
+ responses:
1177
+ '200':
1178
+ description: Hosted job state
1179
+ '401':
1180
+ description: Unauthorized
1181
+ '404':
1182
+ description: Job not found
1183
+ /v1/jobs/{jobId}/control:
1184
+ post:
1185
+ operationId: controlHostedJob
1186
+ parameters:
1187
+ - in: path
1188
+ name: jobId
1189
+ required: true
1190
+ schema:
1191
+ type: string
1192
+ requestBody:
1193
+ required: true
1194
+ content:
1195
+ application/json:
1196
+ schema:
1197
+ type: object
1198
+ required: [action]
1199
+ properties:
1200
+ action:
1201
+ type: string
1202
+ enum: [pause, cancel, resume]
1203
+ metadata:
1204
+ type: object
1205
+ responses:
1206
+ '202':
1207
+ description: Hosted job control accepted
1107
1208
  '401':
1108
1209
  description: Unauthorized
1210
+ '404':
1211
+ description: Job not found
1212
+ '409':
1213
+ description: Job cannot accept the requested control action
1109
1214
  /v1/analytics/databricks/export:
1110
1215
  post:
1111
1216
  operationId: exportDatabricksBundle
@@ -2,13 +2,13 @@
2
2
  "mcpServers": {
3
3
  "thumbgate": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "thumbgate@0.9.13", "thumbgate", "serve"]
5
+ "args": ["--yes", "--package", "thumbgate@1.0.0", "thumbgate", "serve"]
6
6
  }
7
7
  },
8
8
  "hooks": {
9
9
  "preToolUse": {
10
10
  "command": "npx",
11
- "args": ["--yes", "--package", "thumbgate@0.9.13", "thumbgate", "gate-check"]
11
+ "args": ["--yes", "--package", "thumbgate@1.0.0", "thumbgate", "gate-check"]
12
12
  }
13
13
  }
14
14
  }
@@ -1,9 +1,9 @@
1
1
  # Codex MCP profile (copy into ~/.codex/config.toml or merge section)
2
2
  [mcp_servers.thumbgate]
3
3
  command = "npx"
4
- args = ["--yes", "--package", "thumbgate@0.9.13", "thumbgate", "serve"]
4
+ args = ["--yes", "--package", "thumbgate@1.0.0", "thumbgate", "serve"]
5
5
 
6
6
  # Hard PreToolUse hook for Codex
7
7
  [hooks.pre_tool_use]
8
8
  command = "npx"
9
- args = ["--yes", "--package", "thumbgate@0.9.13", "thumbgate", "gate-check"]
9
+ args = ["--yes", "--package", "thumbgate@1.0.0", "thumbgate", "gate-check"]
@@ -0,0 +1,28 @@
1
+ # ForgeCode ThumbGate integration
2
+ # Copy into your project's forge.yaml or merge with existing config.
3
+ #
4
+ # ForgeCode (https://github.com/antinomyhq/forgecode) supports custom skills
5
+ # that ThumbGate uses to gate tool calls before execution.
6
+
7
+ version: "1"
8
+
9
+ skills:
10
+ thumbgate-gate-check:
11
+ description: "ThumbGate PreToolUse gate — blocks known-bad tool calls"
12
+ command: "npx --yes --package thumbgate@0.9.13 thumbgate gate-check"
13
+ trigger: pre_tool_use
14
+
15
+ thumbgate-feedback:
16
+ description: "ThumbGate feedback capture — logs user prompt context"
17
+ command: "npx --yes --package thumbgate@0.9.13 thumbgate hook-auto-capture"
18
+ trigger: user_prompt
19
+
20
+ mcp:
21
+ thumbgate:
22
+ command: "npx"
23
+ args:
24
+ - "--yes"
25
+ - "--package"
26
+ - "thumbgate@0.9.13"
27
+ - "thumbgate"
28
+ - "serve"
@@ -55,6 +55,9 @@ const {
55
55
  const {
56
56
  evaluateOperationalIntegrity,
57
57
  } = require('../../scripts/operational-integrity');
58
+ const {
59
+ evaluateWorkflowSentinel,
60
+ } = require('../../scripts/workflow-sentinel');
58
61
  const { diagnoseFailure } = require('../../scripts/failure-diagnostics');
59
62
  const {
60
63
  analyzeCodeGraphImpact,
@@ -90,6 +93,10 @@ const {
90
93
  const { TOOLS } = require('../../scripts/tool-registry');
91
94
  const { reflect: reflectOnFeedback } = require('../../scripts/reflector-agent');
92
95
  const { submitProductIssue } = require('../../scripts/product-feedback');
96
+ const {
97
+ assembleUnifiedContext,
98
+ formatUnifiedContext,
99
+ } = require('../../scripts/context-manager');
93
100
 
94
101
  const PRO_CHECKOUT_URL = 'https://thumbgate-production.up.railway.app/checkout/pro';
95
102
 
@@ -111,7 +118,7 @@ const {
111
118
  finalizeSession: finalizeFeedbackSession,
112
119
  } = require('../../scripts/feedback-session');
113
120
 
114
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.13' };
121
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.0.0' };
115
122
  const COMMERCE_CATEGORIES = [
116
123
  'product_recommendation',
117
124
  'brand_compliance',
@@ -508,6 +515,16 @@ async function callToolInner(name, args) {
508
515
  });
509
516
  case 'recall':
510
517
  return buildRecallResponse(args);
518
+ case 'unified_context': {
519
+ const ctx = assembleUnifiedContext({
520
+ query: args.query || '',
521
+ toolName: args.toolName,
522
+ toolInput: args.toolInput,
523
+ agentType: args.agentType,
524
+ repoPath: args.repoPath,
525
+ });
526
+ return toTextResult(formatUnifiedContext(ctx));
527
+ }
511
528
  case 'satisfy_gate': {
512
529
  if (!args.gate) {
513
530
  throw new Error('gate is required');
@@ -589,6 +606,20 @@ async function callToolInner(name, args) {
589
606
  requireVersionNotBehindBase: args.requireVersionNotBehindBase === true,
590
607
  branchGovernance: getBranchGovernanceState(),
591
608
  }));
609
+ case 'workflow_sentinel':
610
+ return toTextResult(evaluateWorkflowSentinel(args.toolName, {
611
+ command: args.command,
612
+ path: args.filePath,
613
+ changedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : [],
614
+ repoPath: args.repoPath,
615
+ baseBranch: args.baseBranch,
616
+ }, {
617
+ repoPath: args.repoPath,
618
+ baseBranch: args.baseBranch,
619
+ affectedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : undefined,
620
+ requirePrForReleaseSensitive: args.requirePrForReleaseSensitive === true,
621
+ requireVersionNotBehindBase: args.requireVersionNotBehindBase === true,
622
+ }));
592
623
  case 'register_claim_gate':
593
624
  return toTextResult(registerClaimGate(args.claimPattern, args.requiredActions, args.message));
594
625
  case 'gate_stats':
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@0.9.13",
10
+ "thumbgate@1.0.0",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
package/bin/cli.js CHANGED
@@ -63,6 +63,37 @@ function appendLocalTelemetry(payload) {
63
63
  } catch (_) { /* telemetry is best-effort */ }
64
64
  }
65
65
 
66
+ function syncActiveProjectContext(options = {}) {
67
+ try {
68
+ // Tests and explicitly scoped CLI calls may pin a feedback root directly.
69
+ // In that case, do not inject a project selection that would cause later
70
+ // reads/writes to escape the requested directory.
71
+ if (
72
+ !options.force &&
73
+ process.env.THUMBGATE_FEEDBACK_DIR &&
74
+ !process.env.THUMBGATE_PROJECT_DIR &&
75
+ !process.env.CLAUDE_PROJECT_DIR
76
+ ) {
77
+ return null;
78
+ }
79
+ const {
80
+ resolveProjectDir,
81
+ writeActiveProjectState,
82
+ } = require(path.join(PKG_ROOT, 'scripts', 'feedback-paths'));
83
+ const projectDir = resolveProjectDir({
84
+ cwd: CWD,
85
+ env: process.env,
86
+ includeStored: options.includeStored !== false,
87
+ });
88
+ if (!projectDir) return null;
89
+ process.env.THUMBGATE_PROJECT_DIR = projectDir;
90
+ writeActiveProjectState(projectDir, { env: process.env });
91
+ return projectDir;
92
+ } catch (_) {
93
+ return null;
94
+ }
95
+ }
96
+
66
97
  function telemetryPing(installId) {
67
98
  if (process.env.THUMBGATE_NO_TELEMETRY === '1') return;
68
99
  const payloadObject = {
@@ -411,6 +442,19 @@ function setupCursor() {
411
442
  return mergeMcpJson(path.join(CWD, '.cursor', 'mcp.json'), 'Cursor', 'project');
412
443
  }
413
444
 
445
+ function setupForge() {
446
+ const destPath = path.join(CWD, 'forge.yaml');
447
+ if (fs.existsSync(destPath)) {
448
+ // Don't overwrite existing forge.yaml — user may have custom config
449
+ return false;
450
+ }
451
+ const srcPath = path.join(PKG_ROOT, 'adapters', 'forge', 'forge.yaml');
452
+ if (!fs.existsSync(srcPath)) return false;
453
+ fs.copyFileSync(srcPath, destPath);
454
+ console.log(' ForgeCode: installed forge.yaml with ThumbGate skills');
455
+ return true;
456
+ }
457
+
414
458
  function init() {
415
459
  const args = parseArgs(process.argv.slice(3));
416
460
 
@@ -482,6 +526,7 @@ function init() {
482
526
  { name: 'Gemini', detect: [() => whichExists('gemini'), () => fs.existsSync(path.join(HOME, '.gemini'))], setup: setupGemini },
483
527
  { name: 'Amp', detect: [() => whichExists('amp'), () => fs.existsSync(path.join(HOME, '.amp'))], setup: setupAmp },
484
528
  { name: 'Cursor', detect: [() => fs.existsSync(path.join(HOME, '.cursor', 'mcp.json')), () => fs.existsSync(path.join(CWD, '.cursor'))], setup: setupCursor },
529
+ { name: 'ForgeCode', detect: [() => whichExists('forge'), () => fs.existsSync(path.join(CWD, 'forge.yaml'))], setup: setupForge },
485
530
  ];
486
531
 
487
532
  for (const p of platforms) {
@@ -1158,7 +1203,8 @@ function install() {
1158
1203
  setupCodex(),
1159
1204
  setupGemini(),
1160
1205
  setupCursor(),
1161
- setupAmp()
1206
+ setupAmp(),
1207
+ setupForge()
1162
1208
  ];
1163
1209
  const success = results.some(r => r === true);
1164
1210
  if (success) {
@@ -1178,12 +1224,14 @@ async function gateCheck() {
1178
1224
  }
1179
1225
 
1180
1226
  function cacheUpdate() {
1227
+ syncActiveProjectContext();
1181
1228
  const payload = readStdinText();
1182
1229
  const { updateCacheFromEvent } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
1183
1230
  updateCacheFromEvent(payload ? JSON.parse(payload) : {});
1184
1231
  }
1185
1232
 
1186
1233
  function statuslineRender() {
1234
+ syncActiveProjectContext();
1187
1235
  const payload = readStdinText();
1188
1236
  const output = execFileSync('bash', [path.join(PKG_ROOT, 'scripts', 'statusline.sh')], {
1189
1237
  encoding: 'utf8',
@@ -1194,6 +1242,7 @@ function statuslineRender() {
1194
1242
  }
1195
1243
 
1196
1244
  function hookAutoCapture() {
1245
+ syncActiveProjectContext();
1197
1246
  const prompt = process.env.CLAUDE_USER_PROMPT || process.env.THUMBGATE_USER_PROMPT || readStdinText().trim();
1198
1247
  const { evaluatePromptGuard } = require(path.join(PKG_ROOT, 'scripts', 'prompt-guard'));
1199
1248
  const { processInlineFeedback, formatCliOutput } = require(path.join(PKG_ROOT, 'scripts', 'cli-feedback'));
@@ -1233,6 +1282,7 @@ function hookAutoCapture() {
1233
1282
  }
1234
1283
 
1235
1284
  function sessionStart() {
1285
+ syncActiveProjectContext();
1236
1286
  const { analyzeFeedback } = require(path.join(PKG_ROOT, 'scripts', 'feedback-loop'));
1237
1287
  const { refreshStatuslineCache } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
1238
1288
  refreshStatuslineCache(analyzeFeedback());
@@ -1285,11 +1335,11 @@ function help() {
1285
1335
  console.log('');
1286
1336
  console.log('Commands:');
1287
1337
  console.log(' init Scaffold .thumbgate/ config + MCP server in current project');
1288
- console.log(' --agent=NAME Wire PreToolUse hooks for agent (claude-code|codex|gemini)');
1338
+ console.log(' --agent=NAME Wire PreToolUse hooks for agent (claude-code|codex|gemini|forge)');
1289
1339
  console.log(' --wire-hooks Wire hooks only (auto-detect agent, skip scaffolding)');
1290
1340
  console.log(' --dry-run Preview hook changes without writing');
1291
1341
  console.log(' install-mcp Install ThumbGate MCP server into Claude Code settings (--project for local)');
1292
- console.log(' serve Start MCP server (stdio) — for claude/codex/gemini mcp add');
1342
+ console.log(' serve Start MCP server (stdio) — for claude/codex/gemini/forge mcp add');
1293
1343
  console.log(' gate-check Internal: evaluate a PreToolUse payload from stdin');
1294
1344
  console.log(' cache-update Internal: refresh the Claude statusline cache from stdin');
1295
1345
  console.log(' statusline-render Internal: render the ThumbGate Claude status line');
@@ -3,6 +3,7 @@
3
3
  "profiles": {
4
4
  "default": [
5
5
  "recall",
6
+ "unified_context",
6
7
  "capture_feedback",
7
8
  "open_feedback_session",
8
9
  "append_feedback_context",
@@ -36,6 +37,7 @@
36
37
  "track_action",
37
38
  "verify_claim",
38
39
  "check_operational_integrity",
40
+ "workflow_sentinel",
39
41
  "register_claim_gate",
40
42
  "gate_stats",
41
43
  "dashboard",
@@ -56,6 +58,7 @@
56
58
  "append_feedback_context",
57
59
  "finalize_feedback_session",
58
60
  "recall",
61
+ "unified_context",
59
62
  "search_lessons",
60
63
  "retrieve_lessons",
61
64
  "search_thumbgate",
@@ -69,6 +72,7 @@
69
72
  "track_action",
70
73
  "verify_claim",
71
74
  "check_operational_integrity",
75
+ "workflow_sentinel",
72
76
  "feedback_stats",
73
77
  "feedback_summary",
74
78
  "estimate_uncertainty",
@@ -88,12 +92,14 @@
88
92
  "track_action",
89
93
  "verify_claim",
90
94
  "check_operational_integrity",
95
+ "workflow_sentinel",
91
96
  "prevention_rules",
92
97
  "feedback_stats",
93
98
  "feedback_summary"
94
99
  ],
95
100
  "readonly": [
96
101
  "recall",
102
+ "unified_context",
97
103
  "feedback_summary",
98
104
  "search_lessons",
99
105
  "retrieve_lessons",
@@ -110,6 +116,7 @@
110
116
  "get_branch_governance",
111
117
  "verify_claim",
112
118
  "check_operational_integrity",
119
+ "workflow_sentinel",
113
120
  "gate_stats",
114
121
  "dashboard",
115
122
  "settings_status",
@@ -120,6 +127,7 @@
120
127
  ],
121
128
  "dispatch": [
122
129
  "recall",
130
+ "unified_context",
123
131
  "feedback_summary",
124
132
  "search_lessons",
125
133
  "retrieve_lessons",
@@ -135,6 +143,7 @@
135
143
  "get_branch_governance",
136
144
  "verify_claim",
137
145
  "check_operational_integrity",
146
+ "workflow_sentinel",
138
147
  "gate_stats",
139
148
  "dashboard",
140
149
  "settings_status",
@@ -156,6 +165,7 @@
156
165
  "get_branch_governance",
157
166
  "verify_claim",
158
167
  "check_operational_integrity",
168
+ "workflow_sentinel",
159
169
  "settings_status"
160
170
  ]
161
171
  }
@@ -1101,11 +1101,116 @@ paths:
1101
1101
  type: string
1102
1102
  outputPath:
1103
1103
  type: string
1104
+ async:
1105
+ type: boolean
1106
+ mode:
1107
+ type: string
1108
+ enum: [sync, async]
1109
+ jobId:
1110
+ type: string
1104
1111
  responses:
1105
1112
  '200':
1106
1113
  description: DPO export completed
1114
+ '202':
1115
+ description: DPO export accepted as a hosted background job
1116
+ '401':
1117
+ description: Unauthorized
1118
+ /v1/jobs:
1119
+ get:
1120
+ operationId: listHostedJobs
1121
+ parameters:
1122
+ - in: query
1123
+ name: limit
1124
+ schema:
1125
+ type: integer
1126
+ default: 20
1127
+ - in: query
1128
+ name: status
1129
+ schema:
1130
+ type: string
1131
+ description: Optional comma-separated list of job statuses to filter.
1132
+ responses:
1133
+ '200':
1134
+ description: Hosted job states
1135
+ '401':
1136
+ description: Unauthorized
1137
+ /v1/jobs/harness:
1138
+ post:
1139
+ operationId: launchHostedHarness
1140
+ requestBody:
1141
+ required: true
1142
+ content:
1143
+ application/json:
1144
+ schema:
1145
+ type: object
1146
+ required: [harness]
1147
+ properties:
1148
+ harness:
1149
+ type: string
1150
+ harnessId:
1151
+ type: string
1152
+ jobId:
1153
+ type: string
1154
+ skill:
1155
+ type: string
1156
+ partnerProfile:
1157
+ type: string
1158
+ autoImprove:
1159
+ type: boolean
1160
+ inputs:
1161
+ type: object
1162
+ responses:
1163
+ '202':
1164
+ description: Hosted harness accepted
1165
+ '401':
1166
+ description: Unauthorized
1167
+ /v1/jobs/{jobId}:
1168
+ get:
1169
+ operationId: getHostedJob
1170
+ parameters:
1171
+ - in: path
1172
+ name: jobId
1173
+ required: true
1174
+ schema:
1175
+ type: string
1176
+ responses:
1177
+ '200':
1178
+ description: Hosted job state
1179
+ '401':
1180
+ description: Unauthorized
1181
+ '404':
1182
+ description: Job not found
1183
+ /v1/jobs/{jobId}/control:
1184
+ post:
1185
+ operationId: controlHostedJob
1186
+ parameters:
1187
+ - in: path
1188
+ name: jobId
1189
+ required: true
1190
+ schema:
1191
+ type: string
1192
+ requestBody:
1193
+ required: true
1194
+ content:
1195
+ application/json:
1196
+ schema:
1197
+ type: object
1198
+ required: [action]
1199
+ properties:
1200
+ action:
1201
+ type: string
1202
+ enum: [pause, cancel, resume]
1203
+ metadata:
1204
+ type: object
1205
+ responses:
1206
+ '202':
1207
+ description: Hosted job control accepted
1107
1208
  '401':
1108
1209
  description: Unauthorized
1210
+ '404':
1211
+ description: Job not found
1212
+ '409':
1213
+ description: Job cannot accept the requested control action
1109
1214
  /v1/analytics/databricks/export:
1110
1215
  post:
1111
1216
  operationId: exportDatabricksBundle