@netlify/agent-runner-cli 1.152.0-EX-2670.0 → 1.152.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/agent-runner-cli",
3
3
  "type": "module",
4
- "version": "1.152.0-EX-2670.0",
4
+ "version": "1.152.0",
5
5
  "description": "CLI tool for running Netlify agents",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -0,0 +1,71 @@
1
+ import { readFileSync, appendFileSync, writeFileSync, existsSync } from 'node:fs'
2
+ import path from 'node:path'
3
+
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
6
+ import { createJiti } from 'jiti'
7
+
8
+ const jiti = createJiti(import.meta.url, { interopDefault: true })
9
+ const { ASK_TOOL_DESCRIPTION, askQuestionsShape, formatAskAnswerBlock } = await jiti.import(
10
+ '../../src/lib/ask-schema.js',
11
+ )
12
+ const {
13
+ ASK_LOG_FILENAME,
14
+ ASK_SERVER_READY_FILENAME,
15
+ CANNED_ANSWERS_FILENAME,
16
+ INTERACTIONS_MCP_SERVER,
17
+ UNANTICIPATED_QUESTION_ANSWER,
18
+ } = await jiti.import('../../scenarios/helpers/interactions-stub-contract.js')
19
+
20
+ const WORKSPACE = process.cwd()
21
+ const CANNED_ANSWERS_FILE = path.join(WORKSPACE, CANNED_ANSWERS_FILENAME)
22
+ const ASK_LOG_FILE = path.join(WORKSPACE, ASK_LOG_FILENAME)
23
+ const ASK_SERVER_READY_FILE = path.join(WORKSPACE, ASK_SERVER_READY_FILENAME)
24
+
25
+ const PREAMBLE = 'The user answered, and the run has resumed — the pause is over.'
26
+
27
+ const loadCannedAnswersOrThrow = () => {
28
+ if (!existsSync(CANNED_ANSWERS_FILE)) {
29
+ throw new Error(
30
+ `${CANNED_ANSWERS_FILE} is missing. scenarioCannedAnswersSetup should have written it into the workspace (cwd=${WORKSPACE}).`,
31
+ )
32
+ }
33
+ const parsed = JSON.parse(readFileSync(CANNED_ANSWERS_FILE, 'utf8'))
34
+ if (!Array.isArray(parsed.answers) || parsed.answers.length === 0) {
35
+ throw new Error(`${CANNED_ANSWERS_FILE} has no non-empty "answers" array.`)
36
+ }
37
+ return parsed.answers
38
+ }
39
+
40
+ const logAskCall = (questions) => {
41
+ appendFileSync(ASK_LOG_FILE, `${JSON.stringify({ at: new Date().toISOString(), questions })}\n`)
42
+ }
43
+
44
+ const server = new McpServer({ name: INTERACTIONS_MCP_SERVER, version: '1.0.0' })
45
+
46
+ server.registerTool(
47
+ 'ask',
48
+ {
49
+ description: ASK_TOOL_DESCRIPTION,
50
+ inputSchema: askQuestionsShape,
51
+ },
52
+ ({ questions }) => {
53
+ logAskCall(questions)
54
+ const answersByPosition = loadCannedAnswersOrThrow()
55
+ const pairs = questions.map((question, index) => ({
56
+ question: question.question,
57
+ answer: answersByPosition[index] ?? UNANTICIPATED_QUESTION_ANSWER,
58
+ }))
59
+ return { content: [{ type: 'text', text: formatAskAnswerBlock(pairs, { preamble: PREAMBLE }) }] }
60
+ },
61
+ )
62
+
63
+ const shutdown = () => process.exit(0)
64
+ process.stdin.on('close', shutdown)
65
+ process.stdin.on('end', shutdown)
66
+
67
+ loadCannedAnswersOrThrow()
68
+
69
+ await server.connect(new StdioServerTransport())
70
+
71
+ writeFileSync(ASK_SERVER_READY_FILE, `${new Date().toISOString()}\n`)