Skip to content

Commit 00805b3

Browse files
committed
feat(agent): add kiro as an install target
1 parent 18f6e6e commit 00805b3

4 files changed

Lines changed: 49 additions & 9 deletions

File tree

DOCUMENTATION.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,12 @@ testsprite agent install claude # install the skill for Claude Code
112112
testsprite agent install codex # install into AGENTS.md for Codex (managed-section)
113113
testsprite agent install cursor # .cursor/rules/testsprite-verify.mdc
114114
testsprite agent install cline # .clinerules/testsprite-verify.md
115+
testsprite agent install kiro # .kiro/skills/testsprite-verify/SKILL.md
115116
testsprite agent install antigravity # .agents/skills/testsprite-verify/SKILL.md
116-
testsprite agent list # list all 5 targets with status + mode + path
117+
testsprite agent list # list all 6 targets with status + mode + path
117118
```
118119

119-
Supported targets: `claude` (GA), `codex` (experimental), `cursor` (experimental), `cline` (experimental), `antigravity` (experimental).
120+
Supported targets: `claude` (GA), `codex` (experimental), `cursor` (experimental), `cline` (experimental), `kiro` (experimental), `antigravity` (experimental).
120121

121122
The `codex` target uses **managed-section mode** — it writes only a sentinel-delimited section inside your existing `AGENTS.md`, so your project instructions are never clobbered. Re-running without `--force` replaces the section in-place; user content outside the sentinels is always preserved.
122123

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ npm install -g @testsprite/testsprite-cli
6161
testsprite setup
6262
```
6363

