@t4h.framework/cli 0.0.0-experimental-20261008135920 → 0.0.0-experimental-29d0277

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 CHANGED
@@ -1,64 +1,5 @@
1
1
  # @t4h.framework/cli
2
2
 
3
- ## 0.0.0-experimental-20261008135920
4
-
5
- ### Minor Changes
6
-
7
- - [#216](https://github.com/tech4humans-brasil/framework/pull/216) [`3d2ea34`](https://github.com/tech4humans-brasil/framework/commit/3d2ea3406e857ccaa5b50f26dddf6892d415e239) Thanks [@tony-tsx](https://github.com/tony-tsx)! - The CLI runs the `@t4h.framework/dev` installed in the project instead of its
8
- own copy, so the project picks the dev server version — a pinned or
9
- experimental one included. `dev`, `build`, `workflows` and `runtime` resolve it
10
- from the project's `node_modules` (or a parent workspace) when they run, and
11
- `build` takes `@t4h.framework/core` from the project too. `@t4h.framework/dev`
12
- moves to an optional peer dependency: add it to the project
13
- (`yarn add -D @t4h.framework/dev`). When it is missing, or too old for a
14
- command, the command prints the version it found and exits with `1`; the other
15
- commands no longer need it.
16
-
17
- - [#208](https://github.com/tech4humans-brasil/framework/pull/208) [`c312bfb`](https://github.com/tech4humans-brasil/framework/commit/c312bfb0f1b1ddbc40d8ac0ede113c5614aa9df8) Thanks [@tony-tsx](https://github.com/tony-tsx)! - `framework workflows` lists, describes and runs the workflows of the app from
18
- the terminal, without the dev server: `framework workflows <workflow> run
19
- --input '<json>'` builds the project, runs the workflow, waits for it
20
- (`--timeout`) and prints the run as JSON — with the activities, logs and child
21
- runs under `--trace`. It exits with `0` when the run fulfills, `1` when it is
22
- rejected or the command fails, and `2` on timeout, so scripts and AI agents can
23
- test workflows headlessly.
24
-
25
- `@t4h.framework/dev` exports `HeadlessApp`, the API behind it, and the app
26
- process resolves its bundle root from `file:` URLs.
27
-
28
- - [#210](https://github.com/tech4humans-brasil/framework/pull/210) [`990c074`](https://github.com/tech4humans-brasil/framework/commit/990c074af498cb7610d310e295ad613dce7a9b52) Thanks [@tony-tsx](https://github.com/tony-tsx)! - The dev runtime publishes what it runs: jobs queued, started and finished
29
- (with the queue counts), runs created and settled, activities started, waiting
30
- and settled (with the error of a rejected one), timeouts and lost workers.
31
- - `--debug` on `framework dev` and `framework workflows <workflow> run` prints
32
- those events on stderr; `--debug-log <file>` appends them to a file as NDJSON.
33
- - Every app process registers itself and listens on a local socket (named pipe
34
- on Windows). `framework runtime ls` lists them, `framework runtime status`
35
- prints the queue, the jobs running and waiting and the runs in progress, and
36
- `framework runtime watch` follows the events live (`--json` for NDJSON),
37
- reconnecting across `dev` rebuilds.
38
-
39
- `@t4h.framework/dev` exports `listRuntimes`, `requestRuntimeStatus`,
40
- `watchRuntime` and `formatRuntimeEvent`, and takes `debugLog` on `Server` and
41
- `HeadlessApp.up`.
42
-
43
- ### Patch Changes
44
-
45
- - Updated dependencies [[`c312bfb`](https://github.com/tech4humans-brasil/framework/commit/c312bfb0f1b1ddbc40d8ac0ede113c5614aa9df8), [`a93218a`](https://github.com/tech4humans-brasil/framework/commit/a93218ae284d91de7d94a65e8f306ace0db2d733), [`92db468`](https://github.com/tech4humans-brasil/framework/commit/92db468f819d3c7d01884526598acd5fbef9b4ef), [`990c074`](https://github.com/tech4humans-brasil/framework/commit/990c074af498cb7610d310e295ad613dce7a9b52)]:
46
- - @t4h.framework/dev@0.0.0-experimental-20261008135920
47
-
48
- ## 0.16.17
49
-
50
- ### Patch Changes
51
-
52
- - Updated dependencies [[`fc4db5f`](https://github.com/tech4humans-brasil/framework/commit/fc4db5fa01454a45a3727b76dbacc215aa6b3ab7)]:
53
- - @t4h.framework/dev@0.22.6
54
-
55
- ## 0.16.16
56
-
57
- ### Patch Changes
58
-
59
- - Updated dependencies []:
60
- - @t4h.framework/dev@0.22.5
61
-
62
3
  ## 0.16.15
63
4
 
64
5
  ### Patch Changes
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tech for humans
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/bin/bin.js CHANGED
@@ -1,9 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
3
  import { AIBootstrapCommand } from '../commands/ai/ai-bootstrap.js';
4
+ import { aiHookCommand } from '../commands/ai/ai-hook.js';
4
5
  import { buildCommand } from '../commands/build/build.js';
6
+ import { checkCommand } from '../commands/check/check.js';
5
7
  import { devCommand } from '../commands/dev/dev.js';
6
8
  import { harnessCommand } from '../commands/harness/harness.js';
9
+ import { mcpCommand } from '../commands/mcp/mcp.js';
7
10
  import { publishCommand } from '../commands/publish/publish.js';
8
11
  import { runtimeCommand } from '../commands/runtime/runtime.js';
9
12
  import { workflowsCommand } from '../commands/workflows/workflows.js';
@@ -15,6 +18,9 @@ program.addCommand(AIBootstrapCommand);
15
18
  program.addCommand(harnessCommand);
16
19
  program.addCommand(workflowsCommand);
17
20
  program.addCommand(runtimeCommand);
21
+ program.addCommand(checkCommand);
22
+ program.addCommand(aiHookCommand);
23
+ program.addCommand(mcpCommand);
18
24
  try {
19
25
  await program.parseAsync(process.argv);
20
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAC9B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AACtC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACpC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAElC,IAAI,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AACxC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,IAAI,CAAC,CAAC,KAAK,YAAY,mBAAmB,CAAC;QAAE,MAAM,KAAK,CAAA;IAExD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;IACtC,MAAM,iBAAiB,GACrB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAA;IAE5D,IAAI,iBAAiB;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE7C,MAAM,KAAK,CAAA;AACb,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAC9B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AACtC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACpC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAE9B,IAAI,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AACxC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,IAAI,CAAC,CAAC,KAAK,YAAY,mBAAmB,CAAC;QAAE,MAAM,KAAK,CAAA;IAExD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;IACtC,MAAM,iBAAiB,GACrB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAA;IAE5D,IAAI,iBAAiB;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE7C,MAAM,KAAK,CAAA;AACb,CAAC,CAAC,CAAA"}
@@ -2,44 +2,129 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { confirm, select } from '@inquirer/prompts';
4
4
  import { bootstrap as bootstrapHarness } from '@t4h.framework/harness';
5
- import { Command } from 'commander';
5
+ import { Command, Option } from 'commander';
6
6
  import { AI_PROVIDERS } from './ai-providers.js';
7
+ import { buildAgentInstructions, frameworkBin, writeAgentInstructions, } from './tools/agent-instructions.js';
8
+ import { installClaudeHooks, installMcpServer } from './tools/agent-settings.js';
9
+ import { hashAsset, readAssetsLock, writeAssetsLock, } from './tools/assets-lock.js';
7
10
  import { copy } from './tools/copy.js';
8
11
  import { discoverPackages } from './tools/discover-packages.js';
9
12
  import { findNearestPackageJsonPath } from './tools/find-nearest-package-json-path.js';
10
13
  import { getAssetSources } from './tools/get-asset-sources.js';
11
- import { isDirectoryEqual } from './tools/is-directory-equal.js';
12
- import { isDirectory } from './tools/is-directory.js';
13
- import { pathExists } from './tools/path-exists.js';
14
- async function syncAsset(sourcePath, destinationPath, assetName, row) {
15
- const destinationExists = await pathExists(destinationPath);
16
- if (!destinationExists) {
14
+ import { getPackagePath } from './tools/get-package-path.js';
15
+ import { detectPackageManager } from '../../tools/project-scripts.js';
16
+ async function readPackageVersion(packageName, packageJsonPath) {
17
+ const packagePath = await getPackagePath(packageName, packageJsonPath);
18
+ if (!packagePath)
19
+ return null;
20
+ try {
21
+ const { version } = JSON.parse(await fs.promises.readFile(path.join(packagePath, 'package.json'), 'utf8'));
22
+ return typeof version === 'string' ? version : null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * Copies one asset. A copy nobody edited since the last sync (same hash as
30
+ * the lock) is updated silently; a local edit is only replaced on consent.
31
+ */
32
+ async function syncAsset(sourcePath, destinationPath, key, origin, context) {
33
+ const { options, previousLock, lock, row, kept } = context;
34
+ const sourceHash = await hashAsset(sourcePath);
35
+ const destinationHash = await hashAsset(destinationPath);
36
+ const lockedHash = previousLock?.assets[key]?.hash;
37
+ const record = (hash) => {
38
+ if (hash)
39
+ lock.assets[key] = { ...origin, hash };
40
+ };
41
+ if (destinationHash === null) {
17
42
  await copy(sourcePath, destinationPath);
43
+ record(sourceHash);
18
44
  row.copied++;
19
45
  return;
20
46
  }
21
- const destinationIsDirectory = await isDirectory(destinationPath);
22
- const hasDifferences = !destinationIsDirectory
23
- ? true
24
- : !(await isDirectoryEqual(sourcePath, destinationPath));
25
- if (!hasDifferences) {
47
+ if (destinationHash === sourceHash) {
48
+ record(sourceHash);
26
49
  row.ignored++;
27
50
  return;
28
51
  }
29
- const isOverwriting = await confirm({
30
- message: `Asset "${assetName}" already exists and has differences. Overwrite it?`,
31
- default: false,
32
- });
33
- if (!isOverwriting) {
52
+ const untouched = lockedHash !== undefined && lockedHash === destinationHash;
53
+ const overwrite = untouched ||
54
+ options.yes ||
55
+ (!options.sync &&
56
+ (await confirm({
57
+ message: `Asset "${key}" was edited locally. Overwrite it?`,
58
+ default: false,
59
+ })));
60
+ if (!overwrite) {
61
+ // Keep tracking the framework's version so a later sync still sees the edit.
62
+ if (lockedHash)
63
+ lock.assets[key] = { ...origin, hash: lockedHash };
64
+ kept.push(key);
34
65
  row.skipped++;
35
66
  return;
36
67
  }
37
68
  await copy(sourcePath, destinationPath);
38
- row.copied++;
69
+ record(sourceHash);
70
+ row.updated++;
71
+ }
72
+ /** Removes the assets a package no longer ships, unless edited locally. */
73
+ async function removeStaleAssets(providerDir, summary, context) {
74
+ for (const [key, locked] of Object.entries(context.previousLock?.assets ?? {})) {
75
+ if (context.lock.assets[key])
76
+ continue;
77
+ const assetPath = path.join(providerDir, key);
78
+ const row = (summary[key.split('/')[0]] ??= emptyRow());
79
+ if ((await hashAsset(assetPath)) !== locked.hash) {
80
+ context.kept.push(key);
81
+ row.skipped++;
82
+ continue;
83
+ }
84
+ await fs.promises.rm(assetPath, { recursive: true, force: true });
85
+ row.removed++;
86
+ }
87
+ }
88
+ const emptyRow = () => ({
89
+ copied: 0,
90
+ updated: 0,
91
+ ignored: 0,
92
+ skipped: 0,
93
+ removed: 0,
94
+ });
95
+ async function selectProvider(options, targetDir) {
96
+ const settingsPath = path.join(targetDir, '.framework', 'settings.json');
97
+ const saved = await fs.promises
98
+ .readFile(settingsPath, 'utf8')
99
+ .then(content => JSON.parse(content).provider)
100
+ .catch(() => undefined);
101
+ const value = options.provider ?? (options.sync ? saved : undefined);
102
+ if (value) {
103
+ const provider = AI_PROVIDERS.find(entry => entry.value === value);
104
+ if (!provider)
105
+ throw new Error(`Unknown AI provider: ${value}`);
106
+ return provider;
107
+ }
108
+ if (options.sync)
109
+ throw new Error('No provider saved in .framework/settings.json; pass --provider');
110
+ return select({
111
+ message: 'Select a AI provider',
112
+ choices: AI_PROVIDERS.map(target => ({
113
+ name: target.name,
114
+ value: target,
115
+ })),
116
+ default: AI_PROVIDERS.find(entry => entry.value === saved),
117
+ });
39
118
  }
40
119
  export const AIBootstrapCommand = new Command('ai-bootstrap')
41
- .description('Bootstrap AI assets from framework packages')
42
- .action(async () => {
120
+ .description('Install the AI assets of the framework packages, the agent instructions, hooks and the MCP server')
121
+ .addOption(new Option('--provider <provider>', 'Skip the prompt').choices(AI_PROVIDERS.map(({ value }) => value)))
122
+ .option('-y, --yes', 'Overwrite assets edited locally without asking', false)
123
+ .option('--sync', 'No prompts (CI, postinstall): update untouched assets, keep local edits, remove stale ones', false)
124
+ .option('--no-instructions', 'Do not write the CLAUDE.md / AGENTS.md block')
125
+ .option('--no-hooks', 'Do not install the Claude Code hooks')
126
+ .option('--no-mcp', 'Do not register the framework MCP server')
127
+ .action(async (options) => {
43
128
  const packageJsonPath = await findNearestPackageJsonPath();
44
129
  if (!packageJsonPath) {
45
130
  console.error('package.json was not found from the current directory.');
@@ -51,43 +136,93 @@ export const AIBootstrapCommand = new Command('ai-bootstrap')
51
136
  return;
52
137
  }
53
138
  const assets = await getAssetSources(frameworkPackages, packageJsonPath);
54
- if (!Object.keys(assets).length) {
55
- console.log('No AI assets were found in the declared framework packages.');
56
- return;
57
- }
58
- const provider = await select({
59
- message: 'Select a AI provider',
60
- choices: AI_PROVIDERS.map(target => ({
61
- name: target.name,
62
- value: target,
63
- })),
64
- });
65
139
  const targetDir = process.env.INIT_CWD ?? process.cwd();
140
+ const provider = await selectProvider(options, targetDir);
66
141
  await bootstrapHarness({ targetDir });
67
- const settingsPath = path.join(targetDir, '.framework', 'settings.json');
68
- await fs.promises.writeFile(settingsPath, JSON.stringify({ provider: provider.value }, null, 2));
142
+ await fs.promises.writeFile(path.join(targetDir, '.framework', 'settings.json'), JSON.stringify({ provider: provider.value }, null, 2));
143
+ const versions = new Map(await Promise.all(frameworkPackages.map(async (name) => [name, await readPackageVersion(name, packageJsonPath)])));
144
+ const providerDir = path.join(targetDir, provider.dir);
69
145
  const summary = {};
146
+ const previousLock = await readAssetsLock(targetDir);
147
+ const context = {
148
+ options,
149
+ // Hashes from another provider's directory say nothing about this one.
150
+ previousLock: previousLock?.provider === provider.value ? previousLock : null,
151
+ lock: { provider: provider.value, assets: {} },
152
+ kept: [],
153
+ };
70
154
  const providerNames = new Set(AI_PROVIDERS.map(entry => entry.value));
71
155
  for (const [assetType, sources] of Object.entries(assets)) {
72
- const row = (summary[assetType] ??= {
73
- copied: 0,
74
- ignored: 0,
75
- skipped: 0,
76
- });
77
- const targetPath = path.join(targetDir, provider.dir, assetType);
156
+ const row = (summary[assetType] ??= emptyRow());
157
+ const targetPath = path.join(providerDir, assetType);
78
158
  await fs.promises.mkdir(targetPath, { recursive: true });
79
159
  for (const source of sources) {
80
- if (providerNames.has(source.assetName)) {
81
- if (source.assetName !== provider.value)
82
- continue;
83
- const entries = await fs.promises.readdir(source.sourcePath);
84
- for (const entry of entries)
85
- await syncAsset(path.join(source.sourcePath, entry), path.join(targetPath, entry), entry, row);
86
- continue;
87
- }
88
- await syncAsset(source.sourcePath, path.join(targetPath, source.assetName), source.assetName, row);
160
+ const origin = {
161
+ package: source.packageName,
162
+ version: versions.get(source.packageName) ?? null,
163
+ };
164
+ // A `claude` / `cursor` folder holds assets for that provider only.
165
+ const entries = providerNames.has(source.assetName)
166
+ ? source.assetName === provider.value
167
+ ? (await fs.promises.readdir(source.sourcePath)).map(entry => ({
168
+ name: entry,
169
+ sourcePath: path.join(source.sourcePath, entry),
170
+ }))
171
+ : []
172
+ : [{ name: source.assetName, sourcePath: source.sourcePath }];
173
+ for (const entry of entries)
174
+ await syncAsset(entry.sourcePath, path.join(targetPath, entry.name), `${assetType}/${entry.name}`, origin, { ...context, row });
89
175
  }
90
176
  }
177
+ await removeStaleAssets(providerDir, summary, {
178
+ ...context,
179
+ row: emptyRow(),
180
+ });
181
+ await writeAssetsLock(targetDir, context.lock);
182
+ const packageManager = detectPackageManager(targetDir);
183
+ const bin = frameworkBin(packageManager);
184
+ const [command, ...args] = bin.split(' ');
185
+ const changes = [];
186
+ if (options.instructions) {
187
+ const file = provider.value === 'claude' ? 'CLAUDE.md' : 'AGENTS.md';
188
+ const status = await writeAgentInstructions(path.join(targetDir, file), buildAgentInstructions({
189
+ packageManager,
190
+ packages: frameworkPackages.map(name => ({
191
+ name,
192
+ version: versions.get(name) ?? null,
193
+ })),
194
+ skillsDir: `${provider.dir}/skills`,
195
+ mcp: options.mcp,
196
+ }));
197
+ if (status !== 'unchanged')
198
+ changes.push(`${file} ${status}`);
199
+ }
200
+ if (options.mcp) {
201
+ const configPath = provider.value === 'claude'
202
+ ? path.join(targetDir, '.mcp.json')
203
+ : path.join(providerDir, 'mcp.json');
204
+ if (await installMcpServer(configPath, {
205
+ command,
206
+ args: [...args, 'mcp'],
207
+ }))
208
+ changes.push(`MCP server "framework" registered in ${path.relative(targetDir, configPath)}`);
209
+ }
210
+ if (options.hooks && provider.value === 'claude') {
211
+ const settingsPath = path.join(providerDir, 'settings.json');
212
+ if (await installClaudeHooks(settingsPath, [
213
+ {
214
+ event: 'PostToolUse',
215
+ matcher: 'Edit|MultiEdit|Write',
216
+ command: `${bin} ai-hook post-edit`,
217
+ },
218
+ { event: 'Stop', command: `${bin} ai-hook stop` },
219
+ ]))
220
+ changes.push(`hooks installed in ${path.relative(targetDir, settingsPath)}`);
221
+ }
91
222
  console.table(summary);
223
+ for (const change of changes)
224
+ console.log(change);
225
+ if (context.kept.length)
226
+ console.log(`Kept local edits (run with --yes to replace them): ${context.kept.join(', ')}`);
92
227
  });
93
228
  //# sourceMappingURL=ai-bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-bootstrap.js","sourceRoot":"","sources":["../../../src/commands/ai/ai-bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-bootstrap.js","sourceRoot":"","sources":["../../../src/commands/ai/ai-bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-hook.js","sourceRoot":"","sources":["../../../src/commands/ai/ai-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../../../src/commands/ai/tools/agent-instructions.ts"],"names":[],"mappings":"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"}