@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,45 +0,0 @@
|
|
|
1
|
-
import { sql, type Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.transaction().execute(async (trx) => {
|
|
5
|
-
const existingColumn = await sql<{ name: string }>`
|
|
6
|
-
SELECT name FROM pragma_table_info('device_sessions')
|
|
7
|
-
WHERE name = 'stable_identity_generation'
|
|
8
|
-
`.execute(trx);
|
|
9
|
-
|
|
10
|
-
if (existingColumn.rows.length === 0) {
|
|
11
|
-
await trx.schema
|
|
12
|
-
.alterTable("device_sessions")
|
|
13
|
-
.addColumn("stable_identity_generation", "integer", (column) =>
|
|
14
|
-
column.notNull().defaultTo(0),
|
|
15
|
-
)
|
|
16
|
-
.execute();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_identity`.execute(trx);
|
|
20
|
-
// Older binaries omit stable_identity_generation from their upsert. If they
|
|
21
|
-
// rebind a session to another device transport, erase identity evidence they
|
|
22
|
-
// could not have refreshed before a current binary considers restart recovery.
|
|
23
|
-
await sql`
|
|
24
|
-
CREATE TRIGGER clear_stale_device_session_identity
|
|
25
|
-
AFTER UPDATE OF device_id ON device_sessions
|
|
26
|
-
WHEN NEW.device_id IS NOT OLD.device_id
|
|
27
|
-
AND NEW.stable_identity_generation = OLD.stable_identity_generation
|
|
28
|
-
BEGIN
|
|
29
|
-
UPDATE device_sessions
|
|
30
|
-
SET stable_device_id = NULL
|
|
31
|
-
WHERE session_uuid = NEW.session_uuid;
|
|
32
|
-
END
|
|
33
|
-
`.execute(trx);
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
38
|
-
await db.transaction().execute(async (trx) => {
|
|
39
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_identity`.execute(trx);
|
|
40
|
-
await trx.schema
|
|
41
|
-
.alterTable("device_sessions")
|
|
42
|
-
.dropColumn("stable_identity_generation")
|
|
43
|
-
.execute();
|
|
44
|
-
});
|
|
45
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.schema.alterTable("device_sessions").addColumn("liveness_owner_token", "text").execute();
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
8
|
-
await db.schema.alterTable("device_sessions").dropColumn("liveness_owner_token").execute();
|
|
9
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.transaction().execute(async (trx) => {
|
|
5
|
-
await trx.schema
|
|
6
|
-
.alterTable("device_sessions")
|
|
7
|
-
.addColumn("heartbeat_timeout_source", "text")
|
|
8
|
-
.execute();
|
|
9
|
-
await trx.schema.alterTable("device_sessions").addColumn("liveness_policy", "text").execute();
|
|
10
|
-
await trx.schema
|
|
11
|
-
.alterTable("device_sessions")
|
|
12
|
-
.addColumn("pre_cli_heartbeat_timeout_ms", "integer")
|
|
13
|
-
.execute();
|
|
14
|
-
await trx.schema
|
|
15
|
-
.alterTable("device_sessions")
|
|
16
|
-
.addColumn("pre_cli_heartbeat_timeout_source", "text")
|
|
17
|
-
.execute();
|
|
18
|
-
await trx.schema
|
|
19
|
-
.alterTable("device_sessions")
|
|
20
|
-
.addColumn("pre_cli_session_timeout_ms", "integer")
|
|
21
|
-
.execute();
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
26
|
-
await db.schema.alterTable("device_sessions").dropColumn("pre_cli_session_timeout_ms").execute();
|
|
27
|
-
await db.schema
|
|
28
|
-
.alterTable("device_sessions")
|
|
29
|
-
.dropColumn("pre_cli_heartbeat_timeout_source")
|
|
30
|
-
.execute();
|
|
31
|
-
await db.schema
|
|
32
|
-
.alterTable("device_sessions")
|
|
33
|
-
.dropColumn("pre_cli_heartbeat_timeout_ms")
|
|
34
|
-
.execute();
|
|
35
|
-
await db.schema.alterTable("device_sessions").dropColumn("liveness_policy").execute();
|
|
36
|
-
await db.schema.alterTable("device_sessions").dropColumn("heartbeat_timeout_source").execute();
|
|
37
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { sql, type Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.transaction().execute(async (trx) => {
|
|
5
|
-
const existingColumn = await sql<{ name: string }>`
|
|
6
|
-
SELECT name FROM pragma_table_info('device_sessions')
|
|
7
|
-
WHERE name = 'liveness_contract_generation'
|
|
8
|
-
`.execute(trx);
|
|
9
|
-
|
|
10
|
-
if (existingColumn.rows.length === 0) {
|
|
11
|
-
await trx.schema
|
|
12
|
-
.alterTable("device_sessions")
|
|
13
|
-
.addColumn("liveness_contract_generation", "integer", (column) =>
|
|
14
|
-
column.notNull().defaultTo(0),
|
|
15
|
-
)
|
|
16
|
-
.execute();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// An older binary updates the timeout/heartbeat columns but does not know
|
|
20
|
-
// about this generation or the cli-idle metadata. Erase that stale metadata
|
|
21
|
-
// before a newer daemon tries to recover a mixed-version row.
|
|
22
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_liveness_contract`.execute(trx);
|
|
23
|
-
await sql`
|
|
24
|
-
CREATE TRIGGER clear_stale_device_session_liveness_contract
|
|
25
|
-
AFTER UPDATE OF session_timeout_ms, heartbeat_timeout_ms, has_received_heartbeat ON device_sessions
|
|
26
|
-
WHEN NEW.liveness_contract_generation = OLD.liveness_contract_generation
|
|
27
|
-
BEGIN
|
|
28
|
-
UPDATE device_sessions
|
|
29
|
-
SET heartbeat_timeout_source = NULL,
|
|
30
|
-
liveness_policy = NULL,
|
|
31
|
-
pre_cli_heartbeat_timeout_ms = NULL,
|
|
32
|
-
pre_cli_heartbeat_timeout_source = NULL,
|
|
33
|
-
pre_cli_session_timeout_ms = NULL
|
|
34
|
-
WHERE session_uuid = NEW.session_uuid;
|
|
35
|
-
END
|
|
36
|
-
`.execute(trx);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
41
|
-
await db.transaction().execute(async (trx) => {
|
|
42
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_liveness_contract`.execute(trx);
|
|
43
|
-
await trx.schema
|
|
44
|
-
.alterTable("device_sessions")
|
|
45
|
-
.dropColumn("liveness_contract_generation")
|
|
46
|
-
.execute();
|
|
47
|
-
});
|
|
48
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { sql, type Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
await db.transaction().execute(async (trx) => {
|
|
5
|
-
const existingColumn = await sql<{ name: string }>`
|
|
6
|
-
SELECT name FROM pragma_table_info('device_sessions')
|
|
7
|
-
WHERE name = 'stable_identity_generation'
|
|
8
|
-
`.execute(trx);
|
|
9
|
-
|
|
10
|
-
if (existingColumn.rows.length === 0) {
|
|
11
|
-
await trx.schema
|
|
12
|
-
.alterTable("device_sessions")
|
|
13
|
-
.addColumn("stable_identity_generation", "integer", (column) =>
|
|
14
|
-
column.notNull().defaultTo(0),
|
|
15
|
-
)
|
|
16
|
-
.execute();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_identity`.execute(trx);
|
|
20
|
-
// `upsertActiveSession` always sets both identity columns and advances this
|
|
21
|
-
// generation. `recordActivity`, `replaceLivenessOwnership`,
|
|
22
|
-
// `markAutolockSession`, `markReleased`, and `markStaleActiveSessionsExpired`
|
|
23
|
-
// do not set either identity column, so this scope only fences identity writes.
|
|
24
|
-
await sql`
|
|
25
|
-
CREATE TRIGGER clear_stale_device_session_identity
|
|
26
|
-
AFTER UPDATE OF device_id, stable_device_id ON device_sessions
|
|
27
|
-
WHEN NEW.stable_identity_generation = OLD.stable_identity_generation
|
|
28
|
-
AND OLD.stable_device_id IS NOT NULL
|
|
29
|
-
BEGIN
|
|
30
|
-
UPDATE device_sessions
|
|
31
|
-
SET stable_device_id = NULL
|
|
32
|
-
WHERE session_uuid = NEW.session_uuid;
|
|
33
|
-
END
|
|
34
|
-
`.execute(trx);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
39
|
-
await db.transaction().execute(async (trx) => {
|
|
40
|
-
await sql`DROP TRIGGER IF EXISTS clear_stale_device_session_identity`.execute(trx);
|
|
41
|
-
await sql`
|
|
42
|
-
CREATE TRIGGER clear_stale_device_session_identity
|
|
43
|
-
AFTER UPDATE OF device_id ON device_sessions
|
|
44
|
-
WHEN NEW.device_id IS NOT OLD.device_id
|
|
45
|
-
AND NEW.stable_identity_generation = OLD.stable_identity_generation
|
|
46
|
-
BEGIN
|
|
47
|
-
UPDATE device_sessions
|
|
48
|
-
SET stable_device_id = NULL
|
|
49
|
-
WHERE session_uuid = NEW.session_uuid;
|
|
50
|
-
END
|
|
51
|
-
`.execute(trx);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
// #7377: persist the latest observable provisioning lifecycle state separately
|
|
4
|
-
// from the successful result. A request deadline may detach the caller while
|
|
5
|
-
// readiness or cleanup is still settling, so retries need a durable snapshot
|
|
6
|
-
// that cannot be mistaken for permission to create a duplicate device.
|
|
7
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
8
|
-
const existingColumn = await sql<{ name: string }>`
|
|
9
|
-
SELECT name FROM pragma_table_info('provision_device_operations')
|
|
10
|
-
WHERE name = 'lifecycle_json'
|
|
11
|
-
`.execute(db);
|
|
12
|
-
|
|
13
|
-
if (existingColumn.rows.length === 0) {
|
|
14
|
-
await db.schema
|
|
15
|
-
.alterTable("provision_device_operations")
|
|
16
|
-
.addColumn("lifecycle_json", "text")
|
|
17
|
-
.execute();
|
|
18
|
-
}
|
|
19
|
-
await db.schema
|
|
20
|
-
.createTable("provisioned_device_transport_tombstones")
|
|
21
|
-
.ifNotExists()
|
|
22
|
-
.addColumn("device_id", "text", (column) => column.primaryKey())
|
|
23
|
-
.addColumn("stable_id", "text", (column) => column.notNull())
|
|
24
|
-
.addColumn("reason", "text", (column) => column.notNull())
|
|
25
|
-
.addColumn("retired_at_ms", "integer", (column) => column.notNull())
|
|
26
|
-
.execute();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
30
|
-
await db.schema.dropTable("provisioned_device_transport_tombstones").ifExists().execute();
|
|
31
|
-
await db.schema.alterTable("provision_device_operations").dropColumn("lifecycle_json").execute();
|
|
32
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
/** Per-reach provenance for uncorrelated fingerprints (#5001). Old suggestions
|
|
4
|
-
* deliberately have no observations: their historical build/device is unknown. */
|
|
5
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
6
|
-
await db.schema
|
|
7
|
-
.createTable("navigation_suggestion_observations")
|
|
8
|
-
.ifNotExists()
|
|
9
|
-
.addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
|
|
10
|
-
.addColumn("suggestion_id", "integer", (col) =>
|
|
11
|
-
col.notNull().references("navigation_suggestions.id").onDelete("cascade"),
|
|
12
|
-
)
|
|
13
|
-
.addColumn("build_key_id", "integer", (col) =>
|
|
14
|
-
col.notNull().references("navigation_build_keys.id").onDelete("cascade"),
|
|
15
|
-
)
|
|
16
|
-
.addColumn("device_id", "text", (col) => col.notNull())
|
|
17
|
-
.addColumn("session_uuid", "text", (col) => col.notNull())
|
|
18
|
-
.addColumn("first_seen_at", "integer", (col) => col.notNull())
|
|
19
|
-
.addColumn("last_seen_at", "integer", (col) => col.notNull())
|
|
20
|
-
.addColumn("created_at", "text", (col) => col.notNull().defaultTo(sql`(datetime('now'))`))
|
|
21
|
-
.execute();
|
|
22
|
-
|
|
23
|
-
await db.schema
|
|
24
|
-
.createIndex("idx_navigation_suggestion_observations_unique")
|
|
25
|
-
.ifNotExists()
|
|
26
|
-
.on("navigation_suggestion_observations")
|
|
27
|
-
.columns(["suggestion_id", "build_key_id", "device_id", "session_uuid"])
|
|
28
|
-
.unique()
|
|
29
|
-
.execute();
|
|
30
|
-
|
|
31
|
-
await db.schema
|
|
32
|
-
.createIndex("idx_navigation_suggestion_observations_build")
|
|
33
|
-
.ifNotExists()
|
|
34
|
-
.on("navigation_suggestion_observations")
|
|
35
|
-
.column("build_key_id")
|
|
36
|
-
.execute();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
40
|
-
await db.schema.dropTable("navigation_suggestion_observations").ifExists().execute();
|
|
41
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
for (const column of ["recorded_panel_json", "display_transitions_json"] as const) {
|
|
5
|
-
const existing = await sql<{ name: string }>`
|
|
6
|
-
SELECT name FROM pragma_table_info('video_recordings') WHERE name = ${column}
|
|
7
|
-
`.execute(db);
|
|
8
|
-
if (existing.rows.length === 0) {
|
|
9
|
-
await db.schema.alterTable("video_recordings").addColumn(column, "text").execute();
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
15
|
-
await db.schema.alterTable("video_recordings").dropColumn("display_transitions_json").execute();
|
|
16
|
-
await db.schema.alterTable("video_recordings").dropColumn("recorded_panel_json").execute();
|
|
17
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
for (const [column, type] of [
|
|
5
|
-
["request_id", "text"],
|
|
6
|
-
["connection_id", "text"],
|
|
7
|
-
["direction", "text"],
|
|
8
|
-
["metadata_json", "text"],
|
|
9
|
-
["sequence_number", "integer"],
|
|
10
|
-
] as const) {
|
|
11
|
-
const existing = await sql<{ name: string }>`
|
|
12
|
-
SELECT name FROM pragma_table_info('network_events') WHERE name = ${column}
|
|
13
|
-
`.execute(db);
|
|
14
|
-
if (existing.rows.length === 0) {
|
|
15
|
-
await db.schema.alterTable("network_events").addColumn(column, type).execute();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
21
|
-
for (const column of [
|
|
22
|
-
"sequence_number",
|
|
23
|
-
"metadata_json",
|
|
24
|
-
"direction",
|
|
25
|
-
"connection_id",
|
|
26
|
-
"request_id",
|
|
27
|
-
] as const) {
|
|
28
|
-
await db.schema.alterTable("network_events").dropColumn(column).execute();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Tag each remembered credential with the stable device identity it was learned
|
|
5
|
-
* on (issue #10065).
|
|
6
|
-
*
|
|
7
|
-
* `device_locks` is keyed by adb serial, and emulator serials are port-based, so
|
|
8
|
-
* a different AVD on the same port inherited the previous device's PIN. The new
|
|
9
|
-
* nullable column holds a digest binding the AVD name (or serial for
|
|
10
|
-
* non-emulators) to the credential it was learned with, so an older daemon's
|
|
11
|
-
* upsert (which rewrites the credential but not this column) invalidates the tag;
|
|
12
|
-
* a credential is replayed only when the digest matches. Existing rows keep
|
|
13
|
-
* `NULL`: their provenance
|
|
14
|
-
* is unknown, so they are never replayed and the next successful `pin` unlock
|
|
15
|
-
* re-records them with an identity.
|
|
16
|
-
*/
|
|
17
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
18
|
-
const existingColumn = await sql<{ name: string }>`
|
|
19
|
-
SELECT name FROM pragma_table_info('device_locks') WHERE name = 'device_identity'
|
|
20
|
-
`.execute(db);
|
|
21
|
-
if (existingColumn.rows.length === 0) {
|
|
22
|
-
await db.schema.alterTable("device_locks").addColumn("device_identity", "text").execute();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
27
|
-
await db.schema.alterTable("device_locks").dropColumn("device_identity").execute();
|
|
28
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Seek index for `recordStorageEvent`'s previous-value lookup after it moved
|
|
5
|
-
* from device-clock ordering to insertion ordering (#10044 follow-up):
|
|
6
|
-
*
|
|
7
|
-
* SELECT value FROM storage_events
|
|
8
|
-
* WHERE device_id=? AND file_name=? AND key=?
|
|
9
|
-
* ORDER BY id DESC LIMIT 1
|
|
10
|
-
*
|
|
11
|
-
* `timestamp` is stamped by the DEVICE, so a lagging or reset device clock
|
|
12
|
-
* (snapshot restore, time change) made `ORDER BY timestamp DESC` return an older
|
|
13
|
-
* row than the one most recently stored. `id` (INTEGER PRIMARY KEY) is the
|
|
14
|
-
* insertion order.
|
|
15
|
-
*
|
|
16
|
-
* `idx_storage_events_key_lookup (device_id, file_name, key, timestamp)` cannot
|
|
17
|
-
* serve `ORDER BY id`: SQLite plans it as a prefix seek plus
|
|
18
|
-
* `USE TEMP B-TREE FOR ORDER BY`, sorting every row of a chatty key on each
|
|
19
|
-
* insert. SQLite appends the rowid to every index entry, so a plain
|
|
20
|
-
* `(device_id, file_name, key)` index yields rows in `id` order within the
|
|
21
|
-
* equality prefix and the newest row is reached with no sort.
|
|
22
|
-
*
|
|
23
|
-
* Additive: the older timestamp index is left in place (no remaining query needs
|
|
24
|
-
* it for the lookup; dropping it is a separate follow-up). `.ifNotExists()` /
|
|
25
|
-
* `.ifExists()` keep it safe under destructive-recovery replay.
|
|
26
|
-
*/
|
|
27
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
28
|
-
await db.schema
|
|
29
|
-
.createIndex("idx_storage_events_key_lookup_id")
|
|
30
|
-
.ifNotExists()
|
|
31
|
-
.on("storage_events")
|
|
32
|
-
.columns(["device_id", "file_name", "key"])
|
|
33
|
-
.execute();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
37
|
-
await db.schema.dropIndex("idx_storage_events_key_lookup_id").ifExists().execute();
|
|
38
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Index test edge coverage by edge_id for navigation retention probes and edge
|
|
5
|
-
* foreign-key cascades. The existing unique index starts with session_id, so it
|
|
6
|
-
* cannot efficiently serve lookups by edge_id alone.
|
|
7
|
-
*/
|
|
8
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
9
|
-
await db.schema
|
|
10
|
-
.createIndex("idx_test_edge_coverage_edge")
|
|
11
|
-
.ifNotExists()
|
|
12
|
-
.on("test_edge_coverage")
|
|
13
|
-
.column("edge_id")
|
|
14
|
-
.execute();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
18
|
-
await db.schema.dropIndex("idx_test_edge_coverage_edge").ifExists().execute();
|
|
19
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
|
|
3
|
-
// #6694: minimal AutoMobile-owned simulator service-override metadata. Keyed by
|
|
4
|
-
// the full incarnation identity (UDID + runtime + device type), never the UDID
|
|
5
|
-
// alone, so a runtime replacement does not inherit another incarnation's record.
|
|
6
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
7
|
-
await db.schema
|
|
8
|
-
.createTable("device_resource_applications")
|
|
9
|
-
.ifNotExists()
|
|
10
|
-
.addColumn("identity_key", "text", (column) => column.primaryKey())
|
|
11
|
-
.addColumn("udid", "text", (column) => column.notNull())
|
|
12
|
-
.addColumn("runtime_id", "text", (column) => column.notNull())
|
|
13
|
-
.addColumn("device_type_id", "text", (column) => column.notNull())
|
|
14
|
-
.addColumn("resources_json", "text", (column) => column.notNull())
|
|
15
|
-
.addColumn("profile_fingerprint", "text", (column) => column.notNull())
|
|
16
|
-
.addColumn("updated_at_ms", "integer", (column) => column.notNull())
|
|
17
|
-
.execute();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
21
|
-
await db.schema.dropTable("device_resource_applications").ifExists().execute();
|
|
22
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
// #11065: provisionDevice no longer takes an operationId, so the durable
|
|
4
|
-
// replay/idempotency rows keyed by it have no reader. Concurrent provisions of
|
|
5
|
-
// the same exact device are serialized by the in-process lifecycle lease and
|
|
6
|
-
// ownership refusals instead. Forward-only: the earlier migrations that created
|
|
7
|
-
// and extended this table stay untouched.
|
|
8
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
9
|
-
await db.schema.dropTable("provision_device_operations").ifExists().execute();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Recreates the final pre-#11065 shape (2026_08_22_000 plus the expiry,
|
|
13
|
-
// attempt-fence and lifecycle columns) so a rollback leaves the schema the
|
|
14
|
-
// earlier `down` migrations expect.
|
|
15
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
await db.schema
|
|
17
|
-
.createTable("provision_device_operations")
|
|
18
|
-
.ifNotExists()
|
|
19
|
-
.addColumn("operation_id", "text", (column) => column.primaryKey())
|
|
20
|
-
.addColumn("request_fingerprint", "text", (column) => column.notNull())
|
|
21
|
-
.addColumn("status", "text", (column) => column.notNull())
|
|
22
|
-
.addColumn("result_json", "text")
|
|
23
|
-
.addColumn("error_code", "text")
|
|
24
|
-
.addColumn("error_message", "text")
|
|
25
|
-
.addColumn("creation_started", "integer", (column) => column.notNull().defaultTo(0))
|
|
26
|
-
.addColumn("created_at", "text", (column) => column.notNull().defaultTo(sql`(datetime('now'))`))
|
|
27
|
-
.addColumn("updated_at", "text", (column) => column.notNull().defaultTo(sql`(datetime('now'))`))
|
|
28
|
-
.addColumn("expires_at_ms", "integer", (column) => column.notNull().defaultTo(0))
|
|
29
|
-
.addColumn("attempt_id", "text", (column) => column.notNull().defaultTo(""))
|
|
30
|
-
.addColumn("lifecycle_json", "text")
|
|
31
|
-
.execute();
|
|
32
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
// #11097: deleteDevice no longer takes an operationId, so the durable
|
|
4
|
-
// replay/idempotency rows keyed by it have no reader. Safe teardown comes from
|
|
5
|
-
// the lifecycle lease and the ownership re-check under the assignment mutex.
|
|
6
|
-
// Forward-only: the earlier migrations that created and extended this table
|
|
7
|
-
// stay untouched.
|
|
8
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
9
|
-
await db.schema.dropTable("device_teardown_operations").ifExists().execute();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Recreates the final pre-#11097 shape (2026_08_22_003 plus the owner_token
|
|
13
|
-
// column from 2026_08_23_000) so a rollback leaves the schema the earlier
|
|
14
|
-
// `down` migrations expect.
|
|
15
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
await db.schema
|
|
17
|
-
.createTable("device_teardown_operations")
|
|
18
|
-
.ifNotExists()
|
|
19
|
-
.addColumn("operation_id", "text", (column) => column.primaryKey())
|
|
20
|
-
.addColumn("request_fingerprint", "text", (column) => column.notNull())
|
|
21
|
-
.addColumn("status", "text", (column) => column.notNull())
|
|
22
|
-
.addColumn("result_json", "text")
|
|
23
|
-
.addColumn("expires_at_ms", "integer", (column) => column.notNull())
|
|
24
|
-
.addColumn("created_at", "text", (column) => column.notNull().defaultTo(sql`(datetime('now'))`))
|
|
25
|
-
.addColumn("updated_at", "text", (column) => column.notNull().defaultTo(sql`(datetime('now'))`))
|
|
26
|
-
.addColumn("owner_token", "text", (column) => column.notNull().defaultTo(sql`''`))
|
|
27
|
-
.execute();
|
|
28
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
// #11933: preserve the destination row when both spellings already exist.
|
|
4
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
5
|
-
await sql`DELETE FROM feature_flags WHERE key = 'mcp-recording'
|
|
6
|
-
AND EXISTS (SELECT 1 FROM feature_flags WHERE key = 'tool-call-recording')`.execute(db);
|
|
7
|
-
await sql`UPDATE feature_flags SET key = 'tool-call-recording'
|
|
8
|
-
WHERE key = 'mcp-recording'`.execute(db);
|
|
9
|
-
|
|
10
|
-
await sql`DELETE FROM session_tool_overrides WHERE tool_name = 'recordSteps'
|
|
11
|
-
AND EXISTS (SELECT 1 FROM session_tool_overrides AS destination
|
|
12
|
-
WHERE destination.session_uuid = session_tool_overrides.session_uuid
|
|
13
|
-
AND destination.tool_name = 'recordToolCalls')`.execute(db);
|
|
14
|
-
await sql`UPDATE session_tool_overrides SET tool_name = 'recordToolCalls'
|
|
15
|
-
WHERE tool_name = 'recordSteps'`.execute(db);
|
|
16
|
-
|
|
17
|
-
await sql`DELETE FROM session_tool_overrides WHERE tool_name = 'startTestRecording'
|
|
18
|
-
AND EXISTS (SELECT 1 FROM session_tool_overrides AS destination
|
|
19
|
-
WHERE destination.session_uuid = session_tool_overrides.session_uuid
|
|
20
|
-
AND destination.tool_name = 'recordDeviceGestures')`.execute(db);
|
|
21
|
-
await sql`UPDATE session_tool_overrides SET tool_name = 'recordDeviceGestures'
|
|
22
|
-
WHERE tool_name = 'startTestRecording'`.execute(db);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
26
|
-
await sql`DELETE FROM feature_flags WHERE key = 'tool-call-recording'
|
|
27
|
-
AND EXISTS (SELECT 1 FROM feature_flags WHERE key = 'mcp-recording')`.execute(db);
|
|
28
|
-
await sql`UPDATE feature_flags SET key = 'mcp-recording'
|
|
29
|
-
WHERE key = 'tool-call-recording'`.execute(db);
|
|
30
|
-
|
|
31
|
-
await sql`DELETE FROM session_tool_overrides WHERE tool_name = 'recordToolCalls'
|
|
32
|
-
AND EXISTS (SELECT 1 FROM session_tool_overrides AS destination
|
|
33
|
-
WHERE destination.session_uuid = session_tool_overrides.session_uuid
|
|
34
|
-
AND destination.tool_name = 'recordSteps')`.execute(db);
|
|
35
|
-
await sql`UPDATE session_tool_overrides SET tool_name = 'recordSteps'
|
|
36
|
-
WHERE tool_name = 'recordToolCalls'`.execute(db);
|
|
37
|
-
|
|
38
|
-
await sql`DELETE FROM session_tool_overrides WHERE tool_name = 'recordDeviceGestures'
|
|
39
|
-
AND EXISTS (SELECT 1 FROM session_tool_overrides AS destination
|
|
40
|
-
WHERE destination.session_uuid = session_tool_overrides.session_uuid
|
|
41
|
-
AND destination.tool_name = 'startTestRecording')`.execute(db);
|
|
42
|
-
await sql`UPDATE session_tool_overrides SET tool_name = 'startTestRecording'
|
|
43
|
-
WHERE tool_name = 'recordDeviceGestures'`.execute(db);
|
|
44
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
const existing = await sql<{ name: string }>`
|
|
5
|
-
SELECT name FROM pragma_table_info('video_recordings') WHERE name = 'capture_teardown_json'
|
|
6
|
-
`.execute(db);
|
|
7
|
-
if (existing.rows.length === 0) {
|
|
8
|
-
await db.schema
|
|
9
|
-
.alterTable("video_recordings")
|
|
10
|
-
.addColumn("capture_teardown_json", "text")
|
|
11
|
-
.execute();
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
await db.schema.alterTable("video_recordings").dropColumn("capture_teardown_json").execute();
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type Kysely, sql } from "kysely";
|
|
2
|
-
|
|
3
|
-
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
-
const existing = await sql<{ name: string }>`
|
|
5
|
-
SELECT name FROM pragma_table_info('video_recordings') WHERE name = 'recorder_daemon_session_id'
|
|
6
|
-
`.execute(db);
|
|
7
|
-
if (existing.rows.length === 0) {
|
|
8
|
-
await db.schema
|
|
9
|
-
.alterTable("video_recordings")
|
|
10
|
-
.addColumn("recorder_daemon_session_id", "text")
|
|
11
|
-
.execute();
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
16
|
-
await db.schema.alterTable("video_recordings").dropColumn("recorder_daemon_session_id").execute();
|
|
17
|
-
}
|