@t4h.framework/cli 0.0.0-experimental-29d0277 → 0.0.0-experimental-20261009202408
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/CHANGELOG.md +21 -0
- package/dist/bin/bin.js +1 -20
- package/dist/bin/bin.js.map +1 -1
- package/dist/commands/ai/ai-bootstrap.js +48 -183
- package/dist/commands/ai/ai-bootstrap.js.map +1 -1
- package/dist/commands/build/build.js +2 -6
- package/dist/commands/build/build.js.map +1 -1
- package/dist/commands/dev/dev.js +1 -8
- package/dist/commands/dev/dev.js.map +1 -1
- package/package.json +2 -11
- package/LICENSE +0 -21
- package/dist/commands/ai/ai-hook.js +0 -84
- package/dist/commands/ai/ai-hook.js.map +0 -1
- package/dist/commands/ai/tools/agent-instructions.js +0 -75
- package/dist/commands/ai/tools/agent-instructions.js.map +0 -1
- package/dist/commands/ai/tools/agent-settings.js +0 -56
- package/dist/commands/ai/tools/agent-settings.js.map +0 -1
- package/dist/commands/ai/tools/assets-lock.js +0 -34
- package/dist/commands/ai/tools/assets-lock.js.map +0 -1
- package/dist/commands/check/check.js +0 -185
- package/dist/commands/check/check.js.map +0 -1
- package/dist/commands/mcp/mcp-server.js +0 -235
- package/dist/commands/mcp/mcp-server.js.map +0 -1
- package/dist/commands/mcp/mcp-tools.js +0 -283
- package/dist/commands/mcp/mcp-tools.js.map +0 -1
- package/dist/commands/mcp/mcp.js +0 -71
- package/dist/commands/mcp/mcp.js.map +0 -1
- package/dist/commands/runtime/runtime.js +0 -143
- package/dist/commands/runtime/runtime.js.map +0 -1
- package/dist/commands/workflows/workflows.js +0 -166
- package/dist/commands/workflows/workflows.js.map +0 -1
- package/dist/tools/debug-log-option.js +0 -13
- package/dist/tools/debug-log-option.js.map +0 -1
- package/dist/tools/dev-server-client.js +0 -261
- package/dist/tools/dev-server-client.js.map +0 -1
- package/dist/tools/load-dev.js +0 -23
- package/dist/tools/load-dev.js.map +0 -1
- package/dist/tools/project-package.js +0 -67
- package/dist/tools/project-package.js.map +0 -1
- package/dist/tools/project-scripts.js +0 -53
- package/dist/tools/project-scripts.js.map +0 -1
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
export const INSTRUCTIONS_BEGIN = '<!-- framework:begin — managed by `framework ai-bootstrap`; edits inside this block are overwritten -->';
|
|
3
|
-
export const INSTRUCTIONS_END = '<!-- framework:end -->';
|
|
4
|
-
/** How to call the project's `framework` binary with its package manager. */
|
|
5
|
-
export const frameworkBin = (packageManager) => ({
|
|
6
|
-
yarn: 'yarn framework',
|
|
7
|
-
pnpm: 'pnpm exec framework',
|
|
8
|
-
npm: 'npx framework',
|
|
9
|
-
})[packageManager];
|
|
10
|
-
export function buildAgentInstructions({ packageManager, packages, skillsDir, mcp, }) {
|
|
11
|
-
const bin = frameworkBin(packageManager);
|
|
12
|
-
const has = (name) => packages.some(entry => entry.name === name);
|
|
13
|
-
const lines = [
|
|
14
|
-
INSTRUCTIONS_BEGIN,
|
|
15
|
-
'## T4H Framework',
|
|
16
|
-
'',
|
|
17
|
-
`This is a T4H Framework app. Packages: ${packages
|
|
18
|
-
.map(({ name, version }) => `\`${name}${version ? `@${version}` : ''}\``)
|
|
19
|
-
.join(', ')}.`,
|
|
20
|
-
'',
|
|
21
|
-
'### Workflow code must replay',
|
|
22
|
-
'',
|
|
23
|
-
'A workflow body runs again from its recorded history on every step, so it must make the same calls in the same order every time.',
|
|
24
|
-
'',
|
|
25
|
-
'- No `Date.now()`, `new Date()` without arguments, `Math.random()`, random UUIDs, timers or `process.env` inside a workflow. Take `now` from the input and move time forward with `sleep` (`@t4h.framework/sleep`).',
|
|
26
|
-
'- Side effects only through framework activities (`@t4h.framework/http`, `fs`, `orm`, `sftp`, `smtp`, `sleep`…), never `fetch`, `node:fs` or sockets in a workflow.',
|
|
27
|
-
'- Never declare a `SyncActivity`/`AsyncActivity` in the project: it works in dev and the production runtime rejects it. Compose framework primitives instead.',
|
|
28
|
-
'- A `try/catch` in a workflow rethrows `PushActivity` first: `if (error instanceof PushActivity) throw error`. It is how a run suspends, not a failure.',
|
|
29
|
-
'- Configuration comes from `EnvDesign`, never `process.env`.',
|
|
30
|
-
'- Reordering, removing or inserting activities before the ones a run in progress already recorded makes that run fail with `WorkflowHistoryMismatchError`. Appending steps is safe; otherwise ship a new workflow or start the runs again.',
|
|
31
|
-
'',
|
|
32
|
-
'### Verify before saying it is done',
|
|
33
|
-
'',
|
|
34
|
-
`- \`${bin} check\` type-checks, lints, boots the app and validates its workflows, then runs the tests. \`--json\` prints one verdict; \`--only types,lint\` is the fast loop.`,
|
|
35
|
-
has('@t4h.framework/eslint-plugin')
|
|
36
|
-
? '- `@t4h.framework/eslint-plugin` enforces the rules above; fix its errors instead of disabling them.'
|
|
37
|
-
: '- Add `@t4h.framework/eslint-plugin` to the ESLint config to enforce the rules above.',
|
|
38
|
-
'- Unit-test workflows with `TestWorkflowEnvironment` from `@t4h.framework/core/testing`; it also checks that they replay.',
|
|
39
|
-
'',
|
|
40
|
-
'### Run and inspect workflows',
|
|
41
|
-
'',
|
|
42
|
-
...(mcp
|
|
43
|
-
? [
|
|
44
|
-
'- Prefer the `framework` MCP server: list, describe and run workflows, read runs (activities, logs), advance waiting activities to skip a `sleep`, and read the runtime status.',
|
|
45
|
-
]
|
|
46
|
-
: []),
|
|
47
|
-
`- \`${bin} workflows\` lists the workflows, \`${bin} workflows <id>\` prints the input schema, \`${bin} workflows <id> run --input '<json>' --trace\` runs one and prints JSON (exit 0 fulfilled, 1 rejected, 2 timed out).`,
|
|
48
|
-
`- Runs that sleep or start children need the dev server: \`${bin} dev\`, then \`run --attach\`. \`${bin} runtime status|watch --json\` shows its queue and events.`,
|
|
49
|
-
'',
|
|
50
|
-
`Each package's skill in \`${skillsDir}/framework-*\` documents its API; read it before using the package.`,
|
|
51
|
-
INSTRUCTIONS_END,
|
|
52
|
-
];
|
|
53
|
-
return lines.join('\n');
|
|
54
|
-
}
|
|
55
|
-
/** Replaces the managed block of the file, or appends it; the rest is the project's. */
|
|
56
|
-
export function upsertManagedBlock(content, block) {
|
|
57
|
-
const begin = content.indexOf(INSTRUCTIONS_BEGIN);
|
|
58
|
-
const end = content.indexOf(INSTRUCTIONS_END, begin);
|
|
59
|
-
if (begin !== -1 && end !== -1)
|
|
60
|
-
return (content.slice(0, begin) +
|
|
61
|
-
block +
|
|
62
|
-
content.slice(end + INSTRUCTIONS_END.length));
|
|
63
|
-
if (!content.trim())
|
|
64
|
-
return `${block}\n`;
|
|
65
|
-
return `${content.trimEnd()}\n\n${block}\n`;
|
|
66
|
-
}
|
|
67
|
-
export async function writeAgentInstructions(filePath, block) {
|
|
68
|
-
const current = await fs.readFile(filePath, 'utf8').catch(() => null);
|
|
69
|
-
const next = upsertManagedBlock(current ?? '', block);
|
|
70
|
-
if (current === next)
|
|
71
|
-
return 'unchanged';
|
|
72
|
-
await fs.writeFile(filePath, next);
|
|
73
|
-
return current === null ? 'created' : 'updated';
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=agent-instructions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../../../src/commands/ai/tools/agent-instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
async function readJson(filePath) {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
6
|
-
}
|
|
7
|
-
catch (error) {
|
|
8
|
-
if (error.code === 'ENOENT')
|
|
9
|
-
return {};
|
|
10
|
-
throw new Error(`${filePath} is not valid JSON; fix it and run again`, {
|
|
11
|
-
cause: error,
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
async function writeJson(filePath, value) {
|
|
16
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
17
|
-
await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Adds the hooks to a Claude Code settings object, keeping the project's own;
|
|
21
|
-
* a hook whose command is already there is not added twice.
|
|
22
|
-
*/
|
|
23
|
-
export function mergeClaudeHooks(settings, entries) {
|
|
24
|
-
const hooks = { ...(settings.hooks ?? {}) };
|
|
25
|
-
for (const { event, matcher, command } of entries) {
|
|
26
|
-
const groups = [...(hooks[event] ?? [])];
|
|
27
|
-
const exists = groups.some(group => (group.hooks ?? []).some((hook) => hook.command === command));
|
|
28
|
-
if (!exists)
|
|
29
|
-
groups.push({
|
|
30
|
-
...(matcher ? { matcher } : {}),
|
|
31
|
-
hooks: [{ type: 'command', command }],
|
|
32
|
-
});
|
|
33
|
-
hooks[event] = groups;
|
|
34
|
-
}
|
|
35
|
-
return { ...settings, hooks };
|
|
36
|
-
}
|
|
37
|
-
export async function installClaudeHooks(settingsPath, entries) {
|
|
38
|
-
const settings = await readJson(settingsPath);
|
|
39
|
-
const next = mergeClaudeHooks(settings, entries);
|
|
40
|
-
if (JSON.stringify(next) === JSON.stringify(settings))
|
|
41
|
-
return false;
|
|
42
|
-
await writeJson(settingsPath, next);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
/** Registers the `framework` MCP server in a `.mcp.json`-shaped file. */
|
|
46
|
-
export async function installMcpServer(configPath, server) {
|
|
47
|
-
const config = await readJson(configPath);
|
|
48
|
-
if (config.mcpServers?.framework)
|
|
49
|
-
return false;
|
|
50
|
-
await writeJson(configPath, {
|
|
51
|
-
...config,
|
|
52
|
-
mcpServers: { ...(config.mcpServers ?? {}), framework: server },
|
|
53
|
-
});
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=agent-settings.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-settings.js","sourceRoot":"","sources":["../../../../src/commands/ai/tools/agent-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { createDirectorySnapshot } from './create-directory-snapshot.js';
|
|
5
|
-
import { isDirectory } from './is-directory.js';
|
|
6
|
-
import { pathExists } from './path-exists.js';
|
|
7
|
-
export const ASSETS_LOCK_PATH = path.join('.framework', 'ai-assets.lock.json');
|
|
8
|
-
/** A content hash of a file or a whole directory; null when it doesn't exist. */
|
|
9
|
-
export async function hashAsset(assetPath) {
|
|
10
|
-
if (!(await pathExists(assetPath)))
|
|
11
|
-
return null;
|
|
12
|
-
const hash = crypto.createHash('sha256');
|
|
13
|
-
if (await isDirectory(assetPath))
|
|
14
|
-
for (const [entry, entryHash] of await createDirectorySnapshot(assetPath))
|
|
15
|
-
hash.update(`${entry}\0${entryHash}\n`);
|
|
16
|
-
else
|
|
17
|
-
hash.update(await fs.readFile(assetPath));
|
|
18
|
-
return hash.digest('hex');
|
|
19
|
-
}
|
|
20
|
-
export async function readAssetsLock(targetDir) {
|
|
21
|
-
try {
|
|
22
|
-
return JSON.parse(await fs.readFile(path.join(targetDir, ASSETS_LOCK_PATH), 'utf8'));
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
export async function writeAssetsLock(targetDir, lock) {
|
|
29
|
-
const lockPath = path.join(targetDir, ASSETS_LOCK_PATH);
|
|
30
|
-
await fs.mkdir(path.dirname(lockPath), { recursive: true });
|
|
31
|
-
const assets = Object.fromEntries(Object.entries(lock.assets).sort(([a], [b]) => a.localeCompare(b)));
|
|
32
|
-
await fs.writeFile(lockPath, `${JSON.stringify({ ...lock, assets }, null, 2)}\n`);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=assets-lock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assets-lock.js","sourceRoot":"","sources":["../../../../src/commands/ai/tools/assets-lock.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAe7C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAA;AAE9E,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAiB;IAC/C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAE/C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;IAExC,IAAI,MAAM,WAAW,CAAC,SAAS,CAAC;QAC9B,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,uBAAuB,CAAC,SAAS,CAAC;YACvE,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,SAAS,IAAI,CAAC,CAAA;;QACtC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAA;IAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAiB;IAEjB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CACf,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAClE,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAgB;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAA;IAEvD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE3D,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CACnE,CAAA;IAED,MAAM,EAAE,CAAC,SAAS,CAChB,QAAQ,EACR,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACpD,CAAA;AACH,CAAC"}
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { parseEnv } from 'node:util';
|
|
4
|
-
import { Command, Option } from 'commander';
|
|
5
|
-
import { loadDev, toProjectDir } from '../../tools/load-dev.js';
|
|
6
|
-
import { readProjectScripts, runCommand, runProjectScript, } from '../../tools/project-scripts.js';
|
|
7
|
-
export const CHECK_STEPS = ['types', 'lint', 'manifest', 'test'];
|
|
8
|
-
const OUTPUT_TAIL_LINES = 80;
|
|
9
|
-
const tail = (output, lines = OUTPUT_TAIL_LINES) => output.trimEnd().split('\n').slice(-lines).join('\n');
|
|
10
|
-
/**
|
|
11
|
-
* What an agent (or a person) needs from each workflow: an id to call it, a
|
|
12
|
-
* schema so the input is validated and discoverable, a description of intent.
|
|
13
|
-
*/
|
|
14
|
-
export function validateManifest(manifest) {
|
|
15
|
-
const issues = [];
|
|
16
|
-
const workflows = manifest.workflows.filter(({ id }) => id !== null);
|
|
17
|
-
if (workflows.length === 0)
|
|
18
|
-
issues.push({
|
|
19
|
-
level: 'warning',
|
|
20
|
-
message: 'The App registers no workflow with an id; pass them to `new App({ workflows })`',
|
|
21
|
-
});
|
|
22
|
-
for (const workflow of workflows) {
|
|
23
|
-
const id = workflow.id;
|
|
24
|
-
if (!workflow.schema)
|
|
25
|
-
issues.push({
|
|
26
|
-
level: 'warning',
|
|
27
|
-
workflow: id,
|
|
28
|
-
message: 'No input schema: the input is not validated and callers cannot discover it',
|
|
29
|
-
});
|
|
30
|
-
if (!workflow.description)
|
|
31
|
-
issues.push({
|
|
32
|
-
level: 'warning',
|
|
33
|
-
workflow: id,
|
|
34
|
-
message: 'No description: say what the workflow does and when to run it',
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
return issues;
|
|
38
|
-
}
|
|
39
|
-
const fromCommand = (name, startedAt, { command, exitCode, output }) => exitCode === 0
|
|
40
|
-
? { name, status: 'passed', durationMs: Date.now() - startedAt, command }
|
|
41
|
-
: {
|
|
42
|
-
name,
|
|
43
|
-
status: 'failed',
|
|
44
|
-
durationMs: Date.now() - startedAt,
|
|
45
|
-
command,
|
|
46
|
-
reason: `\`${command}\` exited with ${exitCode}`,
|
|
47
|
-
output: tail(output),
|
|
48
|
-
};
|
|
49
|
-
const skipped = (name, reason) => ({
|
|
50
|
-
name,
|
|
51
|
-
status: 'skipped',
|
|
52
|
-
durationMs: 0,
|
|
53
|
-
reason,
|
|
54
|
-
});
|
|
55
|
-
async function checkTypes(projectDir) {
|
|
56
|
-
const startedAt = Date.now();
|
|
57
|
-
if (readProjectScripts(projectDir)['check-types'])
|
|
58
|
-
return fromCommand('types', startedAt, await runProjectScript(projectDir, 'check-types'));
|
|
59
|
-
const tsc = path.join(projectDir, 'node_modules', '.bin', 'tsc');
|
|
60
|
-
if (!fs.existsSync(tsc))
|
|
61
|
-
return skipped('types', 'No `check-types` script and no local `tsc`');
|
|
62
|
-
return fromCommand('types', startedAt, await runCommand(tsc, ['--noEmit'], projectDir));
|
|
63
|
-
}
|
|
64
|
-
/** Runs the project's own lint: the CLI does not ship or pick the rules. */
|
|
65
|
-
async function checkLint(projectDir) {
|
|
66
|
-
if (!readProjectScripts(projectDir).lint)
|
|
67
|
-
return skipped('lint', 'No `lint` script; add one with @t4h.framework/eslint-plugin to catch non-deterministic workflows');
|
|
68
|
-
const startedAt = Date.now();
|
|
69
|
-
return fromCommand('lint', startedAt, await runProjectScript(projectDir, 'lint'));
|
|
70
|
-
}
|
|
71
|
-
async function checkManifest(options) {
|
|
72
|
-
const startedAt = Date.now();
|
|
73
|
-
let app = null;
|
|
74
|
-
try {
|
|
75
|
-
const { HeadlessApp } = await loadDev(toProjectDir(options.entrypoint), [
|
|
76
|
-
'HeadlessApp',
|
|
77
|
-
]);
|
|
78
|
-
app = await HeadlessApp.up({
|
|
79
|
-
entrypoint: options.entrypoint,
|
|
80
|
-
env: options.env,
|
|
81
|
-
});
|
|
82
|
-
const issues = validateManifest(app.manifest);
|
|
83
|
-
const failed = issues.some(({ level }) => level === 'error');
|
|
84
|
-
return {
|
|
85
|
-
name: 'manifest',
|
|
86
|
-
status: failed ? 'failed' : 'passed',
|
|
87
|
-
durationMs: Date.now() - startedAt,
|
|
88
|
-
issues,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
const details = error.details;
|
|
93
|
-
return {
|
|
94
|
-
name: 'manifest',
|
|
95
|
-
status: 'failed',
|
|
96
|
-
durationMs: Date.now() - startedAt,
|
|
97
|
-
reason: `The app did not build or boot: ${error instanceof Error ? error.message : String(error)}${details?.diagnostics ? '' : ' (the app error is on stderr; a missing variable needs -e or --env-file-if-exists)'}`,
|
|
98
|
-
output: details?.diagnostics
|
|
99
|
-
? tail(details.diagnostics.join('\n'))
|
|
100
|
-
: undefined,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
finally {
|
|
104
|
-
await app?.down().catch(() => { });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
async function checkTest(projectDir) {
|
|
108
|
-
if (!readProjectScripts(projectDir).test)
|
|
109
|
-
return skipped('test', 'No `test` script');
|
|
110
|
-
const startedAt = Date.now();
|
|
111
|
-
return fromCommand('test', startedAt, await runProjectScript(projectDir, 'test'));
|
|
112
|
-
}
|
|
113
|
-
export async function runCheck(options, onStep = () => { }) {
|
|
114
|
-
const projectDir = toProjectDir(options.entrypoint);
|
|
115
|
-
const run = {
|
|
116
|
-
types: () => checkTypes(projectDir),
|
|
117
|
-
lint: () => checkLint(projectDir),
|
|
118
|
-
manifest: () => checkManifest(options),
|
|
119
|
-
test: () => checkTest(projectDir),
|
|
120
|
-
};
|
|
121
|
-
const steps = [];
|
|
122
|
-
for (const name of CHECK_STEPS) {
|
|
123
|
-
const step = options.skip.includes(name) ||
|
|
124
|
-
(options.only && !options.only.includes(name))
|
|
125
|
-
? skipped(name, 'Skipped by option')
|
|
126
|
-
: await run[name]();
|
|
127
|
-
steps.push(step);
|
|
128
|
-
onStep(step);
|
|
129
|
-
}
|
|
130
|
-
return { ok: steps.every(({ status }) => status !== 'failed'), steps };
|
|
131
|
-
}
|
|
132
|
-
const STATUS_MARK = {
|
|
133
|
-
passed: '✔',
|
|
134
|
-
failed: '✖',
|
|
135
|
-
skipped: '-',
|
|
136
|
-
};
|
|
137
|
-
export function formatCheckStep(step) {
|
|
138
|
-
const lines = [
|
|
139
|
-
`${STATUS_MARK[step.status]} ${step.name}${step.status === 'skipped' ? '' : ` (${(step.durationMs / 1000).toFixed(1)}s)`}${step.reason ? ` — ${step.reason}` : ''}`,
|
|
140
|
-
];
|
|
141
|
-
for (const issue of step.issues ?? [])
|
|
142
|
-
lines.push(` ${issue.level}${issue.workflow ? ` [${issue.workflow}]` : ''}: ${issue.message}`);
|
|
143
|
-
if (step.output)
|
|
144
|
-
lines.push(step.output
|
|
145
|
-
.split('\n')
|
|
146
|
-
.map(line => ` ${line}`)
|
|
147
|
-
.join('\n'));
|
|
148
|
-
return lines.join('\n');
|
|
149
|
-
}
|
|
150
|
-
const stepsParser = (value) => {
|
|
151
|
-
const names = value.split(',').map(name => name.trim());
|
|
152
|
-
for (const name of names)
|
|
153
|
-
if (!CHECK_STEPS.includes(name))
|
|
154
|
-
throw new Error(`Unknown step: ${name} (expected ${CHECK_STEPS.join(', ')})`);
|
|
155
|
-
return names;
|
|
156
|
-
};
|
|
157
|
-
export const checkCommand = new Command('check')
|
|
158
|
-
.description('Type-check, lint, boot the app and validate its workflows, then run the tests; one verdict for CI and AI agents')
|
|
159
|
-
.option('--entrypoint <entrypoint path>', 'The entrypoint package json path', './package.json')
|
|
160
|
-
.addOption(new Option('-e, --env <envs..>', 'The env secrets (NAME=value)')
|
|
161
|
-
.argParser((value, previous) => {
|
|
162
|
-
const index = value.indexOf('=');
|
|
163
|
-
if (index < 1)
|
|
164
|
-
throw new Error('Invalid secret format');
|
|
165
|
-
return { ...previous, [value.slice(0, index)]: value.slice(index + 1) };
|
|
166
|
-
})
|
|
167
|
-
.default({}))
|
|
168
|
-
.addOption(new Option('--env-file-if-exists <file-path>', 'Load variables from a .env file if it exists').argParser(value => path.resolve(process.cwd(), value)))
|
|
169
|
-
.addOption(new Option('--only <steps>', `Run only these steps (${CHECK_STEPS.join(',')})`).argParser(stepsParser))
|
|
170
|
-
.addOption(new Option('--skip <steps>', 'Skip these steps')
|
|
171
|
-
.argParser(stepsParser)
|
|
172
|
-
.default([]))
|
|
173
|
-
.option('--json', 'Print one JSON result instead of readable lines', false)
|
|
174
|
-
.action(async (options) => {
|
|
175
|
-
if (options.envFileIfExists && fs.existsSync(options.envFileIfExists))
|
|
176
|
-
Object.assign(options.env, parseEnv(fs.readFileSync(options.envFileIfExists, 'utf8')));
|
|
177
|
-
const result = await runCheck(options, step => {
|
|
178
|
-
if (!options.json)
|
|
179
|
-
process.stdout.write(`${formatCheckStep(step)}\n`);
|
|
180
|
-
});
|
|
181
|
-
if (options.json)
|
|
182
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
183
|
-
process.exit(result.ok ? 0 : 1);
|
|
184
|
-
});
|
|
185
|
-
//# sourceMappingURL=check.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/commands/check/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAE3C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,GAEjB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAU,CAAA;AAsCzE,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,KAAK,GAAG,iBAAiB,EAAE,EAAE,CACzD,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAIvD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;IAEpE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,SAAS;YAChB,OAAO,EACL,iFAAiF;SACpF,CAAC,CAAA;IAEJ,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAY,CAAA;QAEhC,IAAI,CAAC,QAAQ,CAAC,MAAM;YAClB,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EACL,4EAA4E;aAC/E,CAAC,CAAA;QAEJ,IAAI,CAAC,QAAQ,CAAC,WAAW;YACvB,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EACL,+DAA+D;aAClE,CAAC,CAAA;IACN,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,WAAW,GAAG,CAClB,IAAmB,EACnB,SAAiB,EACjB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAiB,EAC3B,EAAE,CACnB,QAAQ,KAAK,CAAC;IACZ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE;IACzE,CAAC,CAAC;QACE,IAAI;QACJ,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAClC,OAAO;QACP,MAAM,EAAE,KAAK,OAAO,kBAAkB,QAAQ,EAAE;QAChD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;KACrB,CAAA;AAEP,MAAM,OAAO,GAAG,CAAC,IAAmB,EAAE,MAAc,EAAmB,EAAE,CAAC,CAAC;IACzE,IAAI;IACJ,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,CAAC;IACb,MAAM;CACP,CAAC,CAAA;AAEF,KAAK,UAAU,UAAU,CAAC,UAAkB;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,IAAI,kBAAkB,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;QAC/C,OAAO,WAAW,CAChB,OAAO,EACP,SAAS,EACT,MAAM,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC,CAClD,CAAA;IAEH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IAEhE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QACrB,OAAO,OAAO,CAAC,OAAO,EAAE,4CAA4C,CAAC,CAAA;IAEvE,OAAO,WAAW,CAChB,OAAO,EACP,SAAS,EACT,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAChD,CAAA;AACH,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,SAAS,CAAC,UAAkB;IACzC,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,IAAI;QACtC,OAAO,OAAO,CACZ,MAAM,EACN,kGAAkG,CACnG,CAAA;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,OAAO,WAAW,CAChB,MAAM,EACN,SAAS,EACT,MAAM,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAC3C,CAAA;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAA4B;IAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,IAAI,GAAG,GAAuB,IAAI,CAAA;IAElC,IAAI,CAAC;QACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;YACtE,aAAa;SACd,CAAC,CAAA;QAEF,GAAG,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC;YACzB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,CAAA;QAE5D,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YACpC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,MAAM;SACP,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAI,KAAkD,CAAC,OAAO,CAAA;QAE3E,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,MAAM,EAAE,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oFAAoF,EAAE;YACrN,MAAM,EAAE,OAAO,EAAE,WAAW;gBAC1B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtC,CAAC,CAAC,SAAS;SACd,CAAA;IACH,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACnC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,UAAkB;IACzC,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,IAAI;QACtC,OAAO,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAE5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,OAAO,WAAW,CAChB,MAAM,EACN,SAAS,EACT,MAAM,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAC3C,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAA4B,EAC5B,SAA0C,GAAG,EAAE,GAAE,CAAC;IAElD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAEnD,MAAM,GAAG,GAA0D;QACjE,KAAK,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QACnC,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC;QACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC;QACtC,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC;KAClC,CAAA;IAED,MAAM,KAAK,GAAsB,EAAE,CAAA;IAEnC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,GACR,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC3B,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC;YACpC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;QAEvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,MAAM,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,KAAK,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAA;AACxE,CAAC;AAED,MAAM,WAAW,GAAoC;IACnD,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,GAAG;CACb,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,MAAM,KAAK,GAAG;QACZ,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;KACpK,CAAA;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;QACnC,KAAK,CAAC,IAAI,CACR,OAAO,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CACtF,CAAA;IAEH,IAAI,IAAI,CAAC,MAAM;QACb,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,MAAM;aACR,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;aAC1B,IAAI,CAAC,IAAI,CAAC,CACd,CAAA;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,KAAa,EAAmB,EAAE;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAEvD,KAAK,MAAM,IAAI,IAAI,KAAK;QACtB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAqB,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,cAAc,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC7D,CAAA;IAEL,OAAO,KAAwB,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CACV,iHAAiH,CAClH;KACA,MAAM,CACL,gCAAgC,EAChC,kCAAkC,EAClC,gBAAgB,CACjB;KACA,SAAS,CACR,IAAI,MAAM,CAAC,oBAAoB,EAAE,8BAA8B,CAAC;KAC7D,SAAS,CAAyB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAEhC,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAEvD,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAA;AACzE,CAAC,CAAC;KACD,OAAO,CAAC,EAAE,CAAC,CACf;KACA,SAAS,CACR,IAAI,MAAM,CACR,kCAAkC,EAClC,8CAA8C,CAC/C,CAAC,SAAS,CAAS,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CACjE;KACA,SAAS,CACR,IAAI,MAAM,CACR,gBAAgB,EAChB,yBAAyB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAClD,CAAC,SAAS,CAAC,WAAW,CAAC,CACzB;KACA,SAAS,CACR,IAAI,MAAM,CAAC,gBAAgB,EAAE,kBAAkB,CAAC;KAC7C,SAAS,CAAC,WAAW,CAAC;KACtB,OAAO,CAAC,EAAE,CAAC,CACf;KACA,MAAM,CAAC,QAAQ,EAAE,iDAAiD,EAAE,KAAK,CAAC;KAC1E,MAAM,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;IAC7C,IAAI,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC;QACnE,MAAM,CAAC,MAAM,CACX,OAAO,CAAC,GAAG,EACX,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAC3D,CAAA;IAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;QAC5C,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IAEF,IAAI,OAAO,CAAC,IAAI;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;IAE9D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACjC,CAAC,CAAC,CAAA"}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import readline from 'node:readline';
|
|
2
|
-
/** MCP revisions this server speaks, newest first. */
|
|
3
|
-
export const MCP_PROTOCOL_VERSIONS = [
|
|
4
|
-
'2025-11-25',
|
|
5
|
-
'2025-06-18',
|
|
6
|
-
'2025-03-26',
|
|
7
|
-
'2024-11-05',
|
|
8
|
-
];
|
|
9
|
-
export const JSON_RPC_ERROR = {
|
|
10
|
-
parseError: -32700,
|
|
11
|
-
invalidRequest: -32600,
|
|
12
|
-
methodNotFound: -32601,
|
|
13
|
-
invalidParams: -32602,
|
|
14
|
-
internalError: -32603,
|
|
15
|
-
};
|
|
16
|
-
/** A JSON-RPC error answered as is, e.g. invalid params. */
|
|
17
|
-
export class JsonRpcError extends Error {
|
|
18
|
-
code;
|
|
19
|
-
data;
|
|
20
|
-
name = 'JsonRpcError';
|
|
21
|
-
constructor(code, message, data) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.code = code;
|
|
24
|
-
this.data = data;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const toText = (value) => typeof value === 'string' ? value : JSON.stringify(value, null, 2);
|
|
28
|
-
/** `{ message, status?, details? }` of any error, for the agent to act on. */
|
|
29
|
-
export function toToolError(error) {
|
|
30
|
-
if (!(error instanceof Error))
|
|
31
|
-
return { error: { message: String(error) } };
|
|
32
|
-
const { status, details } = error;
|
|
33
|
-
return {
|
|
34
|
-
error: {
|
|
35
|
-
message: error.message,
|
|
36
|
-
...(status !== undefined && status !== null ? { status } : {}),
|
|
37
|
-
...(details !== undefined && details !== null ? { details } : {}),
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
42
|
-
const JSON_TYPES = {
|
|
43
|
-
string: value => typeof value === 'string',
|
|
44
|
-
boolean: value => typeof value === 'boolean',
|
|
45
|
-
number: value => typeof value === 'number' && Number.isFinite(value),
|
|
46
|
-
integer: value => Number.isInteger(value),
|
|
47
|
-
object: isObject,
|
|
48
|
-
array: Array.isArray,
|
|
49
|
-
};
|
|
50
|
-
/** Checks the required and top-level typed properties of the arguments. */
|
|
51
|
-
export function checkToolArguments(schema, args) {
|
|
52
|
-
const problems = [];
|
|
53
|
-
const properties = (schema.properties ?? {});
|
|
54
|
-
for (const name of (schema.required ?? []))
|
|
55
|
-
if (args[name] === undefined)
|
|
56
|
-
problems.push(`${name} is required`);
|
|
57
|
-
for (const [name, value] of Object.entries(args)) {
|
|
58
|
-
const property = properties[name];
|
|
59
|
-
if (value === undefined)
|
|
60
|
-
continue;
|
|
61
|
-
if (!property) {
|
|
62
|
-
if (schema.additionalProperties === false)
|
|
63
|
-
problems.push(`${name} is not a known argument`);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (property.type && !JSON_TYPES[property.type]?.(value))
|
|
67
|
-
problems.push(`${name} must be of type ${property.type}`);
|
|
68
|
-
else if (property.enum && !property.enum.includes(value))
|
|
69
|
-
problems.push(`${name} must be one of ${property.enum.join(', ')}`);
|
|
70
|
-
}
|
|
71
|
-
return problems;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* The Model Context Protocol over JSON-RPC 2.0: lifecycle, ping and tools.
|
|
75
|
-
* Transport-free, so tests hand it messages directly.
|
|
76
|
-
*/
|
|
77
|
-
export class McpServer {
|
|
78
|
-
options;
|
|
79
|
-
tools;
|
|
80
|
-
constructor(options) {
|
|
81
|
-
this.options = options;
|
|
82
|
-
this.tools = new Map(options.tools.map(tool => [tool.name, tool]));
|
|
83
|
-
}
|
|
84
|
-
/** Answers one message (or batch); `null` for notifications and responses. */
|
|
85
|
-
async handle(message) {
|
|
86
|
-
if (Array.isArray(message)) {
|
|
87
|
-
if (!message.length)
|
|
88
|
-
return this.error(null, JSON_RPC_ERROR.invalidRequest, 'Empty batch');
|
|
89
|
-
const responses = (await Promise.all(message.map(item => this.handleOne(item)))).filter(response => response !== null);
|
|
90
|
-
return responses.length ? responses : null;
|
|
91
|
-
}
|
|
92
|
-
return this.handleOne(message);
|
|
93
|
-
}
|
|
94
|
-
/** Parses one line of the stdio transport and answers it. */
|
|
95
|
-
async handleLine(line) {
|
|
96
|
-
let message;
|
|
97
|
-
try {
|
|
98
|
-
message = JSON.parse(line);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
return this.error(null, JSON_RPC_ERROR.parseError, `Parse error: ${error.message}`);
|
|
102
|
-
}
|
|
103
|
-
return this.handle(message);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Newline-delimited JSON on `input` / `output` (the MCP stdio transport).
|
|
107
|
-
* Requests are answered as they finish, so `ping` is not stuck behind a
|
|
108
|
-
* long tool call. Resolves when `input` ends.
|
|
109
|
-
*/
|
|
110
|
-
async serve(input, output) {
|
|
111
|
-
const lines = readline.createInterface({ input, crlfDelay: Infinity });
|
|
112
|
-
const pending = new Set();
|
|
113
|
-
for await (const line of lines) {
|
|
114
|
-
if (!line.trim())
|
|
115
|
-
continue;
|
|
116
|
-
const answer = this.handleLine(line)
|
|
117
|
-
.then(response => {
|
|
118
|
-
if (response !== null)
|
|
119
|
-
output.write(`${JSON.stringify(response)}\n`);
|
|
120
|
-
})
|
|
121
|
-
.catch(error => this.options.log?.(`[mcp] ${String(error)}`))
|
|
122
|
-
.finally(() => pending.delete(answer));
|
|
123
|
-
pending.add(answer);
|
|
124
|
-
}
|
|
125
|
-
await Promise.all(pending);
|
|
126
|
-
}
|
|
127
|
-
async handleOne(message) {
|
|
128
|
-
if (!isObject(message))
|
|
129
|
-
return this.error(null, JSON_RPC_ERROR.invalidRequest, 'Invalid Request: not an object');
|
|
130
|
-
const { jsonrpc, id, method, params } = message;
|
|
131
|
-
const isRequest = id !== undefined;
|
|
132
|
-
// A response to a request of ours: the server sends none, so drop it.
|
|
133
|
-
if (method === undefined && ('result' in message || 'error' in message))
|
|
134
|
-
return null;
|
|
135
|
-
if (jsonrpc !== '2.0' ||
|
|
136
|
-
typeof method !== 'string' ||
|
|
137
|
-
(isRequest && typeof id !== 'string' && typeof id !== 'number'))
|
|
138
|
-
return this.error(typeof id === 'string' || typeof id === 'number' ? id : null, JSON_RPC_ERROR.invalidRequest, 'Invalid Request');
|
|
139
|
-
if (!isRequest) {
|
|
140
|
-
// `notifications/initialized`, `notifications/cancelled`, …: nothing to do.
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
const requestId = id;
|
|
144
|
-
try {
|
|
145
|
-
return {
|
|
146
|
-
jsonrpc: '2.0',
|
|
147
|
-
id: requestId,
|
|
148
|
-
result: await this.dispatch(method, params),
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
if (error instanceof JsonRpcError)
|
|
153
|
-
return this.error(requestId, error.code, error.message, error.data);
|
|
154
|
-
this.options.log?.(`[mcp] ${method} failed: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`);
|
|
155
|
-
return this.error(requestId, JSON_RPC_ERROR.internalError, error instanceof Error ? error.message : String(error));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
dispatch(method, params) {
|
|
159
|
-
switch (method) {
|
|
160
|
-
case 'initialize':
|
|
161
|
-
return this.initialize(params);
|
|
162
|
-
case 'ping':
|
|
163
|
-
return {};
|
|
164
|
-
case 'tools/list':
|
|
165
|
-
return {
|
|
166
|
-
tools: [...this.tools.values()].map(({ name, description, inputSchema }) => ({
|
|
167
|
-
name,
|
|
168
|
-
description,
|
|
169
|
-
inputSchema,
|
|
170
|
-
})),
|
|
171
|
-
};
|
|
172
|
-
case 'tools/call':
|
|
173
|
-
return this.callTool(params);
|
|
174
|
-
default:
|
|
175
|
-
throw new JsonRpcError(JSON_RPC_ERROR.methodNotFound, `Method not found: ${method}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
initialize(params) {
|
|
179
|
-
const requested = isObject(params) ? params.protocolVersion : undefined;
|
|
180
|
-
const protocolVersion = MCP_PROTOCOL_VERSIONS.find(version => version === requested);
|
|
181
|
-
return {
|
|
182
|
-
protocolVersion: protocolVersion ?? MCP_PROTOCOL_VERSIONS[0],
|
|
183
|
-
capabilities: { tools: { listChanged: false } },
|
|
184
|
-
serverInfo: { name: this.options.name, version: this.options.version },
|
|
185
|
-
...(this.options.instructions
|
|
186
|
-
? { instructions: this.options.instructions }
|
|
187
|
-
: {}),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
async callTool(params) {
|
|
191
|
-
if (!isObject(params) || typeof params.name !== 'string')
|
|
192
|
-
throw new JsonRpcError(JSON_RPC_ERROR.invalidParams, 'tools/call needs params.name');
|
|
193
|
-
const tool = this.tools.get(params.name);
|
|
194
|
-
if (!tool)
|
|
195
|
-
throw new JsonRpcError(JSON_RPC_ERROR.invalidParams, `Unknown tool: ${params.name}`, { tools: [...this.tools.keys()] });
|
|
196
|
-
const args = params.arguments ?? {};
|
|
197
|
-
if (!isObject(args))
|
|
198
|
-
throw new JsonRpcError(JSON_RPC_ERROR.invalidParams, 'tools/call params.arguments must be an object');
|
|
199
|
-
// Bad arguments are a tool error, so the agent reads them and retries.
|
|
200
|
-
const problems = checkToolArguments(tool.inputSchema, args);
|
|
201
|
-
if (problems.length)
|
|
202
|
-
return {
|
|
203
|
-
content: [
|
|
204
|
-
{
|
|
205
|
-
type: 'text',
|
|
206
|
-
text: toText({
|
|
207
|
-
error: {
|
|
208
|
-
message: `Invalid arguments for ${tool.name}: ${problems.join('; ')}`,
|
|
209
|
-
},
|
|
210
|
-
}),
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
isError: true,
|
|
214
|
-
};
|
|
215
|
-
try {
|
|
216
|
-
return {
|
|
217
|
-
content: [{ type: 'text', text: toText(await tool.call(args)) }],
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
return {
|
|
222
|
-
content: [{ type: 'text', text: toText(toToolError(error)) }],
|
|
223
|
-
isError: true,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
error(id, code, message, data) {
|
|
228
|
-
return {
|
|
229
|
-
jsonrpc: '2.0',
|
|
230
|
-
id,
|
|
231
|
-
error: { code, message, ...(data !== undefined ? { data } : {}) },
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../../src/commands/mcp/mcp-server.ts"],"names":[],"mappings":"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"}
|