@kaeawc/auto-mobile 0.0.85 → 0.0.87
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/README.md +3 -3
- package/README.md.backup +3 -3
- package/dist/build-info.json +10 -10
- package/dist/src/index.js +1173 -840
- package/dist/src/utils/workers/iosBundleExtractWorker.js +3 -3
- package/node_modules/strtok3/lib/stream/StreamReader.js +6 -1
- package/node_modules/strtok3/package.json +1 -1
- package/package.json +21 -17
- package/dist/schemas/managed-slot-contract.json +0 -142
- package/dist/src/db/eventTables.ts +0 -8
- package/dist/src/db/migrations/2025_12_28_000_initial_schema.ts +0 -28
- package/dist/src/db/migrations/2025_12_30_000_performance_thresholds.ts +0 -85
- package/dist/src/db/migrations/2025_12_30_001_navigation_graph.ts +0 -223
- package/dist/src/db/migrations/2025_12_31_000_accessibility_baselines.ts +0 -34
- package/dist/src/db/migrations/2025_12_31_001_memory_audit.ts +0 -120
- package/dist/src/db/migrations/2026_01_01_000_recomposition_metrics.ts +0 -44
- package/dist/src/db/migrations/2026_01_02_000_prediction_history.ts +0 -87
- package/dist/src/db/migrations/2026_01_03_000_feature_flags.ts +0 -17
- package/dist/src/db/migrations/2026_01_03_000_test_executions.ts +0 -45
- package/dist/src/db/migrations/2026_01_05_000_tool_calls.ts +0 -31
- package/dist/src/db/migrations/2026_01_08_000_test_coverage.ts +0 -109
- package/dist/src/db/migrations/2026_01_09_000_video_recordings.ts +0 -66
- package/dist/src/db/migrations/2026_01_10_000_device_snapshots.ts +0 -54
- package/dist/src/db/migrations/2026_01_11_000_installed_apps.ts +0 -33
- package/dist/src/db/migrations/2026_01_11_000_video_recording_highlights.ts +0 -24
- package/dist/src/db/migrations/2026_01_13_000_installed_apps_session_tracking.ts +0 -27
- package/dist/src/db/migrations/2026_01_14_000_appearance_config.ts +0 -16
- package/dist/src/db/migrations/2026_01_25_000_navigation_screenshots.ts +0 -27
- package/dist/src/db/migrations/2026_01_25_001_test_run_details.ts +0 -97
- package/dist/src/db/migrations/2026_01_27_000_crash_anr_monitoring.ts +0 -204
- package/dist/src/db/migrations/2026_01_27_000_failures.ts +0 -217
- package/dist/src/db/migrations/2026_01_29_000_named_nodes.ts +0 -88
- package/dist/src/db/migrations/2026_01_30_000_performance_live_metrics.ts +0 -108
- package/dist/src/db/migrations/2026_03_15_000_telemetry_events.ts +0 -184
- package/dist/src/db/migrations/2026_03_18_000_navigation_events.ts +0 -36
- package/dist/src/db/migrations/2026_03_19_000_storage_events.ts +0 -37
- package/dist/src/db/migrations/2026_03_19_001_layout_events.ts +0 -39
- package/dist/src/db/migrations/2026_03_19_002_storage_events_previous_value.ts +0 -23
- package/dist/src/db/migrations/2026_03_19_003_layout_events_screen_name.ts +0 -23
- package/dist/src/db/migrations/2026_03_20_000_network_event_details.ts +0 -32
- package/dist/src/db/migrations/2026_04_01_000_drop_custom_events.ts +0 -41
- package/dist/src/db/migrations/2026_04_02_000_device_sessions.ts +0 -51
- package/dist/src/db/migrations/2026_07_01_000_failure_groups_signature_unique.ts +0 -162
- package/dist/src/db/migrations/2026_07_02_000_event_composite_indexes.ts +0 -62
- package/dist/src/db/migrations/2026_07_03_000_drop_redundant_device_indexes.ts +0 -66
- package/dist/src/db/migrations/2026_07_03_000_repair_datetime_now_defaults.ts +0 -278
- package/dist/src/db/migrations/2026_07_04_000_storage_events_key_lookup.ts +0 -60
- package/dist/src/db/migrations/2026_07_05_000_repair_updated_at_defaults.ts +0 -239
- package/dist/src/db/migrations/2026_07_24_000_device_locks.ts +0 -27
- package/dist/src/db/migrations/2026_07_27_000_session_tool_capabilities.ts +0 -17
- package/dist/src/db/migrations/2026_07_31_000_video_recordings_owner_session.ts +0 -39
- package/dist/src/db/migrations/2026_08_02_000_navigation_provenance.ts +0 -159
- package/dist/src/db/migrations/2026_08_17_000_emulator_loss_incidents.ts +0 -39
- package/dist/src/db/migrations/2026_08_22_000_provision_device_operations.ts +0 -21
- package/dist/src/db/migrations/2026_08_22_001_session_tool_overrides.ts +0 -106
- package/dist/src/db/migrations/2026_08_22_002_navigation_observation_eviction_index.ts +0 -67
- package/dist/src/db/migrations/2026_08_22_003_device_teardown_operations.ts +0 -19
- package/dist/src/db/migrations/2026_08_23_000_device_teardown_operation_owner.ts +0 -19
- package/dist/src/db/migrations/2026_08_23_001_default_existing_delete_device_disabled.ts +0 -26
- package/dist/src/db/migrations/2026_08_24_000_installed_apps_profile_type.ts +0 -15
- package/dist/src/db/migrations/2026_09_06_000_tool_selection_profile_provenance.ts +0 -36
- package/dist/src/db/migrations/2026_09_08_000_provision_device_operations_expiry.ts +0 -25
- package/dist/src/db/migrations/2026_09_10_000_provision_device_operation_attempt.ts +0 -25
- package/dist/src/db/migrations/2026_09_10_001_device_session_retention_index.ts +0 -14
- package/dist/src/db/migrations/2026_09_13_000_device_snapshot_vm_reclaim.ts +0 -63
- package/dist/src/db/migrations/2026_09_14_000_device_session_stable_identity.ts +0 -9
- package/dist/src/db/migrations/2026_09_14_001_device_session_identity_writer_fence.ts +0 -45
- package/dist/src/db/migrations/2026_09_16_000_device_session_liveness_owner.ts +0 -9
- package/dist/src/db/migrations/2026_09_16_001_device_session_liveness_contract.ts +0 -37
- package/dist/src/db/migrations/2026_09_17_000_device_session_liveness_writer_fence.ts +0 -48
- package/dist/src/db/migrations/2026_09_17_001_device_session_identity_fence_same_serial.ts +0 -53
- package/dist/src/db/migrations/2026_09_20_000_provision_device_lifecycle_outcome.ts +0 -32
- package/dist/src/db/migrations/2026_09_29_000_navigation_suggestion_provenance.ts +0 -41
- package/dist/src/db/migrations/2026_09_30_000_video_recording_display.ts +0 -17
- package/dist/src/db/migrations/2026_09_30_001_network_capture_fields.ts +0 -30
- package/dist/src/db/migrations/2026_10_05_000_device_locks_device_identity.ts +0 -28
- package/dist/src/db/migrations/2026_10_05_001_storage_events_key_lookup_insertion_order.ts +0 -38
- package/dist/src/db/migrations/2026_10_05_002_test_edge_coverage_edge_id_index.ts +0 -19
- package/dist/src/db/migrations/2026_10_09_000_device_resource_applications.ts +0 -22
- package/dist/src/db/migrations/2026_10_09_001_drop_provision_device_operations.ts +0 -32
- package/dist/src/db/migrations/2026_10_09_002_drop_device_teardown_operations.ts +0 -28
- package/dist/src/db/migrations/2026_10_12_000_rename_recording_tool_names.ts +0 -44
- package/dist/src/db/migrations/2026_10_12_001_video_recording_capture_teardown.ts +0 -17
- package/dist/src/db/migrations/2026_10_13_000_video_recording_recorder_daemon.ts +0 -17
- package/dist/src/index.js.map +0 -1
- package/dist/src/utils/workers/iosBundleExtractWorker.js.map +0 -1
- package/schemas/managed-slot-contract.json +0 -142
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
// Create test_coverage_sessions table to track test run sessions
|
|
5
|
-
await db.schema
|
|
6
|
-
.createTable("test_coverage_sessions")
|
|
7
|
-
.ifNotExists()
|
|
8
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
9
|
-
.addColumn("session_uuid", "text", (col) => col.notNull().unique())
|
|
10
|
-
.addColumn("app_id", "text", (col) =>
|
|
11
|
-
col.notNull().references("navigation_apps.app_id").onDelete("cascade"),
|
|
12
|
-
)
|
|
13
|
-
.addColumn("start_time", "integer", (col) => col.notNull())
|
|
14
|
-
.addColumn("end_time", "integer")
|
|
15
|
-
.addColumn("total_nodes_visited", "integer", (col) => col.notNull().defaultTo(0))
|
|
16
|
-
.addColumn("total_edges_traversed", "integer", (col) => col.notNull().defaultTo(0))
|
|
17
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
18
|
-
.execute();
|
|
19
|
-
|
|
20
|
-
// Create index on session_uuid for fast lookups
|
|
21
|
-
await db.schema
|
|
22
|
-
.createIndex("idx_test_coverage_sessions_uuid")
|
|
23
|
-
.ifNotExists()
|
|
24
|
-
.on("test_coverage_sessions")
|
|
25
|
-
.column("session_uuid")
|
|
26
|
-
.execute();
|
|
27
|
-
|
|
28
|
-
// Create index on app_id for filtering by app
|
|
29
|
-
await db.schema
|
|
30
|
-
.createIndex("idx_test_coverage_sessions_app")
|
|
31
|
-
.ifNotExists()
|
|
32
|
-
.on("test_coverage_sessions")
|
|
33
|
-
.column("app_id")
|
|
34
|
-
.execute();
|
|
35
|
-
|
|
36
|
-
// Create test_node_coverage table to track which nodes were visited during tests
|
|
37
|
-
await db.schema
|
|
38
|
-
.createTable("test_node_coverage")
|
|
39
|
-
.ifNotExists()
|
|
40
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
41
|
-
.addColumn("session_id", "integer", (col) =>
|
|
42
|
-
col.notNull().references("test_coverage_sessions.id").onDelete("cascade"),
|
|
43
|
-
)
|
|
44
|
-
.addColumn("node_id", "integer", (col) =>
|
|
45
|
-
col.notNull().references("navigation_nodes.id").onDelete("cascade"),
|
|
46
|
-
)
|
|
47
|
-
.addColumn("visit_count", "integer", (col) => col.notNull().defaultTo(1))
|
|
48
|
-
.addColumn("first_visit_time", "integer", (col) => col.notNull())
|
|
49
|
-
.addColumn("last_visit_time", "integer", (col) => col.notNull())
|
|
50
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
51
|
-
.execute();
|
|
52
|
-
|
|
53
|
-
// Create unique constraint on (session_id, node_id)
|
|
54
|
-
await db.schema
|
|
55
|
-
.createIndex("idx_test_node_coverage_session_node")
|
|
56
|
-
.ifNotExists()
|
|
57
|
-
.on("test_node_coverage")
|
|
58
|
-
.columns(["session_id", "node_id"])
|
|
59
|
-
.unique()
|
|
60
|
-
.execute();
|
|
61
|
-
|
|
62
|
-
// Create index on session_id for efficient queries
|
|
63
|
-
await db.schema
|
|
64
|
-
.createIndex("idx_test_node_coverage_session")
|
|
65
|
-
.ifNotExists()
|
|
66
|
-
.on("test_node_coverage")
|
|
67
|
-
.column("session_id")
|
|
68
|
-
.execute();
|
|
69
|
-
|
|
70
|
-
// Create test_edge_coverage table to track which edges were traversed during tests
|
|
71
|
-
await db.schema
|
|
72
|
-
.createTable("test_edge_coverage")
|
|
73
|
-
.ifNotExists()
|
|
74
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
75
|
-
.addColumn("session_id", "integer", (col) =>
|
|
76
|
-
col.notNull().references("test_coverage_sessions.id").onDelete("cascade"),
|
|
77
|
-
)
|
|
78
|
-
.addColumn("edge_id", "integer", (col) =>
|
|
79
|
-
col.notNull().references("navigation_edges.id").onDelete("cascade"),
|
|
80
|
-
)
|
|
81
|
-
.addColumn("traversal_count", "integer", (col) => col.notNull().defaultTo(1))
|
|
82
|
-
.addColumn("first_traversal_time", "integer", (col) => col.notNull())
|
|
83
|
-
.addColumn("last_traversal_time", "integer", (col) => col.notNull())
|
|
84
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
85
|
-
.execute();
|
|
86
|
-
|
|
87
|
-
// Create unique constraint on (session_id, edge_id)
|
|
88
|
-
await db.schema
|
|
89
|
-
.createIndex("idx_test_edge_coverage_session_edge")
|
|
90
|
-
.ifNotExists()
|
|
91
|
-
.on("test_edge_coverage")
|
|
92
|
-
.columns(["session_id", "edge_id"])
|
|
93
|
-
.unique()
|
|
94
|
-
.execute();
|
|
95
|
-
|
|
96
|
-
// Create index on session_id for efficient queries
|
|
97
|
-
await db.schema
|
|
98
|
-
.createIndex("idx_test_edge_coverage_session")
|
|
99
|
-
.ifNotExists()
|
|
100
|
-
.on("test_edge_coverage")
|
|
101
|
-
.column("session_id")
|
|
102
|
-
.execute();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
106
|
-
await db.schema.dropTable("test_edge_coverage").execute();
|
|
107
|
-
await db.schema.dropTable("test_node_coverage").execute();
|
|
108
|
-
await db.schema.dropTable("test_coverage_sessions").execute();
|
|
109
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.schema
|
|
5
|
-
.createTable("video_recordings")
|
|
6
|
-
.ifNotExists()
|
|
7
|
-
.addColumn("recording_id", "text", (col) => col.primaryKey())
|
|
8
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
9
|
-
.addColumn("platform", "text", (col) => col.notNull())
|
|
10
|
-
.addColumn("status", "text", (col) => col.notNull())
|
|
11
|
-
.addColumn("output_name", "text")
|
|
12
|
-
.addColumn("file_name", "text", (col) => col.notNull())
|
|
13
|
-
.addColumn("file_path", "text", (col) => col.notNull())
|
|
14
|
-
.addColumn("format", "text", (col) => col.notNull())
|
|
15
|
-
.addColumn("size_bytes", "integer", (col) => col.notNull().defaultTo(0))
|
|
16
|
-
.addColumn("duration_ms", "integer")
|
|
17
|
-
.addColumn("codec", "text")
|
|
18
|
-
.addColumn("created_at", "text", (col) => col.notNull())
|
|
19
|
-
.addColumn("started_at", "text", (col) => col.notNull())
|
|
20
|
-
.addColumn("ended_at", "text")
|
|
21
|
-
.addColumn("last_accessed_at", "text", (col) => col.notNull())
|
|
22
|
-
.addColumn("config_json", "text", (col) => col.notNull())
|
|
23
|
-
.execute();
|
|
24
|
-
|
|
25
|
-
await db.schema
|
|
26
|
-
.createIndex("idx_video_recordings_status")
|
|
27
|
-
.ifNotExists()
|
|
28
|
-
.on("video_recordings")
|
|
29
|
-
.column("status")
|
|
30
|
-
.execute();
|
|
31
|
-
|
|
32
|
-
await db.schema
|
|
33
|
-
.createIndex("idx_video_recordings_device_status")
|
|
34
|
-
.ifNotExists()
|
|
35
|
-
.on("video_recordings")
|
|
36
|
-
.columns(["device_id", "status"])
|
|
37
|
-
.execute();
|
|
38
|
-
|
|
39
|
-
await db.schema
|
|
40
|
-
.createIndex("idx_video_recordings_last_accessed_at")
|
|
41
|
-
.ifNotExists()
|
|
42
|
-
.on("video_recordings")
|
|
43
|
-
.column("last_accessed_at")
|
|
44
|
-
.execute();
|
|
45
|
-
|
|
46
|
-
await db.schema
|
|
47
|
-
.createIndex("idx_video_recordings_created_at")
|
|
48
|
-
.ifNotExists()
|
|
49
|
-
.on("video_recordings")
|
|
50
|
-
.column("created_at")
|
|
51
|
-
.execute();
|
|
52
|
-
|
|
53
|
-
await db.schema
|
|
54
|
-
.createTable("video_recording_configs")
|
|
55
|
-
.ifNotExists()
|
|
56
|
-
.addColumn("key", "text", (col) => col.primaryKey())
|
|
57
|
-
.addColumn("config_json", "text", (col) => col.notNull())
|
|
58
|
-
.addColumn("updated_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
59
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
60
|
-
.execute();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
64
|
-
await db.schema.dropTable("video_recordings").execute();
|
|
65
|
-
await db.schema.dropTable("video_recording_configs").execute();
|
|
66
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.schema
|
|
5
|
-
.createTable("device_snapshots")
|
|
6
|
-
.ifNotExists()
|
|
7
|
-
.addColumn("snapshot_name", "text", (col) => col.primaryKey())
|
|
8
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
9
|
-
.addColumn("device_name", "text", (col) => col.notNull())
|
|
10
|
-
.addColumn("platform", "text", (col) => col.notNull())
|
|
11
|
-
.addColumn("snapshot_type", "text", (col) => col.notNull())
|
|
12
|
-
.addColumn("include_app_data", "integer", (col) => col.notNull())
|
|
13
|
-
.addColumn("include_settings", "integer", (col) => col.notNull())
|
|
14
|
-
.addColumn("created_at", "text", (col) => col.notNull())
|
|
15
|
-
.addColumn("last_accessed_at", "text", (col) => col.notNull())
|
|
16
|
-
.addColumn("size_bytes", "integer", (col) => col.notNull().defaultTo(0))
|
|
17
|
-
.addColumn("manifest_json", "text", (col) => col.notNull())
|
|
18
|
-
.execute();
|
|
19
|
-
|
|
20
|
-
await db.schema
|
|
21
|
-
.createIndex("idx_device_snapshots_device_id")
|
|
22
|
-
.ifNotExists()
|
|
23
|
-
.on("device_snapshots")
|
|
24
|
-
.column("device_id")
|
|
25
|
-
.execute();
|
|
26
|
-
|
|
27
|
-
await db.schema
|
|
28
|
-
.createIndex("idx_device_snapshots_last_accessed_at")
|
|
29
|
-
.ifNotExists()
|
|
30
|
-
.on("device_snapshots")
|
|
31
|
-
.column("last_accessed_at")
|
|
32
|
-
.execute();
|
|
33
|
-
|
|
34
|
-
await db.schema
|
|
35
|
-
.createIndex("idx_device_snapshots_created_at")
|
|
36
|
-
.ifNotExists()
|
|
37
|
-
.on("device_snapshots")
|
|
38
|
-
.column("created_at")
|
|
39
|
-
.execute();
|
|
40
|
-
|
|
41
|
-
await db.schema
|
|
42
|
-
.createTable("device_snapshot_configs")
|
|
43
|
-
.ifNotExists()
|
|
44
|
-
.addColumn("key", "text", (col) => col.primaryKey())
|
|
45
|
-
.addColumn("config_json", "text", (col) => col.notNull())
|
|
46
|
-
.addColumn("updated_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
47
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
48
|
-
.execute();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
52
|
-
await db.schema.dropTable("device_snapshots").execute();
|
|
53
|
-
await db.schema.dropTable("device_snapshot_configs").execute();
|
|
54
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.schema
|
|
5
|
-
.createTable("installed_apps")
|
|
6
|
-
.ifNotExists()
|
|
7
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
8
|
-
.addColumn("user_id", "integer", (col) => col.notNull())
|
|
9
|
-
.addColumn("package_name", "text", (col) => col.notNull())
|
|
10
|
-
.addColumn("is_system", "integer", (col) => col.notNull().defaultTo(0))
|
|
11
|
-
.addColumn("installed_at", "integer", (col) => col.notNull())
|
|
12
|
-
.addColumn("last_verified_at", "integer", (col) => col.notNull())
|
|
13
|
-
.addPrimaryKeyConstraint("installed_apps_pk", ["device_id", "user_id", "package_name"])
|
|
14
|
-
.execute();
|
|
15
|
-
|
|
16
|
-
await db.schema
|
|
17
|
-
.createIndex("idx_installed_apps_lookup")
|
|
18
|
-
.ifNotExists()
|
|
19
|
-
.on("installed_apps")
|
|
20
|
-
.columns(["device_id", "package_name"])
|
|
21
|
-
.execute();
|
|
22
|
-
|
|
23
|
-
await db.schema
|
|
24
|
-
.createIndex("idx_installed_apps_last_verified")
|
|
25
|
-
.ifNotExists()
|
|
26
|
-
.on("installed_apps")
|
|
27
|
-
.columns(["device_id", "last_verified_at"])
|
|
28
|
-
.execute();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
32
|
-
await db.schema.dropTable("installed_apps").execute();
|
|
33
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
import { sql } from "kysely";
|
|
3
|
-
|
|
4
|
-
async function columnExists(
|
|
5
|
-
db: Kysely<unknown>,
|
|
6
|
-
tableName: string,
|
|
7
|
-
columnName: string,
|
|
8
|
-
): Promise<boolean> {
|
|
9
|
-
const result = await sql<{ name: string }>`
|
|
10
|
-
SELECT name FROM pragma_table_info(${tableName}) WHERE name = ${columnName}
|
|
11
|
-
`.execute(db);
|
|
12
|
-
return result.rows.length > 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
const exists = await columnExists(db, "video_recordings", "highlights_json");
|
|
17
|
-
if (!exists) {
|
|
18
|
-
await db.schema.alterTable("video_recordings").addColumn("highlights_json", "text").execute();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
23
|
-
await db.schema.alterTable("video_recordings").dropColumn("highlights_json").execute();
|
|
24
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
// Add session tracking columns to installed_apps table
|
|
5
|
-
await db.schema.alterTable("installed_apps").addColumn("daemon_session_id", "text").execute();
|
|
6
|
-
|
|
7
|
-
await db.schema
|
|
8
|
-
.alterTable("installed_apps")
|
|
9
|
-
.addColumn("device_session_start", "integer")
|
|
10
|
-
.execute();
|
|
11
|
-
|
|
12
|
-
// Create index for efficient session-based cleanup queries
|
|
13
|
-
await db.schema
|
|
14
|
-
.createIndex("idx_installed_apps_session")
|
|
15
|
-
.ifNotExists()
|
|
16
|
-
.on("installed_apps")
|
|
17
|
-
.columns(["daemon_session_id", "device_session_start"])
|
|
18
|
-
.execute();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
22
|
-
await db.schema.dropIndex("idx_installed_apps_session").execute();
|
|
23
|
-
|
|
24
|
-
await db.schema.alterTable("installed_apps").dropColumn("daemon_session_id").execute();
|
|
25
|
-
|
|
26
|
-
await db.schema.alterTable("installed_apps").dropColumn("device_session_start").execute();
|
|
27
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.schema
|
|
5
|
-
.createTable("appearance_configs")
|
|
6
|
-
.ifNotExists()
|
|
7
|
-
.addColumn("key", "text", (col) => col.primaryKey())
|
|
8
|
-
.addColumn("config_json", "text", (col) => col.notNull())
|
|
9
|
-
.addColumn("updated_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
10
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
11
|
-
.execute();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
15
|
-
await db.schema.dropTable("appearance_configs").execute();
|
|
16
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
import { sql } from "kysely";
|
|
3
|
-
|
|
4
|
-
async function columnExists(
|
|
5
|
-
db: Kysely<unknown>,
|
|
6
|
-
tableName: string,
|
|
7
|
-
columnName: string,
|
|
8
|
-
): Promise<boolean> {
|
|
9
|
-
const result = await sql<{ name: string }>`
|
|
10
|
-
SELECT name FROM pragma_table_info(${tableName}) WHERE name = ${columnName}
|
|
11
|
-
`.execute(db);
|
|
12
|
-
return result.rows.length > 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
// Add screenshot_path column to navigation_nodes table (if not already present)
|
|
17
|
-
const hasColumn = await columnExists(db, "navigation_nodes", "screenshot_path");
|
|
18
|
-
if (!hasColumn) {
|
|
19
|
-
await db.schema.alterTable("navigation_nodes").addColumn("screenshot_path", "text").execute();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
24
|
-
// SQLite doesn't support dropping columns directly, so we need to recreate the table
|
|
25
|
-
// For simplicity, we'll use a workaround since SQLite 3.35.0+ supports DROP COLUMN
|
|
26
|
-
await db.schema.alterTable("navigation_nodes").dropColumn("screenshot_path").execute();
|
|
27
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
import { sql } from "kysely";
|
|
3
|
-
|
|
4
|
-
async function columnExists(
|
|
5
|
-
db: Kysely<unknown>,
|
|
6
|
-
tableName: string,
|
|
7
|
-
columnName: string,
|
|
8
|
-
): Promise<boolean> {
|
|
9
|
-
const result = await sql<{ name: string }>`
|
|
10
|
-
SELECT name FROM pragma_table_info(${tableName}) WHERE name = ${columnName}
|
|
11
|
-
`.execute(db);
|
|
12
|
-
return result.rows.length > 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function tableExists(db: Kysely<unknown>, tableName: string): Promise<boolean> {
|
|
16
|
-
const result = await sql<{ name: string }>`
|
|
17
|
-
SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${tableName}
|
|
18
|
-
`.execute(db);
|
|
19
|
-
return result.rows.length > 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
23
|
-
// Add error_message column to test_executions for storing failure details
|
|
24
|
-
if (!(await columnExists(db, "test_executions", "error_message"))) {
|
|
25
|
-
await db.schema.alterTable("test_executions").addColumn("error_message", "text").execute();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Add video_path for test recordings
|
|
29
|
-
if (!(await columnExists(db, "test_executions", "video_path"))) {
|
|
30
|
-
await db.schema.alterTable("test_executions").addColumn("video_path", "text").execute();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Add snapshot_path for test snapshots
|
|
34
|
-
if (!(await columnExists(db, "test_executions", "snapshot_path"))) {
|
|
35
|
-
await db.schema.alterTable("test_executions").addColumn("snapshot_path", "text").execute();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Create test_execution_steps table for step-level data (if not exists)
|
|
39
|
-
if (!(await tableExists(db, "test_execution_steps"))) {
|
|
40
|
-
await db.schema
|
|
41
|
-
.createTable("test_execution_steps")
|
|
42
|
-
.ifNotExists()
|
|
43
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
44
|
-
.addColumn("execution_id", "integer", (col) =>
|
|
45
|
-
col.notNull().references("test_executions.id").onDelete("cascade"),
|
|
46
|
-
)
|
|
47
|
-
.addColumn("step_index", "integer", (col) => col.notNull())
|
|
48
|
-
.addColumn("action", "text", (col) => col.notNull()) // Tool name or action type
|
|
49
|
-
.addColumn("target", "text") // Element target description
|
|
50
|
-
.addColumn("status", "text", (col) => col.notNull()) // completed, failed, skipped
|
|
51
|
-
.addColumn("duration_ms", "integer", (col) => col.notNull())
|
|
52
|
-
.addColumn("screen_name", "text") // Screen name when step was executed
|
|
53
|
-
.addColumn("screenshot_path", "text") // Screenshot captured for this step
|
|
54
|
-
.addColumn("error_message", "text") // Error message if step failed
|
|
55
|
-
.addColumn("details_json", "text") // Additional step details as JSON
|
|
56
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
57
|
-
.execute();
|
|
58
|
-
|
|
59
|
-
await db.schema
|
|
60
|
-
.createIndex("idx_test_execution_steps_execution")
|
|
61
|
-
.ifNotExists()
|
|
62
|
-
.on("test_execution_steps")
|
|
63
|
-
.column("execution_id")
|
|
64
|
-
.execute();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Create test_execution_screens table for screens visited during test (if not exists)
|
|
68
|
-
if (!(await tableExists(db, "test_execution_screens"))) {
|
|
69
|
-
await db.schema
|
|
70
|
-
.createTable("test_execution_screens")
|
|
71
|
-
.ifNotExists()
|
|
72
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
73
|
-
.addColumn("execution_id", "integer", (col) =>
|
|
74
|
-
col.notNull().references("test_executions.id").onDelete("cascade"),
|
|
75
|
-
)
|
|
76
|
-
.addColumn("screen_name", "text", (col) => col.notNull())
|
|
77
|
-
.addColumn("visit_order", "integer", (col) => col.notNull())
|
|
78
|
-
.addColumn("timestamp", "integer", (col) => col.notNull())
|
|
79
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
80
|
-
.execute();
|
|
81
|
-
|
|
82
|
-
await db.schema
|
|
83
|
-
.createIndex("idx_test_execution_screens_execution")
|
|
84
|
-
.ifNotExists()
|
|
85
|
-
.on("test_execution_screens")
|
|
86
|
-
.column("execution_id")
|
|
87
|
-
.execute();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
92
|
-
await db.schema.dropTable("test_execution_screens").execute();
|
|
93
|
-
await db.schema.dropTable("test_execution_steps").execute();
|
|
94
|
-
|
|
95
|
-
// Note: SQLite doesn't support DROP COLUMN, so we can't remove the added columns
|
|
96
|
-
// In production, would need to recreate the table without these columns
|
|
97
|
-
}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
import { sql } from "kysely";
|
|
3
|
-
|
|
4
|
-
async function columnExists(
|
|
5
|
-
db: Kysely<unknown>,
|
|
6
|
-
tableName: string,
|
|
7
|
-
columnName: string,
|
|
8
|
-
): Promise<boolean> {
|
|
9
|
-
const result = await sql<{ name: string }>`
|
|
10
|
-
SELECT name FROM pragma_table_info(${tableName}) WHERE name = ${columnName}
|
|
11
|
-
`.execute(db);
|
|
12
|
-
return result.rows.length > 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function tableExists(db: Kysely<unknown>, tableName: string): Promise<boolean> {
|
|
16
|
-
const result = await sql<{ name: string }>`
|
|
17
|
-
SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${tableName}
|
|
18
|
-
`.execute(db);
|
|
19
|
-
return result.rows.length > 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
23
|
-
// Extend tool_calls table with failure tracking columns
|
|
24
|
-
if (!(await columnExists(db, "tool_calls", "status"))) {
|
|
25
|
-
await db.schema
|
|
26
|
-
.alterTable("tool_calls")
|
|
27
|
-
.addColumn("status", "text", (col) => col.defaultTo("success"))
|
|
28
|
-
.execute();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (!(await columnExists(db, "tool_calls", "error_message"))) {
|
|
32
|
-
await db.schema.alterTable("tool_calls").addColumn("error_message", "text").execute();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!(await columnExists(db, "tool_calls", "error_type"))) {
|
|
36
|
-
await db.schema.alterTable("tool_calls").addColumn("error_type", "text").execute();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!(await columnExists(db, "tool_calls", "device_id"))) {
|
|
40
|
-
await db.schema.alterTable("tool_calls").addColumn("device_id", "text").execute();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!(await columnExists(db, "tool_calls", "package_name"))) {
|
|
44
|
-
await db.schema.alterTable("tool_calls").addColumn("package_name", "text").execute();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!(await columnExists(db, "tool_calls", "duration_ms"))) {
|
|
48
|
-
await db.schema.alterTable("tool_calls").addColumn("duration_ms", "integer").execute();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!(await columnExists(db, "tool_calls", "tool_args"))) {
|
|
52
|
-
await db.schema.alterTable("tool_calls").addColumn("tool_args", "text").execute();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Create index for failed tool calls
|
|
56
|
-
await db.schema
|
|
57
|
-
.createIndex("idx_tool_calls_status")
|
|
58
|
-
.ifNotExists()
|
|
59
|
-
.on("tool_calls")
|
|
60
|
-
.column("status")
|
|
61
|
-
.ifNotExists()
|
|
62
|
-
.execute();
|
|
63
|
-
|
|
64
|
-
// Create crashes table
|
|
65
|
-
if (!(await tableExists(db, "crashes"))) {
|
|
66
|
-
await db.schema
|
|
67
|
-
.createTable("crashes")
|
|
68
|
-
.ifNotExists()
|
|
69
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
70
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
71
|
-
.addColumn("package_name", "text", (col) => col.notNull())
|
|
72
|
-
.addColumn("crash_type", "text", (col) => col.notNull()) // java, native, system
|
|
73
|
-
.addColumn("timestamp", "integer", (col) => col.notNull())
|
|
74
|
-
.addColumn("process_name", "text")
|
|
75
|
-
.addColumn("pid", "integer")
|
|
76
|
-
.addColumn("exception_class", "text") // e.g., NullPointerException
|
|
77
|
-
.addColumn("exception_message", "text")
|
|
78
|
-
.addColumn("stacktrace", "text")
|
|
79
|
-
.addColumn("signal", "text") // For native crashes (SIGSEGV, SIGABRT, etc.)
|
|
80
|
-
.addColumn("fault_address", "text") // For native crashes
|
|
81
|
-
.addColumn("tombstone_path", "text") // Path to tombstone file if available
|
|
82
|
-
.addColumn("detection_source", "text", (col) => col.notNull()) // logcat, tombstone, dropbox, accessibility, process_monitor
|
|
83
|
-
.addColumn("raw_log", "text") // Raw crash log output
|
|
84
|
-
// Nullable FKs for linking to navigation and test runs
|
|
85
|
-
.addColumn("navigation_node_id", "integer", (col) =>
|
|
86
|
-
col.references("navigation_nodes.id").onDelete("set null"),
|
|
87
|
-
)
|
|
88
|
-
.addColumn("test_execution_id", "integer", (col) =>
|
|
89
|
-
col.references("test_executions.id").onDelete("set null"),
|
|
90
|
-
)
|
|
91
|
-
.addColumn("session_uuid", "text")
|
|
92
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
93
|
-
.execute();
|
|
94
|
-
|
|
95
|
-
await db.schema
|
|
96
|
-
.createIndex("idx_crashes_device_id")
|
|
97
|
-
.ifNotExists()
|
|
98
|
-
.on("crashes")
|
|
99
|
-
.column("device_id")
|
|
100
|
-
.execute();
|
|
101
|
-
|
|
102
|
-
await db.schema
|
|
103
|
-
.createIndex("idx_crashes_package_name")
|
|
104
|
-
.ifNotExists()
|
|
105
|
-
.on("crashes")
|
|
106
|
-
.column("package_name")
|
|
107
|
-
.execute();
|
|
108
|
-
|
|
109
|
-
await db.schema
|
|
110
|
-
.createIndex("idx_crashes_timestamp")
|
|
111
|
-
.ifNotExists()
|
|
112
|
-
.on("crashes")
|
|
113
|
-
.column("timestamp")
|
|
114
|
-
.execute();
|
|
115
|
-
|
|
116
|
-
await db.schema
|
|
117
|
-
.createIndex("idx_crashes_navigation_node")
|
|
118
|
-
.ifNotExists()
|
|
119
|
-
.on("crashes")
|
|
120
|
-
.column("navigation_node_id")
|
|
121
|
-
.execute();
|
|
122
|
-
|
|
123
|
-
await db.schema
|
|
124
|
-
.createIndex("idx_crashes_test_execution")
|
|
125
|
-
.ifNotExists()
|
|
126
|
-
.on("crashes")
|
|
127
|
-
.column("test_execution_id")
|
|
128
|
-
.execute();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Create ANRs table
|
|
132
|
-
if (!(await tableExists(db, "anrs"))) {
|
|
133
|
-
await db.schema
|
|
134
|
-
.createTable("anrs")
|
|
135
|
-
.ifNotExists()
|
|
136
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
137
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
138
|
-
.addColumn("package_name", "text", (col) => col.notNull())
|
|
139
|
-
.addColumn("timestamp", "integer", (col) => col.notNull())
|
|
140
|
-
.addColumn("process_name", "text")
|
|
141
|
-
.addColumn("pid", "integer")
|
|
142
|
-
.addColumn("reason", "text") // e.g., "Input dispatching timed out"
|
|
143
|
-
.addColumn("activity", "text") // Activity that was ANR'd
|
|
144
|
-
.addColumn("wait_duration_ms", "integer") // How long the wait was
|
|
145
|
-
.addColumn("cpu_usage", "text") // CPU usage info at time of ANR
|
|
146
|
-
.addColumn("main_thread_state", "text") // State of main thread
|
|
147
|
-
.addColumn("stacktrace", "text") // Main thread stacktrace
|
|
148
|
-
.addColumn("detection_source", "text", (col) => col.notNull()) // logcat, dropbox, accessibility
|
|
149
|
-
.addColumn("raw_log", "text") // Raw ANR log output
|
|
150
|
-
// Nullable FKs for linking to navigation and test runs
|
|
151
|
-
.addColumn("navigation_node_id", "integer", (col) =>
|
|
152
|
-
col.references("navigation_nodes.id").onDelete("set null"),
|
|
153
|
-
)
|
|
154
|
-
.addColumn("test_execution_id", "integer", (col) =>
|
|
155
|
-
col.references("test_executions.id").onDelete("set null"),
|
|
156
|
-
)
|
|
157
|
-
.addColumn("session_uuid", "text")
|
|
158
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
159
|
-
.execute();
|
|
160
|
-
|
|
161
|
-
await db.schema
|
|
162
|
-
.createIndex("idx_anrs_device_id")
|
|
163
|
-
.ifNotExists()
|
|
164
|
-
.on("anrs")
|
|
165
|
-
.column("device_id")
|
|
166
|
-
.execute();
|
|
167
|
-
|
|
168
|
-
await db.schema
|
|
169
|
-
.createIndex("idx_anrs_package_name")
|
|
170
|
-
.ifNotExists()
|
|
171
|
-
.on("anrs")
|
|
172
|
-
.column("package_name")
|
|
173
|
-
.execute();
|
|
174
|
-
|
|
175
|
-
await db.schema
|
|
176
|
-
.createIndex("idx_anrs_timestamp")
|
|
177
|
-
.ifNotExists()
|
|
178
|
-
.on("anrs")
|
|
179
|
-
.column("timestamp")
|
|
180
|
-
.execute();
|
|
181
|
-
|
|
182
|
-
await db.schema
|
|
183
|
-
.createIndex("idx_anrs_navigation_node")
|
|
184
|
-
.ifNotExists()
|
|
185
|
-
.on("anrs")
|
|
186
|
-
.column("navigation_node_id")
|
|
187
|
-
.execute();
|
|
188
|
-
|
|
189
|
-
await db.schema
|
|
190
|
-
.createIndex("idx_anrs_test_execution")
|
|
191
|
-
.ifNotExists()
|
|
192
|
-
.on("anrs")
|
|
193
|
-
.column("test_execution_id")
|
|
194
|
-
.execute();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
199
|
-
await db.schema.dropTable("anrs").ifExists().execute();
|
|
200
|
-
await db.schema.dropTable("crashes").ifExists().execute();
|
|
201
|
-
|
|
202
|
-
// Note: SQLite doesn't support DROP COLUMN, so we can't remove the added columns
|
|
203
|
-
// from tool_calls. In production, would need to recreate the table without these columns.
|
|
204
|
-
}
|