@t4h.framework/cli 0.0.0-experimental-2f9c297 → 0.0.0-experimental-20261019200538

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/CHANGELOG.md +14 -0
  2. package/dist/bin/bin.js +1 -20
  3. package/dist/bin/bin.js.map +1 -1
  4. package/dist/commands/ai/ai-bootstrap.js +51 -185
  5. package/dist/commands/ai/ai-bootstrap.js.map +1 -1
  6. package/dist/commands/build/build.js +2 -6
  7. package/dist/commands/build/build.js.map +1 -1
  8. package/dist/commands/dev/dev.js +1 -8
  9. package/dist/commands/dev/dev.js.map +1 -1
  10. package/dist/commands/publish/publish.js +0 -1
  11. package/dist/commands/publish/publish.js.map +1 -1
  12. package/package.json +3 -12
  13. package/LICENSE +0 -21
  14. package/dist/commands/ai/ai-hook.js +0 -84
  15. package/dist/commands/ai/ai-hook.js.map +0 -1
  16. package/dist/commands/ai/tools/agent-instructions.js +0 -75
  17. package/dist/commands/ai/tools/agent-instructions.js.map +0 -1
  18. package/dist/commands/ai/tools/agent-settings.js +0 -61
  19. package/dist/commands/ai/tools/agent-settings.js.map +0 -1
  20. package/dist/commands/ai/tools/assets-lock.js +0 -34
  21. package/dist/commands/ai/tools/assets-lock.js.map +0 -1
  22. package/dist/commands/check/check.js +0 -185
  23. package/dist/commands/check/check.js.map +0 -1
  24. package/dist/commands/mcp/mcp-server.js +0 -235
  25. package/dist/commands/mcp/mcp-server.js.map +0 -1
  26. package/dist/commands/mcp/mcp-tools.js +0 -283
  27. package/dist/commands/mcp/mcp-tools.js.map +0 -1
  28. package/dist/commands/mcp/mcp.js +0 -71
  29. package/dist/commands/mcp/mcp.js.map +0 -1
  30. package/dist/commands/runtime/runtime.js +0 -143
  31. package/dist/commands/runtime/runtime.js.map +0 -1
  32. package/dist/commands/workflows/workflows.js +0 -166
  33. package/dist/commands/workflows/workflows.js.map +0 -1
  34. package/dist/tools/debug-log-option.js +0 -13
  35. package/dist/tools/debug-log-option.js.map +0 -1
  36. package/dist/tools/dev-server-client.js +0 -261
  37. package/dist/tools/dev-server-client.js.map +0 -1
  38. package/dist/tools/load-dev.js +0 -23
  39. package/dist/tools/load-dev.js.map +0 -1
  40. package/dist/tools/project-package.js +0 -67
  41. package/dist/tools/project-package.js.map +0 -1
  42. package/dist/tools/project-scripts.js +0 -53
  43. package/dist/tools/project-scripts.js.map +0 -1
