@evomap/evolver 1.90.0 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -564
- package/bin/evolver-llm-proxy.js +3 -0
- package/bin/evolver-mcp.js +2 -0
- package/bin/evolver-proxy.js +3 -0
- package/bin/evolver.js +4 -0
- package/index.js +1 -3670
- package/package.json +32 -62
- package/CONTRIBUTING.md +0 -19
- package/LICENSE +0 -641
- package/README.ja-JP.md +0 -521
- package/README.ko-KR.md +0 -520
- package/README.zh-CN.md +0 -531
- package/SKILL.md +0 -365
- package/assets/cover.png +0 -0
- package/assets/gep/genes.seed.json +0 -496
- package/conformance/savings-core/constants.json +0 -30
- package/conformance/savings-core/golden-vectors.json +0 -333
- package/scripts/a2a_export.js +0 -63
- package/scripts/a2a_ingest.js +0 -79
- package/scripts/a2a_promote.js +0 -118
- package/scripts/analyze_by_skill.js +0 -121
- package/scripts/build_binaries.js +0 -479
- package/scripts/check-changelog.js +0 -166
- package/scripts/extract_log.js +0 -85
- package/scripts/generate_history.js +0 -75
- package/scripts/gep_append_event.js +0 -96
- package/scripts/gep_personality_report.js +0 -234
- package/scripts/human_report.js +0 -147
- package/scripts/recall-verify-report.js +0 -234
- package/scripts/recover_loop.js +0 -61
- package/scripts/refresh_stars_badge.js +0 -168
- package/scripts/seed-merchants.js +0 -91
- package/scripts/skill2recipes.js +0 -118
- package/scripts/suggest_version.js +0 -89
- package/scripts/validate-modules.js +0 -38
- package/scripts/validate-suite.js +0 -78
- package/src/adapters/claudeCode.js +0 -194
- package/src/adapters/codex.js +0 -216
- package/src/adapters/cursor.js +0 -91
- package/src/adapters/hookAdapter.js +0 -469
- package/src/adapters/kiro.js +0 -195
- package/src/adapters/opencode.js +0 -326
- package/src/adapters/scripts/_lockPaths.js +0 -74
- package/src/adapters/scripts/_memoryFiltering.js +0 -35
- package/src/adapters/scripts/_runtimePaths.js +0 -440
- package/src/adapters/scripts/evolver-session-end.js +0 -321
- package/src/adapters/scripts/evolver-session-start.js +0 -587
- package/src/adapters/scripts/evolver-signal-detect.js +0 -98
- package/src/adapters/scripts/evolver-task-recall.js +0 -173
- package/src/atp/atpExecute.js +0 -283
- package/src/atp/atpTaskPickup.js +0 -233
- package/src/atp/autoBuyer.js +0 -382
- package/src/atp/autoDeliver.js +0 -215
- package/src/atp/cli.js +0 -354
- package/src/atp/cliAutobuyPrompt.js +0 -154
- package/src/atp/consumerAgent.js +0 -157
- package/src/atp/defaultHandler.js +0 -69
- package/src/atp/heartbeatSignalsHandler.js +0 -254
- package/src/atp/hubClient.js +0 -317
- package/src/atp/index.js +0 -38
- package/src/atp/merchantAgent.js +0 -118
- package/src/atp/protocol.js +0 -41
- package/src/atp/questionComposer.js +0 -133
- package/src/atp/serviceHelper.js +0 -92
- package/src/canary.js +0 -13
- package/src/config.js +0 -351
- package/src/evolve/guards.js +0 -1
- package/src/evolve/pipeline/collect.js +0 -1
- package/src/evolve/pipeline/dispatch.js +0 -1
- package/src/evolve/pipeline/enrich.js +0 -1
- package/src/evolve/pipeline/hub.js +0 -1
- package/src/evolve/pipeline/select.js +0 -1
- package/src/evolve/pipeline/signals.js +0 -1
- package/src/evolve/utils.js +0 -1
- package/src/evolve.js +0 -1
- package/src/experiment/agentRunner.js +0 -229
- package/src/experiment/cli.js +0 -159
- package/src/experiment/comparison.js +0 -233
- package/src/experiment/metrics.js +0 -75
- package/src/forceUpdate.js +0 -991
- package/src/gep/a2a.js +0 -173
- package/src/gep/a2aProtocol.js +0 -1
- package/src/gep/analyzer.js +0 -35
- package/src/gep/antiAbuseTelemetry.js +0 -1
- package/src/gep/assetCallLog.js +0 -197
- package/src/gep/assetStore.js +0 -723
- package/src/gep/assets.js +0 -36
- package/src/gep/autoDistillConv.js +0 -1
- package/src/gep/autoDistillLlm.js +0 -1
- package/src/gep/bridge.js +0 -138
- package/src/gep/candidateEval.js +0 -1
- package/src/gep/candidates.js +0 -1
- package/src/gep/claimNudge.js +0 -121
- package/src/gep/cliContracts.js +0 -1190
- package/src/gep/contentHash.js +0 -1
- package/src/gep/conversationDistiller.js +0 -1
- package/src/gep/conversationSniffer.js +0 -1
- package/src/gep/crypto.js +0 -1
- package/src/gep/curriculum.js +0 -1
- package/src/gep/deviceId.js +0 -1
- package/src/gep/directoryClient.js +0 -115
- package/src/gep/envFingerprint.js +0 -1
- package/src/gep/epigenetics.js +0 -1
- package/src/gep/execBridge.js +0 -1
- package/src/gep/executionTrace.js +0 -291
- package/src/gep/explore.js +0 -1
- package/src/gep/featureFlags.js +0 -121
- package/src/gep/gitOps.js +0 -265
- package/src/gep/hash.js +0 -1
- package/src/gep/hostErrorClassifier.js +0 -34
- package/src/gep/hubFetch.js +0 -1
- package/src/gep/hubReview.js +0 -1
- package/src/gep/hubSearch.js +0 -1
- package/src/gep/hubVerify.js +0 -1
- package/src/gep/idleScheduler.js +0 -400
- package/src/gep/issueReporter.js +0 -416
- package/src/gep/learningSignals.js +0 -1
- package/src/gep/llmReview.js +0 -92
- package/src/gep/localStateAwareness.js +0 -243
- package/src/gep/mailboxTransport.js +0 -119
- package/src/gep/memoryGraph.js +0 -1
- package/src/gep/memoryGraphAdapter.js +0 -1
- package/src/gep/mutation.js +0 -1
- package/src/gep/narrativeMemory.js +0 -1
- package/src/gep/oauthLogin.js +0 -181
- package/src/gep/openPRRegistry.js +0 -1
- package/src/gep/paths.js +0 -522
- package/src/gep/personality.js +0 -1
- package/src/gep/policyCheck.js +0 -1
- package/src/gep/portable.js +0 -103
- package/src/gep/privacyClient.js +0 -235
- package/src/gep/prompt.js +0 -1
- package/src/gep/questionGenerator.js +0 -518
- package/src/gep/recallInject.js +0 -1
- package/src/gep/recallVerifier.js +0 -1
- package/src/gep/reflection.js +0 -1
- package/src/gep/sanitize.js +0 -264
- package/src/gep/savingsCore.js +0 -1
- package/src/gep/schemas/capsule.js +0 -170
- package/src/gep/schemas/gene.js +0 -154
- package/src/gep/schemas/index.js +0 -8
- package/src/gep/schemas/protocol.js +0 -51
- package/src/gep/schemas/task.js +0 -74
- package/src/gep/selector.js +0 -1
- package/src/gep/selfPR.js +0 -469
- package/src/gep/signals.js +0 -776
- package/src/gep/skill2gep.js +0 -1056
- package/src/gep/skill2gepAudit.js +0 -303
- package/src/gep/skill2recipes.js +0 -511
- package/src/gep/skillDistiller.js +0 -1
- package/src/gep/skillPublisher.js +0 -358
- package/src/gep/solidify.js +0 -1
- package/src/gep/strategy.js +0 -1
- package/src/gep/taskReceiver.js +0 -575
- package/src/gep/tokenSavings.js +0 -1
- package/src/gep/trajectoryExport.js +0 -1
- package/src/gep/validationReport.js +0 -55
- package/src/gep/validator/index.js +0 -411
- package/src/gep/validator/reporter.js +0 -210
- package/src/gep/validator/sandboxExecutor.js +0 -480
- package/src/gep/validator/stakeBootstrap.js +0 -357
- package/src/gep/workspaceKeychain.js +0 -1
- package/src/ops/cleanup.js +0 -80
- package/src/ops/commentary.js +0 -60
- package/src/ops/health_check.js +0 -104
- package/src/ops/index.js +0 -11
- package/src/ops/innovation.js +0 -67
- package/src/ops/lifecycle.js +0 -798
- package/src/ops/self_repair.js +0 -76
- package/src/ops/skills_monitor.js +0 -147
- package/src/ops/trigger.js +0 -33
- package/src/proxy/clientSettings.js +0 -405
- package/src/proxy/envelope.js +0 -59
- package/src/proxy/extensions/dmHandler.js +0 -45
- package/src/proxy/extensions/sessionHandler.js +0 -141
- package/src/proxy/extensions/skillUpdater.js +0 -64
- package/src/proxy/extensions/traceControl.js +0 -1
- package/src/proxy/index.js +0 -1395
- package/src/proxy/inject.js +0 -1
- package/src/proxy/lifecycle/manager.js +0 -1568
- package/src/proxy/mailbox/state.js +0 -207
- package/src/proxy/mailbox/store.js +0 -602
- package/src/proxy/router/cache_passthrough.js +0 -26
- package/src/proxy/router/features.js +0 -84
- package/src/proxy/router/gemini_route.js +0 -154
- package/src/proxy/router/messages_route.js +0 -535
- package/src/proxy/router/model_router.js +0 -113
- package/src/proxy/router/models_route.js +0 -52
- package/src/proxy/router/ollama_route.js +0 -103
- package/src/proxy/router/responses_route.js +0 -170
- package/src/proxy/router/vertex_route.js +0 -110
- package/src/proxy/server/http.js +0 -363
- package/src/proxy/server/routes.js +0 -558
- package/src/proxy/server/settings.js +0 -115
- package/src/proxy/sync/engine.js +0 -179
- package/src/proxy/sync/inbound.js +0 -211
- package/src/proxy/sync/outbound.js +0 -361
- package/src/proxy/task/monitor.js +0 -131
- package/src/proxy/trace/extractor.js +0 -1
- package/src/proxy/trace/usage.js +0 -1
- package/src/solo/breaker.js +0 -25
- package/src/solo/gitGuard.js +0 -65
- package/src/webui/client/clientJs/assets.js +0 -111
- package/src/webui/client/clientJs/bootstrap.js +0 -92
- package/src/webui/client/clientJs/common.js +0 -77
- package/src/webui/client/clientJs/i18n.js +0 -366
- package/src/webui/client/clientJs/index.js +0 -35
- package/src/webui/client/clientJs/interactions.js +0 -351
- package/src/webui/client/clientJs/overview.js +0 -152
- package/src/webui/client/clientJs/personality.js +0 -285
- package/src/webui/client/clientJs/pipelines.js +0 -330
- package/src/webui/client/indexHtml.js +0 -221
- package/src/webui/client/static.js +0 -23
- package/src/webui/client/stylesCss.js +0 -639
- package/src/webui/client/vendor/README.md +0 -15
- package/src/webui/client/vendor/echarts.min.js +0 -45
- package/src/webui/index.js +0 -14
- package/src/webui/observer/assets.js +0 -146
- package/src/webui/observer/index.js +0 -37
- package/src/webui/observer/interactions.js +0 -127
- package/src/webui/observer/jsonl.js +0 -75
- package/src/webui/observer/paths.js +0 -46
- package/src/webui/observer/personality.js +0 -43
- package/src/webui/observer/pipelineEvents.js +0 -58
- package/src/webui/observer/redact.js +0 -63
- package/src/webui/observer/runs.js +0 -356
- package/src/webui/observer/safety.js +0 -57
- package/src/webui/observer/skills.js +0 -70
- package/src/webui/observer/status.js +0 -71
- package/src/webui/server/http.js +0 -138
- package/src/webui/server/routes.js +0 -41
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Seed Merchants -- registers 3 merchant services on the ATP network.
|
|
3
|
-
// Run once to bootstrap the network with available service listings.
|
|
4
|
-
//
|
|
5
|
-
// Usage:
|
|
6
|
-
// A2A_HUB_URL=https://evomap.ai node scripts/seed-merchants.js
|
|
7
|
-
|
|
8
|
-
const { merchantAgent } = require('../src/atp');
|
|
9
|
-
|
|
10
|
-
const SEED_SERVICES = [
|
|
11
|
-
{
|
|
12
|
-
title: 'Code Review Agent',
|
|
13
|
-
description: 'Automated code review for JavaScript, Python, and TypeScript projects. Identifies bugs, style issues, and performance opportunities.',
|
|
14
|
-
capabilities: ['code_review', 'javascript', 'python', 'typescript', 'bug_detection'],
|
|
15
|
-
useCases: ['Pull request review', 'Code quality audit', 'Security scan'],
|
|
16
|
-
pricePerTask: 5,
|
|
17
|
-
maxConcurrent: 5,
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
title: 'Translation Agent',
|
|
21
|
-
description: 'Translates text between English, Chinese (Simplified/Traditional), and Japanese with context-aware accuracy.',
|
|
22
|
-
capabilities: ['translation', 'english', 'chinese', 'japanese', 'localization'],
|
|
23
|
-
useCases: ['Document translation', 'UI localization', 'README translation'],
|
|
24
|
-
pricePerTask: 3,
|
|
25
|
-
maxConcurrent: 10,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
title: 'Text Summarization Agent',
|
|
29
|
-
description: 'Generates concise summaries from long documents, reports, and codebases. Supports structured and freeform output.',
|
|
30
|
-
capabilities: ['summarization', 'text_analysis', 'report', 'digest'],
|
|
31
|
-
useCases: ['Meeting notes summary', 'Codebase overview', 'Research digest'],
|
|
32
|
-
pricePerTask: 2,
|
|
33
|
-
maxConcurrent: 10,
|
|
34
|
-
},
|
|
35
|
-
];
|
|
36
|
-
|
|
37
|
-
function handleOrder(order) {
|
|
38
|
-
const title = (order.title || '').toLowerCase();
|
|
39
|
-
const signals = (order.signals || '').toLowerCase();
|
|
40
|
-
|
|
41
|
-
let result;
|
|
42
|
-
if (title.includes('review') || signals.includes('code_review')) {
|
|
43
|
-
result = 'Code review completed. No critical issues found. 2 suggestions for improvement.';
|
|
44
|
-
} else if (title.includes('translat') || signals.includes('translation')) {
|
|
45
|
-
result = 'Translation completed. Source and target text verified for accuracy.';
|
|
46
|
-
} else {
|
|
47
|
-
result = 'Analysis completed. Summary generated from provided content.';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
result,
|
|
52
|
-
output: result,
|
|
53
|
-
pass_rate: 1.0,
|
|
54
|
-
processed_at: new Date().toISOString(),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async function main() {
|
|
59
|
-
const hubUrl = process.env.A2A_HUB_URL || process.env.EVOMAP_HUB_URL;
|
|
60
|
-
if (!hubUrl) {
|
|
61
|
-
console.error('[Seed] A2A_HUB_URL or EVOMAP_HUB_URL is required.');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
console.log('[Seed] Hub:', hubUrl);
|
|
66
|
-
console.log('[Seed] Starting merchant with', SEED_SERVICES.length, 'services...');
|
|
67
|
-
|
|
68
|
-
await merchantAgent.start({
|
|
69
|
-
services: SEED_SERVICES,
|
|
70
|
-
onOrder: handleOrder,
|
|
71
|
-
pollMs: 30000,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
console.log('[Seed] Merchant started. Polling for orders. Press Ctrl+C to stop.');
|
|
75
|
-
|
|
76
|
-
process.on('SIGINT', () => {
|
|
77
|
-
console.log('\n[Seed] Shutting down...');
|
|
78
|
-
merchantAgent.stop();
|
|
79
|
-
process.exit(0);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
process.on('SIGTERM', () => {
|
|
83
|
-
merchantAgent.stop();
|
|
84
|
-
process.exit(0);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
main().catch((err) => {
|
|
89
|
-
console.error('[Seed] Fatal:', err.message || err);
|
|
90
|
-
process.exit(1);
|
|
91
|
-
});
|
package/scripts/skill2recipes.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// skill2recipes -- CLI: hydrolyze + verify a set of Skills into GEP assets,
|
|
5
|
-
// then compose and publish them as a Recipe to the EvoMap market
|
|
6
|
-
// (https://evomap.ai/market?tab=recipes).
|
|
7
|
-
//
|
|
8
|
-
// Usage:
|
|
9
|
-
// # From a manifest (recommended -- supports optional/condition per step):
|
|
10
|
-
// node scripts/skill2recipes.js --manifest ./examples/recipe.manifest.json
|
|
11
|
-
//
|
|
12
|
-
// # Inline, ordered by argument position:
|
|
13
|
-
// node scripts/skill2recipes.js --title "Bug Fix Pipeline" \
|
|
14
|
-
// ./skills/triage ./skills/patch ./skills/verify
|
|
15
|
-
//
|
|
16
|
-
// Options:
|
|
17
|
-
// --manifest <path> JSON manifest { title, description, steps:[...] }
|
|
18
|
-
// --title <str> Recipe title (>=3 chars; overrides manifest)
|
|
19
|
-
// --description <str> Recipe description
|
|
20
|
-
// --price <n> price_per_execution (Credits, min 1)
|
|
21
|
-
// --repo-root <path> Where validation commands run (default: cwd)
|
|
22
|
-
// --no-publish Hydrolyze + verify + build asset_ids locally, but do
|
|
23
|
-
// not POST anything to the Hub (dry run).
|
|
24
|
-
// --no-strict Allow steps whose validation falls back to node --version.
|
|
25
|
-
//
|
|
26
|
-
// Env:
|
|
27
|
-
// A2A_NODE_ID (required) registered EvoMap node id -> recipe owner
|
|
28
|
-
// A2A_HUB_URL (default https://evomap.ai)
|
|
29
|
-
|
|
30
|
-
const fs = require('fs');
|
|
31
|
-
const path = require('path');
|
|
32
|
-
|
|
33
|
-
process.env.A2A_TRANSPORT = 'http';
|
|
34
|
-
if (!process.env.A2A_HUB_URL) process.env.A2A_HUB_URL = 'https://evomap.ai';
|
|
35
|
-
// Keep stdout pure JSON: silence the "[evolver] Using host git repository"
|
|
36
|
-
// banner that paths.js prints on first require. Human-readable status lines go
|
|
37
|
-
// to stderr (console.error) so `... | jq` on stdout always works.
|
|
38
|
-
if (!process.env.EVOLVER_QUIET_PARENT_GIT) process.env.EVOLVER_QUIET_PARENT_GIT = '1';
|
|
39
|
-
|
|
40
|
-
const skill2recipes = require('../src/gep/skill2recipes');
|
|
41
|
-
|
|
42
|
-
function parseArgs(argv) {
|
|
43
|
-
const out = { _: [], publish: true, strict: true };
|
|
44
|
-
for (let i = 0; i < argv.length; i++) {
|
|
45
|
-
const a = argv[i];
|
|
46
|
-
if (a === '--manifest') out.manifest = argv[++i];
|
|
47
|
-
else if (a === '--title') out.title = argv[++i];
|
|
48
|
-
else if (a === '--description') out.description = argv[++i];
|
|
49
|
-
else if (a === '--price') out.pricePerExecution = Number(argv[++i]);
|
|
50
|
-
else if (a === '--repo-root') out.repoRoot = argv[++i];
|
|
51
|
-
else if (a === '--no-publish') out.publish = false;
|
|
52
|
-
else if (a === '--no-strict') out.strict = false;
|
|
53
|
-
else if (a === '-h' || a === '--help') out.help = true;
|
|
54
|
-
else if (a.startsWith('--')) { console.error('unknown flag: ' + a); process.exit(2); }
|
|
55
|
-
else out._.push(a);
|
|
56
|
-
}
|
|
57
|
-
return out;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function usage() {
|
|
61
|
-
console.log([
|
|
62
|
-
'skill2recipes -- compose published Skills into a GEP Recipe',
|
|
63
|
-
'',
|
|
64
|
-
'From a manifest:',
|
|
65
|
-
' node scripts/skill2recipes.js --manifest ./examples/recipe.manifest.json',
|
|
66
|
-
'',
|
|
67
|
-
'Inline (ordered by position):',
|
|
68
|
-
' node scripts/skill2recipes.js --title "Bug Fix Pipeline" ./skills/a ./skills/b',
|
|
69
|
-
'',
|
|
70
|
-
'Flags: --title --description --price --repo-root --no-publish --no-strict',
|
|
71
|
-
].join('\n'));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function main() {
|
|
75
|
-
const args = parseArgs(process.argv.slice(2));
|
|
76
|
-
if (args.help) { usage(); return; }
|
|
77
|
-
|
|
78
|
-
if (!process.env.A2A_NODE_ID && args.publish) {
|
|
79
|
-
console.error('WARN: A2A_NODE_ID not set -- recipe owner will be derived from a device fingerprint and the Hub may reject it. Register at https://evomap.ai and export A2A_NODE_ID.');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let manifest;
|
|
83
|
-
if (args.manifest) {
|
|
84
|
-
const p = path.resolve(args.manifest);
|
|
85
|
-
if (!fs.existsSync(p)) { console.error('manifest not found: ' + p); process.exit(1); }
|
|
86
|
-
try { manifest = JSON.parse(fs.readFileSync(p, 'utf8')); }
|
|
87
|
-
catch (e) { console.error('manifest is not valid JSON: ' + e.message); process.exit(1); }
|
|
88
|
-
} else if (args._.length) {
|
|
89
|
-
manifest = { steps: args._ };
|
|
90
|
-
} else {
|
|
91
|
-
usage();
|
|
92
|
-
console.error('\nERROR: provide --manifest <path> or one or more skill paths.');
|
|
93
|
-
process.exit(2);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const res = await skill2recipes.composeRecipeFromSkills(manifest, {
|
|
97
|
-
title: args.title,
|
|
98
|
-
description: args.description,
|
|
99
|
-
pricePerExecution: args.pricePerExecution,
|
|
100
|
-
repoRoot: args.repoRoot,
|
|
101
|
-
publish: args.publish,
|
|
102
|
-
strict: args.strict,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
console.log(JSON.stringify(res, null, 2));
|
|
106
|
-
|
|
107
|
-
if (!res.ok) {
|
|
108
|
-
console.error('\nFAILED: ' + (res.reason || 'unknown') + (res.skill_path ? ' at ' + res.skill_path : ''));
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
if (res.recipe_id) {
|
|
112
|
-
console.error('\nOK recipe ' + res.recipe_id + (args.publish ? ' published -> ' + res.market_url : ' built (dry run, not published)'));
|
|
113
|
-
} else if (!args.publish) {
|
|
114
|
-
console.error('\nOK dry run complete (no network calls; ' + (res.steps ? res.steps.length : 0) + ' step(s) built, not published)');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
main().catch((e) => { console.error('ERROR:', e && e.message ? e.message : e); console.error(e); process.exit(1); });
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
|
|
5
|
-
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
6
|
-
|
|
7
|
-
function ensureDir(dir) {
|
|
8
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function parseSemver(v) {
|
|
12
|
-
const m = String(v || '').trim().match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
13
|
-
if (!m) return null;
|
|
14
|
-
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) };
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function bumpSemver(base, bump) {
|
|
18
|
-
const v = parseSemver(base);
|
|
19
|
-
if (!v) return null;
|
|
20
|
-
if (bump === 'major') return `${v.major + 1}.0.0`;
|
|
21
|
-
if (bump === 'minor') return `${v.major}.${v.minor + 1}.0`;
|
|
22
|
-
if (bump === 'patch') return `${v.major}.${v.minor}.${v.patch + 1}`;
|
|
23
|
-
return `${v.major}.${v.minor}.${v.patch}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function git(cmd) {
|
|
27
|
-
return execSync(cmd, { cwd: REPO_ROOT, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getBaseReleaseCommit() {
|
|
31
|
-
try {
|
|
32
|
-
const hash = git('git log -n 1 --pretty=%H --grep="chore(release): prepare v"');
|
|
33
|
-
return hash || null;
|
|
34
|
-
} catch (e) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getCommitSubjectsSince(baseCommit) {
|
|
40
|
-
try {
|
|
41
|
-
if (!baseCommit) {
|
|
42
|
-
const out = git('git log -n 30 --pretty=%s');
|
|
43
|
-
return out ? out.split('\n').filter(Boolean) : [];
|
|
44
|
-
}
|
|
45
|
-
const out = git(`git log ${baseCommit}..HEAD --pretty=%s`);
|
|
46
|
-
return out ? out.split('\n').filter(Boolean) : [];
|
|
47
|
-
} catch (e) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function inferBumpFromSubjects(subjects) {
|
|
53
|
-
const subs = (subjects || []).map(s => String(s));
|
|
54
|
-
const hasBreaking = subs.some(s => /\bBREAKING CHANGE\b/i.test(s) || /^[a-z]+(\(.+\))?!:/.test(s));
|
|
55
|
-
if (hasBreaking) return { bump: 'major', reason: 'breaking change marker in commit subject' };
|
|
56
|
-
|
|
57
|
-
const hasFeat = subs.some(s => /^feat(\(.+\))?:/i.test(s));
|
|
58
|
-
if (hasFeat) return { bump: 'minor', reason: 'feature commit detected (feat:)' };
|
|
59
|
-
|
|
60
|
-
const hasFix = subs.some(s => /^(fix|perf)(\(.+\))?:/i.test(s));
|
|
61
|
-
if (hasFix) return { bump: 'patch', reason: 'fix/perf commit detected' };
|
|
62
|
-
|
|
63
|
-
if (subs.length === 0) return { bump: 'none', reason: 'no commits since base release commit' };
|
|
64
|
-
return { bump: 'patch', reason: 'default to patch for non-breaking changes' };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function main() {
|
|
68
|
-
const pkgPath = path.join(REPO_ROOT, 'package.json');
|
|
69
|
-
const baseVersion = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version;
|
|
70
|
-
|
|
71
|
-
const baseCommit = getBaseReleaseCommit();
|
|
72
|
-
const subjects = getCommitSubjectsSince(baseCommit);
|
|
73
|
-
const decision = inferBumpFromSubjects(subjects);
|
|
74
|
-
const suggestedVersion = decision.bump === 'none' ? baseVersion : bumpSemver(baseVersion, decision.bump);
|
|
75
|
-
|
|
76
|
-
const out = { baseVersion, baseCommit, subjects, decision, suggestedVersion };
|
|
77
|
-
const memDir = path.join(REPO_ROOT, 'memory');
|
|
78
|
-
ensureDir(memDir);
|
|
79
|
-
fs.writeFileSync(path.join(memDir, 'semver_suggestion.json'), JSON.stringify(out, null, 2) + '\n', 'utf8');
|
|
80
|
-
process.stdout.write(JSON.stringify(out, null, 2) + '\n');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
main();
|
|
85
|
-
} catch (e) {
|
|
86
|
-
process.stderr.write(`${e.message}\n`);
|
|
87
|
-
process.exit(1);
|
|
88
|
-
}
|
|
89
|
-
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// Usage: node scripts/validate-modules.js ./src/evolve ./src/gep/solidify
|
|
2
|
-
// Validates that each module (1) loads without errors, (2) exports something
|
|
3
|
-
// meaningful, and (3) exported functions are callable (typeof check).
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const modules = process.argv.slice(2);
|
|
6
|
-
if (!modules.length) { console.error('No modules specified'); process.exit(1); }
|
|
7
|
-
|
|
8
|
-
let checked = 0;
|
|
9
|
-
for (const m of modules) {
|
|
10
|
-
const resolved = path.resolve(m);
|
|
11
|
-
const exported = require(resolved);
|
|
12
|
-
|
|
13
|
-
if (exported === undefined || exported === null) {
|
|
14
|
-
console.error('FAIL: ' + m + ' exports null/undefined');
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const t = typeof exported;
|
|
19
|
-
if (t === 'object' && Object.keys(exported).length === 0) {
|
|
20
|
-
console.error('FAIL: ' + m + ' exports an empty object (no public API)');
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (t === 'object') {
|
|
25
|
-
const keys = Object.keys(exported);
|
|
26
|
-
for (const k of keys) {
|
|
27
|
-
if (typeof exported[k] === 'function') {
|
|
28
|
-
if (typeof exported[k] !== 'function') {
|
|
29
|
-
console.error('FAIL: ' + m + '.' + k + ' is declared but not a callable function');
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
checked++;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('ok: ' + checked + ' module(s) validated');
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// Usage: node scripts/validate-suite.js [test-glob-pattern | test-file]
|
|
2
|
-
// Runs the evolver test suite -- repo root is derived from script location, no shell glob needed.
|
|
3
|
-
// Accepts either a directory glob pattern (e.g. `test/*.test.js`) or a concrete test file path.
|
|
4
|
-
// See community PR #514.
|
|
5
|
-
const { execFileSync } = require('child_process');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
|
|
9
|
-
const EVOLVER_REPO_ROOT = path.join(__dirname, '..');
|
|
10
|
-
const pattern = process.argv[2] || 'test/*.test.js';
|
|
11
|
-
|
|
12
|
-
function expandTestGlob(repoRoot, pat) {
|
|
13
|
-
const fullPattern = path.isAbsolute(pat) ? pat : path.join(repoRoot, pat);
|
|
14
|
-
if (fs.existsSync(fullPattern) && fs.statSync(fullPattern).isFile()) {
|
|
15
|
-
return fullPattern.endsWith('.test.js') ? [fullPattern] : [];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const dir = path.dirname(pat);
|
|
19
|
-
const basenamePattern = path.basename(pat);
|
|
20
|
-
const fullDir = path.isAbsolute(dir) ? dir : path.join(repoRoot, dir);
|
|
21
|
-
if (!fs.existsSync(fullDir) || !fs.statSync(fullDir).isDirectory()) return [];
|
|
22
|
-
|
|
23
|
-
const escaped = basenamePattern
|
|
24
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
25
|
-
.replace(/\*/g, '.*');
|
|
26
|
-
const matcher = new RegExp('^' + escaped + '$');
|
|
27
|
-
return fs.readdirSync(fullDir)
|
|
28
|
-
.filter(f => f.endsWith('.test.js') && matcher.test(f))
|
|
29
|
-
.map(f => path.join(fullDir, f))
|
|
30
|
-
.sort();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const files = expandTestGlob(EVOLVER_REPO_ROOT, pattern);
|
|
34
|
-
if (files.length === 0) {
|
|
35
|
-
console.error('FAIL: no tests found matching pattern: ' + pattern);
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const env = Object.assign({}, process.env, {
|
|
40
|
-
NODE_ENV: 'test',
|
|
41
|
-
EVOLVER_REPO_ROOT,
|
|
42
|
-
GEP_ASSETS_DIR: path.join(EVOLVER_REPO_ROOT, 'assets', 'gep'),
|
|
43
|
-
});
|
|
44
|
-
delete env.EVOLVE_BRIDGE;
|
|
45
|
-
delete env.OPENCLAW_WORKSPACE;
|
|
46
|
-
// Clear NODE_TEST_CONTEXT so nested runs from within node --test work.
|
|
47
|
-
delete env.NODE_TEST_CONTEXT;
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
const output = execFileSync(process.execPath, ['--test', ...files], {
|
|
51
|
-
cwd: EVOLVER_REPO_ROOT,
|
|
52
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
53
|
-
timeout: 180000,
|
|
54
|
-
env,
|
|
55
|
-
});
|
|
56
|
-
const out = output.toString('utf8');
|
|
57
|
-
const passMatch = out.match(/pass (\d+)/);
|
|
58
|
-
const failMatch = out.match(/fail (\d+)/);
|
|
59
|
-
const passCount = passMatch ? Number(passMatch[1]) : 0;
|
|
60
|
-
const failCount = failMatch ? Number(failMatch[1]) : 0;
|
|
61
|
-
|
|
62
|
-
if (failCount > 0) {
|
|
63
|
-
console.error('FAIL: ' + failCount + ' test(s) failed');
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
if (passCount === 0) {
|
|
67
|
-
console.error('FAIL: no tests found');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
console.log('ok: ' + passCount + ' test(s) passed, 0 failed');
|
|
71
|
-
} catch (e) {
|
|
72
|
-
const stderr = e.stderr ? e.stderr.toString('utf8').slice(-500) : '';
|
|
73
|
-
const stdout = e.stdout ? e.stdout.toString('utf8').slice(-500) : '';
|
|
74
|
-
console.error('FAIL: test suite exited with code ' + (e.status || 'unknown'));
|
|
75
|
-
if (stderr) console.error(stderr);
|
|
76
|
-
if (stdout) console.error(stdout);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { mergeJsonFile, copyHookScripts, appendSectionToFile, removeHookScripts, removeMarkedSection, assertSafeConfigDir, isEvolverHookCommand, buildSafeNodeHookCommand } = require('./hookAdapter');
|
|
4
|
-
|
|
5
|
-
const HOOK_SCRIPTS_DIR_NAME = 'hooks';
|
|
6
|
-
const EVOLVER_MARKER = '<!-- evolver-evolution-memory -->';
|
|
7
|
-
|
|
8
|
-
function buildClaudeHooks(evolverRoot, configRoot) {
|
|
9
|
-
// Resolve hook scripts to an absolute path rooted at the real config dir so
|
|
10
|
-
// the command works regardless of the cwd Claude Code is launched from
|
|
11
|
-
// (#590). Falls back to the legacy relative base only when configRoot is
|
|
12
|
-
// absent (callers should always pass it).
|
|
13
|
-
const scriptsBase = configRoot
|
|
14
|
-
? path.resolve(configRoot, '.claude', 'hooks')
|
|
15
|
-
: path.join('.claude', 'hooks');
|
|
16
|
-
const hookCommand = (scriptName) =>
|
|
17
|
-
buildSafeNodeHookCommand(path.join(scriptsBase, scriptName));
|
|
18
|
-
return {
|
|
19
|
-
hooks: {
|
|
20
|
-
SessionStart: [
|
|
21
|
-
{
|
|
22
|
-
hooks: [
|
|
23
|
-
{
|
|
24
|
-
type: 'command',
|
|
25
|
-
command: hookCommand('evolver-session-start.js'),
|
|
26
|
-
timeout: 3,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
UserPromptSubmit: [
|
|
32
|
-
{
|
|
33
|
-
hooks: [
|
|
34
|
-
{
|
|
35
|
-
type: 'command',
|
|
36
|
-
// Runtime asset injection (P4-c). DEFAULT off (EVOLVER_RECALL_MODE
|
|
37
|
-
// unset/off -> emits {} without reading the prompt). The script
|
|
38
|
-
// owns an absolute 3.3s watchdog that always exits 0 with valid
|
|
39
|
-
// JSON (fail-open); this host timeout (5s) is a strict backstop
|
|
40
|
-
// ABOVE that watchdog, so the host never kills the script
|
|
41
|
-
// mid-write. A stuck/slow recall can never block or erase the
|
|
42
|
-
// user's prompt.
|
|
43
|
-
command: hookCommand('evolver-task-recall.js'),
|
|
44
|
-
timeout: 5,
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
PostToolUse: [
|
|
50
|
-
{
|
|
51
|
-
matcher: 'Write',
|
|
52
|
-
hooks: [
|
|
53
|
-
{
|
|
54
|
-
type: 'command',
|
|
55
|
-
command: hookCommand('evolver-signal-detect.js'),
|
|
56
|
-
timeout: 2,
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
Stop: [
|
|
62
|
-
{
|
|
63
|
-
hooks: [
|
|
64
|
-
{
|
|
65
|
-
type: 'command',
|
|
66
|
-
command: hookCommand('evolver-session-end.js'),
|
|
67
|
-
timeout: 8,
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function buildClaudeMdSection() {
|
|
77
|
-
return `${EVOLVER_MARKER}
|
|
78
|
-
## Evolution Memory (Evolver)
|
|
79
|
-
|
|
80
|
-
This project uses evolver for self-evolution. Hooks automatically:
|
|
81
|
-
1. Run quietly at session start and load recent evolution memory when useful
|
|
82
|
-
2. Detect evolution signals during file edits
|
|
83
|
-
3. Record outcomes at session end
|
|
84
|
-
4. (Opt-in) Surface matching distilled capabilities for each prompt - set
|
|
85
|
-
\`EVOLVER_RECALL_MODE=shadow\` to preview, \`enforce\` to inject (default off).
|
|
86
|
-
|
|
87
|
-
Use Evolver context only when it is directly relevant. Do not narrate routine Evolver checks, hook status, or empty recall/search results to the user.
|
|
88
|
-
Signals: log_error, perf_bottleneck, user_feature_request, capability_gap, deployment_issue, test_failure.`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function install({ configRoot, evolverRoot, force }) {
|
|
92
|
-
const claudeDir = path.join(configRoot, '.claude');
|
|
93
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
94
|
-
const hooksDir = path.join(claudeDir, HOOK_SCRIPTS_DIR_NAME);
|
|
95
|
-
const claudeMdPath = path.join(configRoot, 'CLAUDE.md');
|
|
96
|
-
assertSafeConfigDir(claudeDir, '.claude', { subdirs: [HOOK_SCRIPTS_DIR_NAME] });
|
|
97
|
-
|
|
98
|
-
fs.mkdirSync(claudeDir, { recursive: true });
|
|
99
|
-
|
|
100
|
-
const hooksCfg = buildClaudeHooks(evolverRoot, configRoot);
|
|
101
|
-
mergeJsonFile(settingsPath, hooksCfg);
|
|
102
|
-
console.log('[claude-code] Wrote ' + settingsPath);
|
|
103
|
-
|
|
104
|
-
const copied = copyHookScripts(hooksDir, path.join(evolverRoot, 'src', 'adapters'));
|
|
105
|
-
console.log('[claude-code] Copied ' + copied.length + ' hook scripts to ' + hooksDir);
|
|
106
|
-
|
|
107
|
-
const injected = appendSectionToFile(claudeMdPath, EVOLVER_MARKER, buildClaudeMdSection());
|
|
108
|
-
if (injected) {
|
|
109
|
-
console.log('[claude-code] Injected evolution section into ' + claudeMdPath);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
console.log('[claude-code] Installation complete.');
|
|
113
|
-
|
|
114
|
-
return {
|
|
115
|
-
ok: true,
|
|
116
|
-
platform: 'claude-code',
|
|
117
|
-
files: [settingsPath, claudeMdPath, ...copied],
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function uninstall({ configRoot }) {
|
|
122
|
-
const claudeDir = path.join(configRoot, '.claude');
|
|
123
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
124
|
-
const hooksDir = path.join(claudeDir, HOOK_SCRIPTS_DIR_NAME);
|
|
125
|
-
const claudeMdPath = path.join(configRoot, 'CLAUDE.md');
|
|
126
|
-
assertSafeConfigDir(claudeDir, '.claude', { subdirs: [HOOK_SCRIPTS_DIR_NAME] });
|
|
127
|
-
|
|
128
|
-
let changed = false;
|
|
129
|
-
|
|
130
|
-
// Strip evolver entries from settings.json. Even without the marker we
|
|
131
|
-
// still try to filter by command — a missing/dropped marker should not
|
|
132
|
-
// strand obvious evolver-owned entries (#538).
|
|
133
|
-
try {
|
|
134
|
-
if (fs.existsSync(settingsPath)) {
|
|
135
|
-
const data = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
136
|
-
let touched = false;
|
|
137
|
-
if (data.hooks) {
|
|
138
|
-
for (const event of Object.keys(data.hooks)) {
|
|
139
|
-
if (Array.isArray(data.hooks[event])) {
|
|
140
|
-
const beforeLen = data.hooks[event].length;
|
|
141
|
-
data.hooks[event] = data.hooks[event]
|
|
142
|
-
.map(matcher => {
|
|
143
|
-
if (!matcher || !Array.isArray(matcher.hooks)) return matcher;
|
|
144
|
-
const innerBefore = matcher.hooks.length;
|
|
145
|
-
const filtered = matcher.hooks.filter(h => {
|
|
146
|
-
const cmd = (h && h.command) || '';
|
|
147
|
-
return !isEvolverHookCommand(cmd);
|
|
148
|
-
});
|
|
149
|
-
// A matcher containing both evolver and user hooks shrinks
|
|
150
|
-
// its inner array without changing the outer matcher count.
|
|
151
|
-
// Track the inner-array shrink so `touched` reflects it.
|
|
152
|
-
if (filtered.length !== innerBefore) touched = true;
|
|
153
|
-
return { ...matcher, hooks: filtered };
|
|
154
|
-
})
|
|
155
|
-
.filter(matcher => matcher && Array.isArray(matcher.hooks) && matcher.hooks.length > 0);
|
|
156
|
-
if (data.hooks[event].length !== beforeLen) touched = true;
|
|
157
|
-
if (data.hooks[event].length === 0) delete data.hooks[event];
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (Object.keys(data.hooks).length === 0) delete data.hooks;
|
|
161
|
-
}
|
|
162
|
-
if (data._evolver_managed) {
|
|
163
|
-
delete data._evolver_managed;
|
|
164
|
-
touched = true;
|
|
165
|
-
}
|
|
166
|
-
if (touched) {
|
|
167
|
-
fs.writeFileSync(settingsPath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
168
|
-
changed = true;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
} catch (e) {
|
|
172
|
-
console.warn(`[claude-code] Failed to clean ${settingsPath}: ${e.message || e}`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const scripts = removeHookScripts(hooksDir);
|
|
176
|
-
if (scripts > 0) changed = true;
|
|
177
|
-
try {
|
|
178
|
-
if (fs.existsSync(hooksDir) && fs.readdirSync(hooksDir).length === 0) {
|
|
179
|
-
fs.rmdirSync(hooksDir);
|
|
180
|
-
}
|
|
181
|
-
} catch { /* best-effort */ }
|
|
182
|
-
|
|
183
|
-
if (removeMarkedSection(claudeMdPath, EVOLVER_MARKER)) {
|
|
184
|
-
changed = true;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
console.log(changed
|
|
188
|
-
? '[claude-code] Uninstalled evolver hooks.'
|
|
189
|
-
: '[claude-code] No evolver hooks found to uninstall.');
|
|
190
|
-
|
|
191
|
-
return { ok: true, removed: changed };
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
module.exports = { install, uninstall, buildClaudeHooks };
|