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
| @@ -14,10 +14,52 @@ | ||
| 14 | 14 | Each folder is a complete plugin: `.claude-plugin/plugin.json`, a |
| 15 | 15 | `hooks/hooks.json` naming the module, and TypeScript under `hooks/` typed |
| 16 | 16 | against the declarations `/plugin-types` writes (`import type … from |
| 17 | -'claude-code'`). To read one running from source: | |
| 17 | +'claude-code'`), kept here in `types/`. To read one running from source: | |
| 18 | 18 | |
| 19 | 19 | claude --plugin-dir mods/diff |
| 20 | 20 | |
| 21 | +## Testing | |
| 22 | + | |
| 23 | +A mod's tests are in its `tests/` folder, and run with | |
| 24 | + | |
| 25 | + claude plugin test mods/diff | |
| 26 | + | |
| 27 | +A test gets the engine's own `$` and a plugin's `on`. Each call on `$` is one | |
| 28 | +the engine makes, through every hook of the mod loaded as it ships. The hooks | |
| 29 | +the test registers with `on` sit beneath the mod, where the rest of the world | |
| 30 | +would be, and nothing is beneath them: a call they leave unanswered throws, | |
| 31 | +naming its event. | |
| 32 | + | |
| 33 | +```ts | |
| 34 | +import { expect, seat, test } from 'claude-code/testing' | |
| 35 | + | |
| 36 | +seat('builtin') | |
| 37 | + | |
| 38 | +test('outside a git repository /diff says so and opens nothing', async ($, on) => { | |
| 39 | + const opened: string[] = [] | |
| 40 | + on('session.start', ($, e) => ({ cwd: e.cwd })) | |
| 41 | + on('command.register', ($, e) => ({ value: { command: e.name } })) | |
| 42 | + on('process.run', () => ({ value: { exitCode: 128, stdout: '', stderr: '' } })) | |
| 43 | + on('ui.open', ($, e, next) => { | |
| 44 | + opened.push(e.id) | |
| 45 | + return next(e) | |
| 46 | + }) | |
| 47 | + | |
| 48 | + await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' }) | |
| 49 | + const { text } = await $.command.run({ | |
| 50 | + command: 'diff', | |
| 51 | + args: '', | |
| 52 | + origin: { kind: 'composer' }, | |
| 53 | + }) | |
| 54 | + | |
| 55 | + expect(text).toContain('isn’t in a git repository') | |
| 56 | + expect(opened).toEqual([]) | |
| 57 | +}) | |
| 58 | +``` | |
| 59 | + | |
| 60 | +`tsc -p mods/tsconfig.json` typechecks every mod's hooks and tests against | |
| 61 | +`types/`. | |
| 62 | + | |
| 21 | 63 | Early access: hooks modules load only where function hooks are enabled, and |
| 22 | 64 | the API these mods are written against may change between releases without |
| 23 | 65 | notice. They are not listed in this repository's marketplace; the copies that |