@evomap/evolver 1.89.17 → 1.89.19
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.ja-JP.md +1 -1
- package/README.ko-KR.md +1 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/index.js +272 -18
- package/package.json +7 -2
- package/src/adapters/claudeCode.js +16 -18
- package/src/adapters/hookAdapter.js +92 -5
- package/src/adapters/scripts/evolver-session-start.js +98 -0
- package/src/atp/atpExecute.js +3 -1
- package/src/atp/hubClient.js +5 -3
- package/src/atp/serviceHelper.js +3 -2
- package/src/evolve/guards.js +1 -1
- package/src/evolve/pipeline/collect.js +1 -1
- package/src/evolve/pipeline/dispatch.js +1 -1
- package/src/evolve/pipeline/enrich.js +1 -1
- package/src/evolve/pipeline/hub.js +1 -1
- package/src/evolve/pipeline/select.js +1 -1
- package/src/evolve/pipeline/signals.js +1 -1
- package/src/evolve/utils.js +1 -1
- package/src/evolve.js +1 -1
- package/src/gep/a2aProtocol.js +1 -1
- package/src/gep/antiAbuseTelemetry.js +1 -1
- package/src/gep/autoDistillConv.js +1 -1
- package/src/gep/autoDistillLlm.js +1 -1
- package/src/gep/candidateEval.js +1 -1
- package/src/gep/candidates.js +1 -1
- package/src/gep/cliContracts.js +37 -1
- package/src/gep/contentHash.js +1 -1
- package/src/gep/conversationDistiller.js +1 -1
- package/src/gep/conversationSniffer.js +1 -1
- package/src/gep/crypto.js +1 -1
- package/src/gep/curriculum.js +1 -1
- package/src/gep/deviceId.js +1 -1
- package/src/gep/directoryClient.js +7 -3
- package/src/gep/envFingerprint.js +1 -1
- package/src/gep/epigenetics.js +1 -1
- package/src/gep/execBridge.js +1 -1
- package/src/gep/explore.js +1 -1
- package/src/gep/hash.js +1 -1
- package/src/gep/hubFetch.js +1 -1
- package/src/gep/hubReview.js +1 -1
- package/src/gep/hubSearch.js +1 -1
- package/src/gep/hubVerify.js +1 -1
- package/src/gep/learningSignals.js +1 -1
- package/src/gep/memoryGraph.js +1 -1
- package/src/gep/memoryGraphAdapter.js +1 -1
- package/src/gep/mutation.js +1 -1
- package/src/gep/narrativeMemory.js +1 -1
- package/src/gep/oauthLogin.js +3 -5
- package/src/gep/openPRRegistry.js +1 -1
- package/src/gep/personality.js +1 -1
- package/src/gep/policyCheck.js +1 -1
- package/src/gep/privacyClient.js +28 -10
- package/src/gep/prompt.js +1 -1
- package/src/gep/recallInject.js +1 -1
- package/src/gep/recallVerifier.js +1 -1
- package/src/gep/reflection.js +1 -1
- package/src/gep/savingsCore.js +1 -1
- package/src/gep/selector.js +1 -1
- package/src/gep/skill2gep.js +329 -43
- package/src/gep/skill2gepAudit.js +303 -0
- package/src/gep/skillDistiller.js +1 -1
- package/src/gep/skillPublisher.js +8 -3
- package/src/gep/solidify.js +1 -1
- package/src/gep/strategy.js +1 -1
- package/src/gep/taskReceiver.js +3 -2
- package/src/gep/tokenSavings.js +1 -1
- package/src/gep/trajectoryExport.js +1 -0
- package/src/gep/validator/index.js +7 -2
- package/src/gep/validator/reporter.js +7 -2
- package/src/gep/validator/stakeBootstrap.js +7 -2
- package/src/gep/workspaceKeychain.js +1 -1
- package/src/proxy/clientSettings.js +405 -0
- package/src/proxy/extensions/traceControl.js +1 -1
- package/src/proxy/index.js +13 -5
- package/src/proxy/inject.js +1 -1
- package/src/proxy/lifecycle/manager.js +82 -16
- package/src/proxy/mailbox/state.js +207 -0
- package/src/proxy/mailbox/store.js +164 -64
- package/src/proxy/router/messages_route.js +56 -4
- package/src/proxy/server/http.js +40 -6
- package/src/proxy/sync/inbound.js +31 -12
- package/src/proxy/sync/outbound.js +164 -24
- package/src/proxy/trace/extractor.js +1 -1
- package/src/proxy/trace/usage.js +1 -1
|
@@ -373,6 +373,58 @@ function getNoticeStatePath() {
|
|
|
373
373
|
return path.join(dir, 'session-start-notice-state.json');
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
+
// Resolve the evolver-marked-sessions registry path. This is the v1 "evolver
|
|
377
|
+
// actively marked this session" ledger: only sessions whose session-start hook
|
|
378
|
+
// actually fired (i.e. sessions evolver participated in, after hook install)
|
|
379
|
+
// land here. The trajectory exporter reads it to gate which runtime-session
|
|
380
|
+
// transcripts get collected (strict by default). Lives alongside the proxy
|
|
381
|
+
// trace dir so both collection ledgers share one home. The env override keeps
|
|
382
|
+
// tests hermetic and lets an operator relocate the ledger.
|
|
383
|
+
function getMarkedSessionsPath() {
|
|
384
|
+
if (process.env.EVOLVER_MARKED_SESSIONS_FILE) return process.env.EVOLVER_MARKED_SESSIONS_FILE;
|
|
385
|
+
const dir = process.env.EVOLVER_SETTINGS_DIR
|
|
386
|
+
|| process.env.EVOLVER_SESSION_STATE_DIR
|
|
387
|
+
|| path.join(os.homedir(), '.evolver');
|
|
388
|
+
return path.join(dir, 'marked-sessions.jsonl');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Pull the tool's session_id out of the hook's stdin payload. Claude Code,
|
|
392
|
+
// Codex, and Cursor all pass `session_id` (Claude Code / Cursor) on the
|
|
393
|
+
// SessionStart stdin JSON; some shapes use `sessionId`. Returns '' when absent
|
|
394
|
+
// so callers can skip the registry write without erroring (Kiro's promptSubmit
|
|
395
|
+
// and hosts that pass no stdin simply don't mark — fail-open by design).
|
|
396
|
+
function _extractHookSessionId(input) {
|
|
397
|
+
if (!input || typeof input !== 'object') return '';
|
|
398
|
+
const raw = input.session_id ?? input.sessionId ?? input.sessionID;
|
|
399
|
+
return typeof raw === 'string' ? raw.trim() : '';
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Append one mark record to the registry. Best-effort and idempotent enough for
|
|
403
|
+
// the exporter's needs: the exporter dedupes into a Set, so a session marked on
|
|
404
|
+
// every prompt (Kiro) just appends duplicate lines that collapse on read. We do
|
|
405
|
+
// NOT read-modify-write to dedupe here — that would race across concurrent
|
|
406
|
+
// sessions; append-only is safe and the file is bounded by session count.
|
|
407
|
+
function recordMarkedSession(sessionId, info = {}) {
|
|
408
|
+
const sid = String(sessionId || '').trim();
|
|
409
|
+
if (!sid) return false;
|
|
410
|
+
const file = getMarkedSessionsPath();
|
|
411
|
+
try {
|
|
412
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
413
|
+
const record = {
|
|
414
|
+
session_id: sid,
|
|
415
|
+
...(info.cwd ? { cwd: String(info.cwd) } : {}),
|
|
416
|
+
...(info.source ? { source: String(info.source) } : {}),
|
|
417
|
+
marked_at: new Date().toISOString(),
|
|
418
|
+
};
|
|
419
|
+
fs.appendFileSync(file, JSON.stringify(record) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
420
|
+
return true;
|
|
421
|
+
} catch (_) {
|
|
422
|
+
// Never let a registry write failure break session-start: the context
|
|
423
|
+
// injection (stdout JSON) must always be emitted.
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
376
428
|
// TTL throttle keyed by an arbitrary string. Returns true if `key` fired within
|
|
377
429
|
// the last `ttlMs` (caller should suppress); otherwise records "now" for `key`
|
|
378
430
|
// and returns false. Best-effort: a state read/write failure just means no
|
|
@@ -415,7 +467,50 @@ function shouldSkipInjection() {
|
|
|
415
467
|
return throttled(process.cwd(), ttlMs, getDedupStatePath());
|
|
416
468
|
}
|
|
417
469
|
|
|
470
|
+
// Drain the hook stdin (session context JSON) before running, so we can read the
|
|
471
|
+
// tool's session_id and mark the session in the registry. The host passes the
|
|
472
|
+
// SessionStart payload on stdin; we bound the wait with a short watchdog and
|
|
473
|
+
// fail-open (mark nothing, still emit context) if stdin never closes or isn't a
|
|
474
|
+
// pipe. This mirrors the stdin-draining pattern in evolver-task-recall.js /
|
|
475
|
+
// evolver-session-end.js.
|
|
418
476
|
function main() {
|
|
477
|
+
let done = false;
|
|
478
|
+
let buf = '';
|
|
479
|
+
const finishWithInput = (input) => {
|
|
480
|
+
if (done) return;
|
|
481
|
+
done = true;
|
|
482
|
+
try {
|
|
483
|
+
const sessionId = _extractHookSessionId(input);
|
|
484
|
+
if (sessionId) {
|
|
485
|
+
recordMarkedSession(sessionId, {
|
|
486
|
+
cwd: resolveProjectDir(),
|
|
487
|
+
source: String(process.env.EVOLVER_SESSION_SOURCE || (input && input.source) || '').trim() || undefined,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
} catch (_) { /* marking is best-effort; never block injection */ }
|
|
491
|
+
runInjection();
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// Watchdog: if stdin never ends (host passed no pipe, or hangs), proceed
|
|
495
|
+
// without a session_id rather than stalling the agent's session start.
|
|
496
|
+
const watchdog = setTimeout(() => finishWithInput(null), 1500);
|
|
497
|
+
try {
|
|
498
|
+
process.stdin.setEncoding('utf8');
|
|
499
|
+
} catch (_) { /* some hosts pass no stdin */ }
|
|
500
|
+
process.stdin.on('data', (c) => { buf += c; });
|
|
501
|
+
process.stdin.on('error', () => { clearTimeout(watchdog); finishWithInput(null); });
|
|
502
|
+
process.stdin.on('end', () => {
|
|
503
|
+
clearTimeout(watchdog);
|
|
504
|
+
let input = null;
|
|
505
|
+
try { input = buf.trim() ? JSON.parse(buf) : null; } catch (_) { input = null; }
|
|
506
|
+
finishWithInput(input);
|
|
507
|
+
});
|
|
508
|
+
// Nudge a resume so a paused stdin stream flushes its data/end events; the
|
|
509
|
+
// watchdog covers the case where neither ever arrives (no pipe attached).
|
|
510
|
+
try { process.stdin.resume(); } catch (_) { /* ignore */ }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function runInjection() {
|
|
419
514
|
if (shouldSkipInjection()) {
|
|
420
515
|
process.stdout.write(JSON.stringify({}));
|
|
421
516
|
return;
|
|
@@ -485,5 +580,8 @@ if (require.main === module) {
|
|
|
485
580
|
_proxyExpected,
|
|
486
581
|
_proxyReachable,
|
|
487
582
|
_proxyHealthyIfExpected,
|
|
583
|
+
_extractHookSessionId,
|
|
584
|
+
getMarkedSessionsPath,
|
|
585
|
+
recordMarkedSession,
|
|
488
586
|
};
|
|
489
587
|
}
|
package/src/atp/atpExecute.js
CHANGED
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
getHubUrl,
|
|
32
32
|
getHubNodeSecret,
|
|
33
33
|
buildHubHeaders,
|
|
34
|
+
buildNodeScopedHubHeaders,
|
|
34
35
|
sendHelloToHub,
|
|
35
36
|
} = require('../gep/a2aProtocol');
|
|
36
37
|
const { submitDelivery } = require('./hubClient');
|
|
@@ -126,9 +127,10 @@ function _publishUrl() {
|
|
|
126
127
|
|
|
127
128
|
async function _postJson(urlStr, body, timeoutMs) {
|
|
128
129
|
const payload = JSON.stringify(body || {});
|
|
130
|
+
const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
|
|
129
131
|
const headers = Object.assign(
|
|
130
132
|
{ 'Content-Type': 'application/json' },
|
|
131
|
-
|
|
133
|
+
buildHeaders() || {},
|
|
132
134
|
);
|
|
133
135
|
|
|
134
136
|
try {
|
package/src/atp/hubClient.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// bound to 127.0.0.1).
|
|
16
16
|
|
|
17
17
|
const http = require('http');
|
|
18
|
-
const { getHubUrl, buildHubHeaders, getNodeId } = require('../gep/a2aProtocol');
|
|
18
|
+
const { getHubUrl, buildHubHeaders, buildNodeScopedHubHeaders, getNodeId } = require('../gep/a2aProtocol');
|
|
19
19
|
const { hubFetch } = require('../gep/hubFetch');
|
|
20
20
|
const { getProxyUrl, getProxyToken } = require('../proxy/server/settings');
|
|
21
21
|
|
|
@@ -95,9 +95,10 @@ function _hubPost(pathSuffix, body, timeoutMs) {
|
|
|
95
95
|
if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
|
|
96
96
|
const endpoint = hubUrl.replace(/\/+$/, '') + pathSuffix;
|
|
97
97
|
const timeout = timeoutMs || require('../config').HTTP_TRANSPORT_TIMEOUT_MS;
|
|
98
|
+
const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
|
|
98
99
|
return hubFetch(endpoint, {
|
|
99
100
|
method: 'POST',
|
|
100
|
-
headers:
|
|
101
|
+
headers: buildHeaders(),
|
|
101
102
|
body: JSON.stringify(body),
|
|
102
103
|
signal: AbortSignal.timeout(timeout),
|
|
103
104
|
})
|
|
@@ -123,9 +124,10 @@ function _hubGet(pathSuffix, timeoutMs) {
|
|
|
123
124
|
if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
|
|
124
125
|
const endpoint = hubUrl.replace(/\/+$/, '') + pathSuffix;
|
|
125
126
|
const timeout = timeoutMs || require('../config').HTTP_TRANSPORT_TIMEOUT_MS;
|
|
127
|
+
const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
|
|
126
128
|
return hubFetch(endpoint, {
|
|
127
129
|
method: 'GET',
|
|
128
|
-
headers:
|
|
130
|
+
headers: buildHeaders(),
|
|
129
131
|
signal: AbortSignal.timeout(timeout),
|
|
130
132
|
})
|
|
131
133
|
.then(function (res) {
|
package/src/atp/serviceHelper.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// ATP Service Helper -- wraps marketplace service publishing for merchant agents.
|
|
2
2
|
|
|
3
|
-
const { getNodeId, buildHubHeaders, getHubUrl } = require('../gep/a2aProtocol');
|
|
3
|
+
const { getNodeId, buildHubHeaders, buildNodeScopedHubHeaders, getHubUrl } = require('../gep/a2aProtocol');
|
|
4
4
|
const { hubFetch } = require('../gep/hubFetch');
|
|
5
5
|
const { HTTP_TRANSPORT_TIMEOUT_MS } = require('../config');
|
|
6
6
|
|
|
7
7
|
async function postService(endpoint, body) {
|
|
8
8
|
try {
|
|
9
|
+
const buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
|
|
9
10
|
const res = await hubFetch(endpoint, {
|
|
10
11
|
method: 'POST',
|
|
11
|
-
headers: Object.assign({ 'Content-Type': 'application/json' },
|
|
12
|
+
headers: Object.assign({ 'Content-Type': 'application/json' }, buildHeaders() || {}),
|
|
12
13
|
body: JSON.stringify(body),
|
|
13
14
|
signal: AbortSignal.timeout(HTTP_TRANSPORT_TIMEOUT_MS),
|
|
14
15
|
});
|