@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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tic",
3
3
  "description": "Issue tracking skills for Claude Code",
4
- "version": "2.0.0",
4
+ "version": "2.0.1",
5
5
  "author": {
6
6
  "name": "Sascha Krug"
7
7
  },
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 — local markdown files, GitHub Issues, GitLab Issues, Azure DevOps Work Items, and Jira.
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** — local markdown, GitHub (via `gh`), GitLab (via `glab`), Azure DevOps (via `az`), Jira (via REST API)
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
- - **Local markdown storage** — work items stored as markdown files with YAML frontmatter in a `.tic/` directory
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
- For local storage, `tic init` creates a `.tic/` directory 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:
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 local
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
- Work items live in `.tic/` at the root of your project:
128
+ All data lives in `.tic/` at the root of your project:
127
129
 
128
130
  ```
129
131
  .tic/
130
- ├── config.yml # Types, statuses, iterations, settings
131
- ├── items/
132
- ├── 1.md # Work item #1
133
- ├── 2.md # Work item #2
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
- Each item is a markdown file with YAML frontmatter:
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 `.tic/config.yml`:
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
- You can edit these files directly they're plain text. Customize types, statuses, and iterations by editing `config.yml`.
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 markdown | — | Default fallback |
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`);