thumbgate 1.4.2 → 1.4.4
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/.claude-plugin/README.md +45 -34
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +3 -3
- package/.well-known/llms.txt +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +26 -2
- package/adapters/README.md +4 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/mcp/server-stdio.js +10 -4
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +246 -90
- package/config/mcp-allowlists.json +11 -3
- package/package.json +184 -21
- package/scripts/audit-trail.js +25 -15
- package/scripts/auto-wire-hooks.js +127 -0
- package/scripts/cli-demo.js +102 -0
- package/scripts/cli-schema.js +285 -0
- package/scripts/cli-status.js +166 -0
- package/scripts/cross-encoder-reranker.js +235 -0
- package/scripts/explore-subcommands.js +277 -0
- package/scripts/explore.js +569 -0
- package/scripts/feedback-loop.js +20 -6
- package/scripts/lesson-inference.js +7 -1
- package/scripts/lesson-reranker.js +263 -0
- package/scripts/lesson-retrieval.js +34 -17
- package/scripts/lesson-search.js +69 -0
- package/scripts/perplexity-client.js +210 -0
- package/scripts/reflector-agent.js +2 -2
- package/scripts/statusline-local-stats.js +3 -1
- package/scripts/statusline.sh +12 -11
- package/src/api/server.js +178 -17
- package/src/index.js +3 -0
- package/.claude-plugin/bundle/icon.png +0 -0
- package/.claude-plugin/bundle/icon.svg +0 -18
- package/.claude-plugin/bundle/server/index.js +0 -24
- package/adapters/chatgpt/INSTALL.md +0 -138
- package/bin/memory.sh +0 -64
- package/bin/obsidian-sync.sh +0 -20
- package/plugins/amp-skill/INSTALL.md +0 -52
- package/plugins/amp-skill/SKILL.md +0 -64
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +0 -22
- package/plugins/claude-codex-bridge/.mcp.json +0 -14
- package/plugins/claude-codex-bridge/INSTALL.md +0 -43
- package/plugins/claude-codex-bridge/README.md +0 -46
- package/plugins/claude-codex-bridge/scripts/codex-bridge.js +0 -286
- package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +0 -24
- package/plugins/claude-codex-bridge/skills/result/SKILL.md +0 -22
- package/plugins/claude-codex-bridge/skills/review/SKILL.md +0 -28
- package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +0 -27
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +0 -21
- package/plugins/claude-codex-bridge/skills/status/SKILL.md +0 -19
- package/plugins/claude-skill/INSTALL.md +0 -55
- package/plugins/claude-skill/SKILL.md +0 -46
- package/plugins/codex-profile/.codex-plugin/plugin.json +0 -43
- package/plugins/codex-profile/.mcp.json +0 -14
- package/plugins/codex-profile/AGENTS.md +0 -20
- package/plugins/codex-profile/INSTALL.md +0 -89
- package/plugins/codex-profile/README.md +0 -61
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +0 -23
- package/plugins/cursor-marketplace/CHANGELOG.md +0 -30
- package/plugins/cursor-marketplace/LICENSE +0 -21
- package/plugins/cursor-marketplace/README.md +0 -124
- package/plugins/cursor-marketplace/agents/reliability-reviewer.md +0 -31
- package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
- package/plugins/cursor-marketplace/commands/capture-feedback.md +0 -33
- package/plugins/cursor-marketplace/commands/check-gates.md +0 -25
- package/plugins/cursor-marketplace/commands/show-lessons.md +0 -27
- package/plugins/cursor-marketplace/hooks/hooks.json +0 -10
- package/plugins/cursor-marketplace/mcp.json +0 -14
- package/plugins/cursor-marketplace/rules/feedback-capture.mdc +0 -34
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +0 -30
- package/plugins/cursor-marketplace/rules/session-continuity.mdc +0 -28
- package/plugins/cursor-marketplace/scripts/gate-check.sh +0 -21
- package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +0 -48
- package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +0 -31
- package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +0 -30
- package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +0 -33
- package/plugins/gemini-extension/INSTALL.md +0 -92
- package/plugins/gemini-extension/gemini_prompt.txt +0 -14
- package/plugins/gemini-extension/tool_contract.json +0 -45
- package/plugins/opencode-profile/INSTALL.md +0 -57
- package/public/assets/instagram-card.png +0 -0
- package/public/assets/tiktok-agent-memory.mp4 +0 -0
- package/public/blog.html +0 -474
- package/public/compare/mem0.html +0 -189
- package/public/compare/speclock.html +0 -180
- package/public/compare.html +0 -310
- package/public/dashboard.html +0 -1100
- package/public/guide.html +0 -317
- package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
- package/public/guides/codex-cli-guardrails.html +0 -158
- package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
- package/public/guides/pre-action-gates.html +0 -162
- package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -159
- package/public/index.html +0 -1128
- package/public/js/buyer-intent.js +0 -252
- package/public/learn/agent-harness-pattern.html +0 -180
- package/public/learn/ai-agent-persistent-memory.html +0 -203
- package/public/learn/learn.css +0 -45
- package/public/learn/mcp-pre-action-gates-explained.html +0 -172
- package/public/learn/stop-ai-agent-force-push.html +0 -134
- package/public/learn/vibe-coding-safety-net.html +0 -142
- package/public/learn.html +0 -274
- package/public/lessons.html +0 -967
- package/public/llm-context.md +0 -140
- package/public/pro.html +0 -1087
- package/public/vercel.json +0 -8
- package/scripts/a2ui-engine.js +0 -73
- package/scripts/adk-consolidator.js +0 -274
- package/scripts/agent-security-hardening.js +0 -225
- package/scripts/ai-search-visibility.js +0 -142
- package/scripts/autonomous-sales-agent.js +0 -39
- package/scripts/autoresearch-runner.js +0 -216
- package/scripts/background-agent-governance.js +0 -229
- package/scripts/behavioral-extraction.js +0 -93
- package/scripts/budget-enforcer.js +0 -173
- package/scripts/budget-guard.js +0 -173
- package/scripts/build-claude-mcpb.js +0 -255
- package/scripts/build-codex-plugin.js +0 -152
- package/scripts/capture-railway-diagnostics.sh +0 -97
- package/scripts/changeset-check.js +0 -372
- package/scripts/check-congruence.js +0 -443
- package/scripts/computer-use-firewall.js +0 -280
- package/scripts/content-engine/linkedin-content-generator.js +0 -154
- package/scripts/content-engine/output/linkedin-memento-validation.md +0 -17
- package/scripts/content-engine/output/linkedin-posts-2026-04-09.md +0 -175
- package/scripts/content-engine/reddit-thread-finder.js +0 -154
- package/scripts/context-engine.js +0 -710
- package/scripts/daily-digest.js +0 -11
- package/scripts/data-governance.js +0 -173
- package/scripts/deploy-gcp.sh +0 -44
- package/scripts/deploy-policy.js +0 -249
- package/scripts/disagreement-mining.js +0 -315
- package/scripts/dpo-optimizer.js +0 -206
- package/scripts/ensure-repo-bootstrap.js +0 -130
- package/scripts/ephemeral-agent-store.js +0 -212
- package/scripts/eval-harness.js +0 -56
- package/scripts/export-kto-pairs.js +0 -309
- package/scripts/export-training.js +0 -446
- package/scripts/feedback-fallback.js +0 -111
- package/scripts/feedback-inbox-read.js +0 -162
- package/scripts/feedback-root-consolidator.js +0 -233
- package/scripts/feedback-to-memory.js +0 -185
- package/scripts/gate-satisfy.js +0 -42
- package/scripts/generate-paperbanana-diagrams.sh +0 -99
- package/scripts/generate-pretool-hook.sh +0 -40
- package/scripts/github-about.js +0 -430
- package/scripts/github-outreach.js +0 -65
- package/scripts/gtm-revenue-loop.js +0 -535
- package/scripts/hallucination-detector.js +0 -226
- package/scripts/hf-papers.js +0 -317
- package/scripts/hook-auto-capture.sh +0 -100
- package/scripts/hook-stop-pr-thread-check.sh +0 -68
- package/scripts/hook-stop-self-score.sh +0 -51
- package/scripts/hook-stop-verify-deploy.sh +0 -31
- package/scripts/hook-verify-before-done.sh +0 -20
- package/scripts/managed-dpo-export.js +0 -91
- package/scripts/markdown-escape.js +0 -12
- package/scripts/marketing-experiment.js +0 -657
- package/scripts/memalign-recall.js +0 -111
- package/scripts/memory-migration.js +0 -296
- package/scripts/meta-policy.js +0 -190
- package/scripts/metered-billing.js +0 -16
- package/scripts/model-tier-router.js +0 -310
- package/scripts/money-watcher.js +0 -218
- package/scripts/multi-hop-recall.js +0 -240
- package/scripts/per-step-scoring.js +0 -163
- package/scripts/perplexity-marketing.js +0 -466
- package/scripts/pii-scanner.js +0 -153
- package/scripts/plan-gate.js +0 -154
- package/scripts/post-everywhere.js +0 -341
- package/scripts/post-to-x-retry.sh +0 -22
- package/scripts/post-to-x.js +0 -369
- package/scripts/pr-manager.js +0 -421
- package/scripts/principle-extractor.js +0 -162
- package/scripts/pro-features.js +0 -41
- package/scripts/prompt-dlp.js +0 -222
- package/scripts/prove-adapters.js +0 -860
- package/scripts/prove-attribution.js +0 -361
- package/scripts/prove-automation.js +0 -651
- package/scripts/prove-autoresearch.js +0 -304
- package/scripts/prove-claim-verification.js +0 -277
- package/scripts/prove-cloudflare-sandbox.js +0 -161
- package/scripts/prove-data-pipeline.js +0 -408
- package/scripts/prove-data-quality.js +0 -227
- package/scripts/prove-evolution.js +0 -352
- package/scripts/prove-harnesses.js +0 -287
- package/scripts/prove-intelligence.js +0 -257
- package/scripts/prove-lancedb.js +0 -425
- package/scripts/prove-local-intelligence.js +0 -340
- package/scripts/prove-loop-closure.js +0 -263
- package/scripts/prove-packaged-runtime.js +0 -326
- package/scripts/prove-predictive-insights.js +0 -355
- package/scripts/prove-runtime.js +0 -363
- package/scripts/prove-seo-gsd.js +0 -234
- package/scripts/prove-settings.js +0 -279
- package/scripts/prove-subway-upgrades.js +0 -277
- package/scripts/prove-tessl.js +0 -229
- package/scripts/prove-training-export.js +0 -325
- package/scripts/prove-workflow-contract.js +0 -112
- package/scripts/prove-xmemory.js +0 -332
- package/scripts/publish-decision.js +0 -159
- package/scripts/ralph-loop.js +0 -376
- package/scripts/ralph-mode-ci.js +0 -331
- package/scripts/reddit-dm-outreach.js +0 -192
- package/scripts/reddit-monitor-cron.sh +0 -26
- package/scripts/reminder-engine.js +0 -132
- package/scripts/revenue-status.js +0 -472
- package/scripts/rotate-stripe-webhook-secret.js +0 -314
- package/scripts/schedule-manager.js +0 -249
- package/scripts/self-healing-check.js +0 -193
- package/scripts/shieldcortex-memory-firewall-runner.mjs +0 -53
- package/scripts/skill-exporter.js +0 -260
- package/scripts/skill-materializer.js +0 -134
- package/scripts/skill-packs.js +0 -136
- package/scripts/skill-proposer.js +0 -99
- package/scripts/skill-quality-tracker.js +0 -282
- package/scripts/slow-loop.js +0 -72
- package/scripts/social-analytics/db/analytics.sqlite +0 -0
- package/scripts/social-analytics/db/schema.sql +0 -32
- package/scripts/social-analytics/digest.js +0 -256
- package/scripts/social-analytics/engagement-audit.js +0 -185
- package/scripts/social-analytics/generate-instagram-card.js +0 -97
- package/scripts/social-analytics/instagram-thumbgate-post.js +0 -111
- package/scripts/social-analytics/install-growth-automation.js +0 -114
- package/scripts/social-analytics/load-env.js +0 -77
- package/scripts/social-analytics/mcp-server.js +0 -289
- package/scripts/social-analytics/normalizer.js +0 -580
- package/scripts/social-analytics/notify.js +0 -162
- package/scripts/social-analytics/poll-all.js +0 -107
- package/scripts/social-analytics/pollers/github.js +0 -195
- package/scripts/social-analytics/pollers/instagram.js +0 -253
- package/scripts/social-analytics/pollers/linkedin.js +0 -340
- package/scripts/social-analytics/pollers/plausible.js +0 -245
- package/scripts/social-analytics/pollers/reddit.js +0 -306
- package/scripts/social-analytics/pollers/threads.js +0 -233
- package/scripts/social-analytics/pollers/tiktok.js +0 -203
- package/scripts/social-analytics/pollers/x.js +0 -227
- package/scripts/social-analytics/pollers/youtube.js +0 -304
- package/scripts/social-analytics/pollers/zernio.js +0 -183
- package/scripts/social-analytics/publish-instagram-thumbgate.js +0 -104
- package/scripts/social-analytics/publish-thumbgate-launch.js +0 -322
- package/scripts/social-analytics/publishers/devto.js +0 -122
- package/scripts/social-analytics/publishers/instagram.js +0 -317
- package/scripts/social-analytics/publishers/linkedin.js +0 -294
- package/scripts/social-analytics/publishers/reddit.js +0 -385
- package/scripts/social-analytics/publishers/threads.js +0 -275
- package/scripts/social-analytics/publishers/tiktok.js +0 -217
- package/scripts/social-analytics/publishers/x.js +0 -259
- package/scripts/social-analytics/publishers/youtube.js +0 -223
- package/scripts/social-analytics/publishers/zernio.js +0 -539
- package/scripts/social-analytics/reconcile-thumbgate-campaign.js +0 -165
- package/scripts/social-analytics/run-digest.js +0 -34
- package/scripts/social-analytics/schedule-thumbgate-campaign.js +0 -275
- package/scripts/social-analytics/store.js +0 -455
- package/scripts/social-analytics/sync-launch-assets.js +0 -185
- package/scripts/social-analytics/utm.js +0 -143
- package/scripts/social-pipeline.js +0 -2626
- package/scripts/social-post-hourly.js +0 -228
- package/scripts/social-quality-gate.js +0 -134
- package/scripts/social-reply-monitor.js +0 -592
- package/scripts/status-dashboard.js +0 -155
- package/scripts/stripe-live-status.js +0 -115
- package/scripts/subagent-profiles.js +0 -79
- package/scripts/sync-branch-protection.js +0 -340
- package/scripts/sync-gh-secrets-from-env.sh +0 -70
- package/scripts/sync-github-about.js +0 -55
- package/scripts/sync-version.js +0 -479
- package/scripts/synthetic-dpo.js +0 -234
- package/scripts/tessl-export.js +0 -369
- package/scripts/test-coverage.js +0 -128
- package/scripts/thumbgate_session_start.sh +0 -32
- package/scripts/train_from_feedback.py +0 -929
- package/scripts/validate-feedback.js +0 -581
- package/scripts/verify-obsidian-setup.sh +0 -269
- package/scripts/verify-run.js +0 -269
- package/scripts/weekly-auto-post.js +0 -124
- package/scripts/x-autonomous-marketing.js +0 -139
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require('node:fs');
|
|
3
|
-
const os = require('node:os');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const { spawnSync } = require('node:child_process');
|
|
6
|
-
const { diagnoseFailure } = require('./failure-diagnostics');
|
|
7
|
-
const { appendDiagnosticRecord } = require('./feedback-loop');
|
|
8
|
-
|
|
9
|
-
const PROJECT_ROOT = path.join(__dirname, '..');
|
|
10
|
-
const DEFAULT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
11
|
-
const DEFAULT_TESTS_TIMEOUT_MS = Number.parseInt(
|
|
12
|
-
process.env.THUMBGATE_SELF_HEAL_TEST_TIMEOUT_MS || '',
|
|
13
|
-
10,
|
|
14
|
-
) || 60 * 60_000;
|
|
15
|
-
|
|
16
|
-
const DEFAULT_CHECKS = [
|
|
17
|
-
{ name: 'budget_status', command: ['npm', 'run', 'budget:status'], timeoutMs: 60_000 },
|
|
18
|
-
{ name: 'tests', command: ['npm', 'test'], timeoutMs: DEFAULT_TESTS_TIMEOUT_MS },
|
|
19
|
-
{ name: 'prove_adapters', command: ['npm', 'run', 'prove:adapters'], timeoutMs: 10 * 60_000, useTempProofDir: true },
|
|
20
|
-
{ name: 'prove_automation', command: ['npm', 'run', 'prove:automation'], timeoutMs: 10 * 60_000, useTempProofDir: true },
|
|
21
|
-
{ name: 'prove_data_pipeline', command: ['npm', 'run', 'prove:data-pipeline'], timeoutMs: 10 * 60_000, useTempProofDir: true },
|
|
22
|
-
{ name: 'prove_tessl', command: ['npm', 'run', 'prove:tessl'], timeoutMs: 10 * 60_000, useTempProofDir: true },
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
function runCommand(command, {
|
|
26
|
-
cwd = PROJECT_ROOT,
|
|
27
|
-
timeoutMs = 5 * 60_000,
|
|
28
|
-
env = process.env,
|
|
29
|
-
maxBufferBytes = DEFAULT_MAX_BUFFER_BYTES,
|
|
30
|
-
} = {}) {
|
|
31
|
-
const [cmd, ...args] = command;
|
|
32
|
-
const started = Date.now();
|
|
33
|
-
const result = spawnSync(cmd, args, {
|
|
34
|
-
cwd,
|
|
35
|
-
env,
|
|
36
|
-
encoding: 'utf-8',
|
|
37
|
-
timeout: timeoutMs,
|
|
38
|
-
maxBuffer: maxBufferBytes,
|
|
39
|
-
shell: false,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const durationMs = Date.now() - started;
|
|
43
|
-
const status = Number.isInteger(result.status) ? result.status : 1;
|
|
44
|
-
return {
|
|
45
|
-
exitCode: status,
|
|
46
|
-
durationMs,
|
|
47
|
-
stdout: result.stdout || '',
|
|
48
|
-
stderr: result.stderr || '',
|
|
49
|
-
error: result.error ? result.error.message : null,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function createCheckEnvironment(check) {
|
|
54
|
-
const environment = { ...process.env };
|
|
55
|
-
let cleanup = null;
|
|
56
|
-
|
|
57
|
-
if (check.useTempProofDir) {
|
|
58
|
-
const proofDir = fs.mkdtempSync(path.join(os.tmpdir(), `thumbgate-${check.name}-`));
|
|
59
|
-
environment.THUMBGATE_PROOF_DIR = proofDir;
|
|
60
|
-
if (check.name === 'prove_automation') {
|
|
61
|
-
environment.THUMBGATE_AUTOMATION_PROOF_DIR = proofDir;
|
|
62
|
-
}
|
|
63
|
-
cleanup = () => {
|
|
64
|
-
fs.rmSync(proofDir, { recursive: true, force: true });
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return { env: environment, cleanup };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function collectHealthReport({
|
|
72
|
-
checks = DEFAULT_CHECKS,
|
|
73
|
-
runner = runCommand,
|
|
74
|
-
cwd = PROJECT_ROOT,
|
|
75
|
-
persistDiagnostics = false,
|
|
76
|
-
} = {}) {
|
|
77
|
-
const startedAt = new Date();
|
|
78
|
-
const results = checks.map((check) => {
|
|
79
|
-
const { env, cleanup } = createCheckEnvironment(check);
|
|
80
|
-
let run;
|
|
81
|
-
try {
|
|
82
|
-
run = runner(check.command, { cwd, timeoutMs: check.timeoutMs, env });
|
|
83
|
-
} finally {
|
|
84
|
-
if (cleanup) {
|
|
85
|
-
cleanup();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
const diagnosis = run.exitCode === 0
|
|
89
|
-
? null
|
|
90
|
-
: diagnoseFailure({
|
|
91
|
-
step: check.name,
|
|
92
|
-
context: check.command.join(' '),
|
|
93
|
-
healthCheck: {
|
|
94
|
-
name: check.name,
|
|
95
|
-
exitCode: run.exitCode,
|
|
96
|
-
status: 'unhealthy',
|
|
97
|
-
outputTail: `${run.stdout}\n${run.stderr}`.trim().slice(-2000),
|
|
98
|
-
},
|
|
99
|
-
exitCode: run.exitCode,
|
|
100
|
-
error: run.error,
|
|
101
|
-
output: `${run.stdout}\n${run.stderr}`.trim(),
|
|
102
|
-
});
|
|
103
|
-
const persistedDiagnosis = persistDiagnostics && diagnosis
|
|
104
|
-
? appendDiagnosticRecord({
|
|
105
|
-
source: 'self_heal_check',
|
|
106
|
-
step: check.name,
|
|
107
|
-
context: check.command.join(' '),
|
|
108
|
-
diagnosis,
|
|
109
|
-
metadata: {
|
|
110
|
-
command: check.command.join(' '),
|
|
111
|
-
},
|
|
112
|
-
})
|
|
113
|
-
: null;
|
|
114
|
-
return {
|
|
115
|
-
name: check.name,
|
|
116
|
-
command: check.command.join(' '),
|
|
117
|
-
status: run.exitCode === 0 ? 'healthy' : 'unhealthy',
|
|
118
|
-
exitCode: run.exitCode,
|
|
119
|
-
durationMs: run.durationMs,
|
|
120
|
-
error: run.error,
|
|
121
|
-
outputTail: `${run.stdout}\n${run.stderr}`.trim().slice(-2000),
|
|
122
|
-
diagnosis,
|
|
123
|
-
persistedDiagnosis,
|
|
124
|
-
};
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
const healthyCount = results.filter((x) => x.status === 'healthy').length;
|
|
128
|
-
const unhealthyCount = results.length - healthyCount;
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
generatedAt: startedAt.toISOString(),
|
|
132
|
-
durationMs: Date.now() - startedAt.getTime(),
|
|
133
|
-
overall_status: unhealthyCount === 0 ? 'healthy' : 'unhealthy',
|
|
134
|
-
summary: {
|
|
135
|
-
total: results.length,
|
|
136
|
-
healthy: healthyCount,
|
|
137
|
-
unhealthy: unhealthyCount,
|
|
138
|
-
},
|
|
139
|
-
checks: results,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function reportToText(report) {
|
|
144
|
-
const lines = [];
|
|
145
|
-
lines.push(`Self-Healing Health Check @ ${report.generatedAt}`);
|
|
146
|
-
lines.push(`Overall: ${report.overall_status.toUpperCase()}`);
|
|
147
|
-
lines.push(`Checks: ${report.summary.healthy}/${report.summary.total} healthy`);
|
|
148
|
-
lines.push('');
|
|
149
|
-
|
|
150
|
-
report.checks.forEach((check) => {
|
|
151
|
-
const icon = check.status === 'healthy' ? '✅' : '❌';
|
|
152
|
-
lines.push(`${icon} ${check.name} (${check.durationMs}ms)`);
|
|
153
|
-
if (check.status !== 'healthy') {
|
|
154
|
-
lines.push(` command: ${check.command}`);
|
|
155
|
-
if (check.error) lines.push(` error: ${check.error}`);
|
|
156
|
-
if (check.diagnosis && check.diagnosis.rootCauseCategory) {
|
|
157
|
-
lines.push(` diagnosis: ${check.diagnosis.rootCauseCategory}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
return `${lines.join('\n')}\n`;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function runCli() {
|
|
166
|
-
const args = new Set(process.argv.slice(2));
|
|
167
|
-
const emitJson = args.has('--json');
|
|
168
|
-
const noFail = args.has('--no-fail');
|
|
169
|
-
const report = collectHealthReport({ persistDiagnostics: true });
|
|
170
|
-
|
|
171
|
-
if (emitJson) {
|
|
172
|
-
console.log(JSON.stringify(report, null, 2));
|
|
173
|
-
} else {
|
|
174
|
-
process.stdout.write(reportToText(report));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (!noFail && report.overall_status !== 'healthy') {
|
|
178
|
-
process.exit(1);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
module.exports = {
|
|
183
|
-
DEFAULT_CHECKS,
|
|
184
|
-
DEFAULT_TESTS_TIMEOUT_MS,
|
|
185
|
-
DEFAULT_MAX_BUFFER_BYTES,
|
|
186
|
-
runCommand,
|
|
187
|
-
collectHealthReport,
|
|
188
|
-
reportToText,
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
if (require.main === module) {
|
|
192
|
-
runCli();
|
|
193
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
|
|
5
|
-
async function main() {
|
|
6
|
-
try {
|
|
7
|
-
const raw = readFileSync(0, 'utf8');
|
|
8
|
-
const parsed = raw.trim() ? JSON.parse(raw) : {};
|
|
9
|
-
const { record = {}, options = {} } = parsed;
|
|
10
|
-
|
|
11
|
-
const { ShieldCortexGuardedMemoryBridge } = await import('shieldcortex');
|
|
12
|
-
|
|
13
|
-
const backend = {
|
|
14
|
-
name: 'thumbgate-ingress',
|
|
15
|
-
async save() {
|
|
16
|
-
return { id: 'memory-ingress-probe' };
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const bridge = new ShieldCortexGuardedMemoryBridge(backend, {
|
|
21
|
-
mode: options.mode ?? 'strict',
|
|
22
|
-
sourceType: options.sourceType ?? 'hook',
|
|
23
|
-
sourceIdentifier: options.sourceIdentifier ?? 'feedback-loop',
|
|
24
|
-
blockOnThreat: true,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const result = await bridge.save(record);
|
|
28
|
-
const defence = result.defence || {};
|
|
29
|
-
const firewall = defence.firewall || {};
|
|
30
|
-
|
|
31
|
-
process.stdout.write(JSON.stringify({
|
|
32
|
-
available: true,
|
|
33
|
-
allowed: Boolean(result.allowed),
|
|
34
|
-
provider: 'shieldcortex',
|
|
35
|
-
mode: options.mode ?? 'strict',
|
|
36
|
-
reason: result.reason || firewall.reason || 'ShieldCortex decision completed.',
|
|
37
|
-
threatIndicators: Array.isArray(firewall.threatIndicators) ? firewall.threatIndicators : [],
|
|
38
|
-
blockedPatterns: Array.isArray(firewall.blockedPatterns) ? firewall.blockedPatterns : [],
|
|
39
|
-
firewallResult: firewall.result || null,
|
|
40
|
-
anomalyScore: firewall.anomalyScore ?? null,
|
|
41
|
-
sensitivityLevel: defence.sensitivity ? defence.sensitivity.level : null,
|
|
42
|
-
trustScore: defence.trust ? defence.trust.score : null,
|
|
43
|
-
auditId: defence.auditId ?? null,
|
|
44
|
-
}));
|
|
45
|
-
} catch (error) {
|
|
46
|
-
process.stdout.write(JSON.stringify({
|
|
47
|
-
available: false,
|
|
48
|
-
error: error.message,
|
|
49
|
-
}));
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
await main();
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Skill Exporter — compiles ThumbGate profiles/policy-bundles into
|
|
6
|
-
* OpenAI Skill definitions and Codex Plugin manifests.
|
|
7
|
-
* Vendor-neutral IR → target format compilation.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const fs = require('node:fs');
|
|
11
|
-
const path = require('node:path');
|
|
12
|
-
|
|
13
|
-
const ROOT = path.join(__dirname, '..');
|
|
14
|
-
const SKILL_SPECS_DIR = path.join(ROOT, 'config', 'skill-specs');
|
|
15
|
-
const POLICY_BUNDLES_DIR = path.join(ROOT, 'config', 'policy-bundles');
|
|
16
|
-
const DIST_DIR = path.join(ROOT, 'dist', 'skills');
|
|
17
|
-
const PKG = require(path.join(ROOT, 'package.json'));
|
|
18
|
-
const { ensureDir } = require('./fs-utils');
|
|
19
|
-
|
|
20
|
-
function readJson(filePath) {
|
|
21
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Load a SkillSpec by name from config/skill-specs/.
|
|
27
|
-
* @param {string} name - spec name (without .json)
|
|
28
|
-
* @returns {object} parsed SkillSpec
|
|
29
|
-
*/
|
|
30
|
-
function loadSkillSpec(name) {
|
|
31
|
-
const specPath = path.join(SKILL_SPECS_DIR, `${name}.json`);
|
|
32
|
-
if (!fs.existsSync(specPath)) {
|
|
33
|
-
throw new Error(`Skill spec not found: ${name} (looked at ${specPath})`);
|
|
34
|
-
}
|
|
35
|
-
return readJson(specPath);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* List all available skill specs in config/skill-specs/.
|
|
40
|
-
* @returns {string[]} spec names (without .json extension)
|
|
41
|
-
*/
|
|
42
|
-
function listAvailableSpecs() {
|
|
43
|
-
if (!fs.existsSync(SKILL_SPECS_DIR)) return [];
|
|
44
|
-
return fs.readdirSync(SKILL_SPECS_DIR)
|
|
45
|
-
.filter((f) => f.endsWith('.json'))
|
|
46
|
-
.map((f) => f.replace(/\.json$/, ''));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Load a policy bundle by bundleId.
|
|
51
|
-
* @param {string} bundleId
|
|
52
|
-
* @returns {object} parsed policy bundle
|
|
53
|
-
*/
|
|
54
|
-
function loadPolicyBundle(bundleId) {
|
|
55
|
-
const bundlePath = path.join(POLICY_BUNDLES_DIR, `${bundleId}.json`);
|
|
56
|
-
if (!fs.existsSync(bundlePath)) return null;
|
|
57
|
-
return readJson(bundlePath);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Build instruction text from a policy bundle and escalation rules.
|
|
62
|
-
* @param {object} bundle - parsed policy bundle
|
|
63
|
-
* @param {string[]} escalationRules
|
|
64
|
-
* @returns {string} instruction text
|
|
65
|
-
*/
|
|
66
|
-
function buildInstructions(bundle, escalationRules) {
|
|
67
|
-
const lines = [];
|
|
68
|
-
lines.push(`Policy: ${bundle.description}`);
|
|
69
|
-
lines.push(`Default MCP Profile: ${bundle.defaultMcpProfile}`);
|
|
70
|
-
lines.push('');
|
|
71
|
-
lines.push('## Approval Gates');
|
|
72
|
-
lines.push(`Required risk levels for approval: ${bundle.approval.requiredRisks.join(', ')}`);
|
|
73
|
-
lines.push('');
|
|
74
|
-
lines.push('## Available Intents');
|
|
75
|
-
for (const intent of bundle.intents) {
|
|
76
|
-
const actions = intent.actions.map((a) => a.name).join(', ');
|
|
77
|
-
lines.push(`- ${intent.id} [${intent.risk}]: ${intent.description} (${actions})`);
|
|
78
|
-
}
|
|
79
|
-
if (escalationRules.length > 0) {
|
|
80
|
-
lines.push('');
|
|
81
|
-
lines.push('## Escalation Rules');
|
|
82
|
-
for (const rule of escalationRules) {
|
|
83
|
-
lines.push(`- ${rule}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return lines.join('\n');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Compile a SkillSpec into an OpenAI Skill definition.
|
|
91
|
-
* @param {object} spec - parsed SkillSpec
|
|
92
|
-
* @returns {object} OpenAI Skill JSON
|
|
93
|
-
*/
|
|
94
|
-
function compileToOpenAISkill(spec) {
|
|
95
|
-
const bundle = loadPolicyBundle(spec.policyBundle);
|
|
96
|
-
const instructions = bundle
|
|
97
|
-
? buildInstructions(bundle, spec.escalationRules || [])
|
|
98
|
-
: `Skill: ${spec.description}`;
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
name: spec.name,
|
|
102
|
-
description: spec.description,
|
|
103
|
-
model_class: spec.defaultModelClass,
|
|
104
|
-
instructions,
|
|
105
|
-
scripts: {
|
|
106
|
-
gate_check: `recall --scope ${(spec.memoryScope || []).join(',')} --enforce`,
|
|
107
|
-
recall_injection: `recall --query "{{context}}" --scope ${(spec.memoryScope || []).join(',')}`
|
|
108
|
-
},
|
|
109
|
-
assets: {
|
|
110
|
-
prevention_rules: `config/policy-bundles/${spec.policyBundle}.json`,
|
|
111
|
-
memory_scope: spec.memoryScope || [],
|
|
112
|
-
tools: spec.tools || []
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Compile a SkillSpec into a Codex Plugin manifest.
|
|
119
|
-
* @param {object} spec - parsed SkillSpec
|
|
120
|
-
* @returns {object} { pluginJson, mcpJson, agentsMd }
|
|
121
|
-
*/
|
|
122
|
-
function compileToCodexPlugin(spec) {
|
|
123
|
-
const bundle = loadPolicyBundle(spec.policyBundle);
|
|
124
|
-
const instructions = bundle
|
|
125
|
-
? buildInstructions(bundle, spec.escalationRules || [])
|
|
126
|
-
: `Skill: ${spec.description}`;
|
|
127
|
-
|
|
128
|
-
const pluginJson = {
|
|
129
|
-
name: spec.name,
|
|
130
|
-
version: PKG.version,
|
|
131
|
-
description: spec.description,
|
|
132
|
-
author: {
|
|
133
|
-
name: PKG.author,
|
|
134
|
-
url: 'https://github.com/IgorGanapolsky'
|
|
135
|
-
},
|
|
136
|
-
homepage: PKG.homepage,
|
|
137
|
-
repository: PKG.repository.url.replace(/\.git$/, ''),
|
|
138
|
-
license: PKG.license,
|
|
139
|
-
keywords: ['codex', 'codex-plugin', 'thumbgate', spec.name, ...(spec.memoryScope || [])],
|
|
140
|
-
mcpServers: './.mcp.json',
|
|
141
|
-
interface: {
|
|
142
|
-
displayName: `ThumbGate: ${spec.name}`,
|
|
143
|
-
shortDescription: spec.description,
|
|
144
|
-
longDescription: instructions,
|
|
145
|
-
developerName: PKG.author,
|
|
146
|
-
category: 'Developer Tools',
|
|
147
|
-
capabilities: ['Interactive', 'Write'],
|
|
148
|
-
websiteURL: PKG.homepage,
|
|
149
|
-
brandColor: '#0ea5e9'
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const mcpJson = {
|
|
154
|
-
mcpServers: {
|
|
155
|
-
thumbgate: {
|
|
156
|
-
command: 'npx',
|
|
157
|
-
args: ['-y', `thumbgate@${PKG.version}`, 'serve'],
|
|
158
|
-
tools: spec.tools || []
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const agentsMdLines = [
|
|
164
|
-
`# ${spec.name} — ThumbGate Codex Plugin`,
|
|
165
|
-
'',
|
|
166
|
-
'## Trigger',
|
|
167
|
-
'If user gives explicit positive/negative outcome feedback, capture it immediately.',
|
|
168
|
-
'',
|
|
169
|
-
'## Memory Scope',
|
|
170
|
-
...(spec.memoryScope || []).map((s) => `- ${s}`),
|
|
171
|
-
'',
|
|
172
|
-
'## Gating Instructions',
|
|
173
|
-
instructions,
|
|
174
|
-
'',
|
|
175
|
-
'## Session Start',
|
|
176
|
-
'',
|
|
177
|
-
'```bash',
|
|
178
|
-
'npm run feedback:summary',
|
|
179
|
-
'npm run feedback:rules',
|
|
180
|
-
'```',
|
|
181
|
-
'',
|
|
182
|
-
'Use generated rules as hard guardrails to avoid repeated mistakes.'
|
|
183
|
-
];
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
pluginJson,
|
|
187
|
-
mcpJson,
|
|
188
|
-
agentsMd: agentsMdLines.join('\n')
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Export a skill spec to the given target formats.
|
|
194
|
-
* @param {string} name - spec name
|
|
195
|
-
* @param {string[]} targets - array of 'openai' and/or 'codex'
|
|
196
|
-
* @returns {{ openai?: object, codex?: object, written: string[] }}
|
|
197
|
-
*/
|
|
198
|
-
function exportSkill(name, targets = ['openai', 'codex']) {
|
|
199
|
-
const spec = loadSkillSpec(name);
|
|
200
|
-
const result = { written: [] };
|
|
201
|
-
const outDir = path.join(DIST_DIR, name);
|
|
202
|
-
ensureDir(outDir);
|
|
203
|
-
|
|
204
|
-
if (targets.includes('openai')) {
|
|
205
|
-
const openai = compileToOpenAISkill(spec);
|
|
206
|
-
result.openai = openai;
|
|
207
|
-
const openaiPath = path.join(outDir, 'openai-skill.json');
|
|
208
|
-
fs.writeFileSync(openaiPath, JSON.stringify(openai, null, 2) + '\n');
|
|
209
|
-
result.written.push(openaiPath);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (targets.includes('codex')) {
|
|
213
|
-
const codex = compileToCodexPlugin(spec);
|
|
214
|
-
result.codex = codex;
|
|
215
|
-
const codexDir = path.join(outDir, 'codex');
|
|
216
|
-
ensureDir(path.join(codexDir, '.codex-plugin'));
|
|
217
|
-
|
|
218
|
-
const pluginPath = path.join(codexDir, '.codex-plugin', 'plugin.json');
|
|
219
|
-
fs.writeFileSync(pluginPath, JSON.stringify(codex.pluginJson, null, 2) + '\n');
|
|
220
|
-
result.written.push(pluginPath);
|
|
221
|
-
|
|
222
|
-
const mcpPath = path.join(codexDir, '.mcp.json');
|
|
223
|
-
fs.writeFileSync(mcpPath, JSON.stringify(codex.mcpJson, null, 2) + '\n');
|
|
224
|
-
result.written.push(mcpPath);
|
|
225
|
-
|
|
226
|
-
const agentsPath = path.join(codexDir, 'AGENTS.md');
|
|
227
|
-
fs.writeFileSync(agentsPath, codex.agentsMd + '\n');
|
|
228
|
-
result.written.push(agentsPath);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
module.exports = { loadSkillSpec, compileToOpenAISkill, compileToCodexPlugin, exportSkill, listAvailableSpecs };
|
|
235
|
-
|
|
236
|
-
/* istanbul ignore next — CLI entry */
|
|
237
|
-
if (require.main === module) {
|
|
238
|
-
const args = process.argv.slice(2);
|
|
239
|
-
const cmd = args[0] || 'list';
|
|
240
|
-
if (cmd === 'list') {
|
|
241
|
-
const specs = listAvailableSpecs();
|
|
242
|
-
console.log('Available skill specs:', specs.join(', '));
|
|
243
|
-
} else if (cmd === 'export') {
|
|
244
|
-
const name = args[1];
|
|
245
|
-
if (!name) { console.error('Usage: skill-exporter.js export <name>'); process.exit(1); }
|
|
246
|
-
const targets = args[2] ? args[2].split(',') : ['openai', 'codex'];
|
|
247
|
-
const result = exportSkill(name, targets);
|
|
248
|
-
console.log(`Exported ${name} → ${result.written.length} files`);
|
|
249
|
-
result.written.forEach((f) => console.log(` ${f}`));
|
|
250
|
-
} else if (cmd === 'export-all') {
|
|
251
|
-
const specs = listAvailableSpecs();
|
|
252
|
-
for (const name of specs) {
|
|
253
|
-
const result = exportSkill(name);
|
|
254
|
-
console.log(`Exported ${name} → ${result.written.length} files`);
|
|
255
|
-
}
|
|
256
|
-
} else {
|
|
257
|
-
console.error(`Unknown command: ${cmd}`);
|
|
258
|
-
process.exit(1);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Skill Materializer (EvoSkill Phase 2)
|
|
4
|
-
*
|
|
5
|
-
* Takes a JSON proposal from Skill Proposer and 'materializes'
|
|
6
|
-
* a functional MCP tool definition + SKILL.md documentation.
|
|
7
|
-
*
|
|
8
|
-
* Ensures every skill has a standardized entry point for the agent.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const path = require('path');
|
|
13
|
-
const { discoverFeedbackDir } = require('./skill-generator');
|
|
14
|
-
|
|
15
|
-
function materializeSkills(options = {}) {
|
|
16
|
-
const feedbackDir = options.feedbackDir || discoverFeedbackDir();
|
|
17
|
-
const proposalsDir = path.join(feedbackDir, 'skill-proposals');
|
|
18
|
-
const skillsOutDir = options.skillsOutDir || process.env.THUMBGATE_SKILLS_DIR || path.join(process.cwd(), 'skills');
|
|
19
|
-
|
|
20
|
-
if (!fs.existsSync(proposalsDir)) {
|
|
21
|
-
console.log('No proposals directory found.');
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const proposals = fs.readdirSync(proposalsDir)
|
|
26
|
-
.filter(f => f.endsWith('.json'))
|
|
27
|
-
.map(f => JSON.parse(fs.readFileSync(path.join(proposalsDir, f), 'utf-8')));
|
|
28
|
-
|
|
29
|
-
if (proposals.length === 0) {
|
|
30
|
-
console.log('No pending skill proposals.');
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!fs.existsSync(skillsOutDir)) fs.mkdirSync(skillsOutDir, { recursive: true });
|
|
35
|
-
|
|
36
|
-
const results = [];
|
|
37
|
-
|
|
38
|
-
for (const proposal of proposals) {
|
|
39
|
-
if (proposal.status !== 'pending') continue;
|
|
40
|
-
|
|
41
|
-
const skillName = proposal.suggestedSkill.name;
|
|
42
|
-
const skillDir = path.join(skillsOutDir, skillName);
|
|
43
|
-
if (!fs.existsSync(skillDir)) fs.mkdirSync(skillDir, { recursive: true });
|
|
44
|
-
|
|
45
|
-
// Generate SKILL.md
|
|
46
|
-
const skillMd = generateSkillMarkdown(proposal);
|
|
47
|
-
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), skillMd);
|
|
48
|
-
|
|
49
|
-
// Generate functional tool code (template)
|
|
50
|
-
const toolCode = generateToolCode(proposal);
|
|
51
|
-
fs.writeFileSync(path.join(skillDir, 'tool.js'), toolCode);
|
|
52
|
-
|
|
53
|
-
// Update proposal status
|
|
54
|
-
proposal.status = 'materialized';
|
|
55
|
-
proposal.materializedAt = new Date().toISOString();
|
|
56
|
-
fs.writeFileSync(
|
|
57
|
-
path.join(proposalsDir, `${skillName}.json`),
|
|
58
|
-
JSON.stringify(proposal, null, 2)
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
results.push(skillName);
|
|
62
|
-
console.log(`Materialized skill: ${skillName} -> ${skillDir}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return results;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function generateSkillMarkdown(proposal) {
|
|
69
|
-
const { suggestedSkill, problem, diagnosis } = proposal;
|
|
70
|
-
return `---
|
|
71
|
-
name: ${suggestedSkill.name}
|
|
72
|
-
description: ${suggestedSkill.description}
|
|
73
|
-
diagnosis: ${diagnosis}
|
|
74
|
-
status: materialized
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
# ${suggestedSkill.name.toUpperCase()} Capability
|
|
78
|
-
|
|
79
|
-
## Problem
|
|
80
|
-
${problem}
|
|
81
|
-
|
|
82
|
-
## Automated Diagnosis
|
|
83
|
-
${diagnosis}
|
|
84
|
-
|
|
85
|
-
## Usage
|
|
86
|
-
The agent should call the \`${suggestedSkill.toolSpec.name}\` tool when tasks involve \`${suggestedSkill.tags.join(', ')}\`.
|
|
87
|
-
`;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function generateToolCode(proposal) {
|
|
91
|
-
const { suggestedSkill } = proposal;
|
|
92
|
-
const toolName = suggestedSkill.toolSpec.name;
|
|
93
|
-
|
|
94
|
-
return `/**
|
|
95
|
-
* Automated Skill: ${suggestedSkill.name}
|
|
96
|
-
* Generated: ${new Date().toISOString()}
|
|
97
|
-
*
|
|
98
|
-
* This tool was materialized by the EvoSkill loop to address:
|
|
99
|
-
* "${proposal.problem}"
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
const { execSync } = require('child_process');
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* ${suggestedSkill.toolSpec.description}
|
|
106
|
-
*/
|
|
107
|
-
async function ${toolName}(args) {
|
|
108
|
-
const { context } = args;
|
|
109
|
-
|
|
110
|
-
// LOGIC: Materialized code should implement the fix derived from the diagnosis.
|
|
111
|
-
// For now, we provide a structured wrapper that logs intent and applies
|
|
112
|
-
// the suggested corrective action.
|
|
113
|
-
|
|
114
|
-
console.log(\`[EVOSKILL] Executing ${toolName} to resolve: ${proposal.problem}\`);
|
|
115
|
-
|
|
116
|
-
// Corrective action placeholder - in a full loop, this would be LLM-generated code
|
|
117
|
-
// derived from the 'how-to-avoid' fields in memory-log.jsonl.
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
status: 'success',
|
|
121
|
-
appliedFix: \`Automated handling of ${proposal.problem} pattern.\`,
|
|
122
|
-
context: context
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
module.exports = { ${toolName} };
|
|
127
|
-
`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (require.main === module) {
|
|
131
|
-
materializeSkills();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
module.exports = { materializeSkills };
|