@moda-ai/cli 1.20.0 → 1.21.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.
@@ -1,176 +1,75 @@
1
- import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
- import { readBundledSkillMd } from '../skills-bundled.js';
4
- import { resolveIntegrationSkillId } from './skill-resolver.js';
3
+ import { readBundledIndex } from '../skills-bundled.js';
4
+ import { renderCatalogListing } from './sdk-catalog.js';
5
5
  export const SDK_GUIDE_PATH = '.moda/SDK_INTEGRATION.md';
6
6
  /**
7
7
  * Write the human/agent-readable fallback guide (.moda/SDK_INTEGRATION.md).
8
- *
9
- * When a bundled integration skill matches the detected stack, the guide is
10
- * rendered from that skill's content plus the detection block (one shared
11
- * renderer with the agent-prompt path). When no skill resolves (no language
12
- * detected) the slim generic guide is used; when a skill resolved but its
13
- * content could not be loaded (missing/unreadable bundle) the generic guide is
14
- * flagged as a degraded fallback and pinned to the detected stack.
8
+ * Used when automatic SDK integration did not complete successfully.
15
9
  */
16
10
  export function writeSdkIntegrationGuide(cwd = process.cwd()) {
17
11
  const relativePath = SDK_GUIDE_PATH;
18
12
  const absolutePath = join(cwd, relativePath);
19
- const context = detectSdkGuideContext(cwd);
20
- const skillId = resolveIntegrationSkillId(context);
21
- const skillMd = skillId ? readBundledSkillMd(skillId) : null;
22
- const content = skillId && skillMd
23
- ? renderSkillBasedGuide(skillId, skillMd, context)
24
- : renderSdkIntegrationGuide(context, skillId ?? undefined);
13
+ const content = renderSdkIntegrationGuideContent();
25
14
  mkdirSync(dirname(absolutePath), { recursive: true });
26
15
  writeFileSync(absolutePath, content);
27
16
  return relativePath;
28
17
  }
