11import { describe , expect , test } from 'bun:test'
22import fs from 'node:fs'
3+ import os from 'node:os'
34import path from 'node:path'
45import { pathToFileURL } from 'node:url'
56
@@ -24,6 +25,61 @@ describe('plugin loading', () => {
2425 expect ( pluginModule . SystematicPlugin ) . toBeUndefined ( )
2526 } )
2627
28+ test ( 'plugin snapshots bootstrap content at init instead of re-reading files per transform' , async ( ) => {
29+ const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'systematic-plugin-' ) )
30+ const opencodeDir = path . join ( tempDir , '.opencode' )
31+ const bootstrapPath = path . join ( tempDir , 'bootstrap.md' )
32+ const configPath = path . join ( opencodeDir , 'systematic.json' )
33+
34+ fs . mkdirSync ( opencodeDir , { recursive : true } )
35+ fs . writeFileSync ( bootstrapPath , 'INITIAL bootstrap content' )
36+ fs . writeFileSync (
37+ configPath ,
38+ JSON . stringify ( {
39+ bootstrap : {
40+ enabled : true ,
41+ file : bootstrapPath ,
42+ } ,
43+ } ) ,
44+ )
45+
46+ try {
47+ const pluginPath = path . join ( SRC_DIR , 'index.ts' )
48+ const pluginModule = ( await import ( pathToFileURL ( pluginPath ) . href ) ) as {
49+ default : ( args : {
50+ client : { app : { log : ( entry : unknown ) => Promise < void > } }
51+ directory : string
52+ } ) => Promise < {
53+ 'experimental.chat.system.transform' : (
54+ input : unknown ,
55+ output : { system : string [ ] } ,
56+ ) => Promise < void >
57+ } >
58+ }
59+
60+ const plugin = await pluginModule . default ( {
61+ client : {
62+ app : {
63+ log : async ( ) => { } ,
64+ } ,
65+ } ,
66+ directory : tempDir ,
67+ } )
68+
69+ fs . writeFileSync ( bootstrapPath , 'UPDATED bootstrap content' )
70+
71+ const output = { system : [ 'Existing system prompt' ] }
72+ await plugin [ 'experimental.chat.system.transform' ] ( { } , output )
73+
74+ expect ( output . system ) . toEqual ( [
75+ 'Existing system prompt\n\nINITIAL bootstrap content' ,
76+ ] )
77+ expect ( output . system [ 0 ] ) . not . toContain ( 'UPDATED bootstrap content' )
78+ } finally {
79+ fs . rmSync ( tempDir , { recursive : true , force : true } )
80+ }
81+ } )
82+
2783 test ( 'CI smoke test validates the workflow plugin export and registry drift contract' , ( ) => {
2884 const workflowPath = path . join ( ROOT_DIR , '.github/workflows/main.yaml' )
2985 const workflow = fs . readFileSync ( workflowPath , 'utf8' )
0 commit comments