imprint-mcp 0.7.0 → 0.7.1
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 +64 -2
- package/package.json +1 -1
- package/prompts/auth-compile-agent.md +167 -22
- package/prompts/compile-agent.md +45 -8
- package/prompts/component-recovery.md +40 -0
- package/prompts/master-teach-decision.md +28 -3
- package/prompts/master-teach-focused-planner.md +18 -5
- package/src/cli.ts +26 -18
- package/src/imprint/agent-tool.ts +15 -0
- package/src/imprint/agent.ts +2 -11
- package/src/imprint/audit.ts +35 -13
- package/src/imprint/auth-browser-discovery.ts +276 -0
- package/src/imprint/auth-compile-agent.ts +513 -224
- package/src/imprint/auth-compile-tools.ts +213 -25
- package/src/imprint/auth-discovery-evidence.ts +81 -0
- package/src/imprint/auth-plan.ts +28 -0
- package/src/imprint/auth-verifier.ts +234 -20
- package/src/imprint/authentication-interaction.ts +137 -0
- package/src/imprint/backend-ladder.ts +218 -34
- package/src/imprint/build-plan.ts +2 -22
- package/src/imprint/cdp-browser-fetch.ts +192 -53
- package/src/imprint/chromium.ts +93 -29
- package/src/imprint/claude-cli-compile.ts +2 -0
- package/src/imprint/codex-cli-compile.ts +99 -46
- package/src/imprint/compile-agent-types.ts +9 -5
- package/src/imprint/compile-agent.ts +33 -0
- package/src/imprint/compile-tool-executor.ts +783 -0
- package/src/imprint/compile-tools.ts +42 -9
- package/src/imprint/compile-verification.ts +2 -0
- package/src/imprint/compile.ts +3 -0
- package/src/imprint/compiler-log.ts +16 -0
- package/src/imprint/component-recovery.ts +120 -0
- package/src/imprint/cookie-jar.ts +117 -7
- package/src/imprint/credential-extract.ts +9 -2
- package/src/imprint/credential-lock.ts +146 -0
- package/src/imprint/credential-observation.ts +261 -0
- package/src/imprint/credential-store.ts +247 -44
- package/src/imprint/live-component-recovery.ts +73 -0
- package/src/imprint/llm.ts +4 -3
- package/src/imprint/log.ts +16 -1
- package/src/imprint/login.ts +9 -0
- package/src/imprint/master-teach-agent-contracts.ts +40 -3
- package/src/imprint/master-teach-agents.ts +229 -14
- package/src/imprint/master-teach-checks.ts +8 -1
- package/src/imprint/master-teach-controller.ts +681 -138
- package/src/imprint/master-teach-prompt-projections.ts +2 -0
- package/src/imprint/mcp-compile-server.ts +62 -850
- package/src/imprint/native-teach-agents.ts +232 -108
- package/src/imprint/runtime.ts +357 -36
- package/src/imprint/stealth-chromium.ts +67 -7
- package/src/imprint/teach-browser-resources.ts +88 -0
- package/src/imprint/teach-stage-progress.ts +38 -0
- package/src/imprint/terminal-user-prompt.ts +42 -0
- package/src/imprint/types.ts +46 -18
- package/src/imprint/user-interaction.ts +836 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import type { CallToolResult, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { AuthToolPlanSchema } from './auth-plan.ts';
|
|
4
|
+
import { createCompileToolExecutor } from './compile-tool-executor.ts';
|
|
3
5
|
import { currentNativeTeachAgents } from './native-teach-agents.ts';
|
|
4
6
|
import { SHARED_RESEARCH_INSTRUCTIONS } from './teach-research-memory.ts';
|
|
5
7
|
/**
|
|
@@ -12,17 +14,14 @@ import { SHARED_RESEARCH_INSTRUCTIONS } from './teach-research-memory.ts';
|
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
import type { ChildProcess } from 'node:child_process';
|
|
15
|
-
import {
|
|
16
|
-
appendFileSync,
|
|
17
|
-
existsSync,
|
|
18
|
-
mkdirSync,
|
|
19
|
-
readFileSync,
|
|
20
|
-
unlinkSync,
|
|
21
|
-
writeFileSync,
|
|
22
|
-
} from 'node:fs';
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
23
18
|
import { isAbsolute as pathIsAbsolute, join as pathJoin } from 'node:path';
|
|
24
19
|
import { type Span, context as otelContext } from '@opentelemetry/api';
|
|
25
|
-
import
|
|
20
|
+
import {
|
|
21
|
+
AUTH_CHECKPOINT_TOOLS,
|
|
22
|
+
type AuthCliCompileMode,
|
|
23
|
+
parseAuthCheckpoint,
|
|
24
|
+
} from './auth-compile-tools.ts';
|
|
26
25
|
import { type SharedModuleManifestEntry, resolvePlanSliceFromFile } from './build-plan.ts';
|
|
27
26
|
import type {
|
|
28
27
|
AuthCheckpoint,
|
|
@@ -43,7 +42,7 @@ import {
|
|
|
43
42
|
watchCompileProviderDeadline,
|
|
44
43
|
} from './compile-provider-control.ts';
|
|
45
44
|
import type { CompileStrategyKind } from './compile-strategy.ts';
|
|
46
|
-
import { recordCompilerHostError } from './compiler-log.ts';
|
|
45
|
+
import { compilerToolFailure, recordCompilerHostError } from './compiler-log.ts';
|
|
47
46
|
import {
|
|
48
47
|
collectOwnedProcess,
|
|
49
48
|
spawnOwnedProcess,
|
|
@@ -392,28 +391,30 @@ Use the imprint-compile MCP tools to inspect the session, write artifacts, run t
|
|
|
392
391
|
|
|
393
392
|
const family = currentNativeTeachAgents();
|
|
394
393
|
if (family) {
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
394
|
+
const executor = createCompileToolExecutor(
|
|
395
|
+
{
|
|
396
|
+
sessionPath: sessionPathAbs,
|
|
397
|
+
toolDir: opts.absoluteToolDir,
|
|
398
|
+
site: opts.authMode?.site,
|
|
399
|
+
authToolPlan: opts.authMode
|
|
400
|
+
? AuthToolPlanSchema.parse(JSON.parse(opts.authMode.authPlanJson))
|
|
401
|
+
: undefined,
|
|
402
|
+
provider: 'codex-cli',
|
|
403
|
+
candidate: opts.candidate,
|
|
404
|
+
sharedContext: opts.sharedContext,
|
|
405
|
+
buildPlanPath: opts.buildPlanPath,
|
|
406
|
+
sharedModules: opts.sharedModules,
|
|
407
|
+
strategyKind: opts.strategyKind,
|
|
408
|
+
revisionMode: opts.revisionMode,
|
|
409
|
+
verificationMode: opts.verificationMode,
|
|
410
|
+
sharedTriageSelection: opts.sharedTriageSelection,
|
|
411
|
+
},
|
|
412
|
+
{ session: opts.session, signal: opts.signal, runDeadline },
|
|
402
413
|
);
|
|
403
|
-
const transport = new StdioClientTransport({
|
|
404
|
-
env,
|
|
405
|
-
command: bunPath,
|
|
406
|
-
args: mcpArgs,
|
|
407
|
-
cwd: opts.absoluteToolDir,
|
|
408
|
-
stderr: 'pipe',
|
|
409
|
-
});
|
|
410
414
|
const conversationLogPath = pathJoin(opts.absoluteToolDir, '.compile-log.json');
|
|
411
415
|
const events: unknown[] = existsSync(conversationLogPath)
|
|
412
416
|
? JSON.parse(readFileSync(conversationLogPath, 'utf8'))
|
|
413
417
|
: [];
|
|
414
|
-
transport.stderr?.on('data', (chunk) =>
|
|
415
|
-
appendFileSync(pathJoin(opts.absoluteToolDir, '.native-mcp-stderr.log'), chunk),
|
|
416
|
-
);
|
|
417
418
|
const sharedResearch = family.sharedResearch
|
|
418
419
|
? {
|
|
419
420
|
runId: family.sharedResearch.runId,
|
|
@@ -428,30 +429,83 @@ Use the imprint-compile MCP tools to inspect the session, write artifacts, run t
|
|
|
428
429
|
? `${SHARED_RESEARCH_INSTRUCTIONS}\n${JSON.stringify({ sharedResearch })}\nUse the native shared_research tool with this exchange schema to publish/query findings; do not embed publications in your final compiler summary.\n`
|
|
429
430
|
: '';
|
|
430
431
|
try {
|
|
431
|
-
await client.connect(transport);
|
|
432
432
|
const response = await family.submit(
|
|
433
|
-
`${sharedPrompt}${initialPrompt}\n\nNative compiler: use list_assignment_tools and call_assignment_tool for this assignment in place of direct imprint-compile MCP names. All writes and tests must go through those tools. After done, give_up, or
|
|
433
|
+
`${sharedPrompt}${initialPrompt}\n\nNative compiler: use list_assignment_tools and call_assignment_tool for this assignment in place of direct imprint-compile MCP names. All writes and tests must go through those tools. ${opts.authMode?.executeCheckpoint ? 'Auth host tools execute inline: await each verification, browser operation, human question, or cooldown result and continue this same assignment. Submit a short summary only after done or give_up returns.' : 'After done, give_up, or a recorded auth checkpoint returns, submit a short summary to the host and stop this turn.'} Native subagents can assist with independent implementation questions; retain separate workspaces and do not substitute their prose for test evidence.`,
|
|
434
434
|
{
|
|
435
435
|
// The family already scopes this key to the run. Revision directories
|
|
436
436
|
// change; the public tool's retained compiler conversation must not.
|
|
437
437
|
conversation: `compiler:${opts.candidate?.toolName ?? opts.absoluteToolDir}`,
|
|
438
|
+
contextRef: opts.authMode?.contextRef,
|
|
438
439
|
signal: opts.signal,
|
|
439
|
-
call: async (name, args) => {
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
440
|
+
call: async (name, args, requestSignal) => {
|
|
441
|
+
const signal = requestSignal ?? opts.signal;
|
|
442
|
+
const requestId = randomUUID();
|
|
443
|
+
const started = performance.now();
|
|
444
|
+
const save = () =>
|
|
445
|
+
writeFileSync(conversationLogPath, JSON.stringify(events), { mode: 0o600 });
|
|
446
|
+
events.push({
|
|
447
|
+
type: 'tool.started',
|
|
448
|
+
timestamp: new Date().toISOString(),
|
|
449
|
+
name,
|
|
450
|
+
requestId,
|
|
451
|
+
});
|
|
452
|
+
save();
|
|
453
|
+
let failure: ReturnType<typeof compilerToolFailure> | undefined;
|
|
454
|
+
let result: CallToolResult | { tools: Tool[] };
|
|
455
|
+
try {
|
|
456
|
+
if (name === '__list') {
|
|
457
|
+
const listed = { tools: executor.tools };
|
|
458
|
+
result = opts.authMode?.executeCheckpoint
|
|
459
|
+
? {
|
|
460
|
+
...listed,
|
|
461
|
+
tools: listed.tools.map((tool) => {
|
|
462
|
+
const checkpoint = AUTH_CHECKPOINT_TOOLS.find(
|
|
463
|
+
(definition) => definition.name === tool.name,
|
|
464
|
+
);
|
|
465
|
+
return checkpoint
|
|
466
|
+
? {
|
|
467
|
+
...tool,
|
|
468
|
+
description: `${checkpoint.description} Await the host result and continue in this same assignment.`,
|
|
469
|
+
}
|
|
470
|
+
: tool;
|
|
471
|
+
}),
|
|
472
|
+
}
|
|
473
|
+
: listed;
|
|
474
|
+
} else if (
|
|
475
|
+
opts.authMode?.executeCheckpoint &&
|
|
476
|
+
AUTH_CHECKPOINT_TOOLS.some((tool) => tool.name === name)
|
|
477
|
+
) {
|
|
478
|
+
const executed = await opts.authMode.executeCheckpoint(
|
|
479
|
+
parseAuthCheckpoint(name, args),
|
|
480
|
+
signal,
|
|
481
|
+
);
|
|
482
|
+
result = {
|
|
483
|
+
content: [{ type: 'text', text: executed.result }],
|
|
484
|
+
...(executed.isError ? { isError: true } : {}),
|
|
485
|
+
};
|
|
486
|
+
} else {
|
|
487
|
+
result = await executor.callTool(name, args, signal);
|
|
488
|
+
}
|
|
489
|
+
events.push({ timestamp: new Date().toISOString(), name, args, result });
|
|
490
|
+
return result;
|
|
491
|
+
} catch (error) {
|
|
492
|
+
failure = compilerToolFailure(error);
|
|
493
|
+
throw error;
|
|
494
|
+
} finally {
|
|
495
|
+
events.push({
|
|
496
|
+
type: 'tool.settled',
|
|
497
|
+
timestamp: new Date().toISOString(),
|
|
498
|
+
name,
|
|
499
|
+
requestId,
|
|
500
|
+
durationMs: performance.now() - started,
|
|
501
|
+
status: signal?.aborted ? 'cancelled' : failure ? 'threw' : 'returned',
|
|
502
|
+
...(failure ? { error: failure } : {}),
|
|
503
|
+
});
|
|
504
|
+
save();
|
|
505
|
+
}
|
|
450
506
|
},
|
|
451
507
|
},
|
|
452
508
|
);
|
|
453
|
-
const interruption = providerControl.interruption();
|
|
454
|
-
if (interruption) throw compileProviderInterruptionError(interruption);
|
|
455
509
|
events.push({ type: 'native.completed', ...response });
|
|
456
510
|
writeFileSync(conversationLogPath, JSON.stringify(events), { mode: 0o600 });
|
|
457
511
|
return completedCompileResult(opts, {
|
|
@@ -477,8 +531,7 @@ Use the imprint-compile MCP tools to inspect the session, write artifacts, run t
|
|
|
477
531
|
),
|
|
478
532
|
});
|
|
479
533
|
} finally {
|
|
480
|
-
|
|
481
|
-
await client.close();
|
|
534
|
+
await executor.close();
|
|
482
535
|
}
|
|
483
536
|
}
|
|
484
537
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { AgentProgress } from './agent.ts';
|
|
10
|
+
import type { AuthBrowserAction } from './auth-browser-discovery.ts';
|
|
10
11
|
import { type AssignedSharedModule, describeAssignedModules } from './build-plan.ts';
|
|
11
12
|
import type { ProviderInterruptionReason, ProviderReportedError } from './provider-retry.ts';
|
|
12
13
|
import type { SharedCompileContext, ToolCandidate } from './tool-candidates.ts';
|
|
@@ -123,12 +124,10 @@ export interface CompileAgentProgress extends AgentProgress {
|
|
|
123
124
|
};
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
/** A
|
|
127
|
-
*
|
|
128
|
-
* (teach) performs the action — it owns the live browser session, the TUI, and
|
|
129
|
-
* the cooldown — then resumes the agent (`claude --resume`) with the result as a
|
|
130
|
-
* follow-up user message. Site/channel-agnostic. */
|
|
127
|
+
/** A host operation shared by inline native/API tools and CLI checkpoint/resume.
|
|
128
|
+
* The host owns the browser, prompt references, and declared continuation. */
|
|
131
129
|
export type AuthCheckpoint =
|
|
130
|
+
| ({ kind: 'interact_verification_browser' } & AuthBrowserAction)
|
|
132
131
|
| {
|
|
133
132
|
kind: 'run_verification';
|
|
134
133
|
action: string;
|
|
@@ -144,6 +143,11 @@ export type AuthCheckpoint =
|
|
|
144
143
|
| { kind: 'prompt_user'; message: string; options?: string[] }
|
|
145
144
|
| { kind: 'wait_for_cooldown'; minutes: number; reason?: string };
|
|
146
145
|
|
|
146
|
+
export interface AuthCheckpointResult {
|
|
147
|
+
result: string;
|
|
148
|
+
isError?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
147
151
|
export interface CompileAgentResult {
|
|
148
152
|
/** True only if external verification passed. */
|
|
149
153
|
success: boolean;
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
giveUpTool,
|
|
17
17
|
runAgentLoop,
|
|
18
18
|
} from './agent.ts';
|
|
19
|
+
import { attachRecordedAuthentication } from './authentication-interaction.ts';
|
|
19
20
|
import { type SharedModuleManifestEntry, resolvePlanSliceFromFile } from './build-plan.ts';
|
|
20
21
|
import { compileViaClaudeCli } from './claude-cli-compile.ts';
|
|
21
22
|
import { compileViaCodexCli } from './codex-cli-compile.ts';
|
|
@@ -70,6 +71,12 @@ import {
|
|
|
70
71
|
minimalSharedTriageSelection,
|
|
71
72
|
} from './triage-selection.ts';
|
|
72
73
|
import { type Session, SessionSchema, WorkflowSchema } from './types.ts';
|
|
74
|
+
import {
|
|
75
|
+
type OnUserPrompt,
|
|
76
|
+
UserInteraction,
|
|
77
|
+
currentUserInteraction,
|
|
78
|
+
withUserInteraction,
|
|
79
|
+
} from './user-interaction.ts';
|
|
73
80
|
|
|
74
81
|
export type { CompileAgentProgress } from './compile-agent-types.ts';
|
|
75
82
|
|
|
@@ -105,6 +112,7 @@ function removeEphemeralTests(toolDir: string): void {
|
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
interface CompileAgentOptions {
|
|
115
|
+
onPrompt?: OnUserPrompt;
|
|
108
116
|
/** Path to the recorded session JSON (absolute or relative). */
|
|
109
117
|
sessionPath: string;
|
|
110
118
|
/** Hard wall-clock budget. Default 20 minutes. */
|
|
@@ -172,6 +180,11 @@ function formatRevisionMode(enabled: boolean | undefined): string {
|
|
|
172
180
|
}
|
|
173
181
|
|
|
174
182
|
export async function compileAgent(opts: CompileAgentOptions): Promise<CompileAgentResult> {
|
|
183
|
+
if (!currentUserInteraction()) {
|
|
184
|
+
return await withUserInteraction(new UserInteraction(opts.onPrompt, opts.signal), () =>
|
|
185
|
+
compileAgent(opts),
|
|
186
|
+
);
|
|
187
|
+
}
|
|
175
188
|
const startTime = Date.now();
|
|
176
189
|
// Build-plan fields are bounded proposals for the compile/master agents.
|
|
177
190
|
const { assignedSharedModules } = resolvePlanSliceFromFile(
|
|
@@ -192,6 +205,12 @@ export async function compileAgent(opts: CompileAgentOptions): Promise<CompileAg
|
|
|
192
205
|
'session',
|
|
193
206
|
);
|
|
194
207
|
|
|
208
|
+
const extractedAuthValues = Object.fromEntries(
|
|
209
|
+
extractCredentials(session).replacements.flatMap(({ originalValue, placeholder }) => {
|
|
210
|
+
const match = /^\$\{credential\.([^}]+)\}$/.exec(placeholder);
|
|
211
|
+
return match?.[1] ? [[match[1], originalValue]] : [];
|
|
212
|
+
}),
|
|
213
|
+
);
|
|
195
214
|
// 2. Auto-redact raw direct-generate inputs. Teach normally supplies an
|
|
196
215
|
// already-redacted focused recording.
|
|
197
216
|
const looksRedacted = JSON.stringify(session).includes('[REDACTED:');
|
|
@@ -265,6 +284,7 @@ export async function compileAgent(opts: CompileAgentOptions): Promise<CompileAg
|
|
|
265
284
|
sharedModules: opts.sharedModules,
|
|
266
285
|
strategyKind: opts.strategyKind,
|
|
267
286
|
revisionMode: opts.revisionMode,
|
|
287
|
+
signal: opts.signal,
|
|
268
288
|
}),
|
|
269
289
|
doneTool(),
|
|
270
290
|
giveUpTool(),
|
|
@@ -289,6 +309,19 @@ Begin by calling read_session_summary to orient yourself, then proceed per the s
|
|
|
289
309
|
opts.deadlineMs ?? Date.now() + (opts.maxDurationMs ?? 20 * 60 * 1000),
|
|
290
310
|
);
|
|
291
311
|
|
|
312
|
+
if (!currentUserInteraction()?.hasAuthentication) {
|
|
313
|
+
currentUserInteraction()?.setRunControl(runDeadline, opts.onDeadlineReached);
|
|
314
|
+
attachRecordedAuthentication({
|
|
315
|
+
session,
|
|
316
|
+
sessionPath: sessionPathAbs,
|
|
317
|
+
root: pathJoin(absoluteToolDir, '.authentication'),
|
|
318
|
+
values: { ...extractedAuthValues, ...opts.teachCredentials?.values },
|
|
319
|
+
llmConfig: opts.llmConfig,
|
|
320
|
+
runDeadline,
|
|
321
|
+
report: log,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
292
325
|
// 8. Instantiate provider (or use injected one for testing).
|
|
293
326
|
// CLI providers take a different path: they don't implement Anthropic
|
|
294
327
|
// messageWithTools, so we shell out with the same toolset registered as a
|