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.
Files changed (43) hide show
  1. package/README.md +2 -0
  2. package/package.json +4 -2
  3. package/prompts/audit-agent.md +4 -2
  4. package/prompts/auth-compile-agent.md +149 -158
  5. package/prompts/build-planning.md +14 -9
  6. package/prompts/compile-agent.md +46 -23
  7. package/prompts/live-verifier-agent.md +101 -0
  8. package/prompts/playbook-compilation.md +8 -1
  9. package/prompts/tool-candidate-detection.md +9 -29
  10. package/src/cli.ts +83 -1
  11. package/src/imprint/audit.ts +219 -20
  12. package/src/imprint/auth-compile-agent.ts +215 -155
  13. package/src/imprint/auth-compile-tools.ts +300 -118
  14. package/src/imprint/auth-verifier.ts +167 -180
  15. package/src/imprint/backend-cache.ts +18 -11
  16. package/src/imprint/backend-ladder.ts +225 -177
  17. package/src/imprint/build-plan.ts +3 -8
  18. package/src/imprint/cdp-browser-fetch.ts +930 -83
  19. package/src/imprint/claude-cli-compile.ts +46 -20
  20. package/src/imprint/codex-cli-compile.ts +436 -139
  21. package/src/imprint/compile-agent-types.ts +15 -10
  22. package/src/imprint/compile-agent.ts +88 -28
  23. package/src/imprint/compile-tools.ts +228 -39
  24. package/src/imprint/compile-verification.ts +187 -0
  25. package/src/imprint/compile.ts +71 -2
  26. package/src/imprint/credential-store.ts +57 -44
  27. package/src/imprint/emit.ts +3 -1
  28. package/src/imprint/freeform-redact.ts +27 -6
  29. package/src/imprint/live-verifier.ts +1665 -0
  30. package/src/imprint/llm.ts +22 -3
  31. package/src/imprint/login.ts +107 -25
  32. package/src/imprint/mcp-compile-server.ts +447 -114
  33. package/src/imprint/mcp-live-verifier-server.ts +359 -0
  34. package/src/imprint/mcp-server.ts +116 -35
  35. package/src/imprint/probe-backends.ts +88 -7
  36. package/src/imprint/recording-request.ts +36 -0
  37. package/src/imprint/request-capture.ts +40 -17
  38. package/src/imprint/runtime.ts +490 -337
  39. package/src/imprint/teach-state.ts +36 -2
  40. package/src/imprint/teach.ts +302 -146
  41. package/src/imprint/tool-candidates.ts +8 -10
  42. package/src/imprint/tool-loader.ts +12 -4
  43. package/src/imprint/types.ts +137 -68
@@ -29,7 +29,11 @@ import {
29
29
  relativeToLocalSite,
30
30
  resolveLocalSitePath,
31
31
  } from './paths.ts';
32
- import type { SharedCompileContext, ToolCandidate } from './tool-candidates.ts';
32
+ import {
33
+ type SharedCompileContext,
34
+ SharedCompileContextSchema,
35
+ type ToolCandidate,
36
+ } from './tool-candidates.ts';
33
37
 
34
38
  export const TEACH_STEPS = [
35
39
  'record',
@@ -65,6 +69,14 @@ export interface WorkflowState {
65
69
  * asserts a tool imports the modules the plan assigned it; entries with
66
70
  * `verified: false` are excluded from that assertion. */
67
71
  sharedModules?: SharedModuleManifestEntry[];
72
+ /** A verified auth prerequisite that may be reused by a resumed generate.
73
+ * Both hashes must still match, otherwise teach reruns auth compilation. */
74
+ authCompletion?: {
75
+ toolName: string;
76
+ buildPlanHash: string;
77
+ workflowHash: string;
78
+ completedAt: string;
79
+ };
68
80
  /** Non-fatal flags raised by upstream stages that downstream stages (and
69
81
  * the user) should know about. Currently used by the redact stage to
70
82
  * record `'credentials_not_paired'` when a password-shaped body field
@@ -93,6 +105,11 @@ export function loadTeachState(site: string): TeachState {
93
105
  if (!existsSync(loadPath)) return { workflows: {} };
94
106
  try {
95
107
  const state = JSON.parse(readFileSync(loadPath, 'utf8')) as TeachState;
108
+ for (const workflow of Object.values(state.workflows)) {
109
+ if (!workflow.sharedContext) continue;
110
+ const parsed = SharedCompileContextSchema.safeParse(workflow.sharedContext);
111
+ workflow.sharedContext = parsed.success ? parsed.data : undefined;
112
+ }
96
113
  return isLegacy ? normalizeLegacyTeachState(site, state) : state;
97
114
  } catch {
98
115
  return { workflows: {} };
@@ -393,19 +410,31 @@ interface MultiToolResumeSelection {
393
410
  candidate: WorkflowState['candidate'];
394
411
  sharedContext: WorkflowState['sharedContext'];
395
412
  }[];
396
- skipped: { workflowKey: string; reason: 'different-recording' | 'not-resumable' }[];
413
+ skipped: {
414
+ workflowKey: string;
415
+ reason: 'different-recording' | 'not-resumable' | 'not-in-build-plan';
416
+ }[];
397
417
  }
398
418
 
399
419
  export function selectMultiToolResumePlans(
400
420
  state: TeachState,
401
421
  targetWorkflowKey: string,
402
422
  fromStep: TeachStep,
423
+ opts?: {
424
+ noInteractive?: boolean;
425
+ allTools?: boolean;
426
+ plannedToolNames?: ReadonlySet<string>;
427
+ },
403
428
  ): MultiToolResumeSelection {
404
429
  const target = state.workflows[targetWorkflowKey];
405
430
  const plans: MultiToolResumeSelection['plans'] = [];
406
431
  const skipped: MultiToolResumeSelection['skipped'] = [];
407
432
  for (const [key, ws] of Object.entries(state.workflows)) {
408
433
  if (key.startsWith('_pending_') || !ws.candidate) continue;
434
+ if (opts?.plannedToolNames && !opts.plannedToolNames.has(ws.candidate.toolName)) {
435
+ skipped.push({ workflowKey: key, reason: 'not-in-build-plan' });
436
+ continue;
437
+ }
409
438
  if (target && ws.sessionPath !== target.sessionPath) {
410
439
  skipped.push({ workflowKey: key, reason: 'different-recording' });
411
440
  continue;
@@ -416,6 +445,11 @@ export function selectMultiToolResumePlans(
416
445
  }
417
446
  plans.push({ workflowKey: key, candidate: ws.candidate, sharedContext: ws.sharedContext });
418
447
  }
448
+ if (opts?.noInteractive && !opts.allTools && plans.length > 1) {
449
+ const primary = plans.find((plan) => plan.candidate?.primary);
450
+ const selected = primary ?? plans.find((plan) => plan.workflowKey === targetWorkflowKey);
451
+ return { plans: selected ? [selected] : [], skipped };
452
+ }
419
453
  return { plans, skipped };
420
454
  }
421
455