11/**
2- * kt — Git-Backed Ticket Tracker
2+ * ticket — Git-Backed Ticket Tracker
33 *
44 * A full-featured ticket tracker for AI agents, inspired by kticket.
55 * Stores tickets as markdown files with JSON frontmatter in `.tickets/`.
66 * Supports hierarchy (parent/child), dependencies, types, priorities,
77 * status workflow, test validation, and session assignment.
88 *
99 * Provides:
10- * - `kt ` tool with 9 actions (create, show, update, delete, start, close, reopen, list, add-note)
11- * - `/kt ` TUI browser with fuzzy search and action menu
12- * - `/kt -create` prompt injection for epic + task breakdown
13- * - `/kt -run-all` automated ticket processing loop with session forking
10+ * - `ticket ` tool with 9 actions (create, show, update, delete, start, close, reopen, list, add-note)
11+ * - `/ticket ` TUI browser with fuzzy search and action menu
12+ * - `/ticket -create` prompt injection for epic + task breakdown
13+ * - `/ticket -run-all` automated ticket processing loop with session forking
1414 * - Widget showing current in-progress ticket
1515 * - Status line with ticket counts
1616 * - Auto-nudge on agent_end when tickets remain in-progress
@@ -78,7 +78,7 @@ import {
7878 serializeListForAgent ,
7979 statusIcon ,
8080 writeTicketFile ,
81- } from "./kt -core.ts" ;
81+ } from "./ticket -core.ts" ;
8282
8383/** Tool result details for renderResult. */
8484type KtToolDetails =
@@ -113,7 +113,7 @@ const KtParams = Type.Object({
113113 tests_confirmed : Type . Optional ( Type . Boolean ( { description : "Confirm tests pass when closing a ticket with test requirements" } ) ) ,
114114} ) ;
115115
116- // ── Locking (requires ExtensionContext, stays in kt .ts) ─── ─────────────
116+ // ── Locking (requires ExtensionContext, stays in index .ts) ─────────────
117117
118118async function acquireLock (
119119 dir : string ,
@@ -563,7 +563,7 @@ class TicketDetailOverlayComponent {
563563
564564// ── Extension ──────────────────────────────────────────────────────────
565565
566- export default function ktExtension ( pi : ExtensionAPI ) {
566+ export default function ticketExtension ( pi : ExtensionAPI ) {
567567 let nudgedThisCycle = false ;
568568
569569 // ── Session events ─────────────────────────────────────────────────
@@ -591,7 +591,7 @@ export default function ktExtension(pi: ExtensionAPI) {
591591 nudgedThisCycle = true ;
592592 const list = inProgress . map ( ( t ) => ` ${ statusIcon ( t . status ) } ${ t . id } : ${ t . title } ` ) . join ( "\n" ) ;
593593 pi . sendMessage ( {
594- customType : "kt -nudge" ,
594+ customType : "ticket -nudge" ,
595595 content : `⚠️ You still have ${ inProgress . length } in-progress ticket(s):\n\n${ list } \n\nContinue working on them or close them when done.` ,
596596 display : true ,
597597 } , { triggerTurn : true } ) ;
@@ -612,14 +612,14 @@ export default function ktExtension(pi: ExtensionAPI) {
612612
613613 // Status
614614 if ( ! tickets . length ) {
615- ctx . ui . setStatus ( "🎫 kt: no tickets" , "kt " ) ;
615+ ctx . ui . setStatus ( "🎫 no tickets" , "ticket " ) ;
616616 } else {
617- ctx . ui . setStatus ( `🎫 kt: ${ tickets . length } tickets (${ remaining } remaining)` , "kt " ) ;
617+ ctx . ui . setStatus ( `🎫 ${ tickets . length } tickets (${ remaining } remaining)` , "ticket " ) ;
618618 }
619619
620620 // Widget: current in-progress ticket
621621 if ( inProgress . length ) {
622- ctx . ui . setWidget ( "kt -current" , ( _tui , theme ) => {
622+ ctx . ui . setWidget ( "ticket -current" , ( _tui , theme ) => {
623623 const container = new Container ( ) ;
624624 container . addChild ( new Text ( "" , 0 , 0 ) ) ;
625625 container . addChild ( new DynamicBorder ( ( s : string ) => theme . fg ( "dim" , s ) ) ) ;
@@ -643,7 +643,7 @@ export default function ktExtension(pi: ExtensionAPI) {
643643 } ;
644644 } , { placement : "belowEditor" } ) ;
645645 } else {
646- ctx . ui . setWidget ( "kt -current" , undefined ) ;
646+ ctx . ui . setWidget ( "ticket -current" , undefined ) ;
647647 }
648648 }
649649
@@ -673,11 +673,11 @@ export default function ktExtension(pi: ExtensionAPI) {
673673 return resolved ;
674674 }
675675
676- // ── kt tool ──── ────────────────────────────────────────────────────
676+ // ── ticket tool ────────────────────────────────────────────────────
677677
678678 pi . registerTool ( {
679- name : "kt " ,
680- label : "kt " ,
679+ name : "ticket " ,
680+ label : "ticket " ,
681681 description :
682682 "Git-backed ticket tracker. Actions: create, show, update, delete, start, close, reopen, list, add-note. " +
683683 "Tickets stored in .tickets/ as markdown files. IDs use project prefix (e.g. as-a1b2). Partial ID matching supported. " +
@@ -824,7 +824,7 @@ export default function ktExtension(pi: ExtensionAPI) {
824824 // Test validation: block with criteria if tests exist and aren't confirmed
825825 if ( ticket . tests . trim ( ) && ! ticket . tests_passed && ! params . tests_confirmed ) {
826826 return {
827- error : `Cannot close ${ resolved } : this ticket has test requirements that must pass first.\n\n## Tests\n${ ticket . tests . trim ( ) } \n\nVerify these tests pass, then call \`kt close\` again with tests_confirmed=true.` ,
827+ error : `Cannot close ${ resolved } : this ticket has test requirements that must pass first.\n\n## Tests\n${ ticket . tests . trim ( ) } \n\nVerify these tests pass, then call \`ticket close\` again with tests_confirmed=true.` ,
828828 } as const ;
829829 }
830830
@@ -906,7 +906,7 @@ export default function ktExtension(pi: ExtensionAPI) {
906906 const action = typeof args . action === "string" ? args . action : "" ;
907907 const id = typeof args . id === "string" ? args . id : "" ;
908908 const title = typeof args . title === "string" ? args . title : "" ;
909- let text = theme . fg ( "toolTitle" , theme . bold ( "kt " ) ) + theme . fg ( "muted" , action ) ;
909+ let text = theme . fg ( "toolTitle" , theme . bold ( "ticket " ) ) + theme . fg ( "muted" , action ) ;
910910 if ( id ) text += " " + theme . fg ( "accent" , id ) ;
911911 if ( title ) text += " " + theme . fg ( "dim" , `"${ title } "` ) ;
912912 return new Text ( text , 0 , 0 ) ;
@@ -956,9 +956,9 @@ export default function ktExtension(pi: ExtensionAPI) {
956956 } ,
957957 } ) ;
958958
959- // ── /kt command (TUI browser) ──── ──────────────────────────────────
959+ // ── /ticket command (TUI browser) ──────────────────────────────────
960960
961- pi . registerCommand ( "kt " , {
961+ pi . registerCommand ( "ticket " , {
962962 description : "Browse and manage tickets" ,
963963 getArgumentCompletions : ( prefix : string ) => {
964964 const dir = getTicketsDir ( process . cwd ( ) ) ;
@@ -1144,9 +1144,9 @@ export default function ktExtension(pi: ExtensionAPI) {
11441144 } ,
11451145 } ) ;
11461146
1147- // ── /kt -create command ─── ──────────────────────────────────────────
1147+ // ── /ticket -create command ──────────────────────────────────────────
11481148
1149- pi . registerCommand ( "kt -create" , {
1149+ pi . registerCommand ( "ticket -create" , {
11501150 description : "Create an epic and tasks from a plan" ,
11511151 handler : async ( _args , ctx ) => {
11521152 const prompt =
@@ -1165,21 +1165,21 @@ export default function ktExtension(pi: ExtensionAPI) {
11651165 "- For each task, draft: description, acceptance criteria, and test criteria\n\n" +
11661166 "Ask me to review and adjust the plan before proceeding.\n\n" +
11671167 "**Step 3: Create** — Once I approve the plan, create the tickets:\n" +
1168- "1. `kt create` the epic (type=epic) with description and acceptance criteria\n" +
1169- "2. `kt create` each task (type=task, parent=<epic-id>) with:\n" +
1168+ "1. `ticket create` the epic (type=epic) with description and acceptance criteria\n" +
1169+ "2. `ticket create` each task (type=task, parent=<epic-id>) with:\n" +
11701170 " - description: what to implement\n" +
11711171 " - acceptance: definition of done\n" +
11721172 " - tests: specific test criteria that must pass before closing\n" +
11731173 " - priority and deps as planned\n" +
1174- "3. Show the final ticket list with `kt list`\n\n" +
1174+ "3. Show the final ticket list with `ticket list`\n\n" +
11751175 "Start by asking me: what do you want to build?" ;
11761176 ctx . ui . setEditorText ( prompt ) ;
11771177 } ,
11781178 } ) ;
11791179
1180- // ── /kt -run-all command ─── ─────────────────────────────────────────
1180+ // ── /ticket -run-all command ─────────────────────────────────────────
11811181
1182- pi . registerCommand ( "kt -run-all" , {
1182+ pi . registerCommand ( "ticket -run-all" , {
11831183 description : "Process all ready tickets, optionally in separate sessions" ,
11841184 handler : async ( _args , ctx ) => {
11851185 const dir = getTicketsDir ( ctx . cwd ) ;
@@ -1204,17 +1204,17 @@ export default function ktExtension(pi: ExtensionAPI) {
12041204 "Work through all in this session" ,
12051205 "Cancel" ,
12061206 ] ;
1207- const forkChoice = await ctx . ui . select ( "kt -run-all: Session strategy" , forkOptions ) ;
1207+ const forkChoice = await ctx . ui . select ( "ticket -run-all: Session strategy" , forkOptions ) ;
12081208
12091209 if ( ! forkChoice || forkChoice === "Cancel" ) return ;
12101210
12111211 if ( forkChoice === "Work through all in this session" ) {
12121212 // Inject prompt to work through all tickets
12131213 const prompt =
12141214 `Work through these tickets in order, one at a time. For each ticket:\n` +
1215- `1. Use \`kt start <id>\` to begin\n` +
1215+ `1. Use \`ticket start <id>\` to begin\n` +
12161216 `2. Implement the work\n` +
1217- `3. Use \`kt close <id>\` when done (with tests_confirmed=true if it has tests)\n` +
1217+ `3. Use \`ticket close <id>\` when done (with tests_confirmed=true if it has tests)\n` +
12181218 `4. Move to the next ticket\n\n` +
12191219 `Ready tickets:\n${ ticketList } \n\nStart with the first one.` ;
12201220 ctx . ui . setEditorText ( prompt ) ;
@@ -1231,7 +1231,7 @@ export default function ktExtension(pi: ExtensionAPI) {
12311231 ( record . design ? `Design: ${ record . design } \n\n` : "" ) +
12321232 ( record . acceptance ? `Acceptance: ${ record . acceptance } \n\n` : "" ) +
12331233 ( record . tests ? `Tests: ${ record . tests } \n\n` : "" ) +
1234- `Steps:\n1. \`kt start ${ firstTicket . id } \`\n2. Implement the work\n3. \`kt close ${ firstTicket . id } \`${ record . tests ? " (with tests_confirmed=true after verifying tests)" : "" } \n\n` +
1234+ `Steps:\n1. \`ticket start ${ firstTicket . id } \`\n2. Implement the work\n3. \`ticket close ${ firstTicket . id } \`${ record . tests ? " (with tests_confirmed=true after verifying tests)" : "" } \n\n` +
12351235 `After closing, there are ${ ready . length - 1 } more tickets to process.` ;
12361236
12371237 // For fork-each, create a new session with the prompt
0 commit comments