imprint-mcp 0.6.0 → 0.6.2
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 +2 -0
- package/package.json +4 -2
- package/prompts/audit-agent.md +4 -2
- package/prompts/auth-compile-agent.md +149 -158
- package/prompts/build-planning.md +14 -9
- package/prompts/compile-agent.md +46 -23
- package/prompts/live-verifier-agent.md +101 -0
- package/prompts/playbook-compilation.md +8 -1
- package/prompts/tool-candidate-detection.md +9 -29
- package/src/cli.ts +83 -1
- package/src/imprint/audit.ts +219 -20
- package/src/imprint/auth-compile-agent.ts +215 -155
- package/src/imprint/auth-compile-tools.ts +300 -118
- package/src/imprint/auth-verifier.ts +167 -180
- package/src/imprint/backend-cache.ts +18 -11
- package/src/imprint/backend-ladder.ts +225 -177
- package/src/imprint/build-plan.ts +3 -8
- package/src/imprint/cdp-browser-fetch.ts +930 -83
- package/src/imprint/claude-cli-compile.ts +46 -20
- package/src/imprint/codex-cli-compile.ts +436 -139
- package/src/imprint/compile-agent-types.ts +15 -10
- package/src/imprint/compile-agent.ts +88 -28
- package/src/imprint/compile-tools.ts +228 -39
- package/src/imprint/compile-verification.ts +187 -0
- package/src/imprint/compile.ts +71 -2
- package/src/imprint/credential-store.ts +57 -44
- package/src/imprint/emit.ts +3 -1
- package/src/imprint/freeform-redact.ts +27 -6
- package/src/imprint/live-verifier.ts +1665 -0
- package/src/imprint/llm.ts +22 -3
- package/src/imprint/login.ts +107 -25
- package/src/imprint/mcp-compile-server.ts +447 -114
- package/src/imprint/mcp-live-verifier-server.ts +359 -0
- package/src/imprint/mcp-server.ts +116 -35
- package/src/imprint/probe-backends.ts +88 -7
- package/src/imprint/recording-request.ts +36 -0
- package/src/imprint/request-capture.ts +40 -17
- package/src/imprint/runtime.ts +490 -337
- package/src/imprint/teach-state.ts +36 -2
- package/src/imprint/teach.ts +302 -146
- package/src/imprint/tool-candidates.ts +8 -10
- package/src/imprint/tool-loader.ts +12 -4
- package/src/imprint/types.ts +137 -68
|
@@ -39,7 +39,7 @@ import type {
|
|
|
39
39
|
import { formatCandidateContext, formatToolPlan } from './compile-agent-types.ts';
|
|
40
40
|
import { preferredAgentModel } from './llm.ts';
|
|
41
41
|
import { createLog } from './log.ts';
|
|
42
|
-
import { COMPILE_SENTINELS } from './mcp-compile-server.ts';
|
|
42
|
+
import { COMPILE_SENTINELS, compileDeadlineAfterVerification } from './mcp-compile-server.ts';
|
|
43
43
|
import type { SharedCompileContext, ToolCandidate } from './tool-candidates.ts';
|
|
44
44
|
import {
|
|
45
45
|
endTraceSpan,
|
|
@@ -60,6 +60,12 @@ const CLI_PATH = pathJoin(REPO_ROOT, 'src', 'cli.ts');
|
|
|
60
60
|
const MCP_SERVER_NAME = 'imprint-compile';
|
|
61
61
|
const MAX_VERIFICATION_CYCLES = 5;
|
|
62
62
|
|
|
63
|
+
function formatRevisionMode(enabled: boolean | undefined): string {
|
|
64
|
+
return enabled
|
|
65
|
+
? 'REVISION MODE: inspect read_session_summary.revisionContext and the listed existing artifacts/diagnostics first. Preserve proven behavior; repair or honestly narrow only what evidence contradicts.'
|
|
66
|
+
: '';
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
/**
|
|
64
70
|
* Thinking effort for the compile agent. Deliberately `high`, not `max`:
|
|
65
71
|
* empirically, max-effort thinking generates a large volume of reasoning tokens
|
|
@@ -110,6 +116,8 @@ interface CompileViaClaudeCliOptions {
|
|
|
110
116
|
sharedModules?: SharedModuleManifestEntry[];
|
|
111
117
|
/** Per-tool implementation plan injected into the agent's initial message. */
|
|
112
118
|
toolPlan?: string;
|
|
119
|
+
/** Revise existing generated artifacts from durable verification feedback. */
|
|
120
|
+
revisionMode?: boolean;
|
|
113
121
|
/** Present → drive an auth compile rather than a data compile. */
|
|
114
122
|
authMode?: AuthCliCompileMode;
|
|
115
123
|
/** Auth segments only: resume a prior segment's claude session with a new user
|
|
@@ -117,6 +125,8 @@ interface CompileViaClaudeCliOptions {
|
|
|
117
125
|
* When set, `--resume <sessionId>` is used and `message` replaces the initial
|
|
118
126
|
* prompt. Requires session persistence (auth mode keeps it on). */
|
|
119
127
|
resume?: { sessionId: string; message: string };
|
|
128
|
+
/** Explicit model selected by the caller. Defaults to the provider preference. */
|
|
129
|
+
model?: string;
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
/** Options for the auth-compile entry point. A strict subset of the data
|
|
@@ -133,6 +143,7 @@ interface AuthCompileViaClaudeCliOptions {
|
|
|
133
143
|
authMode: AuthCliCompileMode;
|
|
134
144
|
/** Resume a prior segment (see CompileViaClaudeCliOptions.resume). */
|
|
135
145
|
resume?: { sessionId: string; message: string };
|
|
146
|
+
model?: string;
|
|
136
147
|
}
|
|
137
148
|
|
|
138
149
|
/** Auth-compile entry point for claude-cli. Delegates to the same trace +
|
|
@@ -153,6 +164,7 @@ export function compileAuthViaClaudeCli(
|
|
|
153
164
|
onDeadlineReached: opts.onDeadlineReached,
|
|
154
165
|
authMode: opts.authMode,
|
|
155
166
|
resume: opts.resume,
|
|
167
|
+
model: opts.model,
|
|
156
168
|
});
|
|
157
169
|
}
|
|
158
170
|
|
|
@@ -196,7 +208,7 @@ export async function compileViaClaudeCli(
|
|
|
196
208
|
'imprint.site': opts.session.site,
|
|
197
209
|
'imprint.tool_dir': opts.absoluteToolDir,
|
|
198
210
|
'imprint.provider': 'claude-cli',
|
|
199
|
-
'imprint.model': preferredAgentModel('claude-cli'),
|
|
211
|
+
'imprint.model': opts.model ?? preferredAgentModel('claude-cli'),
|
|
200
212
|
},
|
|
201
213
|
async (span) => {
|
|
202
214
|
const result = await compileViaClaudeCliImpl(opts);
|
|
@@ -210,7 +222,7 @@ export async function compileViaClaudeCli(
|
|
|
210
222
|
'imprint.compile.cache_creation_input_tokens': result.cacheCreationInputTokens,
|
|
211
223
|
...llmSpanAttributes({
|
|
212
224
|
provider: 'claude-cli',
|
|
213
|
-
model: preferredAgentModel('claude-cli'),
|
|
225
|
+
model: opts.model ?? preferredAgentModel('claude-cli'),
|
|
214
226
|
// TOTAL prompt (uncached + cache); the cache split is passed separately
|
|
215
227
|
// for cost. `result.inputTokens` alone is the uncached delta (often a
|
|
216
228
|
// few hundred), which would mislabel `llm.token_count.prompt`.
|
|
@@ -271,6 +283,7 @@ async function runClaudeCliAttempt(opts: CompileViaClaudeCliOptions): Promise<Co
|
|
|
271
283
|
COMPILE_SENTINELS.done,
|
|
272
284
|
COMPILE_SENTINELS.giveUp,
|
|
273
285
|
COMPILE_SENTINELS.checkpoint,
|
|
286
|
+
COMPILE_SENTINELS.verificationState,
|
|
274
287
|
]) {
|
|
275
288
|
const p = pathJoin(opts.absoluteToolDir, name);
|
|
276
289
|
if (existsSync(p)) {
|
|
@@ -321,10 +334,13 @@ async function runClaudeCliAttempt(opts: CompileViaClaudeCliOptions): Promise<Co
|
|
|
321
334
|
sessionPathAbs,
|
|
322
335
|
'--tool-dir',
|
|
323
336
|
opts.absoluteToolDir,
|
|
337
|
+
'--provider',
|
|
338
|
+
'claude-cli',
|
|
324
339
|
...(opts.candidate ? ['--candidate-json', JSON.stringify(opts.candidate)] : []),
|
|
325
340
|
...(opts.sharedContext ? ['--shared-context-json', JSON.stringify(opts.sharedContext)] : []),
|
|
326
341
|
...(opts.buildPlanPath ? ['--build-plan-path', opts.buildPlanPath] : []),
|
|
327
342
|
...(opts.sharedModules ? ['--shared-modules-json', JSON.stringify(opts.sharedModules)] : []),
|
|
343
|
+
...(opts.revisionMode ? ['--revision-mode'] : []),
|
|
328
344
|
];
|
|
329
345
|
allowedToolNames = [
|
|
330
346
|
'read_session_summary',
|
|
@@ -351,6 +367,7 @@ Tool directory: ${opts.absoluteToolDir}
|
|
|
351
367
|
You will write artifacts into the tool directory.
|
|
352
368
|
${formatCandidateContext(opts.candidate, opts.sharedContext, assignedSharedModules)}
|
|
353
369
|
${formatToolPlan(opts.toolPlan)}
|
|
370
|
+
${formatRevisionMode(opts.revisionMode)}
|
|
354
371
|
|
|
355
372
|
Begin by calling read_session_summary to orient yourself, then proceed per the system prompt.`;
|
|
356
373
|
}
|
|
@@ -408,7 +425,7 @@ Begin by calling read_session_summary to orient yourself, then proceed per the s
|
|
|
408
425
|
'--effort',
|
|
409
426
|
COMPILE_EFFORT_LEVEL,
|
|
410
427
|
'--model',
|
|
411
|
-
preferredAgentModel('claude-cli'),
|
|
428
|
+
opts.model ?? preferredAgentModel('claude-cli'),
|
|
412
429
|
promptArg,
|
|
413
430
|
];
|
|
414
431
|
|
|
@@ -421,19 +438,14 @@ Begin by calling read_session_summary to orient yourself, then proceed per the s
|
|
|
421
438
|
child = spawn('claude', args, {
|
|
422
439
|
cwd: REPO_ROOT,
|
|
423
440
|
// Claude CLI's default MCP_TOOL_TIMEOUT is 60s. The compile MCP
|
|
424
|
-
// server's `done` tool runs external verification inline
|
|
425
|
-
//
|
|
426
|
-
//
|
|
427
|
-
//
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
//
|
|
432
|
-
// actually complete and the agent receives the failure feedback
|
|
433
|
-
// (and ships with `liveVerified: false` via the waiver path)
|
|
434
|
-
// rather than getting `-32000: Connection closed` mid-call and
|
|
435
|
-
// wasting the rest of its turn budget. Honor user-set env so an
|
|
436
|
-
// operator on a fast network can tighten without editing source.
|
|
441
|
+
// server's `done` tool runs external verification inline: one live
|
|
442
|
+
// integration suite, parser tests, typechecking, and a fresh semantic
|
|
443
|
+
// verifier agent that may make a narrowly targeted follow-up call. On
|
|
444
|
+
// bot-protected sites one suite can still take 10-15 minutes as each
|
|
445
|
+
// assertion escalates fetch → fetch-bootstrap → stealth-fetch. Keep the
|
|
446
|
+
// 30-minute cap so the agent receives semantic feedback rather than an
|
|
447
|
+
// MCP connection-close midway through review. Honor user-set env so an
|
|
448
|
+
// operator on a fast network can tighten it without editing source.
|
|
437
449
|
// Connection-startup timeout stays at 60s for cold Playwright boot.
|
|
438
450
|
env: {
|
|
439
451
|
...process.env,
|
|
@@ -491,7 +503,7 @@ async function driveStreamJson(
|
|
|
491
503
|
inputTokens,
|
|
492
504
|
outputTokens,
|
|
493
505
|
verificationCycle: 1,
|
|
494
|
-
maxVerificationCycles: MAX_VERIFICATION_CYCLES,
|
|
506
|
+
maxVerificationCycles: opts.authMode ? undefined : MAX_VERIFICATION_CYCLES,
|
|
495
507
|
});
|
|
496
508
|
};
|
|
497
509
|
|
|
@@ -512,9 +524,19 @@ async function driveStreamJson(
|
|
|
512
524
|
};
|
|
513
525
|
|
|
514
526
|
const scheduleDeadlineCheck = (): ReturnType<typeof setTimeout> => {
|
|
515
|
-
const
|
|
527
|
+
const effectiveDeadlineMs = compileDeadlineAfterVerification(
|
|
528
|
+
opts.absoluteToolDir,
|
|
529
|
+
currentDeadlineMs,
|
|
530
|
+
);
|
|
531
|
+
const remaining = Math.max(0, effectiveDeadlineMs - Date.now());
|
|
516
532
|
return setTimeout(async () => {
|
|
517
533
|
if (childExited) return;
|
|
534
|
+
// done() verification runs in the MCP child. Re-read its lifecycle clock
|
|
535
|
+
// before killing the compiler so only reasoning time counts here.
|
|
536
|
+
if (Date.now() < compileDeadlineAfterVerification(opts.absoluteToolDir, currentDeadlineMs)) {
|
|
537
|
+
deadlineTimer = scheduleDeadlineCheck();
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
518
540
|
if (opts.onDeadlineReached) {
|
|
519
541
|
const extensionMs = await opts.onDeadlineReached();
|
|
520
542
|
if (childExited) return;
|
|
@@ -744,7 +766,11 @@ async function driveStreamJson(
|
|
|
744
766
|
}
|
|
745
767
|
|
|
746
768
|
// Wall-clock deadline exceeded?
|
|
747
|
-
if (
|
|
769
|
+
if (
|
|
770
|
+
Date.now() > compileDeadlineAfterVerification(opts.absoluteToolDir, currentDeadlineMs) &&
|
|
771
|
+
!existsSync(doneSentinel) &&
|
|
772
|
+
!existsSync(giveUpSentinel)
|
|
773
|
+
) {
|
|
748
774
|
return {
|
|
749
775
|
success: false,
|
|
750
776
|
outcome: 'timeout',
|