surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
| 1 | import { describe, expect, test, tier } from 'claude-code/testing' |
| 2 | |
| 3 | import Hooks from '../hooks' |
| 4 | import Fixtures from './fixtures' |
| 5 | |
| 6 | tier('builtin') |
| 7 | |
| 8 | /** |
| 9 | * The blocks the engine hands `prompt.context`. |
| 10 | */ |
| 11 | const BLOCKS = [ |
| 12 | { name: 'claudeMd', text: 'x' }, |
| 13 | { name: 'currentDate', text: 'today' }, |
| 14 | ] |
| 15 | |
| 16 | describe('register', () => { |
| 17 | test('by default a project with AGENTS.md alone gets it', async ($, on) => { |
| 18 | const started = Fixtures.projectOf( |
| 19 | on, |
| 20 | [Fixtures.ancestorOf('/repo', 'AGENTS.md', '# top\n')], |
| 21 | [], |
| 22 | ) |
| 23 | |
| 24 | on('prompt.context', ($, e) => ({ |
| 25 | blocks: e.blocks, |
| 26 | instructionFiles: e.instructionFiles, |
| 27 | })) |
| 28 | |
| 29 | const context = await $.prompt.context({ |
| 30 | blocks: BLOCKS, |
| 31 | instructionFiles: [], |
| 32 | }) |
| 33 | |
| 34 | expect(context.instructionFiles).toEqual([ |
| 35 | { path: '/repo/AGENTS.md', kind: 'project', content: '# top\n' }, |
| 36 | ]) |
| 37 | expect(context.blocks?.[0]?.text).toContain( |
| 38 | 'Contents of /repo/AGENTS.md (project instructions, checked into the ' + |
| 39 | 'codebase):\n\n# top', |
| 40 | ) |
| 41 | |
| 42 | await started.clock.settle() |
| 43 | |
| 44 | expect(started.lines).toEqual([ |
| 45 | 'no CLAUDE.md found; AGENTS.md loaded: /repo/AGENTS.md', |
| 46 | ]) |
| 47 | }) |
| 48 | |
| 49 | test('by default a project with a CLAUDE.md is left to the engine', async ($, on) => { |
| 50 | const started = Fixtures.projectOf( |
| 51 | on, |
| 52 | [Fixtures.ancestorOf('/repo', 'AGENTS.md', '# top\n')], |
| 53 | [Fixtures.ancestorOf('/repo/a/b', 'CLAUDE.md', '# mine\n')], |
| 54 | ) |
| 55 | const handed = [ |
| 56 | { path: '/repo/a/b/CLAUDE.md', kind: 'project' as const, content: '#' }, |
| 57 | ] |
| 58 | |
| 59 | on('prompt.context', ($, e) => ({ |
| 60 | blocks: e.blocks, |
| 61 | instructionFiles: e.instructionFiles, |
| 62 | })) |
| 63 | |
| 64 | expect( |
| 65 | await $.prompt.context({ blocks: BLOCKS, instructionFiles: handed }), |
| 66 | ).toEqual({ blocks: BLOCKS, instructionFiles: handed }) |
| 67 | |
| 68 | await started.clock.settle() |
| 69 | |
| 70 | expect(started.walks).toEqual([]) |
| 71 | expect(started.lines).toEqual([]) |
| 72 | }) |
| 73 | |
| 74 | test('a failed walk leaves the context as handed', async ($, on) => { |
| 75 | Fixtures.unreadableProjectOf(on) |
| 76 | |
| 77 | on('prompt.context', ($, e) => ({ |
| 78 | blocks: e.blocks, |
| 79 | instructionFiles: e.instructionFiles, |
| 80 | })) |
| 81 | |
| 82 | expect( |
| 83 | await $.prompt.context({ blocks: BLOCKS, instructionFiles: [] }), |
| 84 | ).toEqual({ blocks: BLOCKS, instructionFiles: [] }) |
| 85 | }) |
| 86 | |
| 87 | test( |
| 88 | 'the start sends the mode row alone: no walk, no toast', |
| 89 | { plugins: [Fixtures.RECORDING] }, |
| 90 | async ($, on) => { |
| 91 | const started = Fixtures.projectOf( |
| 92 | on, |
| 93 | [Fixtures.ancestorOf('/repo', 'AGENTS.md', '# top\n')], |
| 94 | [], |
| 95 | ) |
| 96 | |
| 97 | expect(await $.session.start(Fixtures.SESSION)).toEqual({ |
| 98 | cwd: '/repo/a/b', |
| 99 | }) |
| 100 | |
| 101 | await started.clock.settle() |
| 102 | |
| 103 | expect(Fixtures.rowsOf(started)).toEqual([ |
| 104 | [ |
| 105 | 'log', |
| 106 | { |
| 107 | event: Hooks.MODE_EVENT, |
| 108 | props: { |
| 109 | mode: { value: 'claude-md-or-agents-md', of: [...Hooks.MODES] }, |
| 110 | is_interactive: true, |
| 111 | }, |
| 112 | }, |
| 113 | ], |
| 114 | ]) |
| 115 | expect(Hooks.MODE_EVENT).toBe('agents_md_mode') |
| 116 | expect(started.walks).toEqual([]) |
| 117 | expect(started.toasts).toEqual([]) |
| 118 | }, |
| 119 | ) |
| 120 | |
| 121 | test('with no telemetry noun the start goes on untouched', async ($, on) => { |
| 122 | const started = Fixtures.projectOf( |
| 123 | on, |
| 124 | [Fixtures.ancestorOf('/repo', 'AGENTS.md', '# top\n')], |
| 125 | [], |
| 126 | ) |
| 127 | |
| 128 | expect( |
| 129 | await $.session.start({ ...Fixtures.SESSION, isInteractive: false }), |
| 130 | ).toEqual({ cwd: '/repo/a/b' }) |
| 131 | |
| 132 | await started.clock.settle() |
| 133 | |
| 134 | expect(Fixtures.rowsOf(started)).toEqual([]) |
| 135 | expect(started.toasts).toEqual([]) |
| 136 | }) |
| 137 | }) |