@sascha384/tic 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +17 -63
- package/drizzle/0000_next_vance_astro.sql +183 -0
- package/drizzle/meta/0000_snapshot.json +1188 -0
- package/drizzle/meta/_journal.json +13 -0
- package/package.json +2 -1
- package/skills/config/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# tic
|
|
2
2
|
|
|
3
|
-
A terminal UI for issue tracking, built for developers who live in the terminal. Track work items across multiple backends —
|
|
3
|
+
A terminal UI for issue tracking, built for developers who live in the terminal. Track work items across multiple backends — GitHub Issues, GitLab Issues, Azure DevOps Work Items, and Jira — with local SQLite storage.
|
|
4
4
|
|
|
5
5
|
Built with TypeScript and [Ink](https://github.com/vadimdemedes/ink).
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **Keyboard-driven TUI** — browse, create, edit, and manage work items without leaving the terminal
|
|
10
|
-
- **Multiple backends** —
|
|
10
|
+
- **Multiple backends** — GitHub (via `gh`), GitLab (via `glab`), Azure DevOps (via `az`), Jira (via REST API)
|
|
11
11
|
- **Automatic backend detection** — selects backend based on git remote, or configure manually
|
|
12
|
-
- **
|
|
12
|
+
- **SQLite storage** — all data stored locally in `.tic/tic.db` with optional sync to remote backends
|
|
13
13
|
- **CLI commands** — scriptable commands for all operations (`tic item list`, `tic item create`, etc.)
|
|
14
14
|
- **Work item types** — organize by epic, issue, and task (configurable)
|
|
15
15
|
- **Iterations** — group work into sprints or milestones
|
|
@@ -39,16 +39,18 @@ tic init # Initialize (auto-detects backend from git remote)
|
|
|
39
39
|
tic # Launch the TUI
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
`tic init` creates a `.tic/` directory with a SQLite database to store your work items. For GitHub, GitLab, or Azure DevOps projects, it detects the backend from the git remote automatically. You can also specify a backend explicitly:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
tic init --backend github
|
|
46
46
|
tic init --backend gitlab
|
|
47
47
|
tic init --backend azure
|
|
48
48
|
tic init --backend jira
|
|
49
|
-
tic init --backend
|
|
49
|
+
tic init --backend none
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
The TUI also auto-initializes on first run if no `.tic/` directory exists.
|
|
53
|
+
|
|
52
54
|
## Usage
|
|
53
55
|
|
|
54
56
|
### List View
|
|
@@ -123,70 +125,22 @@ Deleting an item automatically cleans up references — children have their pare
|
|
|
123
125
|
|
|
124
126
|
## Storage
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
All data lives in `.tic/` at the root of your project:
|
|
127
129
|
|
|
128
130
|
```
|
|
129
131
|
.tic/
|
|
130
|
-
├──
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
├── templates/ # Work item templates
|
|
136
|
-
│ └── bug-report.md # Template with YAML frontmatter
|
|
137
|
-
└── trash/ # Soft-deleted items (for undo)
|
|
132
|
+
├── tic.db # SQLite database (all items, config, undo log)
|
|
133
|
+
└── items/ # Markdown mirrors (for sync / human-readable export)
|
|
134
|
+
├── 1.md
|
|
135
|
+
├── 2.md
|
|
136
|
+
└── ...
|
|
138
137
|
```
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```markdown
|
|
143
|
-
---
|
|
144
|
-
id: 1
|
|
145
|
-
title: Implement user login
|
|
146
|
-
type: task
|
|
147
|
-
status: in-progress
|
|
148
|
-
iteration: sprint-1
|
|
149
|
-
priority: high
|
|
150
|
-
assignee: alice
|
|
151
|
-
labels: auth, backend
|
|
152
|
-
parent: 3
|
|
153
|
-
depends_on:
|
|
154
|
-
- 2
|
|
155
|
-
created: 2026-01-15T10:00:00.000Z
|
|
156
|
-
updated: 2026-01-20T14:30:00.000Z
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
Full description of the work item goes here.
|
|
160
|
-
|
|
161
|
-
## Comments
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
author: alice
|
|
165
|
-
date: 2026-01-18T09:00:00.000Z
|
|
166
|
-
|
|
167
|
-
Decided to use JWT tokens for this.
|
|
168
|
-
```
|
|
139
|
+
The SQLite database (`.tic/tic.db`) is the single source of truth for work items, config, templates, and undo history. When a remote backend is configured, `SyncManager` also writes markdown mirrors to `.tic/items/` via `FilesBackend`.
|
|
169
140
|
|
|
170
|
-
Configuration in
|
|
171
|
-
|
|
172
|
-
```yaml
|
|
173
|
-
types:
|
|
174
|
-
- epic
|
|
175
|
-
- issue
|
|
176
|
-
- task
|
|
177
|
-
statuses:
|
|
178
|
-
- backlog
|
|
179
|
-
- todo
|
|
180
|
-
- in-progress
|
|
181
|
-
- review
|
|
182
|
-
- done
|
|
183
|
-
iterations:
|
|
184
|
-
- default
|
|
185
|
-
current_iteration: default
|
|
186
|
-
next_id: 1
|
|
187
|
-
```
|
|
141
|
+
Configuration (types, statuses, iterations, etc.) is stored in the `project_config` table and managed via the TUI settings screen or `tic config` CLI commands.
|
|
188
142
|
|
|
189
|
-
|
|
143
|
+
If upgrading from a legacy `.tic/config.yml` setup, the database will automatically migrate the YAML config on first open.
|
|
190
144
|
|
|
191
145
|
## Claude Code Integration
|
|
192
146
|
|
|
@@ -240,7 +194,7 @@ Add `--json` to any command for machine-readable output, or `--quiet` to suppres
|
|
|
240
194
|
|
|
241
195
|
| Backend | CLI Tool | Detection |
|
|
242
196
|
|---------|----------|-----------|
|
|
243
|
-
| Local
|
|
197
|
+
| Local only (SQLite) | — | Default fallback |
|
|
244
198
|
| GitHub Issues | [`gh`](https://cli.github.com/) | `github.com` in git remote |
|
|
245
199
|
| GitLab Issues | [`glab`](https://gitlab.com/gitlab-org/cli) | `gitlab.com` in git remote |
|
|
246
200
|
| Azure DevOps Work Items | [`az`](https://learn.microsoft.com/en-us/cli/azure/) | `dev.azure.com` or `visualstudio.com` in git remote |
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
CREATE TABLE `comments` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`work_item_id` text NOT NULL,
|
|
4
|
+
`author` text DEFAULT '' NOT NULL,
|
|
5
|
+
`body` text NOT NULL,
|
|
6
|
+
`created` text NOT NULL,
|
|
7
|
+
FOREIGN KEY (`work_item_id`) REFERENCES `work_items`(`id`) ON UPDATE no action ON DELETE cascade
|
|
8
|
+
);
|
|
9
|
+
--> statement-breakpoint
|
|
10
|
+
CREATE INDEX `idx_comment_item` ON `comments` (`work_item_id`);--> statement-breakpoint
|
|
11
|
+
CREATE TABLE `file_sync_state` (
|
|
12
|
+
`item_id` text PRIMARY KEY NOT NULL,
|
|
13
|
+
`hash` text NOT NULL,
|
|
14
|
+
`synced_at` text NOT NULL
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE TABLE `iterations` (
|
|
18
|
+
`name` text PRIMARY KEY NOT NULL,
|
|
19
|
+
`sort_order` integer DEFAULT 0 NOT NULL
|
|
20
|
+
);
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
CREATE TABLE `jira_config` (
|
|
23
|
+
`id` integer PRIMARY KEY DEFAULT 1 NOT NULL,
|
|
24
|
+
`site` text DEFAULT '' NOT NULL,
|
|
25
|
+
`project` text DEFAULT '' NOT NULL,
|
|
26
|
+
`board_id` text DEFAULT '' NOT NULL
|
|
27
|
+
);
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
CREATE TABLE `project_config` (
|
|
30
|
+
`id` integer PRIMARY KEY DEFAULT 1 NOT NULL,
|
|
31
|
+
`backend` text DEFAULT 'none' NOT NULL,
|
|
32
|
+
`current_iteration` text DEFAULT '' NOT NULL,
|
|
33
|
+
`next_id` integer DEFAULT 1 NOT NULL,
|
|
34
|
+
`branch_mode` text DEFAULT 'branch' NOT NULL,
|
|
35
|
+
`branch_command` text DEFAULT '' NOT NULL,
|
|
36
|
+
`copy_to_clipboard` integer DEFAULT true NOT NULL,
|
|
37
|
+
`auto_update` integer DEFAULT true NOT NULL,
|
|
38
|
+
`default_type` text DEFAULT 'issue' NOT NULL,
|
|
39
|
+
`show_detail_panel` integer DEFAULT false NOT NULL,
|
|
40
|
+
`default_view` text DEFAULT '' NOT NULL
|
|
41
|
+
);
|
|
42
|
+
--> statement-breakpoint
|
|
43
|
+
CREATE TABLE `saved_view_filters` (
|
|
44
|
+
`view_name` text NOT NULL,
|
|
45
|
+
`field` text NOT NULL,
|
|
46
|
+
`value` text NOT NULL,
|
|
47
|
+
PRIMARY KEY(`view_name`, `field`, `value`),
|
|
48
|
+
FOREIGN KEY (`view_name`) REFERENCES `saved_views`(`name`) ON UPDATE no action ON DELETE cascade
|
|
49
|
+
);
|
|
50
|
+
--> statement-breakpoint
|
|
51
|
+
CREATE TABLE `saved_view_sort_entries` (
|
|
52
|
+
`view_name` text NOT NULL,
|
|
53
|
+
`column` text NOT NULL,
|
|
54
|
+
`direction` text NOT NULL,
|
|
55
|
+
`sort_order` integer NOT NULL,
|
|
56
|
+
PRIMARY KEY(`view_name`, `sort_order`),
|
|
57
|
+
FOREIGN KEY (`view_name`) REFERENCES `saved_views`(`name`) ON UPDATE no action ON DELETE cascade
|
|
58
|
+
);
|
|
59
|
+
--> statement-breakpoint
|
|
60
|
+
CREATE TABLE `saved_views` (
|
|
61
|
+
`name` text PRIMARY KEY NOT NULL
|
|
62
|
+
);
|
|
63
|
+
--> statement-breakpoint
|
|
64
|
+
CREATE TABLE `statuses` (
|
|
65
|
+
`name` text PRIMARY KEY NOT NULL,
|
|
66
|
+
`sort_order` integer DEFAULT 0 NOT NULL
|
|
67
|
+
);
|
|
68
|
+
--> statement-breakpoint
|
|
69
|
+
CREATE TABLE `sync_queue` (
|
|
70
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
71
|
+
`action` text NOT NULL,
|
|
72
|
+
`item_id` text NOT NULL,
|
|
73
|
+
`timestamp` text NOT NULL,
|
|
74
|
+
`comment_data` text,
|
|
75
|
+
`template_slug` text
|
|
76
|
+
);
|
|
77
|
+
--> statement-breakpoint
|
|
78
|
+
CREATE INDEX `idx_queue_item` ON `sync_queue` (`item_id`,`action`);--> statement-breakpoint
|
|
79
|
+
CREATE TABLE `template_deps` (
|
|
80
|
+
`template_slug` text NOT NULL,
|
|
81
|
+
`depends_on_id` text NOT NULL,
|
|
82
|
+
PRIMARY KEY(`template_slug`, `depends_on_id`),
|
|
83
|
+
FOREIGN KEY (`template_slug`) REFERENCES `templates`(`slug`) ON UPDATE no action ON DELETE cascade
|
|
84
|
+
);
|
|
85
|
+
--> statement-breakpoint
|
|
86
|
+
CREATE TABLE `template_labels` (
|
|
87
|
+
`template_slug` text NOT NULL,
|
|
88
|
+
`label` text NOT NULL,
|
|
89
|
+
PRIMARY KEY(`template_slug`, `label`),
|
|
90
|
+
FOREIGN KEY (`template_slug`) REFERENCES `templates`(`slug`) ON UPDATE no action ON DELETE cascade
|
|
91
|
+
);
|
|
92
|
+
--> statement-breakpoint
|
|
93
|
+
CREATE TABLE `templates` (
|
|
94
|
+
`slug` text PRIMARY KEY NOT NULL,
|
|
95
|
+
`name` text NOT NULL,
|
|
96
|
+
`type` text DEFAULT '' NOT NULL,
|
|
97
|
+
`status` text DEFAULT '' NOT NULL,
|
|
98
|
+
`priority` text DEFAULT '' NOT NULL,
|
|
99
|
+
`assignee` text DEFAULT '' NOT NULL,
|
|
100
|
+
`iteration` text DEFAULT '' NOT NULL,
|
|
101
|
+
`parent` text,
|
|
102
|
+
`description` text DEFAULT '' NOT NULL
|
|
103
|
+
);
|
|
104
|
+
--> statement-breakpoint
|
|
105
|
+
CREATE TABLE `undo_item_snapshot` (
|
|
106
|
+
`undo_id` integer PRIMARY KEY NOT NULL,
|
|
107
|
+
`title` text NOT NULL,
|
|
108
|
+
`type` text NOT NULL,
|
|
109
|
+
`status` text NOT NULL,
|
|
110
|
+
`iteration` text NOT NULL,
|
|
111
|
+
`priority` text NOT NULL,
|
|
112
|
+
`assignee` text NOT NULL,
|
|
113
|
+
`description` text NOT NULL,
|
|
114
|
+
`parent` text,
|
|
115
|
+
`created` text NOT NULL,
|
|
116
|
+
`updated` text NOT NULL,
|
|
117
|
+
FOREIGN KEY (`undo_id`) REFERENCES `undo_stack`(`id`) ON UPDATE no action ON DELETE cascade
|
|
118
|
+
);
|
|
119
|
+
--> statement-breakpoint
|
|
120
|
+
CREATE TABLE `undo_item_snapshot_deps` (
|
|
121
|
+
`undo_id` integer NOT NULL,
|
|
122
|
+
`depends_on_id` text NOT NULL,
|
|
123
|
+
PRIMARY KEY(`undo_id`, `depends_on_id`),
|
|
124
|
+
FOREIGN KEY (`undo_id`) REFERENCES `undo_stack`(`id`) ON UPDATE no action ON DELETE cascade
|
|
125
|
+
);
|
|
126
|
+
--> statement-breakpoint
|
|
127
|
+
CREATE TABLE `undo_item_snapshot_labels` (
|
|
128
|
+
`undo_id` integer NOT NULL,
|
|
129
|
+
`label` text NOT NULL,
|
|
130
|
+
PRIMARY KEY(`undo_id`, `label`),
|
|
131
|
+
FOREIGN KEY (`undo_id`) REFERENCES `undo_stack`(`id`) ON UPDATE no action ON DELETE cascade
|
|
132
|
+
);
|
|
133
|
+
--> statement-breakpoint
|
|
134
|
+
CREATE TABLE `undo_stack` (
|
|
135
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
136
|
+
`action` text NOT NULL,
|
|
137
|
+
`item_id` text NOT NULL,
|
|
138
|
+
`created_at` text NOT NULL
|
|
139
|
+
);
|
|
140
|
+
--> statement-breakpoint
|
|
141
|
+
CREATE TABLE `work_item_deps` (
|
|
142
|
+
`work_item_id` text NOT NULL,
|
|
143
|
+
`depends_on_id` text NOT NULL,
|
|
144
|
+
PRIMARY KEY(`work_item_id`, `depends_on_id`),
|
|
145
|
+
FOREIGN KEY (`work_item_id`) REFERENCES `work_items`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
146
|
+
FOREIGN KEY (`depends_on_id`) REFERENCES `work_items`(`id`) ON UPDATE no action ON DELETE cascade
|
|
147
|
+
);
|
|
148
|
+
--> statement-breakpoint
|
|
149
|
+
CREATE INDEX `idx_dep_target` ON `work_item_deps` (`depends_on_id`);--> statement-breakpoint
|
|
150
|
+
CREATE TABLE `work_item_labels` (
|
|
151
|
+
`work_item_id` text NOT NULL,
|
|
152
|
+
`label` text NOT NULL,
|
|
153
|
+
PRIMARY KEY(`work_item_id`, `label`),
|
|
154
|
+
FOREIGN KEY (`work_item_id`) REFERENCES `work_items`(`id`) ON UPDATE no action ON DELETE cascade
|
|
155
|
+
);
|
|
156
|
+
--> statement-breakpoint
|
|
157
|
+
CREATE INDEX `idx_label` ON `work_item_labels` (`label`);--> statement-breakpoint
|
|
158
|
+
CREATE TABLE `work_item_types` (
|
|
159
|
+
`name` text PRIMARY KEY NOT NULL,
|
|
160
|
+
`sort_order` integer DEFAULT 0 NOT NULL
|
|
161
|
+
);
|
|
162
|
+
--> statement-breakpoint
|
|
163
|
+
CREATE TABLE `work_items` (
|
|
164
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
165
|
+
`title` text NOT NULL,
|
|
166
|
+
`type` text NOT NULL,
|
|
167
|
+
`status` text NOT NULL,
|
|
168
|
+
`iteration` text DEFAULT '' NOT NULL,
|
|
169
|
+
`priority` text DEFAULT '' NOT NULL,
|
|
170
|
+
`assignee` text DEFAULT '' NOT NULL,
|
|
171
|
+
`description` text DEFAULT '' NOT NULL,
|
|
172
|
+
`parent` text,
|
|
173
|
+
`created` text NOT NULL,
|
|
174
|
+
`updated` text NOT NULL,
|
|
175
|
+
`deleted_at` text
|
|
176
|
+
);
|
|
177
|
+
--> statement-breakpoint
|
|
178
|
+
CREATE INDEX `idx_status` ON `work_items` (`status`);--> statement-breakpoint
|
|
179
|
+
CREATE INDEX `idx_type` ON `work_items` (`type`);--> statement-breakpoint
|
|
180
|
+
CREATE INDEX `idx_assignee` ON `work_items` (`assignee`);--> statement-breakpoint
|
|
181
|
+
CREATE INDEX `idx_priority` ON `work_items` (`priority`);--> statement-breakpoint
|
|
182
|
+
CREATE INDEX `idx_iteration` ON `work_items` (`iteration`);--> statement-breakpoint
|
|
183
|
+
CREATE INDEX `idx_parent` ON `work_items` (`parent`);
|