Skip to content

Commit 654254d

Browse files
authored
refactor: rename kt extension to ticket (#19)
* refactor: rename kt extension to ticket * docs: update changelog
1 parent 96148c0 commit 654254d

5 files changed

Lines changed: 47 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ All notable changes to agent-stuff are documented here.
3434

3535

3636

37-
## feat/network-isolation-config
37+
38+
39+
## refactor/rename-kt-to-ticket
40+
41+
Renamed the `kt` extension to `ticket` for improved clarity and consistency (#19). All user-facing commands (`/ticket`, `/ticket-create`, `/ticket-run-all`), the `ticket` tool with its 9 actions, internal modules (`ticket-core.ts`), UI identifiers, and test files have been updated to reflect the new naming. This is a breaking change for users relying on `/kt` commands—they must now use the `/ticket` equivalents. The functionality and file storage structure (`.tickets/` directory) remain unchanged.
42+
43+
## [1.0.7](https://github.com/kostyay/agent-stuff/pull/18) - 2026-03-03
3844

3945
Added configurable network isolation controls to the sandbox extension (#18), enabling users to selectively weaken network restrictions for compatibility with Go-based CLI tools (gh, docker, etc.) that require macOS trust daemon access for TLS certificate verification. The new `enableWeakerNetworkIsolation` option is exposed in the `SandboxConfig` interface with a default value of `true` to support these commonly-used tools out-of-the-box, while still allowing stricter isolation configurations when needed. Configuration merging logic has been updated to properly handle the new isolation setting alongside existing sandbox policies.
4046

pi-extensions/plan-ask.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ export default function planAskExtension(pi: ExtensionAPI) {
329329
const planText = lastAssistant ? getTextContent(lastAssistant) : "";
330330

331331
const action = await ctx.ui.select("Plan complete - what would you like to do?", [
332-
"Create tickets with /kt-create",
332+
"Create tickets with /ticket-create",
333333
"Save plan to file",
334334
"Save plan and execute it",
335335
"Continue refining (stay in plan mode)",
@@ -342,9 +342,9 @@ export default function planAskExtension(pi: ExtensionAPI) {
342342
return;
343343
}
344344

345-
if (action === "Create tickets with /kt-create") {
345+
if (action === "Create tickets with /ticket-create") {
346346
setMode(AGENT, ctx);
347-
pi.sendUserMessage("/kt-create");
347+
pi.sendUserMessage("/ticket-create");
348348
return;
349349
}
350350

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
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. */
8484
type 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

118118
async 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
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/**
2-
* kt-core — Pure logic for the kt ticket tracker.
2+
* ticket-core — Pure logic for the ticket tracker.
33
*
44
* Contains all types, parsing, serialization, sorting, query helpers,
55
* and file I/O that have no dependency on pi extension APIs. Extracted
6-
* so that both kt.ts and unit tests can import this module directly.
6+
* so that both the ticket extension and unit tests can import this module directly.
77
*/
88

99
import crypto from "node:crypto";
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* Unit tests for kt-core — the pure logic layer of the kt ticket tracker.
2+
* Unit tests for ticket-core — the pure logic layer of the ticket tracker.
33
*
44
* Uses Node's built-in test runner (node:test + node:assert).
5-
* Run with: node --experimental-strip-types --test tests/kt-core.test.ts
5+
* Run with: node --experimental-strip-types --test tests/ticket-core.test.ts
66
*/
77

88
import { describe, it, before, after, afterEach, beforeEach } from "node:test";
@@ -46,13 +46,13 @@ import {
4646
splitContent,
4747
statusIcon,
4848
writeTicketFile,
49-
} from "../pi-extensions/kt/kt-core.ts";
49+
} from "../pi-extensions/ticket/ticket-core.ts";
5050

5151
// ── Helpers ────────────────────────────────────────────────────────────
5252

5353
/** Create a temporary directory for test isolation. */
5454
async function makeTmpDir(): Promise<string> {
55-
return fs.mkdtemp(path.join(os.tmpdir(), "kt-test-"));
55+
return fs.mkdtemp(path.join(os.tmpdir(), "ticket-test-"));
5656
}
5757

5858
/** Create a minimal TicketRecord for testing. */

0 commit comments

Comments
 (0)