64-
`testsprite setup` prompts for your [API key](https://www.testsprite.com), verifies it, and installs the verification-loop skill for your coding agent (`claude`, `cursor`, `cline`, `antigravity`, `codex`, etc.) — one command, so your agent is wired to verify its own work. Non-interactive (CI / onboarding scripts):
64+
`testsprite setup` prompts for your [API key](https://www.testsprite.com), verifies it, and installs the verification-loop skill for your coding agent (`claude`, `cursor`, `cline`, `kiro`, `antigravity`, `codex`, etc.) — one command, so your agent is wired to verify its own work. Non-interactive (CI / onboarding scripts):
6565

6666
```bash
6767
TESTSPRITE_API_KEY=sk-... testsprite setup --from-env --yes --agent claude
@@ -110,7 +110,7 @@ Prefer to configure each step by hand (or learn the surface offline with `--dry-
110110
| | `test rerun` | Cheap replay of one/many tests (FE verbatim; BE with deps); `--all --project <id>` reruns all tests |
111111
| | `test wait` | Block on a `runId` until terminal |
112112
| | `test artifact get` | Download the failure bundle for a specific `runId` |
113-
| **Agent** | `agent install` / `agent list` | Add or list coding-agent targets (pure-local): `claude`, `codex`, `cursor`, `cline`, `antigravity` |
113+
| **Agent** | `agent install` / `agent list` | Add or list coding-agent targets (pure-local): `claude`, `codex`, `cursor`, `cline`, `kiro`, `antigravity` |
114114

115115
> The earlier command names — `init`, `auth configure`, `auth whoami`, `auth logout` — still work as hidden, deprecated aliases (each prints a one-line notice pointing at the new name), so existing scripts keep running. `auth configure` now runs the full `setup` (it also installs the skill).
116116

src/lib/agent-targets.test.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,21 @@ testsprite test artifact get <run-id> --out ./out/
6060
// ---------------------------------------------------------------------------
6161

6262
describe('TARGETS', () => {
63-
it('has all five required keys', () => {
63+
it('has all six required keys', () => {
6464
const keys = Object.keys(TARGETS).sort();
65-
expect(keys).toEqual(['antigravity', 'claude', 'cline', 'codex', 'cursor']);
65+
expect(keys).toEqual(['antigravity', 'claude', 'cline', 'codex', 'cursor', 'kiro']);
6666
});
6767

6868
it('claude is GA', () => {
6969
expect(TARGETS.claude.status).toBe('ga');
7070
});
7171

72-
it('cursor, cline, antigravity, and codex are experimental', () => {
72+
it('cursor, cline, antigravity, codex, and kiro are experimental', () => {
7373
expect(TARGETS.cursor.status).toBe('experimental');
7474
expect(TARGETS.cline.status).toBe('experimental');
7575
expect(TARGETS.antigravity.status).toBe('experimental');
7676
expect(TARGETS.codex.status).toBe('experimental');
77+
expect(TARGETS.kiro.status).toBe('experimental');
7778
});
7879

7980
it('each target has a non-empty POSIX path', () => {
@@ -88,6 +89,7 @@ describe('TARGETS', () => {
8889
expect(TARGETS.antigravity.mode).toBe('own-file');
8990
expect(TARGETS.cursor.mode).toBe('own-file');
9091
expect(TARGETS.cline.mode).toBe('own-file');
92+
expect(TARGETS.kiro.mode).toBe('own-file');
9193
});
9294

9395
it('codex target has mode managed-section', () => {
@@ -255,16 +257,47 @@ describe('renderForTarget("cline")', () => {
255257
});
256258
});
257259

260+
describe('renderForTarget("kiro")', () => {
261+
const result = renderForTarget('kiro', STUB_BODY);
262+
263+
it('returns the correct path', () => {
264+
expect(result.path).toBe('.kiro/skills/testsprite-verify/SKILL.md');
265+
});
266+
267+
it('frontmatter contains name: testsprite-verify', () => {
268+
expect(result.content).toContain('name: testsprite-verify');
269+
});
270+
271+
it('frontmatter contains description:', () => {
272+
expect(result.content).toContain(`description: ${SKILL_DESCRIPTION}`);
273+
});
274+
275+
it('content ends with a trailing newline', () => {
276+
expect(result.content.endsWith('\n')).toBe(true);
277+
});
278+
279+
it('produces the same content as claude (same wrapSkill)', () => {
280+
const claude = renderForTarget('claude', STUB_BODY);
281+
expect(result.content).toBe(claude.content);
282+
});
283+
284+
it('differs only in landing path from claude', () => {
285+
const claude = renderForTarget('claude', STUB_BODY);
286+
expect(result.path).not.toBe(claude.path);
287+
});
288+
});
289+
258290
// ---------------------------------------------------------------------------
259291
// Content integrity — load-bearing command strings must survive any body trim
260292
// ---------------------------------------------------------------------------
261293

262294
describe('content integrity — own-file targets', () => {
263-
const ownFileTargets: Array<'claude' | 'cursor' | 'cline' | 'antigravity'> = [
295+
const ownFileTargets: Array<'claude' | 'cursor' | 'cline' | 'antigravity' | 'kiro'> = [
264296
'claude',
265297
'cursor',
266298
'cline',
267299
'antigravity',
300+
'kiro',
268301
];
269302

270303
// Use the real body for these checks, since we're guarding against trimming.

src/lib/agent-targets.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { readFileSync } from 'node:fs';
22

3-
export type AgentTarget = 'claude' | 'cursor' | 'cline' | 'antigravity' | 'codex';
3+
export type AgentTarget = 'claude' | 'cursor' | 'cline' | 'antigravity' | 'codex' | 'kiro';
44

55
export interface TargetSpec {
66
status: 'ga' | 'experimental';
@@ -58,6 +58,12 @@ export const TARGETS: Record<AgentTarget, TargetSpec> = {
5858
mode: 'own-file',
5959
wrap: body => body,
6060
},
61+
kiro: {
62+
status: 'experimental',
63+
path: '.kiro/skills/testsprite-verify/SKILL.md',
64+
mode: 'own-file',
65+
wrap: wrapSkill,
66+
},
6167
/**
6268
* codex target — managed-section mode.
6369
*

0 commit comments

Comments
 (0)