@assistkick/create 1.11.0 → 1.12.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistkick/create",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Scaffold assistkick-product-system into any project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,6 +2,10 @@
2
2
  * Programmatic migration runner for Turso/libSQL.
3
3
  * Uses drizzle-orm/libsql/migrator instead of drizzle-kit CLI,
4
4
  * which has a known bug where it doesn't create __drizzle_migrations.
5
+ *
6
+ * After running migrations, verifies all schema columns exist in the database
7
+ * and adds any missing ones. This catches cases where drizzle-kit silently
8
+ * skips ALTER TABLE generation during db:generate.
5
9
  */
6
10
  import { config } from 'dotenv';
7
11
  config({ path: '../../.env' });
@@ -9,6 +13,8 @@ config({ path: '../../.env' });
9
13
  import { migrate } from 'drizzle-orm/libsql/migrator';
10
14
  import { drizzle } from 'drizzle-orm/libsql';
11
15
  import { createClient } from '@libsql/client';
16
+ import { getTableColumns, getTableName } from 'drizzle-orm';
17
+ import * as schema from './schema.js';
12
18
 
13
19
  const client = createClient({
14
20
  url: process.env.TURSO_DATABASE_URL!,
@@ -17,10 +23,86 @@ const client = createClient({
17
23
 
18
24
  const db = drizzle(client);
19
25
 
26
+ /**
27
+ * Map Drizzle column type to SQLite type string.
28
+ */
29
+ function getSqlType(column: any): string {
30
+ const type = column.columnType;
31
+ if (type.includes('Real')) return 'real';
32
+ if (type.includes('Integer')) return 'integer';
33
+ return 'text';
34
+ }
35
+
36
+ /**
37
+ * Verify all schema columns exist in the database and add any missing ones.
38
+ * This guards against drizzle-kit silently skipping ALTER TABLE generation.
39
+ */
40
+ async function syncColumns() {
41
+ const tables: Array<{ name: string; table: any }> = [];
42
+ for (const value of Object.values(schema)) {
43
+ try {
44
+ const name = getTableName(value as any);
45
+ if (name) tables.push({ name, table: value });
46
+ } catch {
47
+ // Not a table object, skip
48
+ }
49
+ }
50
+
51
+ let added = 0;
52
+ for (const { name: tableName, table } of tables) {
53
+ const result = await client.execute(`PRAGMA table_info('${tableName}')`);
54
+ if (result.rows.length === 0) continue;
55
+
56
+ const existingColumns = new Set(result.rows.map((r: any) => r.name as string));
57
+ const expectedColumns = getTableColumns(table);
58
+
59
+ for (const [, column] of Object.entries(expectedColumns)) {
60
+ const col = column as any;
61
+ if (existingColumns.has(col.name)) continue;
62
+
63
+ const sqlType = getSqlType(col);
64
+ const parts = [`ALTER TABLE \`${tableName}\` ADD \`${col.name}\` ${sqlType}`];
65
+
66
+ // Add DEFAULT clause if it's a SQL-level default
67
+ if (col.hasDefault && col.default !== undefined) {
68
+ const val = col.default;
69
+ if (typeof val === 'string') {
70
+ parts.push(`DEFAULT '${val}'`);
71
+ } else {
72
+ parts.push(`DEFAULT ${val}`);
73
+ }
74
+ }
75
+
76
+ // Add NOT NULL only if there's a default (SQLite requires this for ALTER TABLE ADD COLUMN)
77
+ if (col.notNull && col.hasDefault && col.default !== undefined) {
78
+ parts.push('NOT NULL');
79
+ } else if (col.notNull && !col.hasDefault) {
80
+ console.warn(` Warning: ${tableName}.${col.name} is NOT NULL without default — adding as nullable`);
81
+ }
82
+
83
+ const alterSql = parts.join(' ');
84
+ console.log(` Adding missing column: ${tableName}.${col.name}`);
85
+ await client.execute(alterSql);
86
+ added++;
87
+ }
88
+ }
89
+
90
+ return added;
91
+ }
92
+
20
93
  async function main() {
21
94
  console.log('Running migrations...');
22
95
  await migrate(db, { migrationsFolder: './db/migrations' });
23
96
  console.log('Migrations applied successfully.');
97
+
98
+ console.log('Verifying column sync...');
99
+ const added = await syncColumns();
100
+ if (added > 0) {
101
+ console.log(`Column sync complete — added ${added} missing column(s).`);
102
+ } else {
103
+ console.log('Column sync complete — all columns present.');
104
+ }
105
+
24
106
  client.close();
25
107
  process.exit(0);
26
108
  }
@@ -0,0 +1,277 @@
1
+ CREATE TABLE IF NOT EXISTS `agents` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `name` text NOT NULL,
4
+ `model` text DEFAULT 'claude-opus-4-6' NOT NULL,
5
+ `skills` text DEFAULT '[]' NOT NULL,
6
+ `grounding` text DEFAULT '' NOT NULL,
7
+ `default_grounding` text,
8
+ `project_id` text,
9
+ `is_default` integer DEFAULT 0 NOT NULL,
10
+ `created_at` text NOT NULL,
11
+ `updated_at` text NOT NULL
12
+ );
13
+ --> statement-breakpoint
14
+ CREATE TABLE IF NOT EXISTS `chat_messages` (
15
+ `id` text PRIMARY KEY NOT NULL,
16
+ `session_id` text NOT NULL,
17
+ `role` text NOT NULL,
18
+ `content` text NOT NULL,
19
+ `order_index` integer NOT NULL,
20
+ `created_at` text NOT NULL
21
+ );
22
+ --> statement-breakpoint
23
+ CREATE TABLE IF NOT EXISTS `chat_permission_rules` (
24
+ `id` text PRIMARY KEY NOT NULL,
25
+ `project_id` text NOT NULL,
26
+ `tool_name` text NOT NULL,
27
+ `created_at` text NOT NULL
28
+ );
29
+ --> statement-breakpoint
30
+ CREATE TABLE IF NOT EXISTS `chat_sessions` (
31
+ `id` text PRIMARY KEY NOT NULL,
32
+ `claude_session_id` text NOT NULL,
33
+ `project_id` text NOT NULL,
34
+ `name` text NOT NULL,
35
+ `permission_mode` text,
36
+ `continuation_context` text,
37
+ `system_prompt` text,
38
+ `context_usage_json` text,
39
+ `created_at` text NOT NULL,
40
+ `updated_at` text NOT NULL
41
+ );
42
+ --> statement-breakpoint
43
+ CREATE TABLE IF NOT EXISTS `coherence_reviews` (
44
+ `id` text PRIMARY KEY NOT NULL,
45
+ `type` text NOT NULL,
46
+ `from_id` text,
47
+ `to_id` text,
48
+ `relation` text,
49
+ `proposed_node_type` text,
50
+ `proposed_node_name` text,
51
+ `target_node_id` text,
52
+ `proposed_description` text,
53
+ `confidence` text,
54
+ `batch_id` text,
55
+ `reasoning` text NOT NULL,
56
+ `status` text NOT NULL,
57
+ `created_at` text NOT NULL,
58
+ `resolved_at` text,
59
+ `project_id` text
60
+ );
61
+ --> statement-breakpoint
62
+ CREATE TABLE IF NOT EXISTS `edges` (
63
+ `from_id` text NOT NULL,
64
+ `relation` text NOT NULL,
65
+ `to_id` text NOT NULL,
66
+ `project_id` text,
67
+ PRIMARY KEY(`from_id`, `relation`, `to_id`)
68
+ );
69
+ --> statement-breakpoint
70
+ CREATE TABLE IF NOT EXISTS `invitations` (
71
+ `id` text PRIMARY KEY NOT NULL,
72
+ `email` text NOT NULL,
73
+ `token_hash` text NOT NULL,
74
+ `invited_by` text NOT NULL,
75
+ `expires_at` text NOT NULL,
76
+ `accepted_at` text,
77
+ `created_at` text NOT NULL,
78
+ FOREIGN KEY (`invited_by`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
79
+ );
80
+ --> statement-breakpoint
81
+ CREATE TABLE IF NOT EXISTS `kanban` (
82
+ `node_id` text PRIMARY KEY NOT NULL,
83
+ `column_name` text NOT NULL,
84
+ `position` integer NOT NULL,
85
+ `project_id` text,
86
+ FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON UPDATE no action ON DELETE no action
87
+ );
88
+ --> statement-breakpoint
89
+ CREATE TABLE IF NOT EXISTS `nodes` (
90
+ `id` text PRIMARY KEY NOT NULL,
91
+ `type` text NOT NULL,
92
+ `name` text NOT NULL,
93
+ `status` text NOT NULL,
94
+ `priority` text NOT NULL,
95
+ `completeness` real DEFAULT 0 NOT NULL,
96
+ `open_questions_count` integer DEFAULT 0 NOT NULL,
97
+ `kind` text,
98
+ `feature_type` text,
99
+ `created_at` text NOT NULL,
100
+ `updated_at` text NOT NULL,
101
+ `body` text,
102
+ `project_id` text
103
+ );
104
+ --> statement-breakpoint
105
+ CREATE TABLE IF NOT EXISTS `password_reset_tokens` (
106
+ `id` text PRIMARY KEY NOT NULL,
107
+ `user_id` text NOT NULL,
108
+ `token_hash` text NOT NULL,
109
+ `expires_at` text NOT NULL,
110
+ `created_at` text NOT NULL,
111
+ `used_at` text,
112
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
113
+ );
114
+ --> statement-breakpoint
115
+ CREATE TABLE IF NOT EXISTS `pipeline_outputs` (
116
+ `id` text PRIMARY KEY NOT NULL,
117
+ `feature_id` text NOT NULL,
118
+ `stage` text NOT NULL,
119
+ `cycle` integer NOT NULL,
120
+ `output` text NOT NULL,
121
+ `created_at` text NOT NULL,
122
+ `project_id` text
123
+ );
124
+ --> statement-breakpoint
125
+ CREATE TABLE IF NOT EXISTS `pipeline_state` (
126
+ `feature_id` text PRIMARY KEY NOT NULL,
127
+ `status` text NOT NULL,
128
+ `cycle` integer DEFAULT 1 NOT NULL,
129
+ `tasks_json` text,
130
+ `tool_calls_json` text,
131
+ `work_summaries_json` text,
132
+ `stage_stats_json` text,
133
+ `error` text,
134
+ `updated_at` text NOT NULL,
135
+ `project_id` text
136
+ );
137
+ --> statement-breakpoint
138
+ CREATE TABLE IF NOT EXISTS `projects` (
139
+ `id` text PRIMARY KEY NOT NULL,
140
+ `name` text NOT NULL,
141
+ `type` text DEFAULT 'software' NOT NULL,
142
+ `is_default` integer DEFAULT 0 NOT NULL,
143
+ `archived_at` text,
144
+ `repo_url` text,
145
+ `github_installation_id` text,
146
+ `github_repo_full_name` text,
147
+ `base_branch` text,
148
+ `git_auth_method` text,
149
+ `ssh_private_key_encrypted` text,
150
+ `ssh_public_key` text,
151
+ `preview_command` text,
152
+ `created_at` text NOT NULL,
153
+ `updated_at` text NOT NULL
154
+ );
155
+ --> statement-breakpoint
156
+ CREATE TABLE IF NOT EXISTS `refresh_tokens` (
157
+ `id` text PRIMARY KEY NOT NULL,
158
+ `user_id` text NOT NULL,
159
+ `token_hash` text NOT NULL,
160
+ `expires_at` text NOT NULL,
161
+ `created_at` text NOT NULL,
162
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
163
+ );
164
+ --> statement-breakpoint
165
+ CREATE TABLE IF NOT EXISTS `review_meta` (
166
+ `key` text PRIMARY KEY NOT NULL,
167
+ `value` text NOT NULL,
168
+ `project_id` text
169
+ );
170
+ --> statement-breakpoint
171
+ CREATE TABLE IF NOT EXISTS `sessions` (
172
+ `session_number` integer NOT NULL,
173
+ `started_at` text NOT NULL,
174
+ `ended_at` text,
175
+ `summary` text,
176
+ `nodes_touched` text,
177
+ `questions_resolved` integer DEFAULT 0 NOT NULL,
178
+ `body` text,
179
+ `project_id` text NOT NULL,
180
+ PRIMARY KEY(`session_number`, `project_id`)
181
+ );
182
+ --> statement-breakpoint
183
+ CREATE TABLE IF NOT EXISTS `terminal_sessions` (
184
+ `id` text PRIMARY KEY NOT NULL,
185
+ `claude_session_id` text NOT NULL,
186
+ `project_id` text NOT NULL,
187
+ `project_name` text NOT NULL,
188
+ `name` text NOT NULL,
189
+ `session_type` text DEFAULT 'claude' NOT NULL,
190
+ `created_at` text NOT NULL,
191
+ `last_used_at` text NOT NULL
192
+ );
193
+ --> statement-breakpoint
194
+ CREATE TABLE IF NOT EXISTS `users` (
195
+ `id` text PRIMARY KEY NOT NULL,
196
+ `email` text NOT NULL,
197
+ `password_hash` text NOT NULL,
198
+ `role` text DEFAULT 'user' NOT NULL,
199
+ `created_at` text NOT NULL,
200
+ `updated_at` text NOT NULL
201
+ );
202
+ --> statement-breakpoint
203
+ CREATE UNIQUE INDEX IF NOT EXISTS `users_email_unique` ON `users` (`email`);--> statement-breakpoint
204
+ CREATE TABLE IF NOT EXISTS `video_renders` (
205
+ `id` text PRIMARY KEY NOT NULL,
206
+ `project_id` text NOT NULL,
207
+ `feature_id` text,
208
+ `composition_id` text NOT NULL,
209
+ `status` text NOT NULL,
210
+ `progress` real DEFAULT 0 NOT NULL,
211
+ `file_path` text,
212
+ `file_size` integer,
213
+ `duration_seconds` real,
214
+ `error` text,
215
+ `resolution` text,
216
+ `created_at` text NOT NULL,
217
+ `completed_at` text
218
+ );
219
+ --> statement-breakpoint
220
+ CREATE TABLE IF NOT EXISTS `workflow_executions` (
221
+ `id` text PRIMARY KEY NOT NULL,
222
+ `workflow_id` text NOT NULL,
223
+ `feature_id` text NOT NULL,
224
+ `status` text NOT NULL,
225
+ `current_node_id` text,
226
+ `context` text NOT NULL,
227
+ `started_at` text NOT NULL,
228
+ `updated_at` text NOT NULL,
229
+ FOREIGN KEY (`workflow_id`) REFERENCES `workflows`(`id`) ON UPDATE no action ON DELETE no action
230
+ );
231
+ --> statement-breakpoint
232
+ CREATE TABLE IF NOT EXISTS `workflow_groups` (
233
+ `id` text PRIMARY KEY NOT NULL,
234
+ `name` text NOT NULL,
235
+ `project_id` text,
236
+ `graph_data` text NOT NULL,
237
+ `created_at` text NOT NULL,
238
+ `updated_at` text NOT NULL
239
+ );
240
+ --> statement-breakpoint
241
+ CREATE TABLE IF NOT EXISTS `workflow_node_executions` (
242
+ `id` text PRIMARY KEY NOT NULL,
243
+ `execution_id` text NOT NULL,
244
+ `node_id` text NOT NULL,
245
+ `status` text NOT NULL,
246
+ `started_at` text,
247
+ `completed_at` text,
248
+ `output_data` text,
249
+ `error` text,
250
+ `attempt` integer DEFAULT 1 NOT NULL,
251
+ `cycle` integer DEFAULT 1 NOT NULL,
252
+ `claude_session_id` text,
253
+ FOREIGN KEY (`execution_id`) REFERENCES `workflow_executions`(`id`) ON UPDATE no action ON DELETE no action
254
+ );
255
+ --> statement-breakpoint
256
+ CREATE TABLE IF NOT EXISTS `workflow_tool_calls` (
257
+ `id` text PRIMARY KEY NOT NULL,
258
+ `node_execution_id` text NOT NULL,
259
+ `timestamp` text NOT NULL,
260
+ `tool_name` text NOT NULL,
261
+ `target` text NOT NULL,
262
+ `created_at` text NOT NULL,
263
+ FOREIGN KEY (`node_execution_id`) REFERENCES `workflow_node_executions`(`id`) ON UPDATE no action ON DELETE no action
264
+ );
265
+ --> statement-breakpoint
266
+ CREATE TABLE IF NOT EXISTS `workflows` (
267
+ `id` text PRIMARY KEY NOT NULL,
268
+ `name` text NOT NULL,
269
+ `description` text,
270
+ `project_id` text,
271
+ `feature_type` text,
272
+ `trigger_column` text,
273
+ `is_default` integer DEFAULT 0 NOT NULL,
274
+ `graph_data` text NOT NULL,
275
+ `created_at` text NOT NULL,
276
+ `updated_at` text NOT NULL
277
+ );