@@ -1,84 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { Argument, Command } from 'commander';
4
- import { runCommand } from '../../tools/project-scripts.js';
5
- import { formatCheckStep, runCheck } from '../check/check.js';
6
- /** Claude Code shows stderr to the model when a hook exits with 2. */
7
- const BLOCKING_EXIT_CODE = 2;
8
- const LINTED_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
9
- async function readStdin() {
10
- if (process.stdin.isTTY)
11
- return {};
12
- const chunks = [];
13
- for await (const chunk of process.stdin)
14
- chunks.push(chunk);
15
- try {
16
- return JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}');
17
- }
18
- catch {
19
- return {};
20
- }
21
- }
22
- function findBin(fromDir, name) {
23
- let dir = path.resolve(fromDir);
24
- while (true) {
25
- const bin = path.join(dir, 'node_modules', '.bin', name);
26
- if (fs.existsSync(bin))
27
- return bin;
28
- const parent = path.dirname(dir);
29
- if (parent === dir)
30
- return null;
31
- dir = parent;
32
- }
33
- }
34
- const projectDirOf = (input) => process.env.CLAUDE_PROJECT_DIR ?? input.cwd ?? process.cwd();
35
- /**
36
- * Lints the file the agent just edited with the project's own ESLint, errors
37
- * only, so a non-deterministic workflow is fixed in the same turn.
38
- */
39
- async function postEdit(input) {
40
- const filePath = input.tool_input?.file_path;
41
- if (typeof filePath !== 'string')
42
- return 0;
43
- if (!LINTED_EXTENSIONS.has(path.extname(filePath)))
44
- return 0;
45
- if (!fs.existsSync(filePath))
46
- return 0;
47
- const projectDir = projectDirOf(input);
48
- const eslint = findBin(projectDir, 'eslint');
49
- if (!eslint)
50
- return 0;
51
- const { exitCode, output } = await runCommand(eslint, ['--quiet', '--no-warn-ignored', filePath], projectDir);
52
- if (exitCode === 0)
53
- return 0;
54
- process.stderr.write(`ESLint found errors in ${path.relative(projectDir, filePath)}; fix them:\n${output.trim()}\n`);
55
- return BLOCKING_EXIT_CODE;
56
- }
57
- /** Before the agent stops: types and lint must pass. Once, never in a loop. */
58
- async function stop(input) {
59
- if (input.stop_hook_active)
60
- return 0;
61
- const projectDir = projectDirOf(input);
62
- const result = await runCheck({
63
- entrypoint: path.join(projectDir, 'package.json'),
64
- env: {},
65
- only: ['types', 'lint'],
66
- skip: [],
67
- json: true,
68
- });
69
- if (result.ok)
70
- return 0;
71
- process.stderr.write(`\`framework check --only types,lint\` failed; fix it before finishing:\n${result.steps
72
- .filter(({ status }) => status === 'failed')
73
- .map(formatCheckStep)
74
- .join('\n')}\n`);
75
- return BLOCKING_EXIT_CODE;
76
- }
77
- export const aiHookCommand = new Command('ai-hook')
78
- .description('Hooks installed by `ai-bootstrap` for coding agents; reads the hook JSON on stdin')
79
- .addArgument(new Argument('<hook>').choices(['post-edit', 'stop']))
80
- .action(async (hook) => {
81
- const input = await readStdin();
82
- process.exit(hook === 'post-edit' ? await postEdit(input) : await stop(input));
83
- });
84
- //# sourceMappingURL=ai-hook.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai-hook.js","sourceRoot":"","sources":["../../../src/commands/ai/ai-hook.ts"],"names":[],"mappings":"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"}
@@ -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":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAIjC,MAAM,CAAC,MAAM,kBAAkB,GAC7B,yGAAyG,CAAA;AAE3G,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAA;AAUxD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,cAA8B,EAAE,EAAE,CAC7D,CAAC;IACC,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,qBAAqB;IAC3B,GAAG,EAAE,eAAe;CACrB,CAAC,CAAC,cAAc,CAAC,CAAA;AAEpB,MAAM,UAAU,sBAAsB,CAAC,EACrC,cAAc,EACd,QAAQ,EACR,SAAS,EACT,GAAG,GACsB;IACzB,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,CAAC,CAAA;IACxC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IAEzE,MAAM,KAAK,GAAG;QACZ,kBAAkB;QAClB,kBAAkB;QAClB,EAAE;QACF,0CAA0C,QAAQ;aAC/C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;aACxE,IAAI,CAAC,IAAI,CAAC,GAAG;QAChB,EAAE;QACF,+BAA+B;QAC/B,EAAE;QACF,kIAAkI;QAClI,EAAE;QACF,qNAAqN;QACrN,qKAAqK;QACrK,+JAA+J;QAC/J,yJAAyJ;QACzJ,8DAA8D;QAC9D,4OAA4O;QAC5O,EAAE;QACF,qCAAqC;QACrC,EAAE;QACF,OAAO,GAAG,qKAAqK;QAC/K,GAAG,CAAC,8BAA8B,CAAC;YACjC,CAAC,CAAC,sGAAsG;YACxG,CAAC,CAAC,uFAAuF;QAC3F,2HAA2H;QAC3H,EAAE;QACF,+BAA+B;QAC/B,EAAE;QACF,GAAG,CAAC,GAAG;YACL,CAAC,CAAC;gBACE,iLAAiL;aAClL;YACH,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,GAAG,uCAAuC,GAAG,gDAAgD,GAAG,sHAAsH;QAC7N,8DAA8D,GAAG,oCAAoC,GAAG,4DAA4D;QACpK,EAAE;QACF,6BAA6B,SAAS,qEAAqE;QAC3G,gBAAgB;KACjB,CAAA;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,KAAa;IAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;IAEpD,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC5B,OAAO,CACL,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;YACvB,KAAK;YACL,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAC7C,CAAA;IAEH,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QAAE,OAAO,GAAG,KAAK,IAAI,CAAA;IAExC,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,KAAa;IAEb,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IACrE,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;IAErD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,WAAW,CAAA;IAExC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAElC,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;AACjD,CAAC"}
@@ -1,61 +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
- const sameServer = (a, b) => JSON.stringify({ command: a.command, args: a.args }) === JSON.stringify(b);
46
- /**
47
- * Registers the `framework` MCP server in a `.mcp.json`-shaped file. An entry
48
- * the project wrote is kept; one equal to a `previous` default is upgraded.
49
- */
50
- export async function installMcpServer(configPath, server, previous = []) {
51
- const config = await readJson(configPath);
52
- const current = config.mcpServers?.framework;
53
- if (current && !previous.some(entry => sameServer(current, entry)))
54
- return false;
55
- await writeJson(configPath, {
56
- ...config,
57
- mcpServers: { ...(config.mcpServers ?? {}), framework: server },
58
- });
59
- return true;
60
- }
61
- //# 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":"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"}