29
- /** Shared renderer: detection block + the resolved skill's full content. */
30
- export function renderSkillBasedGuide(skillId, skillMd, context) {
18
+ export function renderSdkIntegrationGuideContent() {
19
+ const index = readBundledIndex();
20
+ const catalogSection = index
21
+ ? [
22
+ '## Available integration skills',
23
+ '',
24
+ renderCatalogListing(index),
25
+ '',
26
+ 'During `moda init`, Moda materializes these skills into a temporary catalog for your',
27
+ 'coding agent. To integrate by hand, read the matching skill inside the installed CLI',
28
+ 'package (`.../@moda-ai/cli/skills/integration/<id>/SKILL.md`), re-run `moda init` with',
29
+ 'a coding agent CLI installed, or follow https://docs.moda.dev/ingestion.',
30
+ '',
31
+ ]
32
+ : [
33
+ '## Available integration skills',
34
+ '',
35
+ '_The bundled skill index is unavailable in this install; use the generic steps below',
36
+ 'and https://docs.moda.dev/ingestion for stack-specific guidance._',
37
+ '',
38
+ ];
31
39
  return [
32
40
  '# Moda SDK Integration Guide',
33
41
  '',
34
- `Generated by \`moda init\` from the bundled integration skill \`${skillId}\`.`,
35
- 'If this project has the skill materialized at',
36
- `\`.claude/skills/${skillId}/SKILL.md\`, prefer reading it there (EXAMPLE.md`,
37
- 'beside it shows the finished integration).',
42
+ 'Generated by `moda init`. **The SDK integration was not applied automatically.**',
43
+ 'This checklist gets you there by hand or with your coding agent.',
38
44
  '',
39
- renderDetectionBlock(context),
45
+ ...catalogSection,
46
+ '## 1. Install the SDK',
40
47
  '',
41
- '---',
48
+ 'Install the Moda SDK for your stack with **your** package manager. If a catalog skill',
49
+ 'above matches your repo, use its exact package name and install command.',
42
50
  '',
43
- stripSkillFrontmatter(skillMd).trim(),
44
- '',
45
- ].join('\n');
46
- }
47
- /** The "What Moda Detected" section, shared by prompts and guides. */
48
- export function renderDetectionBlock(context) {
49
- const languages = context.languages.length > 0 ? context.languages.join(', ') : 'Not detected yet';
50
- const packageManagers = context.packageManagers.length > 0 ? context.packageManagers.join(', ') : 'Not detected yet';
51
- const providers = context.providerHints.length > 0 ? context.providerHints.join(', ') : 'No provider imports detected yet';
52
- const frameworks = context.frameworkHints.length > 0 ? context.frameworkHints.join(', ') : 'No agent framework detected yet';
53
- const runtimeNames = context.runtimeSummary.runtimeAgentNames.slice(0, 8);
54
- return [
55
- '## What Moda Detected',
56
- '',
57
- `- Languages: ${languages}`,
58
- `- Package managers: ${packageManagers}`,
59
- ...(context.installCommands.length > 0 ? [`- Install command(s): ${context.installCommands.join(' | ')}`] : []),
60
- `- Model providers: ${providers}`,
61
- `- Agent frameworks: ${frameworks}`,
62
- `- Harness graph: ${context.runtimeSummary.runtimeAgents} runtime agent(s), ${context.runtimeSummary.agentFamilies} agent family/families`,
63
- ...(runtimeNames.length > 0 ? [`- Runtime agents: ${runtimeNames.join(', ')}`] : []),
64
- ].join('\n');
65
- }
66
- const GUIDE_FRONTMATTER_RE = /^---\r?\n[\s\S]*?\r?\n---\r?\n/;
67
- /** Drop a SKILL.md's YAML frontmatter so only the prose body is rendered. */
68
- export function stripSkillFrontmatter(markdown) {
69
- return markdown.replace(GUIDE_FRONTMATTER_RE, '');
70
- }
71
- export function detectSdkGuideContext(cwd) {
72
- const languages = [];
73
- const installCommands = [];
74
- const packageManagers = [];
75
- const providerHints = new Set();
76
- const frameworkHints = new Set();
77
- const packageJsonPath = join(cwd, 'package.json');
78
- if (existsSync(packageJsonPath)) {
79
- languages.push('Node.js / TypeScript');
80
- const packageManager = detectNodePackageManager(cwd);
81
- packageManagers.push(packageManager);
82
- installCommands.push(nodeInstallCommand(packageManager));
83
- const packageJson = readPackageJson(packageJsonPath);
84
- for (const dependency of packageDependencyNames(packageJson)) {
85
- addDependencyHint(dependency, providerHints, frameworkHints);
86
- }
87
- }
88
- const pythonFiles = ['pyproject.toml', 'requirements.txt', 'requirements-dev.txt', 'Pipfile', 'setup.py']
89
- .filter((file) => existsSync(join(cwd, file)));
90
- if (pythonFiles.length > 0) {
91
- languages.push('Python');
92
- const packageManager = detectPythonPackageManager(cwd);
93
- packageManagers.push(packageManager);
94
- installCommands.push(pythonInstallCommand(packageManager));
95
- for (const file of pythonFiles) {
96
- const text = safeRead(join(cwd, file));
97
- addPythonHints(text, providerHints, frameworkHints);
98
- }
99
- }
100
- const sourceHints = addSourceHints(cwd, providerHints, frameworkHints);
101
- if (sourceHints.hasNodeSource && !languages.includes('Node.js / TypeScript')) {
102
- const packageManager = detectNodePackageManager(cwd);
103
- languages.push('Node.js / TypeScript');
104
- packageManagers.push(packageManager);
105
- installCommands.push(nodeInstallCommand(packageManager));
106
- }
107
- if (sourceHints.hasPythonSource && !languages.includes('Python')) {
108
- const packageManager = detectPythonPackageManager(cwd);
109
- languages.push('Python');
110
- packageManagers.push(packageManager);
111
- installCommands.push(pythonInstallCommand(packageManager));
112
- }
113
- const runtimeSummary = readRuntimeSummary(cwd);
114
- for (const provider of runtimeSummary.providers)
115
- providerHints.add(provider);
116
- for (const framework of runtimeSummary.frameworks)
117
- frameworkHints.add(framework);
118
- return {
119
- languages: unique(languages),
120
- installCommands: unique(installCommands),
121
- providerHints: unique([...providerHints]),
122
- frameworkHints: unique([...frameworkHints]),
123
- packageManagers: unique(packageManagers),
124
- runtimeSummary,
125
- };
126
- }
127
- /**
128
- * Slim last-resort guide, used when no bundled skill resolves (no language
129
- * detected) or when a skill resolved but its content could not be loaded (the
130
- * bundle is missing/unreadable). Detected stacks with readable content get the
131
- * far richer skill-based guide via renderSkillBasedGuide().
132
- *
133
- * When `resolvedSkillId` is set the intro flags the degradation and pins the
134
- * reader to the detection block instead of claiming no stack was detected —
135
- * mirrors the degraded fallback in the agent-prompt path so a successful
136
- * detection never reads as stack-less.
137
- */
138
- export function renderSdkIntegrationGuide(context, resolvedSkillId) {
139
- const installCommands = context.installCommands.length > 0
140
- ? context.installCommands
141
- : ['npm install moda-ai', 'pip install moda-ai'];
142
- const intro = resolvedSkillId
143
- ? [
144
- `Generated by \`moda init\`. This repo's stack resolved to the bundled integration skill`,
145
- `\`${resolvedSkillId}\`, but its content could not be loaded (the skill bundle is missing`,
146
- 'or unreadable in this install), so this is the general checklist. Tailor every step to',
147
- 'the stack in "What Moda Detected" below rather than treating this as a repo with no',
148
- 'detected stack.',
149
- ]
150
- : [
151
- 'Generated by `moda init`. No specific stack was detected, so this is the',
152
- 'general checklist; the full per-framework references live at',
153
- 'https://docs.moda.dev/ingestion.',
154
- ];
155
- return `${[
156
- '# Moda SDK Integration Guide',
51
+ 'Examples (adapt to your stack):',
157
52
  '',
158
- ...intro,
53
+ 'Node.js / TypeScript:',
159
54
  '',
160
- renderDetectionBlock(context),
55
+ '```bash',
56
+ 'npm install moda-ai # or: bun add / pnpm add / yarn add',
57
+ '```',
161
58
  '',
162
- '## 1. Install The SDK',
59
+ 'Python:',
163
60
  '',
164
- 'Use the package manager this repo already uses:',
61
+ '```bash',
62
+ 'pip install moda-ai # or: uv add / poetry add',
63
+ '```',
165
64
  '',
166
- ...installCommands.flatMap((command) => ['```bash', command, '```', '']),
167
- 'Do not paste `MODA_API_KEY` into source or `.env` files. Keep it in your deployment environment, secret manager, or local shell.',
65
+ 'Do not paste `MODA_API_KEY` into source or `.env` files. Keep it in your deployment',
66
+ 'environment, secret manager, or local shell.',
168
67
  '',
169
- '## 2. Initialize Moda Once At Startup',
68
+ '## 2. Initialize Moda before LLM clients',
170
69
  '',
171
70
  'Initialize before any LLM client is created.',
172
71
  '',
173
- 'Node.js / TypeScript:',
72
+ 'Node.js / TypeScript (example):',
174
73
  '',
175
74
  '```ts',
176
75
  "import { Moda } from 'moda-ai';",
@@ -178,7 +77,7 @@ export function renderSdkIntegrationGuide(context, resolvedSkillId) {
178
77
  'await Moda.init(process.env.MODA_API_KEY!);',
179
78
  '```',
180
79
  '',
181
- 'Python:',
80
+ 'Python (example):',
182
81
  '',
183
82
  '```python',
184
83
  'import os',
@@ -188,166 +87,45 @@ export function renderSdkIntegrationGuide(context, resolvedSkillId) {
188
87
  'moda.init(os.environ["MODA_API_KEY"])',
189
88
  '```',
190
89
  '',
191
- '## 3. Set Conversation And User Context',
90
+ '## 3. Set conversation and user context',
192
91
  '',
193
- 'Set a stable conversation id before each LLM call, and a user id when one user can be identified. For concurrent request handlers, use the scoped context helpers from the SDK instead of setting global context across overlapping requests.',
92
+ 'Set a stable conversation id before each LLM call, and a user id when one user can be',
93
+ 'identified. For concurrent request handlers, use scoped context helpers from the SDK',
94
+ 'instead of setting global context across overlapping requests.',
194
95
  '',
195
- 'Node.js / TypeScript:',
96
+ 'Node.js / TypeScript (example):',
196
97
  '',
197
98
  '```ts',
198
99
  'Moda.conversationId = sessionId;',
199
100
  'Moda.userId = userId;',
200
101
  '```',
201
102
  '',
202
- 'Python:',
103
+ 'Python (example):',
203
104
  '',
204
105
  '```python',
205
106
  'moda.conversation_id = session_id',
206
107
  'moda.user_id = user_id',
207
108
  '```',
208
109
  '',
209
- '## 4. Flush Before Exit',
110
+ '## 4. Flush before exit',
210
111
  '',
211
112
  'Node.js / TypeScript: `await Moda.flush();` — Python: `moda.flush()`.',
212
113
  '',
213
114
  '## 5. Validate',
214
115
  '',
116
+ 'Tenant health (does not prove this integration by itself):',
117
+ '',
215
118
  '```bash',
216
119
  'moda doctor --online --json',
217
120
  '```',
218
121
  '',
219
- 'The check should show recent traces/logs/runs. If it does not, confirm `MODA_API_KEY` is available at runtime and that Moda initialization runs before the first LLM client is created.',
122
+ 'Exact-trace confirmation: send one request through your app with a known conversation id,',
123
+ 'then run `moda audit <that-id>` — you should see your llm span(s).',
220
124
  '',
221
- ].join('\n')}`;
222
- }
223
- function detectNodePackageManager(cwd) {
224
- if (existsSync(join(cwd, 'bun.lock')) || existsSync(join(cwd, 'bun.lockb')))
225
- return 'bun';
226
- if (existsSync(join(cwd, 'pnpm-lock.yaml')))
227
- return 'pnpm';
228
- if (existsSync(join(cwd, 'yarn.lock')))
229
- return 'yarn';
230
- return 'npm';
231
- }
232
- function detectPythonPackageManager(cwd) {
233
- if (existsSync(join(cwd, 'uv.lock')))
234
- return 'uv';
235
- if (existsSync(join(cwd, 'poetry.lock')))
236
- return 'poetry';
237
- return 'pip';
238
- }
239
- function nodeInstallCommand(packageManager) {
240
- if (packageManager === 'bun')
241
- return 'bun add moda-ai';
242
- if (packageManager === 'pnpm')
243
- return 'pnpm add moda-ai';
244
- if (packageManager === 'yarn')
245
- return 'yarn add moda-ai';
246
- return 'npm install moda-ai';
247
- }
248
- function pythonInstallCommand(packageManager) {
249
- if (packageManager === 'uv')
250
- return 'uv add moda-ai';
251
- if (packageManager === 'poetry')
252
- return 'poetry add moda-ai';
253
- return 'pip install moda-ai';
254
- }
255
- function readPackageJson(path) {
256
- try {
257
- const parsed = JSON.parse(readFileSync(path, 'utf8'));
258
- return isRecord(parsed) ? parsed : {};
259
- }
260
- catch {
261
- return {};
262
- }
263
- }
264
- function packageDependencyNames(packageJson) {
265
- const names = new Set();
266
- for (const key of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
267
- const deps = packageJson[key];
268
- if (!isRecord(deps))
269
- continue;
270
- for (const name of Object.keys(deps))
271
- names.add(name);
272
- }
273
- return [...names];
274
- }
275
- function addDependencyHint(dependency, providers, frameworks) {
276
- const name = dependency.toLowerCase();
277
- if (name === 'openai' || name.includes('@ai-sdk/openai'))
278
- providers.add('OpenAI');
279
- if (name === '@anthropic-ai/sdk' || name.includes('@ai-sdk/anthropic'))
280
- providers.add('Anthropic');
281
- if (name === 'ai' || name.startsWith('@ai-sdk/'))
282
- frameworks.add('Vercel AI SDK');
283
- if (name.includes('langchain') || name.includes('langgraph'))
284
- frameworks.add('LangChain / LangGraph');
285
- if (name.includes('crewai'))
286
- frameworks.add('CrewAI');
287
- if (name.includes('autogen'))
288
- frameworks.add('AutoGen');
289
- }
290
- function addPythonHints(text, providers, frameworks) {
291
- const lower = text.toLowerCase();
292
- if (/\bopenai\b/.test(lower))
293
- providers.add('OpenAI');
294
- if (/\banthropic\b/.test(lower))
295
- providers.add('Anthropic');
296
- if (/\blangchain\b|\blanggraph\b/.test(lower))
297
- frameworks.add('LangChain / LangGraph');
298
- if (/claude[-_]agent[-_]sdk/.test(lower))
299
- frameworks.add('Claude Agent SDK');
300
- if (/\bcrewai\b/.test(lower))
301
- frameworks.add('CrewAI');
302
- if (/\bautogen\b/.test(lower))
303
- frameworks.add('AutoGen');
304
- }
305
- function addSourceHints(cwd, providers, frameworks) {
306
- let hasNodeSource = false;
307
- let hasPythonSource = false;
308
- for (const dir of ['src', 'app', 'lib', 'agents', 'python']) {
309
- const root = join(cwd, dir);
310
- if (!existsSync(root))
311
- continue;
312
- for (const file of listShallowSourceFiles(root).slice(0, 80)) {
313
- if (/\.(ts|tsx|js|jsx|mjs)$/i.test(file))
314
- hasNodeSource = true;
315
- if (/\.py$/i.test(file))
316
- hasPythonSource = true;
317
- addPythonHints(safeRead(file), providers, frameworks);
318
- }
319
- }
320
- return { hasNodeSource, hasPythonSource };
321
- }
322
- function listShallowSourceFiles(root) {
323
- const files = [];
324
- const stack = [{ path: root, depth: 0 }];
325
- while (stack.length > 0 && files.length < 120) {
326
- const current = stack.pop();
327
- if (!current)
328
- continue;
329
- let entries;
330
- try {
331
- entries = readdirSync(current.path, { withFileTypes: true });
332
- }
333
- catch {
334
- continue;
335
- }
336
- for (const entry of entries) {
337
- const path = join(current.path, entry.name);
338
- if (entry.isDirectory()) {
339
- if (current.depth < 2 && !['node_modules', '.git', 'dist', 'build', '.venv'].includes(entry.name)) {
340
- stack.push({ path, depth: current.depth + 1 });
341
- }
342
- continue;
343
- }
344
- if (/\.(ts|tsx|js|jsx|mjs|py|md|toml|json|ya?ml)$/i.test(entry.name))
345
- files.push(path);
346
- }
347
- }
348
- return files;
125
+ ].join('\n');
349
126
  }
350
- function readRuntimeSummary(cwd) {
127
+ /** Read optional harness discovery context from `.moda/harness.json`. */
128
+ export function readRuntimeSummary(cwd) {
351
129
  const empty = {
352
130
  runtimeAgents: 0,
353
131
  agentFamilies: 0,
@@ -384,16 +162,22 @@ function readRuntimeSummary(cwd) {
384
162
  return empty;
385
163
  }
386
164
  }
387
- function safeRead(path) {
388
- try {
389
- return readFileSync(path, 'utf8');
165
+ export function renderRuntimeSummaryBlock(summary) {
166
+ const runtimeNames = summary.runtimeAgentNames.slice(0, 8);
167
+ const lines = [
168
+ `- Runtime agents: ${summary.runtimeAgents}`,
169
+ `- Agent families: ${summary.agentFamilies}`,
170
+ ];
171
+ if (summary.frameworks.length > 0) {
172
+ lines.push(`- Frameworks: ${summary.frameworks.join(', ')}`);
390
173
  }
391
- catch {
392
- return '';
174
+ if (summary.providers.length > 0) {
175
+ lines.push(`- Providers: ${summary.providers.join(', ')}`);
393
176
  }
394
- }
395
- function unique(values) {
396
- return [...new Set(values.filter(Boolean))];
177
+ if (runtimeNames.length > 0) {
178
+ lines.push(`- Runtime agent names: ${runtimeNames.join(', ')}`);
179
+ }
180
+ return lines.join('\n');
397
181
  }
398
182
  function isRecord(value) {
399
183
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -1,54 +1,53 @@
1
- import { type CodingAgentAdapter, type CodingAgentEvent } from '../harness.js';
1
+ import { type CodingAgentAdapter, type CodingAgentEvent, runCodingAgent } from '../harness.js';
2
+ import { type SdkAgentResult } from './sdk-protocol.js';
3
+ import { verifyExactTrace, type VerificationEvidence } from './sdk-verification.js';
4
+ import { readRuntimeSummary } from './sdk-guide.js';
2
5
  export { describeCodingAgentEvent } from '../harness.js';
3
- import { type SdkGuideContext } from './sdk-guide.js';
4
- export type SdkIntegrationResult = {
5
- status: 'integrated';
6
- adapter: CodingAgentAdapter;
7
- skillId?: string;
8
- } | {
9
- status: 'no-agent';
10
- } | {
11
- status: 'failed';
12
- adapter: CodingAgentAdapter;
13
- detail: string;
14
- };
6
+ export type SdkIntegrationStatus = 'integrated_verified' | 'needs_human_input' | 'repository_checks_failed' | 'smoke_execution_failed' | 'telemetry_not_observed' | 'nothing_to_integrate' | 'agent_failed' | 'agent_unavailable' | 'cancelled';
7
+ export interface SdkIntegrationOutcome {
8
+ status: SdkIntegrationStatus;
9
+ adapter?: CodingAgentAdapter;
10
+ verification_id?: string;
11
+ verification?: VerificationEvidence;
12
+ agent_result?: SdkAgentResult;
13
+ repair_attempts: number;
14
+ security_findings?: string[];
15
+ installed_skill_ids?: string[];
16
+ detail?: string;
17
+ }
15
18
  export interface SdkIntegrationOptions {
16
19
  cwd?: string;
17
- /** Explicit adapter override (e.g. from --analyst); otherwise best-ranked installed CLI. */
18
20
  adapter?: CodingAgentAdapter;
19
- /** Stream the agent's progress to the user (human terminals only). */
20
21
  human?: boolean;
21
22
  onProgress?: (message: string) => void;
22
- /**
23
- * Receive the structured coding-agent stream events incrementally (tool use,
24
- * commands, agent text) so callers like the init progress board can render
25
- * their own live view. Providing it enables the streaming invocation even
26
- * when `human` is false.
27
- */
28
23
  onEvent?: (event: CodingAgentEvent) => void;
24
+ onPhase?: (phase: 'investigating' | 'verifying' | 'repairing', message: string) => void;
25
+ apiKey?: string;
26
+ ingestUrl?: string;
27
+ maxRepairAttempts?: number;
28
+ verifyTimeoutMs?: number;
29
+ runAgent?: typeof runCodingAgent;
30
+ verify?: typeof verifyExactTrace;
31
+ fetchAudit?: (id: string) => Promise<unknown>;
32
+ }
33
+ type RepairableClassification = 'telemetry_not_observed' | 'repository_checks_failed' | 'smoke_execution_failed' | 'protocol_violation' | 'failed';
34
+ export declare function runSdkIntegration(options?: SdkIntegrationOptions): Promise<SdkIntegrationOutcome>;
35
+ export interface SdkIntegrationPromptOptions {
36
+ catalogDir: string;
37
+ catalogListing: string;
38
+ verificationId: string;
39
+ harnessSummary?: ReturnType<typeof readRuntimeSummary>;
29
40
  }
30
- /**
31
- * Pick an installed coding-agent CLI and run it, in write mode, to integrate
32
- * the Moda SDK into the repo. Returns `no-agent` (without throwing) when no
33
- * CLI is installed so the caller can fall back to writing the static guide.
34
- */
35
- export declare function runSdkIntegration(options?: SdkIntegrationOptions): Promise<SdkIntegrationResult>;
36
- /** How the resolved integration skill (if any) reaches the agent prompt. */
37
- export interface SdkIntegrationPromptSkill {
38
- /** Skill materialized to `.claude/skills/<id>/` — point the agent at it. */
39
- installedSkillId?: string;
40
- /** Resolved skill we could read but not materialize — inline its content. */
41
- inlineSkill?: {
42
- skillId: string;
43
- markdown: string;
44
- };
45
- /**
46
- * The skill the detected stack resolved to, if any. Set even when neither
47
- * install nor inline succeeded (e.g. the bundle is entirely absent) so the
48
- * generic fallback can flag the degradation and tell the agent to tailor the
49
- * checklist to the detected stack instead of treating it as stack-less.
50
- */
51
- resolvedSkillId?: string;
41
+ export declare function renderSdkIntegrationPrompt(opts: SdkIntegrationPromptOptions): string;
42
+ export interface SdkRepairPromptOptions extends SdkIntegrationPromptOptions {
43
+ attempt: number;
44
+ maxAttempts: number;
45
+ classification: RepairableClassification;
46
+ previousResult?: SdkAgentResult;
47
+ verification?: VerificationEvidence;
48
+ securityFindings?: string[];
52
49
  }
53
- export declare function renderSdkIntegrationPrompt(context: SdkGuideContext, skill?: SdkIntegrationPromptSkill): string;
50
+ export declare function renderSdkRepairPrompt(opts: SdkRepairPromptOptions): string;
51
+ export declare function parseGitDeltaPaths(deltaLines: string[]): string[];
52
+ export declare function redactSecretText(text: string, apiKey?: string): string;
54
53
  //# sourceMappingURL=sdk-integration.d.ts.map