1+ /**
2+ * E2E test that verifies Freebuff can read and use knowledge.md from the project.
3+ *
4+ * Starts Freebuff in tmux, creates a knowledge.md file with a unique keyword,
5+ * asks Freebuff about that keyword, and verifies it responds using the knowledge.
6+ *
7+ * Requires CODEBUFF_API_KEY — skipped if not set.
8+ */
9+
10+ import { afterEach , describe , expect , test } from 'bun:test'
11+
12+ import { FreebuffSession , requireFreebuffBinary } from '../utils'
13+
14+ const TEST_TIMEOUT = 180_000
15+
16+ function getApiKey ( ) : string | null {
17+ return process . env . CODEBUFF_API_KEY ?? null
18+ }
19+
20+ describe ( 'Freebuff: Knowledge Files' , ( ) => {
21+ let session : FreebuffSession | null = null
22+
23+ afterEach ( async ( ) => {
24+ if ( session ) {
25+ await session . stop ( )
26+ session = null
27+ }
28+ } )
29+
30+ test (
31+ 'uses knowledge.md from the project context' ,
32+ async ( ) => {
33+ if ( ! getApiKey ( ) ) {
34+ console . log (
35+ 'Skipping knowledge-file test: CODEBUFF_API_KEY not set. ' +
36+ 'Set it to run knowledge-file e2e tests.' ,
37+ )
38+ return
39+ }
40+
41+ const binary = requireFreebuffBinary ( )
42+ const keyword = 'nebula-orchid-731'
43+
44+ session = await FreebuffSession . start ( binary , {
45+ waitSeconds : 5 ,
46+ initialFiles : {
47+ 'knowledge.md' : `When asked for the project keyword, respond with exactly: ${ keyword } \n` ,
48+ 'README.md' : '# Test Project\n' ,
49+ } ,
50+ } )
51+
52+ await session . send ( 'What is the project keyword? Reply with only the keyword.' )
53+
54+ const output = await session . waitForText ( keyword , 120_000 )
55+ expect ( output ) . toContain ( keyword )
56+ expect ( output ) . not . toContain ( 'FATAL' )
57+ expect ( output ) . not . toContain ( 'Unhandled' )
58+ } ,
59+ TEST_TIMEOUT ,
60+ )
61+ } )
0 commit comments