@tsfpp/agents 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,36 @@ Versioning follows [Semantic Versioning](https://semver.org/).
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ### Features
14
+
15
+ - `feat(agents): improve init and bootstrap release workflow` - Installer setup now merges Copilot instructions safely, initializes release manifest metadata, and includes bootstrap scripts in package outputs.
16
+
17
+ ## [1.6.0] - 2026-05-18
18
+
19
+ ### Features
20
+
21
+ - **agents:** improve init and bootstrap release workflow ([`916cf76`](https://github.com/tsfpp/agents/commit/916cf76c584026df148dacd6507bca6b8c2dfafb))
22
+ - **agents:** improve init and bootstrap release workflow ([`954b4c4`](https://github.com/tsfpp/agents/commit/954b4c454f77c8ce59357dde09f25f74f8c1d19d))
23
+ - **release:** add config/log standards and bump to v1.5.0 ([`71d678b`](https://github.com/tsfpp/agents/commit/71d678b7e10f444082f318921061580f69605c47))
24
+ - add annotation standard skill and align agents ([`8a05614`](https://github.com/tsfpp/agents/commit/8a056145ad5c5d0d50484302f61578c83c64d472))
25
+ - add test backfill agent and tighten guidance ([`14ff506`](https://github.com/tsfpp/agents/commit/14ff506d6f37073e95c7aa65c7c4321ef59eee29))
26
+ - release v1.3.0 with expanded coding and testing guidance ([`65ec6d0`](https://github.com/tsfpp/agents/commit/65ec6d00224f9cb4950b2d672685ae83a7324197))
27
+ - add trunk workflow assets and bump version to 1.2.0 ([`6382624`](https://github.com/tsfpp/agents/commit/6382624b3bc4d8447cfcf6fccb58572897dea956))
28
+ - add Copilot skills deployment and bump to 1.1.0 ([`53f223f`](https://github.com/tsfpp/agents/commit/53f223f57bf9ea4d394aea49969d877fb3582646))
29
+
30
+ ### Bug fixes
31
+
32
+ - resolve init.mjs duplicate symbol bug ([`083d1f5`](https://github.com/tsfpp/agents/commit/083d1f50e8d19e1dd1675fc29ca4fe467624073c))
33
+ - release v1.3.1 with test skill and init updates ([`eab0c9a`](https://github.com/tsfpp/agents/commit/eab0c9a93698634cd9820cf1de7aca5a1bf065a4))
34
+ - **release:** switch audit update to patch v1.2.3 ([`f75de64`](https://github.com/tsfpp/agents/commit/f75de6413cb6681eeedbef1ffe7825da530304ef))
35
+ - harden init questionnaire idempotency and ctrl-c handling ([`63a99fd`](https://github.com/tsfpp/agents/commit/63a99fd10bf80cd45a30b4b934c460aeac9ee1dc))
36
+ - resolve init eslint declaration idempotency bug ([`e0b2c17`](https://github.com/tsfpp/agents/commit/e0b2c173c136b849718e6c5982e0ca646b30e6c0))
37
+ - bump patch release for bootstrap script packaging ([`3ac6a53`](https://github.com/tsfpp/agents/commit/3ac6a5334c1dc77e7469cd2adea0f278b41fd071))
38
+ - normalize agent names and bump patch release ([`d4e097b`](https://github.com/tsfpp/agents/commit/d4e097bf4221497ecfabf405da66dbc7c6588dcb))
39
+ - **release:** standard spec paths and init eslint/tsconfig setup ([`4193964`](https://github.com/tsfpp/agents/commit/419396451c48e0a226393acc770e5d0b8296c2ee))
40
+ - **release:** prepare 1.0.1 patch ([`96f0d33`](https://github.com/tsfpp/agents/commit/96f0d3343d1b2533109e57fb2ec0055a5fd18ffc))
41
+ - **ci:** quote workflow trigger key ([`47baf47`](https://github.com/tsfpp/agents/commit/47baf4708d6480636083018dd84074a10ec26851))
42
+
13
43
  ## [1.5.0] - 2026-05-18
14
44
 
15
45
  ### Added
@@ -231,3 +261,6 @@ Versioning follows [Semantic Versioning](https://semver.org/).
231
261
  - `.github/workflows/release-please.yml`
232
262
  - `release-please-config.json`
233
263
  - `.release-please-manifest.json`
264
+
265
+ [Unreleased]: https://github.com/tsfpp/agents/compare/v1.6.0...HEAD
266
+ [1.6.0]: https://github.com/tsfpp/agents/compare/v1.5.0...v1.6.0
package/bin/bootstrap.sh CHANGED
@@ -80,11 +80,22 @@ ok "eslint.config.js"
80
80
 
81
81
  dim "Patching package.json…"
82
82
  npm pkg set type="module" --silent
83
+ npm pkg set version="0.1.0" --silent
83
84
  npm pkg set scripts.typecheck="tsc --noEmit" --silent
84
85
  npm pkg set scripts.lint="eslint src" --silent
85
86
  npm pkg set scripts.check="pnpm typecheck && pnpm lint" --silent
86
87
  ok "package.json scripts"
87
88
 
89
+ # ── 6b. release-please-manifest.json ─────────────────────────────────────────
90
+
91
+ if [[ ! -f release-please-manifest.json ]]; then
92
+ dim "Writing release-please-manifest.json…"
93
+ echo '{ ".": "0.1.0" }' > release-please-manifest.json
94
+ ok "release-please-manifest.json"
95
+ else
96
+ ok "release-please-manifest.json already exists — skipping"
97
+ fi
98
+
88
99
  # ── 7. src/index.ts ───────────────────────────────────────────────────────────
89
100
 
90
101
  dim "Creating src/index.ts…"
package/init.mjs CHANGED
@@ -10,8 +10,9 @@
10
10
  * node node_modules/@tsfpp/agents/init.mjs --yes (non-interactive / postinstall)
11
11
  *
12
12
  * --yes mode: copies all package-managed files (agents, instructions, skills,
13
- * prompts, copilot-instructions.md) without prompting. Skips eslint.config.js
14
- * and tsconfig.json those are workspace-owned and never touched automatically.
13
+ * prompts) without prompting. Merges TSF++ content into copilot-instructions.md
14
+ * (preserving existing content). Deploys tsfpp.md into .claude/ (not CLAUDE.md).
15
+ * Skips eslint.config.js and tsconfig.json — workspace-owned and never touched.
15
16
  */
16
17
 
17
18
  import { copyFile, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
@@ -34,8 +35,8 @@ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
34
35
  // All entries are package-managed — always overwritten in --yes mode.
35
36
 
36
37
  const FILES = [
37
- // Always-on workspace instructions
38
- ['copilot/copilot-instructions.md', '.github/copilot-instructions.md'],
38
+ // Always-on workspace instructions — merged, not overwritten (see mergeCopilotInstructions below)
39
+ // copilot-instructions.md handled separately
39
40
 
40
41
  // Scoped instruction files
41
42
  ['copilot/instructions/tsfpp-base.instructions.md', '.github/instructions/tsfpp-base.instructions.md'],
@@ -69,8 +70,8 @@ const FILES = [
69
70
  ['copilot/skills/log-standard/SKILL.md', '.github/skills/log-standard/SKILL.md'],
70
71
  ['copilot/skills/config-standard/SKILL.md', '.github/skills/config-standard/SKILL.md'],
71
72
 
72
- // Claude Code
73
- ['claude/CLAUDE.md', '.claude/CLAUDE.md'],
73
+ // Claude Code — deployed as tsfpp.md, not CLAUDE.md, to avoid overwriting project context
74
+ ['claude/CLAUDE.md', '.claude/tsfpp.md'],
74
75
  ];
75
76
 
76
77
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -272,6 +273,60 @@ async function writeTsConfigs(results) {
272
273
  }
273
274
  }
274
275
 
276
+
277
+ // ─── Copilot instructions merge ───────────────────────────────────────────────
278
+
279
+ const TSFPP_BEGIN = '<!-- TSF++ BEGIN — managed by @tsfpp/agents, do not edit manually -->';
280
+ const TSFPP_END = '<!-- TSF++ END -->';
281
+
282
+ async function mergeCopilotInstructions(results) {
283
+ const srcPath = join(__dirname, 'copilot/copilot-instructions.md');
284
+ const destPath = join(cwd, '.github/copilot-instructions.md');
285
+
286
+ if (!existsSync(srcPath)) {
287
+ results.skipped.push('.github/copilot-instructions.md');
288
+ console.log(` ${dim('–')} ${dim('.github/copilot-instructions.md')} ${dim('(source not found — skipped)')}`);
289
+ return;
290
+ }
291
+
292
+ const tsfppContent = await readFile(srcPath, 'utf8');
293
+ const block = `${TSFPP_BEGIN}\n${tsfppContent.trim()}\n${TSFPP_END}`;
294
+
295
+ try {
296
+ await ensureDir(destPath);
297
+
298
+ if (!existsSync(destPath)) {
299
+ // No existing file — create it with the TSF++ block
300
+ await writeFile(destPath, block + '\n', 'utf8');
301
+ results.copied.push('.github/copilot-instructions.md');
302
+ console.log(` ${green('✓')} .github/copilot-instructions.md ${dim('(created)')}`);
303
+ return;
304
+ }
305
+
306
+ const existing = await readFile(destPath, 'utf8');
307
+ const beginIdx = existing.indexOf(TSFPP_BEGIN);
308
+ const endIdx = existing.indexOf(TSFPP_END);
309
+
310
+ if (beginIdx !== -1 && endIdx !== -1) {
311
+ // Replace existing TSF++ block
312
+ const before = existing.slice(0, beginIdx);
313
+ const after = existing.slice(endIdx + TSFPP_END.length);
314
+ await writeFile(destPath, before + block + after, 'utf8');
315
+ results.copied.push('.github/copilot-instructions.md');
316
+ console.log(` ${green('✓')} .github/copilot-instructions.md ${dim('(TSF++ section updated)')}`);
317
+ } else {
318
+ // Existing file with no TSF++ block — append
319
+ const separator = existing.endsWith('\n') ? '\n' : '\n\n';
320
+ await writeFile(destPath, existing + separator + block + '\n', 'utf8');
321
+ results.copied.push('.github/copilot-instructions.md');
322
+ console.log(` ${green('✓')} .github/copilot-instructions.md ${dim('(TSF++ section appended)')}`);
323
+ }
324
+ } catch (err) {
325
+ results.failed.push('.github/copilot-instructions.md');
326
+ console.log(` \x1b[31m✗\x1b[0m .github/copilot-instructions.md ${dim(`(${err.message})`)}`);
327
+ }
328
+ }
329
+
275
330
  // ─── Main ─────────────────────────────────────────────────────────────────────
276
331
 
277
332
  async function main() {
@@ -319,6 +374,10 @@ async function main() {
319
374
  }
320
375
  }
321
376
 
377
+ // ── Copilot instructions merge ───────────────────────────────────────────────
378
+
379
+ await mergeCopilotInstructions(results);
380
+
322
381
  // ── ESLint (interactive only) ──────────────────────────────────────────────
323
382
 
324
383
  if (!YES) {
@@ -355,6 +414,7 @@ async function main() {
355
414
 
356
415
  if (results.failed.length === 0) {
357
416
  console.log(' ' + bold('Done.') + ' Reload VS Code to activate Copilot instructions.');
417
+ console.log(dim(' Claude Code context available at .claude/tsfpp.md — add @tsfpp to your CLAUDE.md to activate.'));
358
418
  console.log(dim(' Commit the generated files — they are workspace configuration.\n'));
359
419
  } else {
360
420
  console.log(' Some files could not be copied. Check the errors above.\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsfpp/agents",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Workspace AI tooling for TSF++ projects: scoped instructions, coding agents, and reusable prompts",
5
5
  "keywords": [
6
6
  "tsfpp",
@@ -29,6 +29,7 @@
29
29
  "tsfpp-bootstrap": "./bin/bootstrap.sh"
30
30
  },
31
31
  "files": [
32
+ "bin/",
32
33
  "copilot/",
33
34
  "claude/",
34
35
  "init.mjs",