@cleocode/core 2026.9.25 → 2026.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/import-tasks.d.ts.map +1 -1
- package/dist/admin/import-tasks.js +5 -2
- package/dist/admin/import-tasks.js.map +1 -1
- package/dist/admin/import.d.ts.map +1 -1
- package/dist/admin/import.js +7 -2
- package/dist/admin/import.js.map +1 -1
- package/dist/build-provenance.json +2 -2
- package/dist/cloud/index.d.ts +1 -0
- package/dist/cloud/index.d.ts.map +1 -1
- package/dist/cloud/index.js +1 -0
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/nexus-attach.d.ts +94 -0
- package/dist/cloud/nexus-attach.d.ts.map +1 -0
- package/dist/cloud/nexus-attach.js +192 -0
- package/dist/cloud/nexus-attach.js.map +1 -0
- package/dist/cloud/nexus-auth.d.ts +41 -4
- package/dist/cloud/nexus-auth.d.ts.map +1 -1
- package/dist/cloud/nexus-auth.js +151 -38
- package/dist/cloud/nexus-auth.js.map +1 -1
- package/dist/cloud/nexus-cloud-status.d.ts +132 -0
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-status.js +440 -0
- package/dist/cloud/nexus-cloud-status.js.map +1 -0
- package/dist/cloud/nexus-cloud.d.ts +179 -0
- package/dist/cloud/nexus-cloud.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud.js +296 -0
- package/dist/cloud/nexus-cloud.js.map +1 -0
- package/dist/cloud/nexus-credentials.js +2 -2
- package/dist/cloud/nexus-credentials.js.map +1 -1
- package/dist/cloud/nexus-device.d.ts +834 -0
- package/dist/cloud/nexus-device.d.ts.map +1 -0
- package/dist/cloud/nexus-device.js +1727 -0
- package/dist/cloud/nexus-device.js.map +1 -0
- package/dist/cloud/nexus-enrol.d.ts +241 -0
- package/dist/cloud/nexus-enrol.d.ts.map +1 -0
- package/dist/cloud/nexus-enrol.js +1163 -0
- package/dist/cloud/nexus-enrol.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +10 -0
- package/dist/cloud/nexus-link.d.ts.map +1 -1
- package/dist/cloud/nexus-link.js +172 -11
- package/dist/cloud/nexus-link.js.map +1 -1
- package/dist/cloud/nexus-logout.d.ts +114 -0
- package/dist/cloud/nexus-logout.d.ts.map +1 -0
- package/dist/cloud/nexus-logout.js +429 -0
- package/dist/cloud/nexus-logout.js.map +1 -0
- package/dist/cloud/signing.d.ts +20 -0
- package/dist/cloud/signing.d.ts.map +1 -1
- package/dist/cloud/signing.js +14 -0
- package/dist/cloud/signing.js.map +1 -1
- package/dist/crypto/credentials.d.ts +61 -0
- package/dist/crypto/credentials.d.ts.map +1 -1
- package/dist/crypto/credentials.js +154 -58
- package/dist/crypto/credentials.js.map +1 -1
- package/dist/docs/export-document.js +1072 -227
- package/dist/docs/export-document.js.map +3 -3
- package/dist/doctor/dependency-cycles.d.ts +41 -0
- package/dist/doctor/dependency-cycles.d.ts.map +1 -0
- package/dist/doctor/dependency-cycles.js +39 -0
- package/dist/doctor/dependency-cycles.js.map +1 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.d.ts.map +1 -1
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/index.js.map +1 -1
- package/dist/doctor/row-identity.d.ts +11 -0
- package/dist/doctor/row-identity.d.ts.map +1 -1
- package/dist/doctor/row-identity.js +67 -9
- package/dist/doctor/row-identity.js.map +1 -1
- package/dist/error-catalog.d.ts.map +1 -1
- package/dist/error-catalog.js +4 -0
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.d.ts.map +1 -1
- package/dist/error-registry.js +8 -0
- package/dist/error-registry.js.map +1 -1
- package/dist/llm/plugin-facade.js +1200 -355
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/nexus/workspace.d.ts.map +1 -1
- package/dist/nexus/workspace.js +54 -4
- package/dist/nexus/workspace.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +1 -1
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +4 -2
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +3 -3
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.js +1 -1
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +3 -3
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/parallel.js +1 -1
- package/dist/orchestration/parallel.js.map +1 -1
- package/dist/orchestration/wave-topic.d.ts +4 -2
- package/dist/orchestration/wave-topic.d.ts.map +1 -1
- package/dist/orchestration/wave-topic.js +6 -4
- package/dist/orchestration/wave-topic.js.map +1 -1
- package/dist/orchestration/waves.d.ts +2 -1
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +4 -3
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +4 -2
- package/dist/phases/index.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +1203 -358
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +77 -49
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +69 -23
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +113 -27
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/handoff.js +1 -1
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +24 -13
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/terminal-identity.d.ts +165 -17
- package/dist/sessions/terminal-identity.d.ts.map +1 -1
- package/dist/sessions/terminal-identity.js +341 -32
- package/dist/sessions/terminal-identity.js.map +1 -1
- package/dist/setup/sections/nexus-account.d.ts +8 -6
- package/dist/setup/sections/nexus-account.d.ts.map +1 -1
- package/dist/setup/sections/nexus-account.js +53 -9
- package/dist/setup/sections/nexus-account.js.map +1 -1
- package/dist/skills/orchestrator/startup.js +2 -2
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/snapshot/index.d.ts +4 -0
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +50 -3
- package/dist/snapshot/index.js.map +1 -1
- package/dist/store/db-helpers.d.ts +15 -2
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +84 -3
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dependency-cycles.d.ts +164 -0
- package/dist/store/dependency-cycles.d.ts.map +1 -0
- package/dist/store/dependency-cycles.js +360 -0
- package/dist/store/dependency-cycles.js.map +1 -0
- package/dist/store/display-id-alias.d.ts +93 -37
- package/dist/store/display-id-alias.d.ts.map +1 -1
- package/dist/store/display-id-alias.js +590 -115
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +34 -7
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +8 -1
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/global-salt.d.ts +35 -0
- package/dist/store/global-salt.d.ts.map +1 -1
- package/dist/store/global-salt.js +136 -16
- package/dist/store/global-salt.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +19 -11
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +6 -0
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +11 -3
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts +91 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +276 -7
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/safety-data-accessor.d.ts +3 -2
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +5 -2
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/session-store.d.ts +63 -3
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +121 -8
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/split-brain-import.d.ts.map +1 -1
- package/dist/store/split-brain-import.js +36 -0
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +50 -3
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +246 -13
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sync/replica.d.ts +34 -3
- package/dist/store/sync/replica.d.ts.map +1 -1
- package/dist/store/sync/replica.js +39 -2
- package/dist/store/sync/replica.js.map +1 -1
- package/dist/store/sync/schema.d.ts +6 -3
- package/dist/store/sync/schema.d.ts.map +1 -1
- package/dist/store/sync/schema.js +6 -3
- package/dist/store/sync/schema.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +14 -2
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +3 -2
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +5 -2
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/system/health.d.ts +2 -0
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +54 -0
- package/dist/system/health.js.map +1 -1
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +9 -6
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +3 -2
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/evidence.d.ts +19 -1
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +79 -18
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/infer-add-params.js +1 -1
- package/dist/tasks/infer-add-params.js.map +1 -1
- package/dist/tasks/task-context.d.ts.map +1 -1
- package/dist/tasks/task-context.js +3 -1
- package/dist/tasks/task-context.js.map +1 -1
- package/dist/tasks/task-import.d.ts.map +1 -1
- package/dist/tasks/task-import.js +11 -3
- package/dist/tasks/task-import.js.map +1 -1
- package/dist/tasks/task-next.d.ts +5 -1
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +7 -2
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +3 -2
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
- package/dist/workgraph/scaffold-apply.js +14 -5
- package/dist/workgraph/scaffold-apply.js.map +1 -1
- package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/migration.sql +76 -0
- package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/revert.sql +7 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +2 -2
- package/templates/CLEO-REFERENCE.md +1 -1
|
@@ -1874,7 +1874,7 @@ var init_output_contracts_data = __esm({
|
|
|
1874
1874
|
// T12503: the optimistic-concurrency version agents pass to --if-match.
|
|
1875
1875
|
updatedAt: {
|
|
1876
1876
|
type: ["string", "null"],
|
|
1877
|
-
description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`."
|
|
1877
|
+
description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`. A stale version fails with E_CONFLICT (23); E_TASK_RENAMED (26) when sync re-numbered the task you read (details.expected is its new id)."
|
|
1878
1878
|
},
|
|
1879
1879
|
// T12502: the human assignee and the agent claim lease are separate.
|
|
1880
1880
|
assignee: {
|
|
@@ -13135,6 +13135,7 @@ var init_exit_codes = __esm({
|
|
|
13135
13135
|
ExitCode2[ExitCode2["VERSION_CONFLICT"] = 23] = "VERSION_CONFLICT";
|
|
13136
13136
|
ExitCode2[ExitCode2["SESSION_UNBOUND"] = 24] = "SESSION_UNBOUND";
|
|
13137
13137
|
ExitCode2[ExitCode2["WORKTREE_LOCKED"] = 25] = "WORKTREE_LOCKED";
|
|
13138
|
+
ExitCode2[ExitCode2["TASK_RENAMED"] = 26] = "TASK_RENAMED";
|
|
13138
13139
|
ExitCode2[ExitCode2["SESSION_EXISTS"] = 30] = "SESSION_EXISTS";
|
|
13139
13140
|
ExitCode2[ExitCode2["SESSION_NOT_FOUND"] = 31] = "SESSION_NOT_FOUND";
|
|
13140
13141
|
ExitCode2[ExitCode2["SCOPE_CONFLICT"] = 32] = "SCOPE_CONFLICT";
|
|
@@ -17462,6 +17463,210 @@ var init_nexus_account = __esm({
|
|
|
17462
17463
|
}
|
|
17463
17464
|
});
|
|
17464
17465
|
|
|
17466
|
+
// packages/contracts/src/nexus-cloud.ts
|
|
17467
|
+
import { z as z26 } from "zod";
|
|
17468
|
+
var NEXUS_DEVICE_STATES, NEXUS_CLOUD_PROFILES, NEXUS_DEVICE_STATE_UNKNOWN, isoTime, profile, deviceState, nexusCloudCredentialSchema, nexusCloudDeviceSchema, nexusCloudOrganizationSchema, nexusCloudUserSchema, nexusCloudWhoamiSchema, nexusCloudDevicePageSchema, nexusCloudPresenceSchema, nexusCloudReplicaSchema, nexusCloudDeviceCountsSchema, projectFields, nexusCloudProjectListItemSchema, nexusCloudProjectPageSchema, nexusCloudProjectDetailSchema, nexusCloudReplicaPageSchema, NEXUS_STATUS_CHECK_IDS, NEXUS_STATUS_VERDICTS, CLOUD_STATUS_VERDICTS, knownCheckId, nexusCloudStatusCheckSchema, nexusCloudStatusSchema;
|
|
17469
|
+
var init_nexus_cloud = __esm({
|
|
17470
|
+
"packages/contracts/src/nexus-cloud.ts"() {
|
|
17471
|
+
"use strict";
|
|
17472
|
+
NEXUS_DEVICE_STATES = ["active", "signed-out", "revoked"];
|
|
17473
|
+
NEXUS_CLOUD_PROFILES = ["device", "read-only"];
|
|
17474
|
+
NEXUS_DEVICE_STATE_UNKNOWN = "unknown";
|
|
17475
|
+
isoTime = z26.iso.datetime({ offset: true });
|
|
17476
|
+
profile = z26.enum(NEXUS_CLOUD_PROFILES).nullable().catch(null);
|
|
17477
|
+
deviceState = z26.enum([...NEXUS_DEVICE_STATES, NEXUS_DEVICE_STATE_UNKNOWN]).catch(NEXUS_DEVICE_STATE_UNKNOWN);
|
|
17478
|
+
nexusCloudCredentialSchema = z26.object({
|
|
17479
|
+
kind: z26.enum(["device", "session"]),
|
|
17480
|
+
credentialId: z26.string().nullable().optional(),
|
|
17481
|
+
profile: profile.optional(),
|
|
17482
|
+
scopes: z26.array(z26.string()).default([]),
|
|
17483
|
+
createdAt: isoTime.nullable().optional(),
|
|
17484
|
+
lastUsedAt: isoTime.nullable().optional(),
|
|
17485
|
+
/** When the credential expires if it is not used again; null for sessions. */
|
|
17486
|
+
idleExpiresAt: isoTime.nullable().optional()
|
|
17487
|
+
});
|
|
17488
|
+
nexusCloudDeviceSchema = z26.object({
|
|
17489
|
+
deviceId: z26.string(),
|
|
17490
|
+
name: z26.string(),
|
|
17491
|
+
platform: z26.string().optional(),
|
|
17492
|
+
arch: z26.string().nullable().optional(),
|
|
17493
|
+
cliVersion: z26.string().nullable().optional(),
|
|
17494
|
+
createdAt: isoTime.optional(),
|
|
17495
|
+
lastSeenAt: isoTime.nullable().optional(),
|
|
17496
|
+
state: deviceState,
|
|
17497
|
+
signedOutAt: isoTime.nullable().optional(),
|
|
17498
|
+
/** Base64 device certificate; null until the device holds a key grant. */
|
|
17499
|
+
certificate: z26.string().nullable().optional(),
|
|
17500
|
+
/** The current credential's profile, or null with none (signed out or revoked). */
|
|
17501
|
+
profile: profile.optional(),
|
|
17502
|
+
/** True for the device whose credential made this request. */
|
|
17503
|
+
current: z26.boolean().default(false),
|
|
17504
|
+
projects: z26.number().int().nonnegative().optional(),
|
|
17505
|
+
replicas: z26.number().int().nonnegative().optional(),
|
|
17506
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17507
|
+
lastPresenceAt: isoTime.nullable().optional()
|
|
17508
|
+
});
|
|
17509
|
+
nexusCloudOrganizationSchema = z26.object({
|
|
17510
|
+
id: z26.string(),
|
|
17511
|
+
name: z26.string(),
|
|
17512
|
+
slug: z26.string().nullable().optional(),
|
|
17513
|
+
role: z26.string().optional(),
|
|
17514
|
+
personal: z26.boolean().optional()
|
|
17515
|
+
});
|
|
17516
|
+
nexusCloudUserSchema = z26.object({
|
|
17517
|
+
id: z26.string(),
|
|
17518
|
+
email: z26.string(),
|
|
17519
|
+
name: z26.string().nullable().optional()
|
|
17520
|
+
});
|
|
17521
|
+
nexusCloudWhoamiSchema = z26.object({
|
|
17522
|
+
serverTime: isoTime.optional(),
|
|
17523
|
+
user: nexusCloudUserSchema,
|
|
17524
|
+
organizations: z26.array(nexusCloudOrganizationSchema).default([]),
|
|
17525
|
+
credential: nexusCloudCredentialSchema,
|
|
17526
|
+
/** The calling device; null for a session caller. */
|
|
17527
|
+
device: nexusCloudDeviceSchema.nullable()
|
|
17528
|
+
});
|
|
17529
|
+
nexusCloudDevicePageSchema = z26.object({
|
|
17530
|
+
devices: z26.array(nexusCloudDeviceSchema),
|
|
17531
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17532
|
+
truncated: z26.boolean().default(false)
|
|
17533
|
+
});
|
|
17534
|
+
nexusCloudPresenceSchema = z26.looseObject({
|
|
17535
|
+
observedAt: isoTime.optional(),
|
|
17536
|
+
sync: z26.object({ enabled: z26.boolean() }).optional()
|
|
17537
|
+
});
|
|
17538
|
+
nexusCloudReplicaSchema = z26.object({
|
|
17539
|
+
projectId: z26.string(),
|
|
17540
|
+
replicaId: z26.string(),
|
|
17541
|
+
deviceId: z26.string(),
|
|
17542
|
+
deviceName: z26.string(),
|
|
17543
|
+
deviceState: deviceState.optional(),
|
|
17544
|
+
attachedAt: isoTime.optional(),
|
|
17545
|
+
lastSyncAt: isoTime.nullable(),
|
|
17546
|
+
presence: nexusCloudPresenceSchema.nullable(),
|
|
17547
|
+
presenceAt: isoTime.nullable()
|
|
17548
|
+
});
|
|
17549
|
+
nexusCloudDeviceCountsSchema = z26.object({
|
|
17550
|
+
active: z26.number().int().nonnegative(),
|
|
17551
|
+
total: z26.number().int().nonnegative()
|
|
17552
|
+
});
|
|
17553
|
+
projectFields = {
|
|
17554
|
+
projectId: z26.string(),
|
|
17555
|
+
label: z26.string().nullable(),
|
|
17556
|
+
organizationId: z26.string(),
|
|
17557
|
+
organizationName: z26.string().optional(),
|
|
17558
|
+
remoteUrl: z26.string().nullable().optional(),
|
|
17559
|
+
createdAt: isoTime.optional()
|
|
17560
|
+
};
|
|
17561
|
+
nexusCloudProjectListItemSchema = z26.object({
|
|
17562
|
+
...projectFields,
|
|
17563
|
+
role: z26.string(),
|
|
17564
|
+
streamId: z26.string().optional(),
|
|
17565
|
+
headSeq: z26.number().int().nonnegative().nullable().optional(),
|
|
17566
|
+
openConflicts: z26.number().int().nonnegative().optional(),
|
|
17567
|
+
replicas: z26.array(nexusCloudReplicaSchema).default([]),
|
|
17568
|
+
devices: nexusCloudDeviceCountsSchema.optional(),
|
|
17569
|
+
replicaCount: z26.number().int().nonnegative().optional(),
|
|
17570
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17571
|
+
lastPresenceAt: isoTime.nullable().optional(),
|
|
17572
|
+
/** This project's replica list was cut at 50 (T12858). */
|
|
17573
|
+
replicasTruncated: z26.boolean().default(false)
|
|
17574
|
+
});
|
|
17575
|
+
nexusCloudProjectPageSchema = z26.object({
|
|
17576
|
+
projects: z26.array(nexusCloudProjectListItemSchema),
|
|
17577
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17578
|
+
/** Anything in the page was cut (the project list or a replica list). */
|
|
17579
|
+
truncated: z26.boolean().default(false),
|
|
17580
|
+
/** The project list itself was cut at 1000 (T12858). */
|
|
17581
|
+
projectsTruncated: z26.boolean().default(false)
|
|
17582
|
+
});
|
|
17583
|
+
nexusCloudProjectDetailSchema = z26.object({
|
|
17584
|
+
project: z26.object({ ...projectFields, deletedAt: isoTime.nullable().optional() }),
|
|
17585
|
+
role: z26.string(),
|
|
17586
|
+
canTrash: z26.boolean().optional(),
|
|
17587
|
+
openConflicts: z26.number().int().nonnegative(),
|
|
17588
|
+
/** At most 50, oldest attachment first. */
|
|
17589
|
+
replicas: z26.array(nexusCloudReplicaSchema),
|
|
17590
|
+
devices: nexusCloudDeviceCountsSchema,
|
|
17591
|
+
replicaCount: z26.number().int().nonnegative().optional(),
|
|
17592
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17593
|
+
/** `replicas` was cut at 50. */
|
|
17594
|
+
truncated: z26.boolean().default(false),
|
|
17595
|
+
stream: z26.object({
|
|
17596
|
+
streamId: z26.string(),
|
|
17597
|
+
headSeq: z26.number().int().nonnegative(),
|
|
17598
|
+
headCheckpointId: z26.string().nullable()
|
|
17599
|
+
}).nullable()
|
|
17600
|
+
});
|
|
17601
|
+
nexusCloudReplicaPageSchema = z26.object({
|
|
17602
|
+
replicas: z26.array(nexusCloudReplicaSchema),
|
|
17603
|
+
devices: nexusCloudDeviceCountsSchema.optional(),
|
|
17604
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17605
|
+
truncated: z26.boolean().default(false)
|
|
17606
|
+
});
|
|
17607
|
+
NEXUS_STATUS_CHECK_IDS = [
|
|
17608
|
+
"credential.valid",
|
|
17609
|
+
"device.registered",
|
|
17610
|
+
"device.active",
|
|
17611
|
+
"device.certified",
|
|
17612
|
+
"project.registered",
|
|
17613
|
+
"project.writable",
|
|
17614
|
+
"replica.attached",
|
|
17615
|
+
"presence.fresh",
|
|
17616
|
+
"replica.synced",
|
|
17617
|
+
"conflicts.none"
|
|
17618
|
+
];
|
|
17619
|
+
NEXUS_STATUS_VERDICTS = ["ok", "attention", "not-linked", "not-registered"];
|
|
17620
|
+
CLOUD_STATUS_VERDICTS = [...NEXUS_STATUS_VERDICTS, "not-signed-in"];
|
|
17621
|
+
knownCheckId = z26.enum(NEXUS_STATUS_CHECK_IDS);
|
|
17622
|
+
nexusCloudStatusCheckSchema = z26.object({
|
|
17623
|
+
id: z26.enum(NEXUS_STATUS_CHECK_IDS),
|
|
17624
|
+
ok: z26.boolean(),
|
|
17625
|
+
required: z26.boolean(),
|
|
17626
|
+
detail: z26.string()
|
|
17627
|
+
});
|
|
17628
|
+
nexusCloudStatusSchema = z26.object({
|
|
17629
|
+
serverTime: isoTime.optional(),
|
|
17630
|
+
apiVersion: z26.string().optional(),
|
|
17631
|
+
user: nexusCloudUserSchema,
|
|
17632
|
+
credential: nexusCloudCredentialSchema,
|
|
17633
|
+
device: nexusCloudDeviceSchema.nullable(),
|
|
17634
|
+
project: z26.object({
|
|
17635
|
+
projectId: z26.string(),
|
|
17636
|
+
registered: z26.boolean(),
|
|
17637
|
+
organizationId: z26.string().nullable(),
|
|
17638
|
+
organizationName: z26.string().nullable(),
|
|
17639
|
+
role: z26.string().nullable()
|
|
17640
|
+
}).nullable(),
|
|
17641
|
+
replica: z26.object({
|
|
17642
|
+
replicaId: z26.string(),
|
|
17643
|
+
attached: z26.boolean(),
|
|
17644
|
+
attachedElsewhere: z26.boolean(),
|
|
17645
|
+
attachedAt: isoTime.nullable(),
|
|
17646
|
+
lastSyncAt: isoTime.nullable(),
|
|
17647
|
+
presenceAt: isoTime.nullable(),
|
|
17648
|
+
lastReplicaSeq: z26.number().int().nonnegative().nullable().optional()
|
|
17649
|
+
}).nullable(),
|
|
17650
|
+
stream: z26.object({
|
|
17651
|
+
streamId: z26.string(),
|
|
17652
|
+
headSeq: z26.number().int().nonnegative(),
|
|
17653
|
+
headCheckpointId: z26.string().nullable(),
|
|
17654
|
+
openConflicts: z26.number().int().nonnegative(),
|
|
17655
|
+
devices: nexusCloudDeviceCountsSchema
|
|
17656
|
+
}).nullable(),
|
|
17657
|
+
/** Check ids added by a newer server are dropped, never a parse failure. */
|
|
17658
|
+
checks: z26.array(nexusCloudStatusCheckSchema.extend({ id: z26.string() })).transform(
|
|
17659
|
+
(list) => list.flatMap((c) => {
|
|
17660
|
+
const id = knownCheckId.safeParse(c.id);
|
|
17661
|
+
return id.success ? [{ ...c, id: id.data }] : [];
|
|
17662
|
+
})
|
|
17663
|
+
),
|
|
17664
|
+
/** A verdict added by a newer server reads as `attention`: never `ok` by accident. */
|
|
17665
|
+
verdict: z26.enum(NEXUS_STATUS_VERDICTS).catch("attention")
|
|
17666
|
+
});
|
|
17667
|
+
}
|
|
17668
|
+
});
|
|
17669
|
+
|
|
17465
17670
|
// packages/contracts/src/task-id.ts
|
|
17466
17671
|
var init_task_id = __esm({
|
|
17467
17672
|
"packages/contracts/src/task-id.ts"() {
|
|
@@ -17546,6 +17751,7 @@ var init_src = __esm({
|
|
|
17546
17751
|
init_decide();
|
|
17547
17752
|
init_decide_sites();
|
|
17548
17753
|
init_nexus_account();
|
|
17754
|
+
init_nexus_cloud();
|
|
17549
17755
|
init_task_id();
|
|
17550
17756
|
}
|
|
17551
17757
|
});
|
|
@@ -17890,6 +18096,19 @@ var init_error_catalog = __esm({
|
|
|
17890
18096
|
`Bind a session: run 'cleo session start --scope global --name "<name>"', 'cleo session resume <id>', or set CLEO_SESSION_ID=<id>.`
|
|
17891
18097
|
)
|
|
17892
18098
|
],
|
|
18099
|
+
[
|
|
18100
|
+
26 /* TASK_RENAMED */,
|
|
18101
|
+
def(
|
|
18102
|
+
26 /* TASK_RENAMED */,
|
|
18103
|
+
"TASK_RENAMED",
|
|
18104
|
+
"CONFLICT",
|
|
18105
|
+
"Task was re-numbered by sync",
|
|
18106
|
+
409,
|
|
18107
|
+
true,
|
|
18108
|
+
"E_TASK_RENAMED",
|
|
18109
|
+
"The task you addressed now has another id (a display-id collision re-numbered it). Re-read it with 'cleo show <new id>' and retry against that id."
|
|
18110
|
+
)
|
|
18111
|
+
],
|
|
17893
18112
|
[
|
|
17894
18113
|
25 /* WORKTREE_LOCKED */,
|
|
17895
18114
|
def(
|
|
@@ -19837,10 +20056,10 @@ var init_table2 = __esm({
|
|
|
19837
20056
|
[IsDrizzleTable] = true;
|
|
19838
20057
|
/** @internal */
|
|
19839
20058
|
[ExtraConfigBuilder] = void 0;
|
|
19840
|
-
constructor(name15, schema,
|
|
20059
|
+
constructor(name15, schema, baseName2) {
|
|
19841
20060
|
this[TableName] = this[OriginalName] = name15;
|
|
19842
20061
|
this[TableSchema] = schema;
|
|
19843
|
-
this[BaseName] =
|
|
20062
|
+
this[BaseName] = baseName2;
|
|
19844
20063
|
}
|
|
19845
20064
|
};
|
|
19846
20065
|
}
|
|
@@ -21770,9 +21989,9 @@ var init_casing = __esm({
|
|
|
21770
21989
|
});
|
|
21771
21990
|
|
|
21772
21991
|
// node_modules/.pnpm/drizzle-orm@1.0.0-rc.4_@opentelemetry+api@1.9.0_@sinclair+typebox@0.34.49_@types+mssql@_b4e81f2ea693a7363d3e5dc2205249c6/node_modules/drizzle-orm/sqlite-core/table.js
|
|
21773
|
-
function sqliteTableBase(name15, columns, extraConfig, schema, casing,
|
|
21992
|
+
function sqliteTableBase(name15, columns, extraConfig, schema, casing, baseName2 = name15) {
|
|
21774
21993
|
const casingFn = getCasingFn(casing);
|
|
21775
|
-
const rawTable = new SQLiteTable(name15, schema,
|
|
21994
|
+
const rawTable = new SQLiteTable(name15, schema, baseName2);
|
|
21776
21995
|
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
21777
21996
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name16, colBuilderBase]) => {
|
|
21778
21997
|
const colBuilder = colBuilderBase;
|
|
@@ -25561,6 +25780,10 @@ function decisionFor(dbPath) {
|
|
|
25561
25780
|
if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
|
|
25562
25781
|
return decisions.get(key) ?? null;
|
|
25563
25782
|
}
|
|
25783
|
+
function schemaWritesAllowed(nativeDb) {
|
|
25784
|
+
const dbPath = nativeDb.location();
|
|
25785
|
+
return !dbPath || decisionFor(dbPath) === null;
|
|
25786
|
+
}
|
|
25564
25787
|
function isWorktreeBuildSchemaError(error48) {
|
|
25565
25788
|
return error48 instanceof Error && error48.message.includes(E_WORKTREE_BUILD_SCHEMA);
|
|
25566
25789
|
}
|
|
@@ -26599,7 +26822,10 @@ var init_row_identity_registry = __esm({
|
|
|
26599
26822
|
key: ["id"],
|
|
26600
26823
|
birth: "recorded_at",
|
|
26601
26824
|
content: ["ac_id", "previous_text", "reason"],
|
|
26602
|
-
|
|
26825
|
+
// v2 (T12802): no @refFp: the criterion's fingerprint is unknowable when
|
|
26826
|
+
// it was gone before this row got its identity, so it made the value
|
|
26827
|
+
// depend on fill timing. ac_id is always known.
|
|
26828
|
+
birthFacts: ["ac_id", "previous_text", "reason"],
|
|
26603
26829
|
storedRefUids: [{ column: "ac_uid", from: "ac_id", table: ACS }],
|
|
26604
26830
|
task: "T12341"
|
|
26605
26831
|
},
|
|
@@ -26608,7 +26834,10 @@ var init_row_identity_registry = __esm({
|
|
|
26608
26834
|
kind: "minted",
|
|
26609
26835
|
key: ["id"],
|
|
26610
26836
|
birth: "created_at",
|
|
26611
|
-
|
|
26837
|
+
// v2 (T12802): ac_id in place of @refFp:ac_uid and ac_text_hash. Both
|
|
26838
|
+
// were filled from the criterion, so a backfilled binding whose
|
|
26839
|
+
// criterion was already gone got a different value (see AC history).
|
|
26840
|
+
birthFacts: ["evidence_atom_id", "binding_type", "ac_id"],
|
|
26612
26841
|
storedRefUids: [
|
|
26613
26842
|
{ column: "ac_uid", from: "ac_id", table: ACS },
|
|
26614
26843
|
{ column: "ac_text_hash", from: "ac_id", table: ACS, source: "text_hash" }
|
|
@@ -26650,7 +26879,9 @@ var init_row_identity_registry = __esm({
|
|
|
26650
26879
|
// The uid IS the primary key: display-id-alias.ts computes it on write.
|
|
26651
26880
|
table: "tasks_display_id_aliases",
|
|
26652
26881
|
kind: "natural",
|
|
26653
|
-
|
|
26882
|
+
// T12800: the reason is part of the key (collision-remint and
|
|
26883
|
+
// remint-assigned of one id and row are distinct facts).
|
|
26884
|
+
key: ["entity_table", "display_id", "entity_uid", "reason"],
|
|
26654
26885
|
task: "T12341"
|
|
26655
26886
|
},
|
|
26656
26887
|
{
|
|
@@ -27232,6 +27463,20 @@ function installRowUidTriggers(db, scope) {
|
|
|
27232
27463
|
);
|
|
27233
27464
|
}
|
|
27234
27465
|
}
|
|
27466
|
+
function v1ReleaseBirthFp(db, table, row) {
|
|
27467
|
+
const col = (c) => row[c] ?? null;
|
|
27468
|
+
const facts = table === "tasks_task_acceptance_criteria_history" ? [col("ac_id"), col("previous_text"), col("reason")] : table === "tasks_evidence_ac_bindings" ? [col("evidence_atom_id"), col("binding_type"), col("ac_text_hash")] : [];
|
|
27469
|
+
if (facts.length === 0) return null;
|
|
27470
|
+
const acUid = col("ac_uid");
|
|
27471
|
+
let ref = "ref:none";
|
|
27472
|
+
if (acUid !== null) {
|
|
27473
|
+
const ac = db.prepare("SELECT birth_fp AS fp FROM main.tasks_task_acceptance_criteria WHERE uid = ?").get(acUid);
|
|
27474
|
+
ref = ac === void 0 ? "ref:missing" : ac.fp;
|
|
27475
|
+
if (ref === null) return null;
|
|
27476
|
+
}
|
|
27477
|
+
const spec = rowIdentitySpec("project", table);
|
|
27478
|
+
return birthFingerprint(table, spec?.birth ? col(spec.birth) : null, [...facts, ref]);
|
|
27479
|
+
}
|
|
27235
27480
|
function hasObject(db, type, name15) {
|
|
27236
27481
|
return db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = ? AND name = ?").get(type, name15) !== void 0;
|
|
27237
27482
|
}
|
|
@@ -27315,24 +27560,41 @@ function preReleaseBirthFp(db, table, row) {
|
|
|
27315
27560
|
function resetStaleIdentity(db, scope, writers) {
|
|
27316
27561
|
if (scope !== "project" || !hasTable(db, ROW_IDENTITY_META_TABLE)) return "none";
|
|
27317
27562
|
if (readMeta(db, ROW_IDENTITY_RECIPE_KEY) === ROW_IDENTITY_RECIPE) return "none";
|
|
27318
|
-
const minted = ROW_IDENTITY.project.filter(
|
|
27319
|
-
(spec) =>
|
|
27563
|
+
const minted = fingerprintOrder("project", ROW_IDENTITY.project).filter(
|
|
27564
|
+
(spec) => hasTable(db, spec.table) && columnsOf(db, spec.table).has(BIRTH_FP_COLUMN)
|
|
27320
27565
|
);
|
|
27321
27566
|
const stale = [];
|
|
27567
|
+
const cleared = /* @__PURE__ */ new Map();
|
|
27568
|
+
const mark = (table, column, value) => {
|
|
27569
|
+
if (value === null || value === void 0) return;
|
|
27570
|
+
const key = `${table}.${column}`;
|
|
27571
|
+
const set2 = cleared.get(key) ?? /* @__PURE__ */ new Set();
|
|
27572
|
+
set2.add(String(value));
|
|
27573
|
+
cleared.set(key, set2);
|
|
27574
|
+
};
|
|
27322
27575
|
for (const spec of minted) {
|
|
27576
|
+
const deps = (spec.birthFacts ?? []).map((fact) => fingerprintRef("project", spec, fact)).filter((d) => d !== null);
|
|
27577
|
+
const keyColumn = targetKey("project", spec.table);
|
|
27323
27578
|
const rows = db.prepare(
|
|
27324
27579
|
`SELECT rowid AS _rowid, * FROM main.${q(spec.table)} WHERE ${q(BIRTH_FP_COLUMN)} IS NOT NULL`
|
|
27325
27580
|
).all();
|
|
27326
27581
|
for (const row of rows) {
|
|
27327
|
-
|
|
27582
|
+
const derivedFromStale = deps.some(
|
|
27583
|
+
(d) => cleared.get(`${d.table}.${d.key}`)?.has(String(row[d.column] ?? ""))
|
|
27584
|
+
);
|
|
27585
|
+
if (derivedFromStale || row[BIRTH_FP_COLUMN] === preReleaseBirthFp(db, spec.table, row) || row[BIRTH_FP_COLUMN] === v1ReleaseBirthFp(db, spec.table, row)) {
|
|
27328
27586
|
stale.push({ table: spec.table, rowid: row._rowid });
|
|
27587
|
+
mark(spec.table, keyColumn, row[keyColumn]);
|
|
27588
|
+
mark(spec.table, UID_COLUMN, row[UID_COLUMN]);
|
|
27329
27589
|
}
|
|
27330
27590
|
}
|
|
27331
27591
|
}
|
|
27332
|
-
|
|
27592
|
+
const graveyardRows = scope === "project" && hasTable(db, AC_UID_GRAVEYARD) ? db.prepare(`SELECT count(*) AS n FROM main.${AC_UID_GRAVEYARD}`).get().n : 0;
|
|
27593
|
+
if (stale.length === 0 && graveyardRows === 0) return "none";
|
|
27333
27594
|
if (readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0) return "refused";
|
|
27334
27595
|
db.exec("SAVEPOINT row_identity_reset");
|
|
27335
27596
|
try {
|
|
27597
|
+
if (graveyardRows > 0) writers.clearAcUidGraveyardNative(db);
|
|
27336
27598
|
for (const { table, rowid } of stale) {
|
|
27337
27599
|
writers.clearBirthFpNative(db, table, rowid);
|
|
27338
27600
|
}
|
|
@@ -27348,6 +27610,106 @@ function writeRecipeMarker(db, writers = requireWriters()) {
|
|
|
27348
27610
|
if (!hasTable(db, ROW_IDENTITY_META_TABLE)) return;
|
|
27349
27611
|
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_RECIPE);
|
|
27350
27612
|
}
|
|
27613
|
+
function rowIdentityShared(db) {
|
|
27614
|
+
return readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0;
|
|
27615
|
+
}
|
|
27616
|
+
function healRowIdentitySchema(db, scope, writers = registeredWriters) {
|
|
27617
|
+
const log15 = getLogger("row-identity");
|
|
27618
|
+
if (ROW_IDENTITY[scope].length === 0) {
|
|
27619
|
+
return [];
|
|
27620
|
+
}
|
|
27621
|
+
if (!schemaWritesAllowed(db)) {
|
|
27622
|
+
log15.debug({ scope }, "row identity schema heal skipped: schema writes refused for this build");
|
|
27623
|
+
return [];
|
|
27624
|
+
}
|
|
27625
|
+
try {
|
|
27626
|
+
db.exec("SAVEPOINT row_identity_heal");
|
|
27627
|
+
try {
|
|
27628
|
+
const healed = [
|
|
27629
|
+
...scope === "project" ? ensureIdentityTables(db) : [],
|
|
27630
|
+
...ensureRowIdentitySchema(db, scope)
|
|
27631
|
+
];
|
|
27632
|
+
if (healed.length > 0) recordHealReceipt(db, scope, healed, writers);
|
|
27633
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27634
|
+
if (healed.length > 0)
|
|
27635
|
+
log15.info({ scope, healed: healed.length }, "row identity schema healed");
|
|
27636
|
+
return healed;
|
|
27637
|
+
} catch (error48) {
|
|
27638
|
+
db.exec("ROLLBACK TO SAVEPOINT row_identity_heal");
|
|
27639
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27640
|
+
throw error48;
|
|
27641
|
+
}
|
|
27642
|
+
} catch (error48) {
|
|
27643
|
+
log15.error({ scope, error: error48 }, "row identity schema heal failed");
|
|
27644
|
+
return [];
|
|
27645
|
+
}
|
|
27646
|
+
}
|
|
27647
|
+
function recordHealReceipt(db, scope, healed, writers) {
|
|
27648
|
+
const table = HEAL_RECEIPT_TABLE[scope];
|
|
27649
|
+
const log15 = getLogger("row-identity");
|
|
27650
|
+
if (table === null || !hasTable(db, table) || !writers) {
|
|
27651
|
+
log15.warn({ scope, healed: healed.length }, "row identity schema healed; no receipt table");
|
|
27652
|
+
return;
|
|
27653
|
+
}
|
|
27654
|
+
const objects = healed.map((stmt) => {
|
|
27655
|
+
const col = /ALTER TABLE main\.("?)(\w+)\1 ADD COLUMN ("?)(\w+)\3/.exec(stmt);
|
|
27656
|
+
if (col) return `${col[2]}.${col[4]}`;
|
|
27657
|
+
const obj = /(TABLE|INDEX|TRIGGER) IF NOT EXISTS main\.("?)(\w+)\2/.exec(stmt);
|
|
27658
|
+
return obj ? `${obj[1].toLowerCase()} ${obj[3]}` : stmt.slice(0, 60);
|
|
27659
|
+
});
|
|
27660
|
+
const receipt2 = {
|
|
27661
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27662
|
+
scope,
|
|
27663
|
+
statements: healed.length,
|
|
27664
|
+
objects
|
|
27665
|
+
};
|
|
27666
|
+
const history = [...readRowIdentityHealHistory(db), receipt2].slice(-HEAL_RECEIPTS_KEPT);
|
|
27667
|
+
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_HEAL_KEY, JSON.stringify(history));
|
|
27668
|
+
}
|
|
27669
|
+
function readRowIdentityHealHistory(db) {
|
|
27670
|
+
const raw = readMeta(db, ROW_IDENTITY_HEAL_KEY);
|
|
27671
|
+
if (raw === void 0) return [];
|
|
27672
|
+
try {
|
|
27673
|
+
const parsed = JSON.parse(raw);
|
|
27674
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
27675
|
+
} catch {
|
|
27676
|
+
return [];
|
|
27677
|
+
}
|
|
27678
|
+
}
|
|
27679
|
+
function missingRowIdentitySchema(db) {
|
|
27680
|
+
if (!hasTable(db, "tasks_task_acceptance_criteria")) return [];
|
|
27681
|
+
const missing = [];
|
|
27682
|
+
for (const table of Object.keys(IDENTITY_TABLE_DDL)) {
|
|
27683
|
+
if (!hasTable(db, table)) missing.push(`table ${table}`);
|
|
27684
|
+
}
|
|
27685
|
+
for (const [table, column] of [
|
|
27686
|
+
["tasks_display_id_aliases", "displaced_hlc"],
|
|
27687
|
+
["tasks_display_id_aliases", "entity_birth_fp"],
|
|
27688
|
+
[AC_UID_GRAVEYARD, "birth_fp"]
|
|
27689
|
+
]) {
|
|
27690
|
+
if (hasTable(db, table) && !columnsOf(db, table).has(column)) {
|
|
27691
|
+
missing.push(`column ${table}.${column}`);
|
|
27692
|
+
}
|
|
27693
|
+
}
|
|
27694
|
+
if (!hasObject(db, "trigger", "trg_tasks_ac_uid_graveyard")) {
|
|
27695
|
+
missing.push("trigger trg_tasks_ac_uid_graveyard");
|
|
27696
|
+
}
|
|
27697
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
27698
|
+
if (!hasTable(db, spec.table)) continue;
|
|
27699
|
+
const cols = columnsOf(db, spec.table);
|
|
27700
|
+
for (const column of rowIdentityColumns("project", spec.table)) {
|
|
27701
|
+
if (!cols.has(column)) missing.push(`column ${spec.table}.${column}`);
|
|
27702
|
+
}
|
|
27703
|
+
if (!uidIsPrimaryKey(db, spec.table) && !hasObject(db, "index", `uq_${spec.table}_uid`)) {
|
|
27704
|
+
missing.push(`index uq_${spec.table}_uid`);
|
|
27705
|
+
}
|
|
27706
|
+
for (const ref of spec.storedRefUids ?? []) {
|
|
27707
|
+
const index2 = `idx_${spec.table}_${ref.column}`;
|
|
27708
|
+
if (!hasObject(db, "index", index2)) missing.push(`index ${index2}`);
|
|
27709
|
+
}
|
|
27710
|
+
}
|
|
27711
|
+
return missing;
|
|
27712
|
+
}
|
|
27351
27713
|
function prepareRowIdentity(db, scope, options = {}) {
|
|
27352
27714
|
if (ROW_IDENTITY[scope].length === 0) return null;
|
|
27353
27715
|
if (!rowUidFillEnabled()) return null;
|
|
@@ -27386,7 +27748,7 @@ function prepareRowIdentity(db, scope, options = {}) {
|
|
|
27386
27748
|
return null;
|
|
27387
27749
|
}
|
|
27388
27750
|
}
|
|
27389
|
-
var ROW_UID_DOMAIN, ROW_BIRTH_DOMAIN, ROW_UID_SQL_FUNCTION, ROW_BIRTH_FP_SQL_FUNCTION, ROW_RANDOM_UID_SQL_FUNCTION, AC_TEXT_HASH_SQL_FUNCTION, AC_UID_GRAVEYARD, registeredWriters, STORE_TIMESTAMP, MAX_UUID_MS, ROW_IDENTITY_RECIPE, ROW_IDENTITY_META_TABLE, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_SYNCED_KEY, IDENTITY_TABLE_DDL, AC_UID_GRAVEYARD_TRIGGER;
|
|
27751
|
+
var ROW_UID_DOMAIN, ROW_BIRTH_DOMAIN, ROW_UID_SQL_FUNCTION, ROW_BIRTH_FP_SQL_FUNCTION, ROW_RANDOM_UID_SQL_FUNCTION, AC_TEXT_HASH_SQL_FUNCTION, AC_UID_GRAVEYARD, registeredWriters, STORE_TIMESTAMP, MAX_UUID_MS, ROW_IDENTITY_RECIPE, ROW_IDENTITY_META_TABLE, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_SYNCED_KEY, IDENTITY_TABLE_DDL, AC_UID_GRAVEYARD_TRIGGER, ROW_IDENTITY_HEAL_KEY, HEAL_RECEIPT_TABLE, HEAL_RECEIPTS_KEPT;
|
|
27390
27752
|
var init_row_identity = __esm({
|
|
27391
27753
|
"packages/core/src/store/row-identity.ts"() {
|
|
27392
27754
|
"use strict";
|
|
@@ -27395,6 +27757,7 @@ var init_row_identity = __esm({
|
|
|
27395
27757
|
init_ac_table();
|
|
27396
27758
|
init_row_identity_flag();
|
|
27397
27759
|
init_row_identity_registry();
|
|
27760
|
+
init_worktree_build_guard();
|
|
27398
27761
|
ROW_UID_DOMAIN = "cleo/row-uid/v1";
|
|
27399
27762
|
ROW_BIRTH_DOMAIN = "cleo/row-birth/v1";
|
|
27400
27763
|
ROW_UID_SQL_FUNCTION = "cleo_row_uid";
|
|
@@ -27404,7 +27767,7 @@ var init_row_identity = __esm({
|
|
|
27404
27767
|
AC_UID_GRAVEYARD = "tasks_ac_uid_graveyard";
|
|
27405
27768
|
STORE_TIMESTAMP = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
27406
27769
|
MAX_UUID_MS = 2 ** 48 - 1;
|
|
27407
|
-
ROW_IDENTITY_RECIPE = "cleo/row-identity/
|
|
27770
|
+
ROW_IDENTITY_RECIPE = "cleo/row-identity/v2";
|
|
27408
27771
|
ROW_IDENTITY_META_TABLE = "tasks_row_identity_meta";
|
|
27409
27772
|
ROW_IDENTITY_RECIPE_KEY = "row_identity_recipe";
|
|
27410
27773
|
ROW_IDENTITY_SYNCED_KEY = "row_identity_synced";
|
|
@@ -27449,6 +27812,15 @@ BEGIN
|
|
|
27449
27812
|
INSERT INTO ${AC_UID_GRAVEYARD} (ac_id, uid, task_id, ordinal, text, birth_fp, deleted_at)
|
|
27450
27813
|
VALUES (OLD.id, OLD.uid, OLD.task_id, OLD.ordinal, OLD.text, OLD.birth_fp, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
27451
27814
|
END`;
|
|
27815
|
+
ROW_IDENTITY_HEAL_KEY = "row_identity_schema_healed";
|
|
27816
|
+
HEAL_RECEIPT_TABLE = {
|
|
27817
|
+
project: ROW_IDENTITY_META_TABLE,
|
|
27818
|
+
// The global store declares no identity table yet (ROW_IDENTITY.global is
|
|
27819
|
+
// empty, so its heal never runs); the change that declares one adds its
|
|
27820
|
+
// meta table here.
|
|
27821
|
+
global: null
|
|
27822
|
+
};
|
|
27823
|
+
HEAL_RECEIPTS_KEPT = 20;
|
|
27452
27824
|
}
|
|
27453
27825
|
});
|
|
27454
27826
|
|
|
@@ -33128,7 +33500,7 @@ var init_task_claim = __esm({
|
|
|
33128
33500
|
});
|
|
33129
33501
|
|
|
33130
33502
|
// packages/core/src/store/converters.ts
|
|
33131
|
-
import { z as
|
|
33503
|
+
import { z as z27 } from "zod";
|
|
33132
33504
|
function readStoredAcceptance(row) {
|
|
33133
33505
|
if (row.acceptanceJson === null || row.acceptanceJson === void 0) return void 0;
|
|
33134
33506
|
try {
|
|
@@ -33286,7 +33658,7 @@ var init_converters = __esm({
|
|
|
33286
33658
|
init_src();
|
|
33287
33659
|
init_parsers();
|
|
33288
33660
|
init_task_claim();
|
|
33289
|
-
storedAcceptanceSchema =
|
|
33661
|
+
storedAcceptanceSchema = z27.custom(
|
|
33290
33662
|
(value) => Array.isArray(value) && value.every((item) => acceptanceItemSchema.safeParse(item).success)
|
|
33291
33663
|
);
|
|
33292
33664
|
}
|
|
@@ -35949,7 +36321,7 @@ import {
|
|
|
35949
36321
|
} from "node:fs";
|
|
35950
36322
|
import { createRequire as createRequire5 } from "node:module";
|
|
35951
36323
|
import { basename as basename7, dirname as dirname12, join as join13 } from "node:path";
|
|
35952
|
-
import { z as
|
|
36324
|
+
import { z as z28 } from "zod";
|
|
35953
36325
|
function formatBackupTimestamp(d) {
|
|
35954
36326
|
const pad = (n, len = 2) => String(n).padStart(len, "0");
|
|
35955
36327
|
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
|
|
@@ -36086,16 +36458,16 @@ var init_backup_sidecar = __esm({
|
|
|
36086
36458
|
init_logger2();
|
|
36087
36459
|
PRE_COLLAPSE_BACKUP_TYPE = "migration";
|
|
36088
36460
|
MARKER_PREFIX = "twin_collapse:";
|
|
36089
|
-
backupSidecarSchema =
|
|
36090
|
-
backupId:
|
|
36091
|
-
type:
|
|
36092
|
-
timestamp:
|
|
36093
|
-
note:
|
|
36094
|
-
files:
|
|
36095
|
-
pinned:
|
|
36096
|
-
pinnedReason:
|
|
36097
|
-
releasedAt:
|
|
36098
|
-
releasedReason:
|
|
36461
|
+
backupSidecarSchema = z28.object({
|
|
36462
|
+
backupId: z28.string().min(1),
|
|
36463
|
+
type: z28.string().min(1),
|
|
36464
|
+
timestamp: z28.string().min(1),
|
|
36465
|
+
note: z28.string().optional(),
|
|
36466
|
+
files: z28.array(z28.string()),
|
|
36467
|
+
pinned: z28.boolean().optional(),
|
|
36468
|
+
pinnedReason: z28.string().optional(),
|
|
36469
|
+
releasedAt: z28.string().optional(),
|
|
36470
|
+
releasedReason: z28.string().optional()
|
|
36099
36471
|
}).passthrough();
|
|
36100
36472
|
}
|
|
36101
36473
|
});
|
|
@@ -36267,7 +36639,7 @@ var init_pre_repair_snapshot = __esm({
|
|
|
36267
36639
|
import { createHash as createHash5 } from "node:crypto";
|
|
36268
36640
|
import { basename as basename8, dirname as dirname15 } from "node:path";
|
|
36269
36641
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
36270
|
-
import { z as
|
|
36642
|
+
import { z as z29 } from "zod";
|
|
36271
36643
|
function hasMainTable(db, name15) {
|
|
36272
36644
|
return db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = 'table' AND name = ?").get(name15) !== void 0;
|
|
36273
36645
|
}
|
|
@@ -37400,20 +37772,20 @@ var init_twin_collapse = __esm({
|
|
|
37400
37772
|
SHADOW_WRITE_REFUSED = "E_TWIN_COLLAPSE_FAILED: store is read-only until the twin collapse succeeds; run cleo doctor twin-collapse";
|
|
37401
37773
|
SHADOW_WRITE_OPS = ["INSERT", "UPDATE", "DELETE"];
|
|
37402
37774
|
STICKY_ARCHIVE_KEY = `${TWIN_COLLAPSE_ARCHIVE_PREFIX}sticky_tags`;
|
|
37403
|
-
FocusNotesShape =
|
|
37404
|
-
StickyArchiveShape =
|
|
37405
|
-
RecoveryReceiptShape =
|
|
37406
|
-
task:
|
|
37407
|
-
id:
|
|
37408
|
-
recoveredAt:
|
|
37409
|
-
snapshot:
|
|
37410
|
-
archived:
|
|
37411
|
-
focusNotesAdded:
|
|
37412
|
-
stickyArchived:
|
|
37413
|
-
stickyArchiveKey:
|
|
37414
|
-
before:
|
|
37415
|
-
after:
|
|
37416
|
-
rolledBackAt:
|
|
37775
|
+
FocusNotesShape = z29.object({ sessionNotes: z29.array(z29.unknown()) }).passthrough();
|
|
37776
|
+
StickyArchiveShape = z29.array(z29.string());
|
|
37777
|
+
RecoveryReceiptShape = z29.object({
|
|
37778
|
+
task: z29.literal("T12727"),
|
|
37779
|
+
id: z29.string(),
|
|
37780
|
+
recoveredAt: z29.string(),
|
|
37781
|
+
snapshot: z29.string().nullable(),
|
|
37782
|
+
archived: z29.array(z29.object({ key: z29.string(), archiveKey: z29.string(), sha: z29.string() })),
|
|
37783
|
+
focusNotesAdded: z29.number(),
|
|
37784
|
+
stickyArchived: z29.array(z29.string()),
|
|
37785
|
+
stickyArchiveKey: z29.string(),
|
|
37786
|
+
before: z29.object({ focusState: z29.string().nullable(), stickyArchive: z29.string().nullable() }),
|
|
37787
|
+
after: z29.object({ focusState: z29.string().nullable(), stickyArchive: z29.string().nullable() }),
|
|
37788
|
+
rolledBackAt: z29.string().nullable()
|
|
37417
37789
|
});
|
|
37418
37790
|
}
|
|
37419
37791
|
});
|
|
@@ -40995,12 +41367,12 @@ var init_safety_data_accessor = __esm({
|
|
|
40995
41367
|
this.getSafetyOptions()
|
|
40996
41368
|
);
|
|
40997
41369
|
}
|
|
40998
|
-
async insertNewTask(task) {
|
|
41370
|
+
async insertNewTask(task, identity) {
|
|
40999
41371
|
this.logVerbose(`Inserting new task ${task.id}`);
|
|
41000
41372
|
await safeSingleTaskWrite(
|
|
41001
41373
|
this.inner,
|
|
41002
41374
|
task.id,
|
|
41003
|
-
() => this.inner.insertNewTask(task),
|
|
41375
|
+
() => this.inner.insertNewTask(task, identity),
|
|
41004
41376
|
this.cwd,
|
|
41005
41377
|
this.getSafetyOptions()
|
|
41006
41378
|
);
|
|
@@ -41048,6 +41420,9 @@ var init_safety_data_accessor = __esm({
|
|
|
41048
41420
|
return this.inner.findOrphanAcBindings();
|
|
41049
41421
|
}
|
|
41050
41422
|
// ---- Metadata (pass-through to inner) ----
|
|
41423
|
+
async getTaskIdentities(taskIds) {
|
|
41424
|
+
return await this.inner.getTaskIdentities?.(taskIds) ?? [];
|
|
41425
|
+
}
|
|
41051
41426
|
async getMetaValue(key) {
|
|
41052
41427
|
return this.inner.getMetaValue(key);
|
|
41053
41428
|
}
|
|
@@ -41421,13 +41796,147 @@ var init_cross_db_cleanup = __esm({
|
|
|
41421
41796
|
}
|
|
41422
41797
|
});
|
|
41423
41798
|
|
|
41799
|
+
// packages/core/src/store/dependency-cycles.ts
|
|
41800
|
+
function formatDependencyCycle(cycle) {
|
|
41801
|
+
return cycle.join(" \u2192 ");
|
|
41802
|
+
}
|
|
41803
|
+
function buildAdjacency(edges) {
|
|
41804
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
41805
|
+
for (const { taskId, dependsOn } of edges) {
|
|
41806
|
+
const next = adjacency.get(taskId);
|
|
41807
|
+
if (next) next.push(dependsOn);
|
|
41808
|
+
else adjacency.set(taskId, [dependsOn]);
|
|
41809
|
+
}
|
|
41810
|
+
for (const next of adjacency.values()) next.sort();
|
|
41811
|
+
return adjacency;
|
|
41812
|
+
}
|
|
41813
|
+
function shortestPath(adjacency, from, to) {
|
|
41814
|
+
if (from === to) return [from];
|
|
41815
|
+
const previous = /* @__PURE__ */ new Map([[from, from]]);
|
|
41816
|
+
const queue = [from];
|
|
41817
|
+
for (let head = 0; head < queue.length; head++) {
|
|
41818
|
+
const id = queue[head];
|
|
41819
|
+
for (const next of adjacency.get(id) ?? []) {
|
|
41820
|
+
if (previous.has(next)) continue;
|
|
41821
|
+
previous.set(next, id);
|
|
41822
|
+
if (next === to) {
|
|
41823
|
+
const path = [to];
|
|
41824
|
+
let cursor = id;
|
|
41825
|
+
while (cursor !== from) {
|
|
41826
|
+
path.push(cursor);
|
|
41827
|
+
cursor = previous.get(cursor);
|
|
41828
|
+
}
|
|
41829
|
+
path.push(from);
|
|
41830
|
+
return path.reverse();
|
|
41831
|
+
}
|
|
41832
|
+
queue.push(next);
|
|
41833
|
+
}
|
|
41834
|
+
}
|
|
41835
|
+
return null;
|
|
41836
|
+
}
|
|
41837
|
+
function findClosedCycle(existing, edge) {
|
|
41838
|
+
if (edge.taskId === edge.dependsOn) return [edge.taskId, edge.taskId];
|
|
41839
|
+
const path = shortestPath(buildAdjacency(existing), edge.dependsOn, edge.taskId);
|
|
41840
|
+
return path ? [edge.taskId, ...path] : null;
|
|
41841
|
+
}
|
|
41842
|
+
function dependencyCycleError(edge, cycle) {
|
|
41843
|
+
const self = edge.taskId === edge.dependsOn;
|
|
41844
|
+
const message = self ? `${DEPENDENCY_CYCLE_CODE}: task ${edge.taskId} cannot depend on itself` : `${DEPENDENCY_CYCLE_CODE}: ${edge.taskId} depends on ${edge.dependsOn} would close a dependency cycle: ${formatDependencyCycle(cycle)}`;
|
|
41845
|
+
const closing = cycle.length >= 3 ? cycle[cycle.length - 2] : void 0;
|
|
41846
|
+
const fix = self ? `Drop ${edge.taskId} from its own --depends list` : `Drop this dependency, or first remove another edge of the cycle, e.g. cleo update ${closing} --remove-depends ${edge.taskId}`;
|
|
41847
|
+
return new CleoError(14 /* CIRCULAR_REFERENCE */, message, {
|
|
41848
|
+
fix,
|
|
41849
|
+
details: {
|
|
41850
|
+
field: "depends",
|
|
41851
|
+
actual: edge.dependsOn,
|
|
41852
|
+
taskId: edge.taskId,
|
|
41853
|
+
cycle: [...cycle]
|
|
41854
|
+
}
|
|
41855
|
+
});
|
|
41856
|
+
}
|
|
41857
|
+
function isDependencyCycleAbort(err) {
|
|
41858
|
+
for (let e = err, depth = 0; e instanceof Error && depth < 8; depth++) {
|
|
41859
|
+
if (e.message.includes(DEPENDENCY_CYCLE_CODE)) return true;
|
|
41860
|
+
e = e.cause;
|
|
41861
|
+
}
|
|
41862
|
+
return false;
|
|
41863
|
+
}
|
|
41864
|
+
function readDependencyEdges(db) {
|
|
41865
|
+
return db.select({
|
|
41866
|
+
taskId: tasksTaskDependencies.taskId,
|
|
41867
|
+
dependsOn: tasksTaskDependencies.dependsOn
|
|
41868
|
+
}).from(tasksTaskDependencies).all();
|
|
41869
|
+
}
|
|
41870
|
+
function rethrowDependencyCycle(db, err, attempted) {
|
|
41871
|
+
if (!isDependencyCycleAbort(err)) throw err;
|
|
41872
|
+
const edges = readDependencyEdges(db);
|
|
41873
|
+
for (const edge of attempted) {
|
|
41874
|
+
const cycle = findClosedCycle(edges, edge);
|
|
41875
|
+
if (cycle) throw dependencyCycleError(edge, cycle);
|
|
41876
|
+
edges.push(edge);
|
|
41877
|
+
}
|
|
41878
|
+
throw err;
|
|
41879
|
+
}
|
|
41880
|
+
var DEPENDENCY_CYCLE_CODE;
|
|
41881
|
+
var init_dependency_cycles = __esm({
|
|
41882
|
+
"packages/core/src/store/dependency-cycles.ts"() {
|
|
41883
|
+
"use strict";
|
|
41884
|
+
init_src();
|
|
41885
|
+
init_errors2();
|
|
41886
|
+
init_tasks_schema();
|
|
41887
|
+
DEPENDENCY_CYCLE_CODE = "E_TASK_DEPENDENCY_CYCLE";
|
|
41888
|
+
}
|
|
41889
|
+
});
|
|
41890
|
+
|
|
41424
41891
|
// packages/core/src/store/db-helpers.ts
|
|
41425
41892
|
import { and as and5, eq as eq7, inArray as inArray3, sql as sql27 } from "drizzle-orm";
|
|
41426
41893
|
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
41427
41894
|
await writeTaskRow(db, row, archiveFields, allowOrphanParent, false);
|
|
41428
41895
|
}
|
|
41429
|
-
async function insertNewTask(db, row) {
|
|
41430
|
-
await writeTaskRow(
|
|
41896
|
+
async function insertNewTask(db, row, identity = { origin: "new" }) {
|
|
41897
|
+
await writeTaskRow(
|
|
41898
|
+
db,
|
|
41899
|
+
{ ...row, ...await importedIdentity(db, identity, row) },
|
|
41900
|
+
void 0,
|
|
41901
|
+
false,
|
|
41902
|
+
true
|
|
41903
|
+
);
|
|
41904
|
+
}
|
|
41905
|
+
async function tableExists2(db, table) {
|
|
41906
|
+
const rows = await db.all(
|
|
41907
|
+
sql27`SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ${table}`
|
|
41908
|
+
);
|
|
41909
|
+
return rows.length > 0;
|
|
41910
|
+
}
|
|
41911
|
+
async function importedIdentity(db, identity, row) {
|
|
41912
|
+
if (identity.origin === "new" || !rowUidFillEnabled()) return {};
|
|
41913
|
+
const fp = identity.birthFp ?? null;
|
|
41914
|
+
const carried2 = identity.uid ?? null;
|
|
41915
|
+
if (carried2 !== null && fp !== null) {
|
|
41916
|
+
let uid = carried2;
|
|
41917
|
+
if (await tableExists2(db, "tasks_uid_aliases")) {
|
|
41918
|
+
for (let hop = 0; hop < 32; hop++) {
|
|
41919
|
+
const found = await db.all(
|
|
41920
|
+
sql27`SELECT new_uid AS uid FROM tasks_uid_aliases
|
|
41921
|
+
WHERE entity_table = 'tasks_tasks' AND old_uid = ${uid} AND old_birth_fp = ${fp}`
|
|
41922
|
+
);
|
|
41923
|
+
const next = found[0];
|
|
41924
|
+
if (!next) break;
|
|
41925
|
+
uid = next.uid;
|
|
41926
|
+
}
|
|
41927
|
+
}
|
|
41928
|
+
const [holder] = await db.select({ id: tasksTasks.id, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(eq7(tasksTasks.uid, uid)).limit(1).all();
|
|
41929
|
+
if (holder && holder.birthFp === fp) throw new SameRowPresentError(row.id, holder.id);
|
|
41930
|
+
if (await tableExists2(db, "tasks_identity_quarantine")) {
|
|
41931
|
+
const [held] = await db.all(
|
|
41932
|
+
sql27`SELECT 1 AS x FROM tasks_identity_quarantine
|
|
41933
|
+
WHERE entity_table = 'tasks_tasks' AND uid = ${uid} AND birth_fp = ${fp}`
|
|
41934
|
+
);
|
|
41935
|
+
if (held) throw new SameRowPresentError(row.id, "held");
|
|
41936
|
+
}
|
|
41937
|
+
if (!holder) return { uid, birthFp: fp };
|
|
41938
|
+
}
|
|
41939
|
+
return { uid: null, birthFp: null };
|
|
41431
41940
|
}
|
|
41432
41941
|
async function writeTaskRow(db, row, archiveFields, allowOrphanParent, insertOnly) {
|
|
41433
41942
|
if (row.parentId && row.parentId === row.id) {
|
|
@@ -41578,7 +42087,11 @@ async function batchUpdateDependencies(db, tasks2, validIds) {
|
|
|
41578
42087
|
for (const depId of want) if (!have.has(depId)) added.push({ taskId, dependsOn: depId });
|
|
41579
42088
|
}
|
|
41580
42089
|
if (added.length > 0) {
|
|
41581
|
-
|
|
42090
|
+
try {
|
|
42091
|
+
await db.insert(tasksTaskDependencies).values(added).onConflictDoNothing().run();
|
|
42092
|
+
} catch (err) {
|
|
42093
|
+
rethrowDependencyCycle(db, err, added);
|
|
42094
|
+
}
|
|
41582
42095
|
}
|
|
41583
42096
|
}
|
|
41584
42097
|
async function loadDependenciesForTasks(db, tasks2, _validationIds) {
|
|
@@ -41623,15 +42136,29 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
41623
42136
|
task.relates = relations && relations.length > 0 ? relations : [];
|
|
41624
42137
|
}
|
|
41625
42138
|
}
|
|
41626
|
-
var log6;
|
|
42139
|
+
var log6, SameRowPresentError;
|
|
41627
42140
|
var init_db_helpers = __esm({
|
|
41628
42141
|
"packages/core/src/store/db-helpers.ts"() {
|
|
41629
42142
|
"use strict";
|
|
41630
42143
|
init_src();
|
|
41631
42144
|
init_errors2();
|
|
41632
42145
|
init_logger2();
|
|
42146
|
+
init_dependency_cycles();
|
|
42147
|
+
init_row_identity_flag();
|
|
41633
42148
|
init_tasks_schema();
|
|
41634
42149
|
log6 = getLogger("db-helpers");
|
|
42150
|
+
SameRowPresentError = class extends CleoError {
|
|
42151
|
+
/** Where the row already is: its display id, or `held` when quarantined. */
|
|
42152
|
+
presentAs;
|
|
42153
|
+
constructor(taskId, presentAs) {
|
|
42154
|
+
super(
|
|
42155
|
+
22 /* ID_COLLISION */,
|
|
42156
|
+
`Task ${taskId} is already in this store (${presentAs === "held" ? "held for sync" : `as ${presentAs}`}): same uid and birth fingerprint; not written again`,
|
|
42157
|
+
{ details: { field: "taskId", actual: taskId, expected: presentAs } }
|
|
42158
|
+
);
|
|
42159
|
+
this.presentAs = presentAs;
|
|
42160
|
+
}
|
|
42161
|
+
};
|
|
41635
42162
|
}
|
|
41636
42163
|
});
|
|
41637
42164
|
|
|
@@ -41716,46 +42243,133 @@ function readProcessEntry(pid) {
|
|
|
41716
42243
|
return null;
|
|
41717
42244
|
}
|
|
41718
42245
|
}
|
|
41719
|
-
function
|
|
42246
|
+
function readProcessArgs(pid) {
|
|
42247
|
+
if (process.platform === "win32" || !Number.isInteger(pid) || pid <= 1) return null;
|
|
42248
|
+
try {
|
|
42249
|
+
const out = execFileSync("ps", ["-o", "args=", "-p", String(pid)], {
|
|
42250
|
+
encoding: "utf8",
|
|
42251
|
+
timeout: 1e3,
|
|
42252
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
42253
|
+
env: { ...process.env, ...PS_STABLE_ENV }
|
|
42254
|
+
}).trim();
|
|
42255
|
+
return out === "" ? null : out;
|
|
42256
|
+
} catch {
|
|
42257
|
+
return null;
|
|
42258
|
+
}
|
|
42259
|
+
}
|
|
42260
|
+
function baseName(token) {
|
|
42261
|
+
return token.slice(token.lastIndexOf("/") + 1).replace(/^-/, "");
|
|
42262
|
+
}
|
|
42263
|
+
function programName(commandLine) {
|
|
42264
|
+
const tokens = commandLine.trim().split(/\s+/);
|
|
42265
|
+
const head = baseName(tokens[0] ?? "");
|
|
42266
|
+
if (!RUNTIME_PATTERN.test(head)) return head;
|
|
42267
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
42268
|
+
const token = tokens[i] ?? "";
|
|
42269
|
+
if (token === "-m") return (tokens[i + 1] ?? head).split(".")[0] ?? head;
|
|
42270
|
+
if (token.startsWith("-")) continue;
|
|
42271
|
+
return baseName(token).replace(/\.(c|m)?(js|ts)$|\.py$/, "");
|
|
42272
|
+
}
|
|
42273
|
+
return head;
|
|
42274
|
+
}
|
|
42275
|
+
function isCommandStringShell(args) {
|
|
42276
|
+
const tokens = args.trim().split(/\s+/);
|
|
42277
|
+
const shell = programName(args);
|
|
42278
|
+
let first = 1;
|
|
42279
|
+
if (RUNTIME_PATTERN.test(baseName(tokens[0] ?? ""))) {
|
|
42280
|
+
while (first < tokens.length && (tokens[first] ?? "").startsWith("-")) first++;
|
|
42281
|
+
first++;
|
|
42282
|
+
}
|
|
42283
|
+
const rest = tokens.slice(first);
|
|
42284
|
+
if (shell === "pwsh" || shell === "powershell") {
|
|
42285
|
+
return rest.some((t) => PWSH_COMMAND_SWITCHES.has(t.toLowerCase()));
|
|
42286
|
+
}
|
|
42287
|
+
for (let i = 0; i < rest.length; i++) {
|
|
42288
|
+
const token = rest[i] ?? "";
|
|
42289
|
+
if (token === "--") return false;
|
|
42290
|
+
if (token === "--command" || token === "--commands") return true;
|
|
42291
|
+
if (SHELL_OPTIONS_WITH_ARGUMENT.has(token)) {
|
|
42292
|
+
i++;
|
|
42293
|
+
continue;
|
|
42294
|
+
}
|
|
42295
|
+
if (token.startsWith("--")) continue;
|
|
42296
|
+
if (!/^[-+][A-Za-z]+$/.test(token)) return false;
|
|
42297
|
+
if (token.startsWith("-") && token.slice(1).includes("c")) return true;
|
|
42298
|
+
}
|
|
42299
|
+
return false;
|
|
42300
|
+
}
|
|
42301
|
+
function resolveAncestor(ppid, lookupProcess, lookupArgs, agentId = null) {
|
|
41720
42302
|
let pid = ppid;
|
|
41721
|
-
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH
|
|
42303
|
+
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH; depth++) {
|
|
42304
|
+
if (pid <= 1) return null;
|
|
41722
42305
|
const entry = lookupProcess(pid);
|
|
41723
|
-
if (!entry) return null;
|
|
41724
|
-
|
|
41725
|
-
|
|
42306
|
+
if (!entry || entry.pid <= 1) return null;
|
|
42307
|
+
const args = lookupArgs(entry.pid);
|
|
42308
|
+
const program = programName(args ?? entry.command);
|
|
42309
|
+
if (INIT_PROCESSES.has(program) || INIT_PROCESSES.has(entry.command)) return null;
|
|
42310
|
+
if (OWNER_PROCESS_SHELLS.has(program)) {
|
|
42311
|
+
if (args === null) return null;
|
|
42312
|
+
if (!isCommandStringShell(args)) return { entry, program, type: "shell" };
|
|
42313
|
+
} else if (!ANCESTOR_WRAPPERS.has(program)) {
|
|
42314
|
+
if (KNOWN_HARNESSES.has(program)) return { entry, program, type: "harness" };
|
|
42315
|
+
return agentId ? { entry, program, type: "host" } : null;
|
|
41726
42316
|
}
|
|
41727
42317
|
pid = entry.ppid;
|
|
41728
42318
|
}
|
|
41729
42319
|
return null;
|
|
41730
42320
|
}
|
|
42321
|
+
function anchorKey(anchor, agentId, under) {
|
|
42322
|
+
const proc = `${anchor.entry.pid}@${anchor.entry.startedAt}`;
|
|
42323
|
+
if (anchor.type === "shell" && !agentId) {
|
|
42324
|
+
return { key: `proc:${proc}`, source: "process", kind: "process" };
|
|
42325
|
+
}
|
|
42326
|
+
const agent = agentId ? `#agent=${agentId}` : "";
|
|
42327
|
+
const scope = under ? `|${under.key}` : "";
|
|
42328
|
+
return {
|
|
42329
|
+
key: `harness:${anchor.program}:${proc}${agent}${scope}`,
|
|
42330
|
+
source: "process",
|
|
42331
|
+
kind: "harness"
|
|
42332
|
+
};
|
|
42333
|
+
}
|
|
41731
42334
|
function resolveTerminalKeys(options = {}) {
|
|
41732
42335
|
const env = options.env ?? process.env;
|
|
41733
42336
|
const keys = [];
|
|
41734
42337
|
for (const source of TERMINAL_KEY_SOURCES) {
|
|
41735
42338
|
const value = envValue(env, source.envVar);
|
|
41736
42339
|
if (value === null) continue;
|
|
41737
|
-
const
|
|
42340
|
+
const qualifiers = [source.qualifierEnvVar, ...source.extraQualifierEnvVars ?? []].map((name15) => envValue(env, name15)).filter((q2) => q2 !== null);
|
|
41738
42341
|
keys.push({
|
|
41739
|
-
key: `env:${source.envVar}=${
|
|
42342
|
+
key: `env:${source.envVar}=${[...qualifiers, value].join("|")}`,
|
|
41740
42343
|
source: source.envVar,
|
|
41741
42344
|
kind: source.kind
|
|
41742
42345
|
});
|
|
41743
42346
|
}
|
|
41744
|
-
if (keys.
|
|
41745
|
-
const
|
|
41746
|
-
|
|
42347
|
+
if (keys.some((k) => k.kind === "provider")) return keys;
|
|
42348
|
+
const agentId = envValue(env, "CLEO_AGENT_ID");
|
|
42349
|
+
const live = options.ppid === void 0 && options.lookupProcess === void 0 && options.lookupArgs === void 0;
|
|
42350
|
+
let anchor;
|
|
41747
42351
|
if (live) {
|
|
41748
|
-
|
|
41749
|
-
|
|
42352
|
+
const memoKey2 = agentId ?? "";
|
|
42353
|
+
if (!liveAnchors.has(memoKey2))
|
|
42354
|
+
liveAnchors.set(
|
|
42355
|
+
memoKey2,
|
|
42356
|
+
resolveAncestor(process.ppid, readProcessEntry, readProcessArgs, agentId)
|
|
42357
|
+
);
|
|
42358
|
+
anchor = liveAnchors.get(memoKey2) ?? null;
|
|
41750
42359
|
} else {
|
|
41751
|
-
|
|
42360
|
+
anchor = resolveAncestor(
|
|
41752
42361
|
options.ppid ?? process.ppid,
|
|
41753
|
-
options.lookupProcess ?? readProcessEntry
|
|
42362
|
+
options.lookupProcess ?? readProcessEntry,
|
|
42363
|
+
options.lookupArgs ?? readProcessArgs,
|
|
42364
|
+
agentId
|
|
41754
42365
|
);
|
|
41755
42366
|
}
|
|
41756
|
-
|
|
42367
|
+
if (!anchor) return keys;
|
|
42368
|
+
if (keys.length === 0) return [anchorKey(anchor, agentId, void 0)];
|
|
42369
|
+
if (anchor.type === "shell" && !agentId) return keys;
|
|
42370
|
+
return [...keys, anchorKey(anchor, agentId, keys[0])];
|
|
41757
42371
|
}
|
|
41758
|
-
var TERMINAL_KEY_SOURCES,
|
|
42372
|
+
var TERMINAL_KEY_SOURCES, PPID_CHAIN_MAX_DEPTH, KNOWN_HARNESSES, RUNTIME_PATTERN, ANCESTOR_WRAPPERS, INIT_PROCESSES, SHELL_OPTIONS_WITH_ARGUMENT, PWSH_COMMAND_SWITCHES, OWNER_PROCESS_SHELLS, liveAnchors;
|
|
41759
42373
|
var init_terminal_identity = __esm({
|
|
41760
42374
|
"packages/core/src/sessions/terminal-identity.ts"() {
|
|
41761
42375
|
"use strict";
|
|
@@ -41787,24 +42401,100 @@ var init_terminal_identity = __esm({
|
|
|
41787
42401
|
kind: "terminal",
|
|
41788
42402
|
origin: "konsole",
|
|
41789
42403
|
qualifierEnvVar: "KONSOLE_DBUS_SERVICE"
|
|
42404
|
+
},
|
|
42405
|
+
// T12864 — non-terminal callers whose platform exports a per-job / per-login id.
|
|
42406
|
+
// GitHub Actions: GITHUB_RUN_ID is per run and shared by its jobs, so it is
|
|
42407
|
+
// qualified by GITHUB_RUN_ATTEMPT and GITHUB_JOB ("Variables reference",
|
|
42408
|
+
// docs.github.com/en/actions/reference/workflows-and-actions/variables).
|
|
42409
|
+
// Every step of one job shares the key; the steps run sequentially.
|
|
42410
|
+
{
|
|
42411
|
+
envVar: "GITHUB_RUN_ID",
|
|
42412
|
+
kind: "terminal",
|
|
42413
|
+
origin: "github-actions",
|
|
42414
|
+
qualifierEnvVar: "GITHUB_RUN_ATTEMPT",
|
|
42415
|
+
extraQualifierEnvVars: ["GITHUB_JOB"]
|
|
42416
|
+
},
|
|
42417
|
+
// GitLab CI: CI_JOB_ID is unique per job across the instance ("Predefined
|
|
42418
|
+
// CI/CD variables reference", docs.gitlab.com/ci/variables/predefined_variables).
|
|
42419
|
+
{ envVar: "CI_JOB_ID", kind: "terminal", origin: "gitlab-ci" },
|
|
42420
|
+
// OpenSSH login with a tty: SSH_TTY names the login's tty and is set only
|
|
42421
|
+
// when one was allocated; SSH_CONNECTION ("client-ip client-port server-ip
|
|
42422
|
+
// server-port", ssh(1) ENVIRONMENT) disambiguates it across connections. A
|
|
42423
|
+
// one-shot `ssh host 'cmd'` has no tty and falls through to the ancestor walk.
|
|
42424
|
+
{
|
|
42425
|
+
envVar: "SSH_TTY",
|
|
42426
|
+
kind: "terminal",
|
|
42427
|
+
origin: "openssh",
|
|
42428
|
+
qualifierEnvVar: "SSH_CONNECTION"
|
|
41790
42429
|
}
|
|
41791
42430
|
];
|
|
41792
|
-
|
|
41793
|
-
|
|
42431
|
+
PPID_CHAIN_MAX_DEPTH = 12;
|
|
42432
|
+
KNOWN_HARNESSES = /* @__PURE__ */ new Set([
|
|
42433
|
+
"claude",
|
|
42434
|
+
"codex",
|
|
42435
|
+
"aider",
|
|
42436
|
+
"gemini",
|
|
42437
|
+
"kimi",
|
|
42438
|
+
"cursor-agent",
|
|
42439
|
+
"amp"
|
|
42440
|
+
]);
|
|
42441
|
+
RUNTIME_PATTERN = /^(node|nodejs|bun|deno|python[0-9.]*|pypy[0-9.]*|ruby|java|php|perl)$/;
|
|
42442
|
+
ANCESTOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
42443
|
+
"env",
|
|
42444
|
+
"timeout",
|
|
42445
|
+
"gtimeout",
|
|
42446
|
+
"nohup",
|
|
42447
|
+
"nice",
|
|
42448
|
+
"time",
|
|
42449
|
+
"xargs",
|
|
42450
|
+
"stdbuf",
|
|
42451
|
+
"sudo",
|
|
42452
|
+
"doas",
|
|
41794
42453
|
"npm",
|
|
42454
|
+
"npm-cli",
|
|
41795
42455
|
"npx",
|
|
42456
|
+
"npx-cli",
|
|
41796
42457
|
"pnpm",
|
|
41797
42458
|
"pnpx",
|
|
41798
42459
|
"yarn",
|
|
41799
|
-
"bun",
|
|
41800
42460
|
"bunx",
|
|
41801
|
-
"tsx",
|
|
41802
42461
|
"corepack",
|
|
41803
42462
|
"mise",
|
|
41804
|
-
"env",
|
|
41805
42463
|
"cleo"
|
|
41806
42464
|
]);
|
|
41807
|
-
|
|
42465
|
+
INIT_PROCESSES = /* @__PURE__ */ new Set(["launchd", "systemd", "init"]);
|
|
42466
|
+
SHELL_OPTIONS_WITH_ARGUMENT = /* @__PURE__ */ new Set([
|
|
42467
|
+
"-o",
|
|
42468
|
+
"+o",
|
|
42469
|
+
"-O",
|
|
42470
|
+
"+O",
|
|
42471
|
+
"--rcfile",
|
|
42472
|
+
"--init-file"
|
|
42473
|
+
]);
|
|
42474
|
+
PWSH_COMMAND_SWITCHES = /* @__PURE__ */ new Set([
|
|
42475
|
+
"-c",
|
|
42476
|
+
"-command",
|
|
42477
|
+
"-commandwithargs",
|
|
42478
|
+
"-cwa",
|
|
42479
|
+
"-e",
|
|
42480
|
+
"-ec",
|
|
42481
|
+
"-encodedcommand"
|
|
42482
|
+
]);
|
|
42483
|
+
OWNER_PROCESS_SHELLS = /* @__PURE__ */ new Set([
|
|
42484
|
+
"sh",
|
|
42485
|
+
"bash",
|
|
42486
|
+
"zsh",
|
|
42487
|
+
"dash",
|
|
42488
|
+
"fish",
|
|
42489
|
+
"ksh",
|
|
42490
|
+
"tcsh",
|
|
42491
|
+
"csh",
|
|
42492
|
+
"pwsh",
|
|
42493
|
+
"powershell",
|
|
42494
|
+
"nu",
|
|
42495
|
+
"xonsh"
|
|
42496
|
+
]);
|
|
42497
|
+
liveAnchors = /* @__PURE__ */ new Map();
|
|
41808
42498
|
}
|
|
41809
42499
|
});
|
|
41810
42500
|
|
|
@@ -41844,7 +42534,8 @@ var init_session_binding_schema = __esm({
|
|
|
41844
42534
|
});
|
|
41845
42535
|
|
|
41846
42536
|
// packages/core/src/store/session-store.ts
|
|
41847
|
-
import {
|
|
42537
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
42538
|
+
import { and as and6, desc as desc2, eq as eq8, inArray as inArray4, isNull as isNull3, lte as lte2, or as or4 } from "drizzle-orm";
|
|
41848
42539
|
async function getSession(sessionId, cwd) {
|
|
41849
42540
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
41850
42541
|
return worktreeScope.run(scope, async () => {
|
|
@@ -41866,8 +42557,9 @@ async function getActiveSession(cwd) {
|
|
|
41866
42557
|
function splitTerminalKeys(keys) {
|
|
41867
42558
|
return {
|
|
41868
42559
|
provider: keys.find((k) => k.kind === "provider"),
|
|
41869
|
-
|
|
41870
|
-
|
|
42560
|
+
// A harness / CLEO_AGENT_ID agent (T12864) is more specific than a pane.
|
|
42561
|
+
pane: keys.find((k) => k.kind === "harness") ?? keys.find((k) => k.kind === "multiplexer"),
|
|
42562
|
+
tab: keys.find((k) => k.kind === "terminal" || k.kind === "process" || k.kind === "ppid")
|
|
41871
42563
|
};
|
|
41872
42564
|
}
|
|
41873
42565
|
async function readBinding(db, key) {
|
|
@@ -41947,6 +42639,7 @@ async function resolveCurrentSession(cwd) {
|
|
|
41947
42639
|
async function resolveBoundSession(cwd) {
|
|
41948
42640
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
41949
42641
|
return worktreeScope.run(scope, async () => {
|
|
42642
|
+
if (!existsSync19(getDbPath(scope.worktreeRoot))) return null;
|
|
41950
42643
|
const connId = getCurrentConnectionSessionId();
|
|
41951
42644
|
if (connId) {
|
|
41952
42645
|
const byConn = await getSession(connId, scope.worktreeRoot);
|
|
@@ -42098,7 +42791,7 @@ __export(registry_exports2, {
|
|
|
42098
42791
|
updateAgentStatus: () => updateAgentStatus
|
|
42099
42792
|
});
|
|
42100
42793
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
42101
|
-
import { and as and7, eq as eq9, inArray as
|
|
42794
|
+
import { and as and7, eq as eq9, inArray as inArray5, lt as lt2, sql as sql29 } from "drizzle-orm";
|
|
42102
42795
|
function generateAgentId() {
|
|
42103
42796
|
const now = /* @__PURE__ */ new Date();
|
|
42104
42797
|
const ts = now.toISOString().replace(/[-:T]/g, "").substring(0, 14);
|
|
@@ -42187,11 +42880,11 @@ async function listAgentInstances(filters, cwd) {
|
|
|
42187
42880
|
const conditions = [];
|
|
42188
42881
|
if (filters?.status) {
|
|
42189
42882
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
42190
|
-
conditions.push(
|
|
42883
|
+
conditions.push(inArray5(agentInstances.status, statuses));
|
|
42191
42884
|
}
|
|
42192
42885
|
if (filters?.agentType) {
|
|
42193
42886
|
const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
|
|
42194
|
-
conditions.push(
|
|
42887
|
+
conditions.push(inArray5(agentInstances.agentType, types));
|
|
42195
42888
|
}
|
|
42196
42889
|
if (filters?.sessionId) {
|
|
42197
42890
|
conditions.push(eq9(agentInstances.sessionId, filters.sessionId));
|
|
@@ -42228,7 +42921,7 @@ async function checkAgentHealth(thresholdMs = 3e4, cwd) {
|
|
|
42228
42921
|
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
42229
42922
|
return db.select().from(agentInstances).where(
|
|
42230
42923
|
and7(
|
|
42231
|
-
|
|
42924
|
+
inArray5(agentInstances.status, ["active", "idle", "starting"]),
|
|
42232
42925
|
lt2(agentInstances.lastHeartbeat, cutoff)
|
|
42233
42926
|
)
|
|
42234
42927
|
).all();
|
|
@@ -42323,12 +43016,14 @@ var init_registry2 = __esm({
|
|
|
42323
43016
|
// packages/core/src/store/sqlite-data-accessor.ts
|
|
42324
43017
|
var sqlite_data_accessor_exports = {};
|
|
42325
43018
|
__export(sqlite_data_accessor_exports, {
|
|
43019
|
+
RENAMED_RECENT_MS: () => RENAMED_RECENT_MS,
|
|
42326
43020
|
addTaskLabelsNative: () => addTaskLabelsNative,
|
|
42327
43021
|
advanceTaskIdSequence: () => advanceTaskIdSequence,
|
|
42328
43022
|
bindTaskAccessorScope: () => bindTaskAccessorScope,
|
|
42329
43023
|
captureTaskAccessorScope: () => captureProjectScope,
|
|
42330
43024
|
clearAcUidGraveyardNative: () => clearAcUidGraveyardNative,
|
|
42331
43025
|
clearBirthFpNative: () => clearBirthFpNative,
|
|
43026
|
+
clearReplacedTaskIdentityNative: () => clearReplacedTaskIdentityNative,
|
|
42332
43027
|
clearRowUidNative: () => clearRowUidNative,
|
|
42333
43028
|
createSqliteDataAccessor: () => createSqliteDataAccessor,
|
|
42334
43029
|
deleteDisplayIdAliasNative: () => deleteDisplayIdAliasNative,
|
|
@@ -42339,6 +43034,7 @@ __export(sqlite_data_accessor_exports, {
|
|
|
42339
43034
|
insertIdentityRowNative: () => insertIdentityRowNative,
|
|
42340
43035
|
insertQuarantineNative: () => insertQuarantineNative,
|
|
42341
43036
|
insertUidAliasNative: () => insertUidAliasNative,
|
|
43037
|
+
readReplacedTaskBirthNative: () => readReplacedTaskBirthNative,
|
|
42342
43038
|
rederiveAcIdsNative: () => rederiveAcIdsNative,
|
|
42343
43039
|
rekeyQuarantineNative: () => rekeyQuarantineNative,
|
|
42344
43040
|
relinkAcUidNative: () => relinkAcUidNative,
|
|
@@ -42355,7 +43051,7 @@ import {
|
|
|
42355
43051
|
and as and8,
|
|
42356
43052
|
eq as eq10,
|
|
42357
43053
|
getTableColumns as getTableColumns2,
|
|
42358
|
-
inArray as
|
|
43054
|
+
inArray as inArray6,
|
|
42359
43055
|
isNull as isNull4,
|
|
42360
43056
|
like as like2,
|
|
42361
43057
|
lte as lte3,
|
|
@@ -42379,8 +43075,8 @@ async function selectAcBindings(db, acIds) {
|
|
|
42379
43075
|
bindingType: b.bindingType,
|
|
42380
43076
|
createdAt: b.createdAt
|
|
42381
43077
|
};
|
|
42382
|
-
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
42383
|
-
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
43078
|
+
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(ac.id, ids)).all();
|
|
43079
|
+
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(b.acId, ids)).all();
|
|
42384
43080
|
const rows = [...byUid, ...byId];
|
|
42385
43081
|
const wanted = new Set(ids);
|
|
42386
43082
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -42473,6 +43169,7 @@ function renameTaskDisplayIdNative(nativeDb, uid, toId, refs, guard = {}) {
|
|
|
42473
43169
|
if (Number(changed) !== 1) {
|
|
42474
43170
|
throw taskConflictError(current.id, taskVersion(current), null);
|
|
42475
43171
|
}
|
|
43172
|
+
recordLocalRename(nativeDb, uid, current.id, toId, taskVersion(current));
|
|
42476
43173
|
const rewritten = {};
|
|
42477
43174
|
const q2 = (name15) => `"${name15.replaceAll('"', '""')}"`;
|
|
42478
43175
|
for (const ref of refs) {
|
|
@@ -42528,23 +43225,39 @@ function rederiveAcIdsNative(nativeDb, fromId, toId) {
|
|
|
42528
43225
|
}
|
|
42529
43226
|
return count;
|
|
42530
43227
|
}
|
|
42531
|
-
function insertDisplayIdAliasNative(nativeDb, row) {
|
|
43228
|
+
function insertDisplayIdAliasNative(nativeDb, row, precedes) {
|
|
43229
|
+
const stored = nativeDb.prepare(
|
|
43230
|
+
`SELECT uid, entity_table AS entityTable, display_id AS displayId, entity_uid AS entityUid,
|
|
43231
|
+
reason, origin, displaced_hlc AS displacedHlc, created_at AS createdAt,
|
|
43232
|
+
entity_birth_fp AS entityBirthFp
|
|
43233
|
+
FROM tasks_display_id_aliases WHERE uid = ?`
|
|
43234
|
+
).get(row.uid);
|
|
43235
|
+
if (!stored) {
|
|
43236
|
+
nativeDb.prepare(
|
|
43237
|
+
`INSERT INTO tasks_display_id_aliases
|
|
43238
|
+
(uid, entity_table, display_id, entity_uid, reason, origin, displaced_hlc, created_at,
|
|
43239
|
+
entity_birth_fp)
|
|
43240
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
43241
|
+
).run(
|
|
43242
|
+
row.uid,
|
|
43243
|
+
row.entityTable,
|
|
43244
|
+
row.displayId,
|
|
43245
|
+
row.entityUid,
|
|
43246
|
+
row.reason,
|
|
43247
|
+
row.origin,
|
|
43248
|
+
row.displacedHlc,
|
|
43249
|
+
row.createdAt,
|
|
43250
|
+
row.entityBirthFp
|
|
43251
|
+
);
|
|
43252
|
+
return;
|
|
43253
|
+
}
|
|
43254
|
+
if (!precedes(row, stored)) return;
|
|
42532
43255
|
nativeDb.prepare(
|
|
42533
|
-
`
|
|
42534
|
-
|
|
42535
|
-
|
|
42536
|
-
|
|
42537
|
-
).run(
|
|
42538
|
-
row.uid,
|
|
42539
|
-
row.entityTable,
|
|
42540
|
-
row.displayId,
|
|
42541
|
-
row.entityUid,
|
|
42542
|
-
row.reason,
|
|
42543
|
-
row.origin,
|
|
42544
|
-
row.displacedHlc,
|
|
42545
|
-
row.createdAt,
|
|
42546
|
-
row.entityBirthFp
|
|
42547
|
-
);
|
|
43256
|
+
`UPDATE tasks_display_id_aliases
|
|
43257
|
+
SET origin = ?, displaced_hlc = ?, created_at = ?,
|
|
43258
|
+
entity_birth_fp = coalesce(entity_birth_fp, ?)
|
|
43259
|
+
WHERE uid = ?`
|
|
43260
|
+
).run(row.origin, row.displacedHlc, row.createdAt, row.entityBirthFp, row.uid);
|
|
42548
43261
|
}
|
|
42549
43262
|
function deleteDisplayIdAliasNative(nativeDb, uid) {
|
|
42550
43263
|
nativeDb.prepare("DELETE FROM tasks_display_id_aliases WHERE uid = ?").run(uid);
|
|
@@ -42606,6 +43319,63 @@ function relinkAcUidNative(nativeDb, acId, uid, birthFp) {
|
|
|
42606
43319
|
function clearAcUidGraveyardNative(nativeDb) {
|
|
42607
43320
|
nativeDb.exec("DELETE FROM tasks_ac_uid_graveyard");
|
|
42608
43321
|
}
|
|
43322
|
+
function readReplacedTaskBirthNative(nativeDb, taskId) {
|
|
43323
|
+
return nativeDb.prepare("SELECT created_at AS createdAt, uid FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43324
|
+
}
|
|
43325
|
+
function clearReplacedTaskIdentityNative(nativeDb, taskId, before) {
|
|
43326
|
+
const row = nativeDb.prepare("SELECT uid, birth_fp AS fp, created_at AS createdAt FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43327
|
+
if (!row || row.uid === null && row.fp === null) return;
|
|
43328
|
+
if (before) {
|
|
43329
|
+
const was = parseStoreTimestamp(before.createdAt);
|
|
43330
|
+
if (was !== null && was === parseStoreTimestamp(row.createdAt)) {
|
|
43331
|
+
return;
|
|
43332
|
+
}
|
|
43333
|
+
}
|
|
43334
|
+
if (rowIdentityShared(nativeDb)) {
|
|
43335
|
+
throw new CleoError(
|
|
43336
|
+
6 /* VALIDATION_ERROR */,
|
|
43337
|
+
`Task ${taskId} cannot be overwritten by an import: its identity is shared with other devices`,
|
|
43338
|
+
{
|
|
43339
|
+
fix: "Import it under a new id (the default duplicate strategy), or edit the task instead of overwriting it.",
|
|
43340
|
+
details: { field: "taskId", actual: taskId }
|
|
43341
|
+
}
|
|
43342
|
+
);
|
|
43343
|
+
}
|
|
43344
|
+
const has = (table) => nativeDb.prepare("SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== void 0;
|
|
43345
|
+
nativeDb.prepare("UPDATE tasks_tasks SET uid = NULL, birth_fp = NULL WHERE id = ?").run(taskId);
|
|
43346
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
43347
|
+
if (spec.kind !== "natural" || !has(spec.table)) continue;
|
|
43348
|
+
const cols = (spec.keyRefs ?? []).filter((r) => r.table === "tasks_tasks").map((r) => r.column);
|
|
43349
|
+
if (cols.length === 0) continue;
|
|
43350
|
+
nativeDb.prepare(
|
|
43351
|
+
`UPDATE main.${quoteIdent2(spec.table)} SET uid = NULL WHERE ${cols.map((c) => `${quoteIdent2(c)} = ?`).join(" OR ")}`
|
|
43352
|
+
).run(...cols.map(() => taskId));
|
|
43353
|
+
}
|
|
43354
|
+
const children = ["tasks_task_acceptance_criteria_history", "tasks_evidence_ac_bindings"].filter(
|
|
43355
|
+
has
|
|
43356
|
+
);
|
|
43357
|
+
const criteria = has("tasks_task_acceptance_criteria") ? nativeDb.prepare("SELECT id, uid FROM tasks_task_acceptance_criteria WHERE task_id = ?").all(taskId) : [];
|
|
43358
|
+
if (criteria.length > 0) {
|
|
43359
|
+
nativeDb.prepare(
|
|
43360
|
+
"UPDATE tasks_task_acceptance_criteria SET uid = NULL, birth_fp = NULL WHERE task_id = ?"
|
|
43361
|
+
).run(taskId);
|
|
43362
|
+
}
|
|
43363
|
+
fillRowUids(nativeDb, "project");
|
|
43364
|
+
const newUid = nativeDb.prepare("SELECT uid FROM tasks_task_acceptance_criteria WHERE id = ?");
|
|
43365
|
+
let rekeyed = 0;
|
|
43366
|
+
for (const ac of criteria) {
|
|
43367
|
+
const now = newUid.get(ac.id)?.uid ?? null;
|
|
43368
|
+
for (const table of children) {
|
|
43369
|
+
rekeyed += Number(
|
|
43370
|
+
nativeDb.prepare(
|
|
43371
|
+
`UPDATE main.${quoteIdent2(table)} SET ac_uid = ?, birth_fp = NULL
|
|
43372
|
+
WHERE ac_id = ? OR (? IS NOT NULL AND ac_uid = ?)`
|
|
43373
|
+
).run(now, ac.id, ac.uid, ac.uid).changes
|
|
43374
|
+
);
|
|
43375
|
+
}
|
|
43376
|
+
}
|
|
43377
|
+
if (rekeyed > 0) fillRowUids(nativeDb, "project");
|
|
43378
|
+
}
|
|
42609
43379
|
function quoteIdent2(name15) {
|
|
42610
43380
|
return `"${name15.replaceAll('"', '""')}"`;
|
|
42611
43381
|
}
|
|
@@ -42693,10 +43463,50 @@ function claimPredicate(guard, allowedHolders) {
|
|
|
42693
43463
|
if (guard.mode === "force") return void 0;
|
|
42694
43464
|
const mine = guard.sessionId === null ? void 0 : eq10(holder, guard.sessionId);
|
|
42695
43465
|
if (guard.mode === "renew" || guard.mode === "release") return mine ?? sql30`0`;
|
|
42696
|
-
const related = allowedHolders.length > 0 ?
|
|
43466
|
+
const related = allowedHolders.length > 0 ? inArray6(holder, [...allowedHolders]) : void 0;
|
|
42697
43467
|
const expired = guard.mode === "take-over" ? or5(isNull4(tasksTasks.leaseExpiresAt), lte3(tasksTasks.leaseExpiresAt, guard.now)) : void 0;
|
|
42698
43468
|
return or5(isNull4(holder), mine, related, expired);
|
|
42699
43469
|
}
|
|
43470
|
+
function renameRecordKey(fromId) {
|
|
43471
|
+
return `renamed_from:tasks_tasks:${fromId}`;
|
|
43472
|
+
}
|
|
43473
|
+
function hasIdentityMeta(nativeDb) {
|
|
43474
|
+
return nativeDb.prepare(
|
|
43475
|
+
"SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = 'tasks_row_identity_meta'"
|
|
43476
|
+
).get() !== void 0;
|
|
43477
|
+
}
|
|
43478
|
+
function recordLocalRename(nativeDb, uid, fromId, toId, fromVersion) {
|
|
43479
|
+
if (!hasIdentityMeta(nativeDb)) return;
|
|
43480
|
+
const record2 = { uid, fromVersion, toId, at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
43481
|
+
writeRowIdentityMetaNative(nativeDb, renameRecordKey(fromId), JSON.stringify(record2));
|
|
43482
|
+
}
|
|
43483
|
+
function assertNotRenamed(nativeDb, taskId, guard, current) {
|
|
43484
|
+
if (!nativeDb || !hasIdentityMeta(nativeDb)) return;
|
|
43485
|
+
const raw = nativeDb.prepare("SELECT value FROM tasks_row_identity_meta WHERE key = ?").get(renameRecordKey(taskId));
|
|
43486
|
+
if (!raw) return;
|
|
43487
|
+
let record2;
|
|
43488
|
+
try {
|
|
43489
|
+
record2 = JSON.parse(raw.value);
|
|
43490
|
+
} catch {
|
|
43491
|
+
return;
|
|
43492
|
+
}
|
|
43493
|
+
if (Date.now() - Date.parse(record2.at) > RENAMED_RECENT_MS) return;
|
|
43494
|
+
const renamed = nativeDb.prepare("SELECT id, claimed_by_session AS claimedBySession FROM tasks_tasks WHERE uid = ?").get(record2.uid);
|
|
43495
|
+
if (!renamed || renamed.id === taskId) return;
|
|
43496
|
+
const expected = guard.expectedUpdatedAt;
|
|
43497
|
+
const session = guard.claim?.sessionId ?? null;
|
|
43498
|
+
const holdsRenamedClaim = session !== null && (guard.claim?.mode === "renew" || guard.claim?.mode === "release") && renamed.claimedBySession === session && current?.claimedBySession !== session;
|
|
43499
|
+
const readRenamed = expected !== void 0 && expected === record2.fromVersion && (current === void 0 || taskVersion(current) !== expected);
|
|
43500
|
+
if (!(current === void 0 || holdsRenamedClaim || readRenamed)) return;
|
|
43501
|
+
throw new CleoError(
|
|
43502
|
+
26 /* TASK_RENAMED */,
|
|
43503
|
+
`Task ${taskId} is now ${renamed.id}: sync re-numbered it after a display-id collision, and ${taskId} ${current ? "names another task" : "names no task"}; nothing was written`,
|
|
43504
|
+
{
|
|
43505
|
+
fix: `Re-read it with 'cleo show ${renamed.id}' and retry against ${renamed.id}.`,
|
|
43506
|
+
details: { field: "taskId", actual: taskId, expected: renamed.id }
|
|
43507
|
+
}
|
|
43508
|
+
);
|
|
43509
|
+
}
|
|
42700
43510
|
function assertClaimAllowed(taskId, row, guard, allowedHolders) {
|
|
42701
43511
|
const stored = claimFromColumns(row);
|
|
42702
43512
|
if (claimAllows(stored, guard.mode, guard.sessionId, guard.now, allowedHolders)) return;
|
|
@@ -42871,13 +43681,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
42871
43681
|
const db = await getDb(cwd);
|
|
42872
43682
|
const conditions = [];
|
|
42873
43683
|
if (query.ids && query.ids.length > 0) {
|
|
42874
|
-
conditions.push(
|
|
43684
|
+
conditions.push(inArray6(tasksAuditLog.id, [...query.ids]));
|
|
42875
43685
|
}
|
|
42876
43686
|
if (query.taskIds && query.taskIds.length > 0) {
|
|
42877
|
-
conditions.push(
|
|
43687
|
+
conditions.push(inArray6(tasksAuditLog.taskId, [...query.taskIds]));
|
|
42878
43688
|
}
|
|
42879
43689
|
if (query.actions && query.actions.length > 0) {
|
|
42880
|
-
conditions.push(
|
|
43690
|
+
conditions.push(inArray6(tasksAuditLog.action, [...query.actions]));
|
|
42881
43691
|
}
|
|
42882
43692
|
if (query.since) {
|
|
42883
43693
|
conditions.push(sql30`${tasksAuditLog.timestamp} >= ${query.since}`);
|
|
@@ -42910,8 +43720,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
42910
43720
|
async upsertSingleTask(task) {
|
|
42911
43721
|
await accessor.transaction((tx) => tx.upsertSingleTask(task));
|
|
42912
43722
|
},
|
|
42913
|
-
async insertNewTask(task) {
|
|
42914
|
-
await accessor.transaction((tx) => tx.insertNewTask(task));
|
|
43723
|
+
async insertNewTask(task, identity) {
|
|
43724
|
+
await accessor.transaction((tx) => tx.insertNewTask(task, identity));
|
|
43725
|
+
},
|
|
43726
|
+
async getTaskIdentities(taskIds) {
|
|
43727
|
+
if (taskIds.length === 0) return [];
|
|
43728
|
+
const db = await getDb(cwd);
|
|
43729
|
+
return db.select({ id: tasksTasks.id, uid: tasksTasks.uid, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
42915
43730
|
},
|
|
42916
43731
|
async addRelation(taskId, relatedTo, relationType, reason) {
|
|
42917
43732
|
return accessor.transaction(async () => {
|
|
@@ -43088,7 +43903,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43088
43903
|
if (!statuses.includes("archived")) {
|
|
43089
43904
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43090
43905
|
}
|
|
43091
|
-
conditions.push(
|
|
43906
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43092
43907
|
} else if (filters.excludeStatus) {
|
|
43093
43908
|
const excluded = Array.isArray(filters.excludeStatus) ? filters.excludeStatus : [filters.excludeStatus];
|
|
43094
43909
|
for (const s of excluded) {
|
|
@@ -43102,11 +43917,11 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43102
43917
|
if (filters.phase) conditions.push(eq10(tasksTasks.phase, filters.phase));
|
|
43103
43918
|
if (filters.severity) {
|
|
43104
43919
|
const severities = Array.isArray(filters.severity) ? filters.severity : [filters.severity];
|
|
43105
|
-
conditions.push(
|
|
43920
|
+
conditions.push(inArray6(tasksTasks.severity, severities));
|
|
43106
43921
|
}
|
|
43107
43922
|
if (filters.kind) {
|
|
43108
43923
|
const kinds = Array.isArray(filters.kind) ? filters.kind : [filters.kind];
|
|
43109
|
-
conditions.push(
|
|
43924
|
+
conditions.push(inArray6(tasksTasks.kind, kinds));
|
|
43110
43925
|
}
|
|
43111
43926
|
if (filters.parentId !== void 0) {
|
|
43112
43927
|
if (filters.parentId === null) {
|
|
@@ -43127,7 +43942,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43127
43942
|
}
|
|
43128
43943
|
if (filters.label) {
|
|
43129
43944
|
const labelMatchIds = db.select({ taskId: tasksTaskLabels.taskId }).from(tasksTaskLabels).where(eq10(tasksTaskLabels.label, filters.label));
|
|
43130
|
-
conditions.push(
|
|
43945
|
+
conditions.push(inArray6(tasksTasks.id, labelMatchIds));
|
|
43131
43946
|
}
|
|
43132
43947
|
const where = conditions.length > 0 ? and8(...conditions) : void 0;
|
|
43133
43948
|
const countResult = await db.select({ count: sql30`count(*)` }).from(tasksTasks).where(where).get();
|
|
@@ -43170,7 +43985,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43170
43985
|
const conditions = [];
|
|
43171
43986
|
if (filters?.status) {
|
|
43172
43987
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
43173
|
-
conditions.push(
|
|
43988
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43174
43989
|
} else {
|
|
43175
43990
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43176
43991
|
}
|
|
@@ -43235,7 +44050,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43235
44050
|
if (idRows.length === 0) return [];
|
|
43236
44051
|
const db = await getDb(cwd);
|
|
43237
44052
|
const ids = idRows.map((r) => r.id);
|
|
43238
|
-
const taskRows = await db.select().from(tasksTasks).where(
|
|
44053
|
+
const taskRows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43239
44054
|
const tasks2 = taskRows.map(rowToTask);
|
|
43240
44055
|
if (tasks2.length > 0) {
|
|
43241
44056
|
const allIds = await getAllTaskIds();
|
|
@@ -43264,7 +44079,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43264
44079
|
if (idRows.length === 0) return [];
|
|
43265
44080
|
const db = await getDb(cwd);
|
|
43266
44081
|
const ids = idRows.map((r) => r.id);
|
|
43267
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44082
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43268
44083
|
const tasks2 = rows.map(rowToTask);
|
|
43269
44084
|
if (tasks2.length > 0) {
|
|
43270
44085
|
const allIds = await getAllTaskIds();
|
|
@@ -43278,7 +44093,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43278
44093
|
const depRows = await db.select().from(tasksTaskDependencies).where(eq10(tasksTaskDependencies.dependsOn, taskId)).all();
|
|
43279
44094
|
if (depRows.length === 0) return [];
|
|
43280
44095
|
const dependentIds = depRows.map((r) => r.taskId);
|
|
43281
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44096
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, dependentIds)).all();
|
|
43282
44097
|
const tasks2 = rows.map(rowToTask);
|
|
43283
44098
|
if (tasks2.length > 0) {
|
|
43284
44099
|
const allIds = await getAllTaskIds();
|
|
@@ -43308,7 +44123,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43308
44123
|
async loadTasks(taskIds) {
|
|
43309
44124
|
if (taskIds.length === 0) return [];
|
|
43310
44125
|
const db = await getDb(cwd);
|
|
43311
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44126
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
43312
44127
|
const tasks2 = rows.map(rowToTask);
|
|
43313
44128
|
if (tasks2.length > 0) {
|
|
43314
44129
|
const allIds = await getAllTaskIds();
|
|
@@ -43362,6 +44177,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43362
44177
|
createdAt: tasksTasks.createdAt,
|
|
43363
44178
|
...CLAIM_COLUMNS
|
|
43364
44179
|
}).from(tasksTasks).where(eq10(tasksTasks.id, taskId)).limit(1).all();
|
|
44180
|
+
if (guard?.claim || guard?.expectedUpdatedAt !== void 0) {
|
|
44181
|
+
assertNotRenamed(getNativeTasksDb(cwd), taskId, guard, current);
|
|
44182
|
+
}
|
|
43365
44183
|
if (!current) throw new Error(`Task not found: ${taskId}`);
|
|
43366
44184
|
const claimGuard = guard?.claim;
|
|
43367
44185
|
const allowedHolders = claimGuard ? await claimAllowedHolders(db, claimGuard) : [];
|
|
@@ -43439,24 +44257,37 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43439
44257
|
nativeDb.prepare(`SAVEPOINT ${spName}`).run();
|
|
43440
44258
|
}
|
|
43441
44259
|
try {
|
|
44260
|
+
const replacedBirths = /* @__PURE__ */ new Map();
|
|
43442
44261
|
const tx = {
|
|
43443
44262
|
async upsertSingleTask(task) {
|
|
43444
44263
|
scope.assertActive();
|
|
43445
44264
|
return accessor.transaction(async () => {
|
|
43446
44265
|
scope.assertActive();
|
|
44266
|
+
if (rowUidFillEnabled() && !replacedBirths.has(task.id)) {
|
|
44267
|
+
const before = readReplacedTaskBirthNative(nativeDb, task.id);
|
|
44268
|
+
if (before) replacedBirths.set(task.id, before);
|
|
44269
|
+
}
|
|
43447
44270
|
const row = taskToRow(task);
|
|
43448
44271
|
await upsertTask(db, row);
|
|
43449
44272
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43450
44273
|
});
|
|
43451
44274
|
},
|
|
43452
|
-
async insertNewTask(task) {
|
|
44275
|
+
async insertNewTask(task, identity) {
|
|
43453
44276
|
scope.assertActive();
|
|
43454
44277
|
return accessor.transaction(async () => {
|
|
43455
44278
|
scope.assertActive();
|
|
43456
|
-
await insertNewTask(db, taskToRow(task));
|
|
44279
|
+
await insertNewTask(db, taskToRow(task), identity);
|
|
43457
44280
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43458
44281
|
});
|
|
43459
44282
|
},
|
|
44283
|
+
async clearTaskIdentity(taskId) {
|
|
44284
|
+
scope.assertActive();
|
|
44285
|
+
if (!rowUidFillEnabled()) return;
|
|
44286
|
+
return accessor.transaction(async () => {
|
|
44287
|
+
scope.assertActive();
|
|
44288
|
+
clearReplacedTaskIdentityNative(nativeDb, taskId, replacedBirths.get(taskId));
|
|
44289
|
+
});
|
|
44290
|
+
},
|
|
43460
44291
|
async archiveSingleTask(taskId, fields) {
|
|
43461
44292
|
scope.assertActive();
|
|
43462
44293
|
return accessor.transaction(async () => {
|
|
@@ -43603,7 +44434,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43603
44434
|
const owned = await db.select({ id: tasksTaskAcceptanceCriteria.id }).from(tasksTaskAcceptanceCriteria).where(
|
|
43604
44435
|
and8(
|
|
43605
44436
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43606
|
-
|
|
44437
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43607
44438
|
)
|
|
43608
44439
|
).all();
|
|
43609
44440
|
await pruneAcBindingsForAcIds(
|
|
@@ -43616,7 +44447,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43616
44447
|
await db.delete(tasksTaskAcceptanceCriteria).where(
|
|
43617
44448
|
and8(
|
|
43618
44449
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43619
|
-
|
|
44450
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43620
44451
|
)
|
|
43621
44452
|
).run();
|
|
43622
44453
|
});
|
|
@@ -43875,7 +44706,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43875
44706
|
};
|
|
43876
44707
|
return accessor;
|
|
43877
44708
|
}
|
|
43878
|
-
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS;
|
|
44709
|
+
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS, RENAMED_RECENT_MS;
|
|
43879
44710
|
var init_sqlite_data_accessor = __esm({
|
|
43880
44711
|
"packages/core/src/store/sqlite-data-accessor.ts"() {
|
|
43881
44712
|
"use strict";
|
|
@@ -43889,6 +44720,8 @@ var init_sqlite_data_accessor = __esm({
|
|
|
43889
44720
|
init_cross_db_cleanup();
|
|
43890
44721
|
init_db_helpers();
|
|
43891
44722
|
init_row_identity();
|
|
44723
|
+
init_row_identity_flag();
|
|
44724
|
+
init_row_identity_registry();
|
|
43892
44725
|
init_audit2();
|
|
43893
44726
|
init_session_store();
|
|
43894
44727
|
init_sqlite3();
|
|
@@ -43921,6 +44754,7 @@ var init_sqlite_data_accessor = __esm({
|
|
|
43921
44754
|
claimedAt: tasksTasks.claimedAt,
|
|
43922
44755
|
leaseExpiresAt: tasksTasks.leaseExpiresAt
|
|
43923
44756
|
};
|
|
44757
|
+
RENAMED_RECENT_MS = 24 * 60 * 60 * 1e3;
|
|
43924
44758
|
registerRowIdentityWriters({
|
|
43925
44759
|
relinkAcUidNative,
|
|
43926
44760
|
clearAcUidGraveyardNative,
|
|
@@ -44391,7 +45225,7 @@ __export(governor_exports, {
|
|
|
44391
45225
|
resolveGovernorMode: () => resolveGovernorMode,
|
|
44392
45226
|
slotFileCount: () => slotFileCount
|
|
44393
45227
|
});
|
|
44394
|
-
import { existsSync as
|
|
45228
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync6, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
44395
45229
|
import { availableParallelism, totalmem } from "node:os";
|
|
44396
45230
|
import { join as join25 } from "node:path";
|
|
44397
45231
|
import lockfile2 from "proper-lockfile";
|
|
@@ -44465,11 +45299,11 @@ function governorSlotDir(cls) {
|
|
|
44465
45299
|
return join25(getCleoHome(), "locks", `resource-${cls}`);
|
|
44466
45300
|
}
|
|
44467
45301
|
function ensureSlotFiles(dir, count) {
|
|
44468
|
-
if (!
|
|
45302
|
+
if (!existsSync20(dir)) mkdirSync6(dir, { recursive: true });
|
|
44469
45303
|
const paths = [];
|
|
44470
45304
|
for (let i = 0; i < count; i++) {
|
|
44471
45305
|
const p = join25(dir, `slot-${i}.lock`);
|
|
44472
|
-
if (!
|
|
45306
|
+
if (!existsSync20(p)) writeFileSync5(p, "", { flag: "a" });
|
|
44473
45307
|
paths.push(p);
|
|
44474
45308
|
}
|
|
44475
45309
|
return paths;
|
|
@@ -44509,7 +45343,7 @@ function shuffledIndices(n) {
|
|
|
44509
45343
|
}
|
|
44510
45344
|
async function countHeldSlots(cls, budget) {
|
|
44511
45345
|
const dir = governorSlotDir(cls);
|
|
44512
|
-
if (!
|
|
45346
|
+
if (!existsSync20(dir)) return 0;
|
|
44513
45347
|
const slots = ensureSlotFiles(dir, budget);
|
|
44514
45348
|
let held = 0;
|
|
44515
45349
|
for (const path of slots) {
|
|
@@ -44524,7 +45358,7 @@ async function countHeldSlots(cls, budget) {
|
|
|
44524
45358
|
}
|
|
44525
45359
|
function slotFileCount(cls) {
|
|
44526
45360
|
const dir = governorSlotDir(cls);
|
|
44527
|
-
if (!
|
|
45361
|
+
if (!existsSync20(dir)) return 0;
|
|
44528
45362
|
return readdirSync5(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
|
|
44529
45363
|
}
|
|
44530
45364
|
var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
|
|
@@ -44675,7 +45509,7 @@ var init_governor = __esm({
|
|
|
44675
45509
|
// packages/core/src/store/exodus/recovery.ts
|
|
44676
45510
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
44677
45511
|
import { constants } from "node:sqlite";
|
|
44678
|
-
import { z as
|
|
45512
|
+
import { z as z30 } from "zod";
|
|
44679
45513
|
function identityValues(encoded) {
|
|
44680
45514
|
return identitySchema.parse(JSON.parse(encoded)).map(([kind, value]) => {
|
|
44681
45515
|
if (kind === "null") return null;
|
|
@@ -45011,8 +45845,8 @@ var init_recovery = __esm({
|
|
|
45011
45845
|
"use strict";
|
|
45012
45846
|
init_row_identity_registry();
|
|
45013
45847
|
RECEIPTS = "_exodus_recovery_rows";
|
|
45014
|
-
identitySchema =
|
|
45015
|
-
|
|
45848
|
+
identitySchema = z30.array(
|
|
45849
|
+
z30.tuple([z30.enum(["null", "integer", "real", "text", "blob"]), z30.string()])
|
|
45016
45850
|
);
|
|
45017
45851
|
ExodusRecoveryError = class extends Error {
|
|
45018
45852
|
};
|
|
@@ -45022,7 +45856,7 @@ var init_recovery = __esm({
|
|
|
45022
45856
|
// packages/core/src/store/exodus/archive.ts
|
|
45023
45857
|
import {
|
|
45024
45858
|
copyFileSync as copyFileSync5,
|
|
45025
|
-
existsSync as
|
|
45859
|
+
existsSync as existsSync21,
|
|
45026
45860
|
mkdirSync as mkdirSync7,
|
|
45027
45861
|
readFileSync as readFileSync8,
|
|
45028
45862
|
renameSync as renameSync7,
|
|
@@ -45030,7 +45864,7 @@ import {
|
|
|
45030
45864
|
writeFileSync as writeFileSync6
|
|
45031
45865
|
} from "node:fs";
|
|
45032
45866
|
import { basename as basename9, dirname as dirname19, join as join26, resolve as resolve12 } from "node:path";
|
|
45033
|
-
import { z as
|
|
45867
|
+
import { z as z31 } from "zod";
|
|
45034
45868
|
function scopeBaseDir(scope, cwd, targetDbPath) {
|
|
45035
45869
|
if (targetDbPath !== void 0) return dirname19(targetDbPath);
|
|
45036
45870
|
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
@@ -45050,7 +45884,7 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
|
45050
45884
|
if (targetDbPath) throw error48;
|
|
45051
45885
|
return false;
|
|
45052
45886
|
}
|
|
45053
|
-
if (!
|
|
45887
|
+
if (!existsSync21(markerPath)) return false;
|
|
45054
45888
|
const marker16 = markerIdentity.parse(JSON.parse(readFileSync8(markerPath, "utf8")));
|
|
45055
45889
|
if (nativeDb && (!marker16.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker16.databaseIdentity)))
|
|
45056
45890
|
throw new Error(
|
|
@@ -45080,7 +45914,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
45080
45914
|
function moveFileInto(srcPath, destDir) {
|
|
45081
45915
|
mkdirSync7(destDir, { recursive: true });
|
|
45082
45916
|
let dest = join26(destDir, basename9(srcPath));
|
|
45083
|
-
if (
|
|
45917
|
+
if (existsSync21(dest)) {
|
|
45084
45918
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
45085
45919
|
dest = join26(destDir, `${basename9(srcPath)}.${stamp}`);
|
|
45086
45920
|
}
|
|
@@ -45093,14 +45927,14 @@ function moveFileInto(srcPath, destDir) {
|
|
|
45093
45927
|
return dest;
|
|
45094
45928
|
}
|
|
45095
45929
|
function archiveSourceDb(source, cwd, targetDbPath) {
|
|
45096
|
-
if (!
|
|
45930
|
+
if (!existsSync21(source.path)) {
|
|
45097
45931
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
45098
45932
|
}
|
|
45099
45933
|
const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
|
|
45100
45934
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
45101
45935
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
45102
45936
|
const sidecar = `${source.path}${suffix}`;
|
|
45103
|
-
if (
|
|
45937
|
+
if (existsSync21(sidecar)) {
|
|
45104
45938
|
try {
|
|
45105
45939
|
moveFileInto(sidecar, destDir);
|
|
45106
45940
|
} catch (err) {
|
|
@@ -45148,7 +45982,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
45148
45982
|
const stranded = [];
|
|
45149
45983
|
for (const source of sources) {
|
|
45150
45984
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
45151
|
-
if (
|
|
45985
|
+
if (existsSync21(source.path)) {
|
|
45152
45986
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
45153
45987
|
}
|
|
45154
45988
|
}
|
|
@@ -45173,11 +46007,11 @@ var init_archive2 = __esm({
|
|
|
45173
46007
|
init_ensure_config();
|
|
45174
46008
|
init_recovery();
|
|
45175
46009
|
log8 = getLogger("exodus-archive");
|
|
45176
|
-
markerIdentity =
|
|
45177
|
-
version:
|
|
45178
|
-
scope:
|
|
45179
|
-
targetDbPath:
|
|
45180
|
-
databaseIdentity:
|
|
46010
|
+
markerIdentity = z31.object({
|
|
46011
|
+
version: z31.literal(1),
|
|
46012
|
+
scope: z31.enum(["project", "global"]),
|
|
46013
|
+
targetDbPath: z31.string().optional(),
|
|
46014
|
+
databaseIdentity: z31.string().optional()
|
|
45181
46015
|
});
|
|
45182
46016
|
ARCHIVE_DIR_NAME = "_archive";
|
|
45183
46017
|
MARKER_FILENAME_BY_SCOPE = {
|
|
@@ -45189,13 +46023,13 @@ var init_archive2 = __esm({
|
|
|
45189
46023
|
});
|
|
45190
46024
|
|
|
45191
46025
|
// packages/core/src/store/exodus/count-parity.ts
|
|
45192
|
-
import { existsSync as
|
|
46026
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
45193
46027
|
function listTables2(db) {
|
|
45194
46028
|
return db.prepare(
|
|
45195
46029
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
45196
46030
|
).all().map((r) => r.name);
|
|
45197
46031
|
}
|
|
45198
|
-
function
|
|
46032
|
+
function tableExists3(db, tableName) {
|
|
45199
46033
|
const escaped = tableName.replace(/'/g, "''");
|
|
45200
46034
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
45201
46035
|
}
|
|
@@ -45210,14 +46044,14 @@ function rowCount(db, tableName) {
|
|
|
45210
46044
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
45211
46045
|
const entries = [];
|
|
45212
46046
|
let skipped = 0;
|
|
45213
|
-
if (!
|
|
46047
|
+
if (!existsSync22(projectDbPath) || !existsSync22(globalDbPath)) {
|
|
45214
46048
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45215
46049
|
}
|
|
45216
46050
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
45217
46051
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
45218
46052
|
try {
|
|
45219
46053
|
for (const src of sources) {
|
|
45220
|
-
if (!
|
|
46054
|
+
if (!existsSync22(src.path)) continue;
|
|
45221
46055
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
45222
46056
|
try {
|
|
45223
46057
|
for (const legacyTable of listTables2(srcSnap.db)) {
|
|
@@ -45234,7 +46068,7 @@ function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
|
45234
46068
|
skipped++;
|
|
45235
46069
|
continue;
|
|
45236
46070
|
}
|
|
45237
|
-
const targetCount =
|
|
46071
|
+
const targetCount = tableExists3(targetSnap.db, targetTable) ? rowCount(targetSnap.db, targetTable) ?? 0 : 0;
|
|
45238
46072
|
const deficit = targetCount < sourceCount ? sourceCount - targetCount : 0;
|
|
45239
46073
|
entries.push({
|
|
45240
46074
|
sourceDb: src.name,
|
|
@@ -45275,7 +46109,7 @@ var init_count_parity = __esm({
|
|
|
45275
46109
|
});
|
|
45276
46110
|
|
|
45277
46111
|
// packages/core/src/store/exodus/plan.ts
|
|
45278
|
-
import { existsSync as
|
|
46112
|
+
import { existsSync as existsSync23, readdirSync as readdirSync6, statfsSync as statfsSync2, statSync as statSync6 } from "node:fs";
|
|
45279
46113
|
import { join as join27 } from "node:path";
|
|
45280
46114
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
45281
46115
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
@@ -45377,7 +46211,7 @@ function buildExodusPlan(cwd) {
|
|
|
45377
46211
|
};
|
|
45378
46212
|
}
|
|
45379
46213
|
function sourcesPresent(sources) {
|
|
45380
|
-
return sources.some((s) =>
|
|
46214
|
+
return sources.some((s) => existsSync23(s.path));
|
|
45381
46215
|
}
|
|
45382
46216
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
45383
46217
|
var init_plan2 = __esm({
|
|
@@ -45391,18 +46225,18 @@ var init_plan2 = __esm({
|
|
|
45391
46225
|
});
|
|
45392
46226
|
|
|
45393
46227
|
// packages/core/src/store/exodus/health.ts
|
|
45394
|
-
import { existsSync as
|
|
46228
|
+
import { existsSync as existsSync24, statSync as statSync7 } from "node:fs";
|
|
45395
46229
|
function buildExodusHealth(cwd) {
|
|
45396
46230
|
const plan = buildExodusPlan(cwd);
|
|
45397
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
46231
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync24(s.path));
|
|
45398
46232
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45399
46233
|
const consolidatedExistsByScope = {
|
|
45400
|
-
project:
|
|
45401
|
-
global:
|
|
46234
|
+
project: existsSync24(plan.projectDbPath),
|
|
46235
|
+
global: existsSync24(plan.globalDbPath)
|
|
45402
46236
|
};
|
|
45403
46237
|
const buildScope = (scope) => {
|
|
45404
46238
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
45405
|
-
const present =
|
|
46239
|
+
const present = existsSync24(s.path);
|
|
45406
46240
|
let bytes = 0;
|
|
45407
46241
|
if (present) {
|
|
45408
46242
|
try {
|
|
@@ -45507,7 +46341,7 @@ var init_types = __esm({
|
|
|
45507
46341
|
// packages/core/src/store/exodus/migrate.ts
|
|
45508
46342
|
import {
|
|
45509
46343
|
copyFileSync as copyFileSync6,
|
|
45510
|
-
existsSync as
|
|
46344
|
+
existsSync as existsSync25,
|
|
45511
46345
|
mkdirSync as mkdirSync8,
|
|
45512
46346
|
readFileSync as readFileSync9,
|
|
45513
46347
|
renameSync as renameSync8,
|
|
@@ -45553,7 +46387,7 @@ function writeJournal(stagingDir, journal) {
|
|
|
45553
46387
|
}
|
|
45554
46388
|
function readJournal(stagingDir) {
|
|
45555
46389
|
const journalPath = join28(stagingDir, JOURNAL_FILENAME);
|
|
45556
|
-
if (!
|
|
46390
|
+
if (!existsSync25(journalPath)) return null;
|
|
45557
46391
|
try {
|
|
45558
46392
|
return JSON.parse(readFileSync9(journalPath, "utf8"));
|
|
45559
46393
|
} catch {
|
|
@@ -45563,7 +46397,7 @@ function readJournal(stagingDir) {
|
|
|
45563
46397
|
function clearExodusJournal(stagingDir) {
|
|
45564
46398
|
const journalPath = join28(stagingDir, JOURNAL_FILENAME);
|
|
45565
46399
|
try {
|
|
45566
|
-
if (!
|
|
46400
|
+
if (!existsSync25(journalPath)) return false;
|
|
45567
46401
|
unlinkSync5(journalPath);
|
|
45568
46402
|
log10.info(
|
|
45569
46403
|
{ stagingDir },
|
|
@@ -45859,7 +46693,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45859
46693
|
mkdirSync8(stagingDir, { recursive: true });
|
|
45860
46694
|
let sqliteVersion = "unknown";
|
|
45861
46695
|
for (const src of sources) {
|
|
45862
|
-
if (
|
|
46696
|
+
if (existsSync25(src.path)) {
|
|
45863
46697
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
45864
46698
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
45865
46699
|
snap.close();
|
|
@@ -45889,7 +46723,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45889
46723
|
let reseedProject = null;
|
|
45890
46724
|
try {
|
|
45891
46725
|
for (const src of sources) {
|
|
45892
|
-
if (!
|
|
46726
|
+
if (!existsSync25(src.path)) continue;
|
|
45893
46727
|
const backupDest = join28(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
45894
46728
|
const srcBytes = safeStatBytes(src.path);
|
|
45895
46729
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
@@ -45897,7 +46731,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45897
46731
|
onProgress?.(
|
|
45898
46732
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
45899
46733
|
);
|
|
45900
|
-
} else if (!
|
|
46734
|
+
} else if (!existsSync25(backupDest)) {
|
|
45901
46735
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
45902
46736
|
copyFileSync6(src.path, backupDest);
|
|
45903
46737
|
backupPaths.push(backupDest);
|
|
@@ -45930,8 +46764,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45930
46764
|
}
|
|
45931
46765
|
prepareExodusRecovery(projectNative, stagingDir);
|
|
45932
46766
|
if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
|
|
45933
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
45934
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
46767
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync25(s.path));
|
|
46768
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync25(s.path));
|
|
45935
46769
|
if (globalNative === null && globalSources.length > 0)
|
|
45936
46770
|
throw new Error("A projectOnly exodus run was given global-scope sources");
|
|
45937
46771
|
await migrateScope(
|
|
@@ -46180,7 +47014,8 @@ var init_migrate = __esm({
|
|
|
46180
47014
|
GRANDFATHERED_GUARD_TRIGGERS = [
|
|
46181
47015
|
"tasks_tasks_parent_type_matrix_insert",
|
|
46182
47016
|
"tasks_task_relations_non_containment_insert",
|
|
46183
|
-
"tasks_task_acceptance_child_target_insert"
|
|
47017
|
+
"tasks_task_acceptance_child_target_insert",
|
|
47018
|
+
"tasks_task_dependencies_cycle_guard_insert"
|
|
46184
47019
|
];
|
|
46185
47020
|
SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
|
|
46186
47021
|
["conduit", "seconds"],
|
|
@@ -46239,7 +47074,7 @@ __export(reconcile_exports, {
|
|
|
46239
47074
|
reconcileSupersededStores: () => reconcileSupersededStores,
|
|
46240
47075
|
unmigratedBareSources: () => unmigratedBareSources
|
|
46241
47076
|
});
|
|
46242
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
47077
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync26, mkdirSync as mkdirSync9, mkdtempSync, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
46243
47078
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
46244
47079
|
import { basename as basename10, join as join29 } from "node:path";
|
|
46245
47080
|
function ident2(name15) {
|
|
@@ -46310,7 +47145,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
|
|
|
46310
47145
|
}
|
|
46311
47146
|
function legacySourcesHoldRows(sources) {
|
|
46312
47147
|
for (const src of sources) {
|
|
46313
|
-
if (!
|
|
47148
|
+
if (!existsSync26(src.path)) continue;
|
|
46314
47149
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
46315
47150
|
try {
|
|
46316
47151
|
for (const table of orderTablesForCopy(snap.db)) {
|
|
@@ -46558,8 +47393,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
46558
47393
|
}
|
|
46559
47394
|
}
|
|
46560
47395
|
async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
|
|
46561
|
-
const fileSources = plan.sources.filter((s) => s.targetScope === "project" &&
|
|
46562
|
-
const bare = !additive &&
|
|
47396
|
+
const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync26(s.path));
|
|
47397
|
+
const bare = !additive && existsSync26(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
|
|
46563
47398
|
const copyResolver = additive ? (sourceName, legacyTable) => {
|
|
46564
47399
|
const r = resolveTarget(sourceName, legacyTable);
|
|
46565
47400
|
return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
|
|
@@ -46578,7 +47413,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
46578
47413
|
stagingDir: null,
|
|
46579
47414
|
receiptPath: null
|
|
46580
47415
|
};
|
|
46581
|
-
if (sources.length === 0 || !
|
|
47416
|
+
if (sources.length === 0 || !existsSync26(liveStorePath)) {
|
|
46582
47417
|
return {
|
|
46583
47418
|
...base,
|
|
46584
47419
|
outcome: "nothing-to-reconcile",
|
|
@@ -46770,11 +47605,11 @@ var init_seal = __esm({
|
|
|
46770
47605
|
});
|
|
46771
47606
|
|
|
46772
47607
|
// packages/core/src/store/exodus/status.ts
|
|
46773
|
-
import { existsSync as
|
|
47608
|
+
import { existsSync as existsSync27, readdirSync as readdirSync7, readFileSync as readFileSync10, statSync as statSync9 } from "node:fs";
|
|
46774
47609
|
import { join as join30 } from "node:path";
|
|
46775
47610
|
function readJournal2(stagingDir) {
|
|
46776
47611
|
const p = join30(stagingDir, JOURNAL_FILENAME2);
|
|
46777
|
-
if (!
|
|
47612
|
+
if (!existsSync27(p)) return null;
|
|
46778
47613
|
try {
|
|
46779
47614
|
return JSON.parse(readFileSync10(p, "utf8"));
|
|
46780
47615
|
} catch {
|
|
@@ -46806,15 +47641,15 @@ function runExodusStatus(cwd) {
|
|
|
46806
47641
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
46807
47642
|
name: s.name,
|
|
46808
47643
|
path: s.path,
|
|
46809
|
-
exists:
|
|
47644
|
+
exists: existsSync27(s.path),
|
|
46810
47645
|
bytes: safeBytes(s.path)
|
|
46811
47646
|
}));
|
|
46812
47647
|
return {
|
|
46813
47648
|
hasStaging: latestStaging !== null,
|
|
46814
47649
|
stagingDir: latestStaging,
|
|
46815
47650
|
journal,
|
|
46816
|
-
projectDbExists:
|
|
46817
|
-
globalDbExists:
|
|
47651
|
+
projectDbExists: existsSync27(projectDbPath),
|
|
47652
|
+
globalDbExists: existsSync27(globalDbPath),
|
|
46818
47653
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
46819
47654
|
sources: sourcesInfo
|
|
46820
47655
|
};
|
|
@@ -46831,7 +47666,7 @@ var init_status = __esm({
|
|
|
46831
47666
|
});
|
|
46832
47667
|
|
|
46833
47668
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
46834
|
-
import { existsSync as
|
|
47669
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
46835
47670
|
import { createRequire as createRequire10 } from "node:module";
|
|
46836
47671
|
function orderByClause(db, tableName) {
|
|
46837
47672
|
try {
|
|
@@ -46946,7 +47781,7 @@ function listTables3(db) {
|
|
|
46946
47781
|
).all();
|
|
46947
47782
|
return rows.map((r) => r.name);
|
|
46948
47783
|
}
|
|
46949
|
-
function
|
|
47784
|
+
function tableExists4(db, tableName) {
|
|
46950
47785
|
try {
|
|
46951
47786
|
const escaped = tableName.replace(/'/g, "''");
|
|
46952
47787
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
@@ -47096,10 +47931,10 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
|
|
|
47096
47931
|
const anyFeeder = (targetTable, probe) => {
|
|
47097
47932
|
for (const feeder of feedersOf(targetTable)) {
|
|
47098
47933
|
const src = sources.find((s) => s.name === feeder.sourceName);
|
|
47099
|
-
if (src === void 0 || !
|
|
47934
|
+
if (src === void 0 || !existsSync28(src.path)) continue;
|
|
47100
47935
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
47101
47936
|
try {
|
|
47102
|
-
if (!
|
|
47937
|
+
if (!tableExists4(snap.db, feeder.legacyTable)) continue;
|
|
47103
47938
|
const cols = new Set(
|
|
47104
47939
|
snap.db.prepare(`PRAGMA table_info("${feeder.legacyTable}")`).all().map((c) => c.name)
|
|
47105
47940
|
);
|
|
@@ -47151,7 +47986,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47151
47986
|
const preExistingForeignKeyViolations = [];
|
|
47152
47987
|
const failureLines = [];
|
|
47153
47988
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
47154
|
-
if (!
|
|
47989
|
+
if (!existsSync28(projectDbPath)) {
|
|
47155
47990
|
return {
|
|
47156
47991
|
ok: false,
|
|
47157
47992
|
tables: [],
|
|
@@ -47162,7 +47997,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47162
47997
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
47163
47998
|
};
|
|
47164
47999
|
}
|
|
47165
|
-
if (!
|
|
48000
|
+
if (!existsSync28(globalDbPath)) {
|
|
47166
48001
|
return {
|
|
47167
48002
|
ok: false,
|
|
47168
48003
|
tables: [],
|
|
@@ -47177,7 +48012,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47177
48012
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
47178
48013
|
try {
|
|
47179
48014
|
for (const src of sources) {
|
|
47180
|
-
if (!
|
|
48015
|
+
if (!existsSync28(src.path)) {
|
|
47181
48016
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
47182
48017
|
continue;
|
|
47183
48018
|
}
|
|
@@ -47302,7 +48137,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47302
48137
|
targetOrphans.push(...foreignKeyCheck(globalSnap.db, "global"));
|
|
47303
48138
|
foreignKeyViolations.push(...targetOrphans);
|
|
47304
48139
|
for (const fk of targetOrphans) {
|
|
47305
|
-
const orphanDb =
|
|
48140
|
+
const orphanDb = tableExists4(projectSnap.db, fk.table) ? projectSnap.db : globalSnap.db;
|
|
47306
48141
|
const sig = orphanSignature(orphanDb, fk);
|
|
47307
48142
|
const preExisting = sourceOrphanSigs.has(sig) || orphanAlreadyInSource(orphanDb, fk, sources, resolveTarget);
|
|
47308
48143
|
if (preExisting) {
|
|
@@ -47468,7 +48303,7 @@ __export(on_open_exports, {
|
|
|
47468
48303
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
|
|
47469
48304
|
withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
|
|
47470
48305
|
});
|
|
47471
|
-
import { existsSync as
|
|
48306
|
+
import { existsSync as existsSync29, mkdtempSync as mkdtempSync2, rmSync as rmSync4 } from "node:fs";
|
|
47472
48307
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
47473
48308
|
import { join as join31, resolve as resolve13 } from "node:path";
|
|
47474
48309
|
async function withExodusOnOpenSuppressed(dbPath, fn) {
|
|
@@ -47510,7 +48345,7 @@ function remedyFor(scope) {
|
|
|
47510
48345
|
}
|
|
47511
48346
|
async function strandedLegacySources(scope, cwd) {
|
|
47512
48347
|
const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
47513
|
-
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope &&
|
|
48348
|
+
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync29(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
|
|
47514
48349
|
}
|
|
47515
48350
|
async function exodusStoreRewriteRefusal(dbPath, cwd) {
|
|
47516
48351
|
const { assertOwnerStoreRewriteConfirmed: assertOwnerStoreRewriteConfirmed2, invocationDirectory: invocationDirectory2 } = await Promise.resolve().then(() => (init_worktree_isolation_guard(), worktree_isolation_guard_exports));
|
|
@@ -47642,7 +48477,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47642
48477
|
};
|
|
47643
48478
|
}
|
|
47644
48479
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
47645
|
-
if (!scopeSources.some((s) =>
|
|
48480
|
+
if (!scopeSources.some((s) => existsSync29(s.path))) {
|
|
47646
48481
|
return {
|
|
47647
48482
|
outcome: "skipped",
|
|
47648
48483
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -47667,7 +48502,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47667
48502
|
{
|
|
47668
48503
|
scope,
|
|
47669
48504
|
dbPath,
|
|
47670
|
-
sources: plan.sources.filter((s) =>
|
|
48505
|
+
sources: plan.sources.filter((s) => existsSync29(s.path)).map((s) => s.name)
|
|
47671
48506
|
},
|
|
47672
48507
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
47673
48508
|
);
|
|
@@ -47680,7 +48515,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47680
48515
|
const bare = scope === "project" ? await unmigratedBareSources2(
|
|
47681
48516
|
dbPath,
|
|
47682
48517
|
resolveTarget,
|
|
47683
|
-
plan.sources.find((s) => s.name === "tasks" &&
|
|
48518
|
+
plan.sources.find((s) => s.name === "tasks" && existsSync29(s.path))?.path,
|
|
47684
48519
|
bareScratch
|
|
47685
48520
|
) : { first: [], last: [] };
|
|
47686
48521
|
const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
|
|
@@ -47744,7 +48579,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47744
48579
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
47745
48580
|
);
|
|
47746
48581
|
try {
|
|
47747
|
-
const consumed = plan.sources.filter((s) =>
|
|
48582
|
+
const consumed = plan.sources.filter((s) => existsSync29(s.path));
|
|
47748
48583
|
const identities = await sealTargets(plan, consumed);
|
|
47749
48584
|
const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
|
|
47750
48585
|
log14.info(
|
|
@@ -47819,7 +48654,7 @@ __export(dual_scope_db_exports, {
|
|
|
47819
48654
|
upsertIdempotent: () => upsertIdempotent,
|
|
47820
48655
|
withStoreSchemaOwnership: () => withStoreSchemaOwnership
|
|
47821
48656
|
});
|
|
47822
|
-
import { existsSync as
|
|
48657
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync10 } from "node:fs";
|
|
47823
48658
|
import { createRequire as createRequire11 } from "node:module";
|
|
47824
48659
|
import { dirname as dirname20, join as join32, resolve as resolve14 } from "node:path";
|
|
47825
48660
|
function getDualScopeNativeDb(handle) {
|
|
@@ -47892,11 +48727,15 @@ async function openDualScopeDb(scope, cwd, options) {
|
|
|
47892
48727
|
open
|
|
47893
48728
|
) : open();
|
|
47894
48729
|
}
|
|
48730
|
+
function identityWorkOnOpen(nativeDb, scope) {
|
|
48731
|
+
if (ROW_IDENTITY[scope].length === 0) return false;
|
|
48732
|
+
return rowUidFillEnabled() || missingRowIdentitySchema(nativeDb).length > 0;
|
|
48733
|
+
}
|
|
47895
48734
|
async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
47896
48735
|
execution?.assertActive();
|
|
47897
48736
|
log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
47898
48737
|
const dir = dirname20(dbPath);
|
|
47899
|
-
if (!
|
|
48738
|
+
if (!existsSync30(dir)) {
|
|
47900
48739
|
mkdirSync10(dir, { recursive: true });
|
|
47901
48740
|
}
|
|
47902
48741
|
execution?.assertActive();
|
|
@@ -47929,9 +48768,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
47929
48768
|
`dual-scope-db[${scope}]`
|
|
47930
48769
|
);
|
|
47931
48770
|
execution?.assertActive();
|
|
47932
|
-
if (
|
|
48771
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
47933
48772
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
47934
|
-
|
|
48773
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
48774
|
+
if (rowUidFillEnabled()) {
|
|
48775
|
+
prepareRowIdentity(nativeDb, scope, { triggers: false });
|
|
48776
|
+
}
|
|
47935
48777
|
}
|
|
47936
48778
|
execution?.assertActive();
|
|
47937
48779
|
log15.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
|
|
@@ -48044,7 +48886,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48044
48886
|
execution?.assertActive();
|
|
48045
48887
|
log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
|
|
48046
48888
|
const dir = dirname20(normalizedPath);
|
|
48047
|
-
if (!
|
|
48889
|
+
if (!existsSync30(dir)) {
|
|
48048
48890
|
mkdirSync10(dir, { recursive: true });
|
|
48049
48891
|
}
|
|
48050
48892
|
execution?.assertActive();
|
|
@@ -48077,9 +48919,12 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48077
48919
|
`dual-scope-db[${scope}]`
|
|
48078
48920
|
);
|
|
48079
48921
|
execution?.assertActive();
|
|
48080
|
-
if (
|
|
48922
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
48081
48923
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
48082
|
-
|
|
48924
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
48925
|
+
if (rowUidFillEnabled()) {
|
|
48926
|
+
prepareRowIdentity(nativeDb, scope);
|
|
48927
|
+
}
|
|
48083
48928
|
}
|
|
48084
48929
|
execution?.assertActive();
|
|
48085
48930
|
log15.debug({ scope, dbPath: normalizedPath }, "dual-scope cleo.db ready");
|
|
@@ -49209,7 +50054,7 @@ __export(nexus_sqlite_exports, {
|
|
|
49209
50054
|
resetNexusDbState: () => resetNexusDbState,
|
|
49210
50055
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
49211
50056
|
});
|
|
49212
|
-
import { copyFileSync as copyFileSync8, existsSync as
|
|
50057
|
+
import { copyFileSync as copyFileSync8, existsSync as existsSync31 } from "node:fs";
|
|
49213
50058
|
import { join as join33 } from "node:path";
|
|
49214
50059
|
function getNexusDbPath(cwd) {
|
|
49215
50060
|
return resolveDualScopeDbPath("project", cwd);
|
|
@@ -49261,7 +50106,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49261
50106
|
} catch {
|
|
49262
50107
|
return false;
|
|
49263
50108
|
}
|
|
49264
|
-
if (!
|
|
50109
|
+
if (!existsSync31(nestedPath)) return false;
|
|
49265
50110
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
49266
50111
|
_warnedNestedPaths.add(nestedPath);
|
|
49267
50112
|
const canonicalPath = getNexusDbPath();
|
|
@@ -49281,7 +50126,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49281
50126
|
function _resetNestedNexusWarningGate() {
|
|
49282
50127
|
_warnedNestedPaths.clear();
|
|
49283
50128
|
}
|
|
49284
|
-
function
|
|
50129
|
+
function tableExists5(nativeDb, tableName) {
|
|
49285
50130
|
const result = nativeDb.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(tableName);
|
|
49286
50131
|
return !!result;
|
|
49287
50132
|
}
|
|
@@ -49290,7 +50135,7 @@ function objectExists(nativeDb, type, name15) {
|
|
|
49290
50135
|
return !!result;
|
|
49291
50136
|
}
|
|
49292
50137
|
function ensureNexusFts5(nativeDb) {
|
|
49293
|
-
if (!
|
|
50138
|
+
if (!tableExists5(nativeDb, "nexus_nodes")) return;
|
|
49294
50139
|
if (!objectExists(nativeDb, "table", "nexus_symbols_fts")) {
|
|
49295
50140
|
nativeDb.exec(`
|
|
49296
50141
|
CREATE VIRTUAL TABLE nexus_symbols_fts USING fts5(
|
|
@@ -49336,7 +50181,7 @@ function ensureNexusFts5(nativeDb) {
|
|
|
49336
50181
|
`);
|
|
49337
50182
|
}
|
|
49338
50183
|
function ensureNexusRelationWeights(nativeDb) {
|
|
49339
|
-
if (!
|
|
50184
|
+
if (!tableExists5(nativeDb, "nexus_relations")) return;
|
|
49340
50185
|
nativeDb.exec(`
|
|
49341
50186
|
CREATE TABLE IF NOT EXISTS nexus_relation_weights (
|
|
49342
50187
|
relation_id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -49418,9 +50263,9 @@ function ensureNexusRelationWeights(nativeDb) {
|
|
|
49418
50263
|
}
|
|
49419
50264
|
function runNexusMigrations(nativeDb, db, dbPath) {
|
|
49420
50265
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
49421
|
-
if (
|
|
50266
|
+
if (tableExists5(nativeDb, "nexus_nodes")) {
|
|
49422
50267
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
49423
|
-
if (!
|
|
50268
|
+
if (!existsSync31(backupPath)) {
|
|
49424
50269
|
try {
|
|
49425
50270
|
copyFileSync8(dbPath, backupPath);
|
|
49426
50271
|
} catch {
|
|
@@ -49550,13 +50395,13 @@ var init_legacy_alias = __esm({
|
|
|
49550
50395
|
|
|
49551
50396
|
// packages/core/src/llm/stable-device-id.ts
|
|
49552
50397
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
49553
|
-
import { existsSync as
|
|
50398
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync11, readFileSync as readFileSync11, renameSync as renameSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
49554
50399
|
import { dirname as dirname21 } from "node:path";
|
|
49555
50400
|
import { resolveStableDeviceIdPath } from "@cleocode/paths";
|
|
49556
50401
|
function getStableDeviceId() {
|
|
49557
50402
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
49558
50403
|
const path = resolveStableDeviceIdPath();
|
|
49559
|
-
if (
|
|
50404
|
+
if (existsSync32(path)) {
|
|
49560
50405
|
try {
|
|
49561
50406
|
const raw = readFileSync11(path, "utf-8").trim();
|
|
49562
50407
|
if (raw.length > 0) {
|
|
@@ -49569,7 +50414,7 @@ function getStableDeviceId() {
|
|
|
49569
50414
|
const fresh = randomUUID3();
|
|
49570
50415
|
try {
|
|
49571
50416
|
const dir = dirname21(path);
|
|
49572
|
-
if (!
|
|
50417
|
+
if (!existsSync32(dir)) {
|
|
49573
50418
|
mkdirSync11(dir, { recursive: true });
|
|
49574
50419
|
}
|
|
49575
50420
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
@@ -49645,11 +50490,11 @@ __export(path_map_exports, {
|
|
|
49645
50490
|
supersededRegistryPath: () => supersededRegistryPath,
|
|
49646
50491
|
touchProjectLocation: () => touchProjectLocation
|
|
49647
50492
|
});
|
|
49648
|
-
import { existsSync as
|
|
50493
|
+
import { existsSync as existsSync33, lstatSync, readdirSync as readdirSync8 } from "node:fs";
|
|
49649
50494
|
import { lstat, readdir as readdir2 } from "node:fs/promises";
|
|
49650
50495
|
import { isAbsolute as isAbsolute5, join as join34, relative as relative3, sep as sep5 } from "node:path";
|
|
49651
50496
|
import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity4 } from "@cleocode/paths";
|
|
49652
|
-
import { and as and9, desc as desc3, eq as eq12, inArray as
|
|
50497
|
+
import { and as and9, desc as desc3, eq as eq12, inArray as inArray7, ne as ne3 } from "drizzle-orm";
|
|
49653
50498
|
function holdingKey(projectId, path) {
|
|
49654
50499
|
return `${projectId}\0${path}`;
|
|
49655
50500
|
}
|
|
@@ -49797,7 +50642,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49797
50642
|
const here = db.select({ state: projectLocations.state, checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49798
50643
|
and9(
|
|
49799
50644
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49800
|
-
|
|
50645
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49801
50646
|
eq12(projectLocations.path, record2.projectPath)
|
|
49802
50647
|
)
|
|
49803
50648
|
).all();
|
|
@@ -49808,7 +50653,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49808
50653
|
const previous = () => db.select({ checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49809
50654
|
and9(
|
|
49810
50655
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49811
|
-
|
|
50656
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49812
50657
|
eq12(projectLocations.path, oldPath)
|
|
49813
50658
|
)
|
|
49814
50659
|
).all();
|
|
@@ -49856,7 +50701,7 @@ function hasOtherLiveLocation(db, record2, deviceId) {
|
|
|
49856
50701
|
ne3(projectLocations.path, record2.projectPath)
|
|
49857
50702
|
)
|
|
49858
50703
|
).all().some(
|
|
49859
|
-
(location) => isStrictlyInside(record2.projectPath, location.path) &&
|
|
50704
|
+
(location) => isStrictlyInside(record2.projectPath, location.path) && existsSync33(location.path) && readDeclaredProjectIdentity4(location.path)?.projectId === record2.projectId
|
|
49860
50705
|
);
|
|
49861
50706
|
}
|
|
49862
50707
|
function demoteProjectLocation(db, record2, state) {
|
|
@@ -49907,7 +50752,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
|
|
|
49907
50752
|
).orderBy(desc3(projectLocations.lastSeen)).all();
|
|
49908
50753
|
const present = (path) => {
|
|
49909
50754
|
const holding = probed?.get(holdingKey(row.projectId, path));
|
|
49910
|
-
return holding === void 0 ?
|
|
50755
|
+
return holding === void 0 ? existsSync33(path) : holding === "yes";
|
|
49911
50756
|
};
|
|
49912
50757
|
const home = candidates.find(
|
|
49913
50758
|
(c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq12(projectRegistry.projectPath, c.path)).all().length === 0
|
|
@@ -49936,7 +50781,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
|
|
|
49936
50781
|
projectHash: generateProjectHash(row.path),
|
|
49937
50782
|
firstSeen: row.firstSeen,
|
|
49938
50783
|
lastSeen: row.lastSeen,
|
|
49939
|
-
exists: local &&
|
|
50784
|
+
exists: local && existsSync33(row.path),
|
|
49940
50785
|
deviceId: local ? deviceId : row.deviceId,
|
|
49941
50786
|
state: row.state
|
|
49942
50787
|
});
|
|
@@ -49969,7 +50814,7 @@ __export(project_activity_exports, {
|
|
|
49969
50814
|
projectLastActivitySql: () => projectLastActivitySql,
|
|
49970
50815
|
projectLastActivitySqlText: () => projectLastActivitySqlText
|
|
49971
50816
|
});
|
|
49972
|
-
import { eq as eq13, inArray as
|
|
50817
|
+
import { eq as eq13, inArray as inArray8, sql as sql32 } from "drizzle-orm";
|
|
49973
50818
|
function normalizeRegistryTimestamp(value) {
|
|
49974
50819
|
if (value === null || value === void 0 || value.length === 0) return null;
|
|
49975
50820
|
const iso = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value) ? `${value.replace(" ", "T")}Z` : value;
|
|
@@ -49998,7 +50843,7 @@ function markProjectsProbed(db, projectIds, now = /* @__PURE__ */ new Date()) {
|
|
|
49998
50843
|
for (let i = 0; i < ids.length; i += PROBED_CHUNK) {
|
|
49999
50844
|
const chunk = ids.slice(i, i + PROBED_CHUNK);
|
|
50000
50845
|
changed += Number(
|
|
50001
|
-
db.update(projectRegistry).set({ lastProbedAt: at }).where(
|
|
50846
|
+
db.update(projectRegistry).set({ lastProbedAt: at }).where(inArray8(projectRegistry.projectId, chunk)).run().changes
|
|
50002
50847
|
);
|
|
50003
50848
|
}
|
|
50004
50849
|
return changed;
|
|
@@ -50031,11 +50876,11 @@ __export(checkout_nonce_exports, {
|
|
|
50031
50876
|
readCheckoutNonce: () => readCheckoutNonce
|
|
50032
50877
|
});
|
|
50033
50878
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
50034
|
-
import { existsSync as
|
|
50879
|
+
import { existsSync as existsSync34, readFileSync as readFileSync12, renameSync as renameSync10, writeFileSync as writeFileSync10 } from "node:fs";
|
|
50035
50880
|
import { join as join35 } from "node:path";
|
|
50036
50881
|
function readInfo(projectRoot) {
|
|
50037
50882
|
const path = join35(projectRoot, ".cleo", "project-info.json");
|
|
50038
|
-
if (!
|
|
50883
|
+
if (!existsSync34(path)) return null;
|
|
50039
50884
|
try {
|
|
50040
50885
|
const parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
50041
50886
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
@@ -50128,7 +50973,7 @@ __export(paths_exports, {
|
|
|
50128
50973
|
validateProjectRoot: () => validateProjectRoot,
|
|
50129
50974
|
worktreeScope: () => worktreeScope
|
|
50130
50975
|
});
|
|
50131
|
-
import { existsSync as
|
|
50976
|
+
import { existsSync as existsSync35, readFileSync as readFileSync13, statSync as statSync10 } from "node:fs";
|
|
50132
50977
|
import { createRequire as createRequire12 } from "node:module";
|
|
50133
50978
|
import { homedir as homedir2 } from "node:os";
|
|
50134
50979
|
import { dirname as dirname22, join as join36, resolve as resolve15 } from "node:path";
|
|
@@ -50154,7 +50999,7 @@ function runWithWorktreeScopeFromEnv(fn) {
|
|
|
50154
50999
|
function isProjectInitialized(projectRoot) {
|
|
50155
51000
|
const root = projectRoot ?? getProjectRoot();
|
|
50156
51001
|
const cleoDir = join36(root, ".cleo");
|
|
50157
|
-
return
|
|
51002
|
+
return existsSync35(cleoDir) && existsSync35(join36(cleoDir, "tasks.db"));
|
|
50158
51003
|
}
|
|
50159
51004
|
function getCleoHome() {
|
|
50160
51005
|
return getPlatformPaths().data;
|
|
@@ -50260,7 +51105,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
50260
51105
|
try {
|
|
50261
51106
|
const cleoHome = getCleoHome();
|
|
50262
51107
|
const globalDbPath = join36(cleoHome, "cleo.db");
|
|
50263
|
-
if (!
|
|
51108
|
+
if (!existsSync35(globalDbPath)) return null;
|
|
50264
51109
|
const start = resolve15(cwd ?? process.cwd());
|
|
50265
51110
|
let current = start;
|
|
50266
51111
|
const DatabaseSync3 = _getDatabaseSyncCtor();
|
|
@@ -50423,7 +51268,7 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
50423
51268
|
while (true) {
|
|
50424
51269
|
const gitMarker = join36(current, ".git");
|
|
50425
51270
|
try {
|
|
50426
|
-
if (
|
|
51271
|
+
if (existsSync35(gitMarker)) {
|
|
50427
51272
|
return true;
|
|
50428
51273
|
}
|
|
50429
51274
|
} catch {
|
|
@@ -50501,7 +51346,7 @@ function getCleoGlobalCantAgentsDir() {
|
|
|
50501
51346
|
function getAgentOutputsDir(cwd) {
|
|
50502
51347
|
const projectRoot = getProjectRoot(cwd);
|
|
50503
51348
|
const configPath = join36(projectRoot, ".cleo", "config.json");
|
|
50504
|
-
if (
|
|
51349
|
+
if (existsSync35(configPath)) {
|
|
50505
51350
|
try {
|
|
50506
51351
|
const config2 = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
50507
51352
|
if (typeof config2.agentOutputs === "object" && config2.agentOutputs?.directory) {
|
|
@@ -50534,7 +51379,7 @@ function getManifestPath(cwd) {
|
|
|
50534
51379
|
const configPath = join36(projectRoot, ".cleo", "config.json");
|
|
50535
51380
|
const legacyFileName = ["MANIFEST", "jsonl"].join(".");
|
|
50536
51381
|
let manifestFile = legacyFileName;
|
|
50537
|
-
if (
|
|
51382
|
+
if (existsSync35(configPath)) {
|
|
50538
51383
|
try {
|
|
50539
51384
|
const config2 = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
50540
51385
|
const customFile = config2.agentOutputs?.manifestFile ?? config2.research?.manifestFile;
|
|
@@ -50590,7 +51435,7 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
50590
51435
|
while (current !== home && current !== "/" && current !== "") {
|
|
50591
51436
|
const gitPath = join36(current, ".git");
|
|
50592
51437
|
try {
|
|
50593
|
-
if (
|
|
51438
|
+
if (existsSync35(gitPath)) {
|
|
50594
51439
|
const stat3 = statSync10(gitPath);
|
|
50595
51440
|
if (stat3.isFile()) {
|
|
50596
51441
|
worktreePath = current;
|
|
@@ -50629,7 +51474,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50629
51474
|
}
|
|
50630
51475
|
const tasksDbPath = join36(routing.worktreePath, ".cleo", "tasks.db");
|
|
50631
51476
|
try {
|
|
50632
|
-
if (
|
|
51477
|
+
if (existsSync35(tasksDbPath) && statSync10(tasksDbPath).isFile()) {
|
|
50633
51478
|
return tasksDbPath;
|
|
50634
51479
|
}
|
|
50635
51480
|
} catch {
|
|
@@ -50639,7 +51484,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50639
51484
|
async function resolveProjectById(projectId) {
|
|
50640
51485
|
try {
|
|
50641
51486
|
const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50642
|
-
if (!
|
|
51487
|
+
if (!existsSync35(getNexusRegistryDbPath2())) return null;
|
|
50643
51488
|
const { eq: eq14 } = await import("drizzle-orm");
|
|
50644
51489
|
const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50645
51490
|
const db = await getNexusDb2();
|
|
@@ -50675,7 +51520,7 @@ function _rowToRegistryEntry(row) {
|
|
|
50675
51520
|
}
|
|
50676
51521
|
function _assertProjectInfoReadable(projectRoot) {
|
|
50677
51522
|
const infoPath = join36(projectRoot, ".cleo", "project-info.json");
|
|
50678
|
-
if (
|
|
51523
|
+
if (existsSync35(infoPath)) JSON.parse(readFileSync13(infoPath, "utf-8"));
|
|
50679
51524
|
}
|
|
50680
51525
|
function startProjectEncounter(key, projectRoot, infoProjectId) {
|
|
50681
51526
|
const inFlight2 = _encountersInFlight.get(key);
|
|
@@ -50724,7 +51569,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50724
51569
|
if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
|
|
50725
51570
|
const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
|
|
50726
51571
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50727
|
-
if (
|
|
51572
|
+
if (existsSync35(getNexusRegistryDbPath2(cleoHome))) {
|
|
50728
51573
|
const { and: and10, eq: eq14 } = await import("drizzle-orm");
|
|
50729
51574
|
const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50730
51575
|
const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
|
|
@@ -50750,7 +51595,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50750
51595
|
}
|
|
50751
51596
|
async function markEncounterOpened(cleoHome, projectId) {
|
|
50752
51597
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50753
|
-
if (!
|
|
51598
|
+
if (!existsSync35(getNexusRegistryDbPath2(cleoHome))) return;
|
|
50754
51599
|
const { markProjectOpened: markProjectOpened2 } = await Promise.resolve().then(() => (init_project_activity(), project_activity_exports));
|
|
50755
51600
|
markProjectOpened2(await getNexusRegistryDb2(cleoHome), projectId);
|
|
50756
51601
|
}
|
|
@@ -50912,7 +51757,7 @@ var init_paths = __esm({
|
|
|
50912
51757
|
// packages/core/src/store/file-utils.ts
|
|
50913
51758
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
50914
51759
|
import {
|
|
50915
|
-
existsSync as
|
|
51760
|
+
existsSync as existsSync36,
|
|
50916
51761
|
mkdirSync as mkdirSync12,
|
|
50917
51762
|
readdirSync as readdirSync9,
|
|
50918
51763
|
readFileSync as readFileSync14,
|
|
@@ -50927,7 +51772,7 @@ function rotateBackup(filePath, mode) {
|
|
|
50927
51772
|
const name15 = basename11(filePath);
|
|
50928
51773
|
const backupDir = join37(dir, ".backups");
|
|
50929
51774
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
50930
|
-
if (!
|
|
51775
|
+
if (!existsSync36(backupDir)) {
|
|
50931
51776
|
mkdirSync12(backupDir, { recursive: true, mode: dirMode });
|
|
50932
51777
|
}
|
|
50933
51778
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
@@ -50940,7 +51785,7 @@ function rotateBackup(filePath, mode) {
|
|
|
50940
51785
|
} else {
|
|
50941
51786
|
const next = join37(backupDir, `${name15}.${i + 1}`);
|
|
50942
51787
|
try {
|
|
50943
|
-
if (
|
|
51788
|
+
if (existsSync36(current)) renameSync11(current, next);
|
|
50944
51789
|
} catch {
|
|
50945
51790
|
}
|
|
50946
51791
|
}
|
|
@@ -50976,7 +51821,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
50976
51821
|
writeFileSync11(tempPath, content, "utf-8");
|
|
50977
51822
|
}
|
|
50978
51823
|
try {
|
|
50979
|
-
if (
|
|
51824
|
+
if (existsSync36(filePath)) {
|
|
50980
51825
|
rotateBackup(filePath, mode);
|
|
50981
51826
|
}
|
|
50982
51827
|
renameSync11(tempPath, filePath);
|
|
@@ -51002,10 +51847,10 @@ function readJsonFile(filePath) {
|
|
|
51002
51847
|
async function withLock2(filePath, transform2, opts = {}) {
|
|
51003
51848
|
const dir = dirname23(filePath);
|
|
51004
51849
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
51005
|
-
if (!
|
|
51850
|
+
if (!existsSync36(dir)) {
|
|
51006
51851
|
mkdirSync12(dir, { recursive: true, mode: dirMode });
|
|
51007
51852
|
}
|
|
51008
|
-
if (!
|
|
51853
|
+
if (!existsSync36(filePath)) {
|
|
51009
51854
|
if (typeof opts.mode === "number") {
|
|
51010
51855
|
writeFileSync11(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
51011
51856
|
} else {
|
|
@@ -51027,10 +51872,10 @@ async function withLock2(filePath, transform2, opts = {}) {
|
|
|
51027
51872
|
}
|
|
51028
51873
|
async function withFileLock(filePath, operation) {
|
|
51029
51874
|
const dir = dirname23(filePath);
|
|
51030
|
-
if (!
|
|
51875
|
+
if (!existsSync36(dir)) {
|
|
51031
51876
|
mkdirSync12(dir, { recursive: true });
|
|
51032
51877
|
}
|
|
51033
|
-
if (!
|
|
51878
|
+
if (!existsSync36(filePath)) {
|
|
51034
51879
|
writeFileSync11(filePath, "", "utf-8");
|
|
51035
51880
|
}
|
|
51036
51881
|
let release;
|
|
@@ -51402,7 +52247,7 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
51402
52247
|
});
|
|
51403
52248
|
|
|
51404
52249
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
51405
|
-
import { existsSync as
|
|
52250
|
+
import { existsSync as existsSync37, readFileSync as readFileSync17 } from "node:fs";
|
|
51406
52251
|
import { homedir as homedir4 } from "node:os";
|
|
51407
52252
|
import { join as join41 } from "node:path";
|
|
51408
52253
|
function getCodexAuthPath() {
|
|
@@ -51427,7 +52272,7 @@ var init_codex_cli_seeder = __esm({
|
|
|
51427
52272
|
*/
|
|
51428
52273
|
async seed() {
|
|
51429
52274
|
const authPath = getCodexAuthPath();
|
|
51430
|
-
if (!
|
|
52275
|
+
if (!existsSync37(authPath)) {
|
|
51431
52276
|
return { entries: [] };
|
|
51432
52277
|
}
|
|
51433
52278
|
let raw;
|
|
@@ -51622,7 +52467,7 @@ var init_google_pkce = __esm({
|
|
|
51622
52467
|
});
|
|
51623
52468
|
|
|
51624
52469
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
51625
|
-
import { existsSync as
|
|
52470
|
+
import { existsSync as existsSync38, readFileSync as readFileSync18 } from "node:fs";
|
|
51626
52471
|
import { join as join42 } from "node:path";
|
|
51627
52472
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
51628
52473
|
function getGoogleOauthPath() {
|
|
@@ -51671,7 +52516,7 @@ var init_gemini_cli_seeder = __esm({
|
|
|
51671
52516
|
*/
|
|
51672
52517
|
async seed() {
|
|
51673
52518
|
const path = getGoogleOauthPath();
|
|
51674
|
-
if (!
|
|
52519
|
+
if (!existsSync38(path)) {
|
|
51675
52520
|
return { entries: [] };
|
|
51676
52521
|
}
|
|
51677
52522
|
let raw;
|
|
@@ -51896,7 +52741,7 @@ var init_credential_seeders = __esm({
|
|
|
51896
52741
|
|
|
51897
52742
|
// packages/core/src/llm/global-config-migration.ts
|
|
51898
52743
|
import {
|
|
51899
|
-
existsSync as
|
|
52744
|
+
existsSync as existsSync39,
|
|
51900
52745
|
mkdirSync as mkdirSync13,
|
|
51901
52746
|
readFileSync as readFileSync19,
|
|
51902
52747
|
renameSync as renameSync12,
|
|
@@ -51922,12 +52767,12 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
51922
52767
|
const source = legacyGlobalConfigPath();
|
|
51923
52768
|
const target = configDirGlobalConfigPath();
|
|
51924
52769
|
const marker16 = migrationMarkerPath();
|
|
51925
|
-
if (
|
|
51926
|
-
if (!
|
|
52770
|
+
if (existsSync39(marker16)) return false;
|
|
52771
|
+
if (!existsSync39(source)) {
|
|
51927
52772
|
stampMarker(marker16);
|
|
51928
52773
|
return false;
|
|
51929
52774
|
}
|
|
51930
|
-
if (
|
|
52775
|
+
if (existsSync39(target)) {
|
|
51931
52776
|
backupSourceQuiet(source);
|
|
51932
52777
|
stampMarker(marker16);
|
|
51933
52778
|
return false;
|
|
@@ -51960,7 +52805,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
51960
52805
|
} catch (err) {
|
|
51961
52806
|
try {
|
|
51962
52807
|
const temp = tempTargetPath();
|
|
51963
|
-
if (
|
|
52808
|
+
if (existsSync39(temp)) unlinkSync8(temp);
|
|
51964
52809
|
} catch {
|
|
51965
52810
|
}
|
|
51966
52811
|
console.error(
|
|
@@ -51980,7 +52825,7 @@ function stampMarker(markerPath) {
|
|
|
51980
52825
|
function backupSourceQuiet(source) {
|
|
51981
52826
|
try {
|
|
51982
52827
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
51983
|
-
if (
|
|
52828
|
+
if (existsSync39(backup)) return;
|
|
51984
52829
|
renameSync12(source, backup);
|
|
51985
52830
|
} catch {
|
|
51986
52831
|
}
|
|
@@ -52003,7 +52848,7 @@ var init_global_config_migration = __esm({
|
|
|
52003
52848
|
});
|
|
52004
52849
|
|
|
52005
52850
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
52006
|
-
import { existsSync as
|
|
52851
|
+
import { existsSync as existsSync40, readFileSync as readFileSync20, renameSync as renameSync13, writeFileSync as writeFileSync13 } from "node:fs";
|
|
52007
52852
|
import { join as join44 } from "node:path";
|
|
52008
52853
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
52009
52854
|
function migrationPaths() {
|
|
@@ -52032,7 +52877,7 @@ function writeMarker(markerPath) {
|
|
|
52032
52877
|
}
|
|
52033
52878
|
function readFlatKey(flatPath) {
|
|
52034
52879
|
try {
|
|
52035
|
-
if (!
|
|
52880
|
+
if (!existsSync40(flatPath)) return null;
|
|
52036
52881
|
const raw = readFileSync20(flatPath, "utf-8").trim();
|
|
52037
52882
|
return raw || null;
|
|
52038
52883
|
} catch (err) {
|
|
@@ -52045,7 +52890,7 @@ function readFlatKey(flatPath) {
|
|
|
52045
52890
|
}
|
|
52046
52891
|
async function importLegacyFlatAnthropicKey() {
|
|
52047
52892
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
52048
|
-
if (
|
|
52893
|
+
if (existsSync40(markerPath)) {
|
|
52049
52894
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
52050
52895
|
}
|
|
52051
52896
|
let existing = null;
|
|
@@ -52062,7 +52907,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
52062
52907
|
writeMarker(markerPath);
|
|
52063
52908
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
52064
52909
|
}
|
|
52065
|
-
if (!
|
|
52910
|
+
if (!existsSync40(flatPath)) {
|
|
52066
52911
|
writeMarker(markerPath);
|
|
52067
52912
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
52068
52913
|
}
|
|
@@ -52139,7 +52984,7 @@ __export(credentials_exports, {
|
|
|
52139
52984
|
resolveProviderStatus: () => resolveProviderStatus,
|
|
52140
52985
|
storeAnthropicApiKey: () => storeAnthropicApiKey
|
|
52141
52986
|
});
|
|
52142
|
-
import { existsSync as
|
|
52987
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, readFileSync as readFileSync21, writeFileSync as writeFileSync14 } from "node:fs";
|
|
52143
52988
|
import { join as join45 } from "node:path";
|
|
52144
52989
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
52145
52990
|
function globalConfigPath() {
|
|
@@ -52158,7 +53003,7 @@ function readGlobalProviderKey(provider) {
|
|
|
52158
53003
|
function readFlatAnthropicKey() {
|
|
52159
53004
|
try {
|
|
52160
53005
|
const keyFile = join45(getCleoHome8(), "anthropic-key");
|
|
52161
|
-
if (!
|
|
53006
|
+
if (!existsSync41(keyFile)) return null;
|
|
52162
53007
|
const stored = readFileSync21(keyFile, "utf-8").trim();
|
|
52163
53008
|
return stored || null;
|
|
52164
53009
|
} catch {
|
|
@@ -52167,7 +53012,7 @@ function readFlatAnthropicKey() {
|
|
|
52167
53012
|
}
|
|
52168
53013
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
52169
53014
|
try {
|
|
52170
|
-
if (!
|
|
53015
|
+
if (!existsSync41(configFile)) return null;
|
|
52171
53016
|
const raw = readFileSync21(configFile, "utf-8");
|
|
52172
53017
|
const config2 = JSON.parse(raw);
|
|
52173
53018
|
const llm = config2["llm"];
|
|
@@ -52340,7 +53185,7 @@ function resolveProviderStatus(provider) {
|
|
|
52340
53185
|
}
|
|
52341
53186
|
function storeAnthropicApiKey(apiKey) {
|
|
52342
53187
|
const dir = getCleoHome8();
|
|
52343
|
-
if (!
|
|
53188
|
+
if (!existsSync41(dir)) {
|
|
52344
53189
|
mkdirSync14(dir, { recursive: true });
|
|
52345
53190
|
}
|
|
52346
53191
|
const keyFile = join45(dir, "anthropic-key");
|
|
@@ -52408,16 +53253,16 @@ __export(credentials_store_exports, {
|
|
|
52408
53253
|
pickCredentialForProviderSync: () => pickCredentialForProviderSync,
|
|
52409
53254
|
removeCredential: () => removeCredential
|
|
52410
53255
|
});
|
|
52411
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
53256
|
+
import { chmodSync as chmodSync2, existsSync as existsSync42, mkdirSync as mkdirSync15, readFileSync as readFileSync22, statSync as statSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
52412
53257
|
import { dirname as dirname24, join as join46 } from "node:path";
|
|
52413
53258
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
52414
53259
|
function credentialsStorePath() {
|
|
52415
53260
|
return join46(getCleoHome9(), "llm-credentials.json");
|
|
52416
53261
|
}
|
|
52417
53262
|
function ensureFileInitialized(path) {
|
|
52418
|
-
if (
|
|
53263
|
+
if (existsSync42(path)) return;
|
|
52419
53264
|
const dir = dirname24(path);
|
|
52420
|
-
if (!
|
|
53265
|
+
if (!existsSync42(dir)) {
|
|
52421
53266
|
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
52422
53267
|
} else {
|
|
52423
53268
|
try {
|
|
@@ -53115,8 +53960,8 @@ async function scanAndLoadPlugins(pluginDir, api) {
|
|
|
53115
53960
|
}
|
|
53116
53961
|
async function runDiscovery(registerProvider2, builtins) {
|
|
53117
53962
|
const api = { registerProvider: registerProvider2 };
|
|
53118
|
-
for (const
|
|
53119
|
-
registerProvider2(
|
|
53963
|
+
for (const profile2 of builtins) {
|
|
53964
|
+
registerProvider2(profile2);
|
|
53120
53965
|
}
|
|
53121
53966
|
await scanAndLoadPlugins(getPluginDir(), api);
|
|
53122
53967
|
}
|
|
@@ -53139,16 +53984,16 @@ __export(provider_registry_exports, {
|
|
|
53139
53984
|
listProviders: () => listProviders,
|
|
53140
53985
|
registerProvider: () => registerProvider
|
|
53141
53986
|
});
|
|
53142
|
-
function registerProvider(
|
|
53143
|
-
const key =
|
|
53144
|
-
_registry.set(key,
|
|
53145
|
-
for (const alias of
|
|
53987
|
+
function registerProvider(profile2) {
|
|
53988
|
+
const key = profile2.name.toLowerCase();
|
|
53989
|
+
_registry.set(key, profile2);
|
|
53990
|
+
for (const alias of profile2.aliases ?? []) {
|
|
53146
53991
|
const aliasKey = alias.toLowerCase();
|
|
53147
53992
|
const existing = _aliases.get(aliasKey);
|
|
53148
53993
|
if (existing !== void 0 && existing !== key) {
|
|
53149
53994
|
if (_registry.has(aliasKey) && aliasKey !== key) {
|
|
53150
53995
|
throw new TypeError(
|
|
53151
|
-
`[provider-registry] Alias "${alias}" for provider "${
|
|
53996
|
+
`[provider-registry] Alias "${alias}" for provider "${profile2.name}" conflicts with the primary name of provider "${_registry.get(aliasKey)?.name ?? aliasKey}".`
|
|
53152
53997
|
);
|
|
53153
53998
|
}
|
|
53154
53999
|
}
|
|
@@ -53213,7 +54058,7 @@ var init_provider_registry = __esm({
|
|
|
53213
54058
|
});
|
|
53214
54059
|
|
|
53215
54060
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
53216
|
-
import { existsSync as
|
|
54061
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9 } from "node:fs";
|
|
53217
54062
|
import { join as join48 } from "node:path";
|
|
53218
54063
|
import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
|
|
53219
54064
|
function sanitize(value) {
|
|
@@ -53269,7 +54114,7 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
53269
54114
|
}
|
|
53270
54115
|
const filePath = rateLimitStatePath(provider, label);
|
|
53271
54116
|
const dir = join48(getCleoHome10(), "rate-limit-state");
|
|
53272
|
-
if (!
|
|
54117
|
+
if (!existsSync43(dir)) {
|
|
53273
54118
|
mkdirSync16(dir, { recursive: true });
|
|
53274
54119
|
}
|
|
53275
54120
|
const state = { resetAt, recordedAt: now, source };
|
|
@@ -53621,8 +54466,8 @@ var init_credential_pool = __esm({
|
|
|
53621
54466
|
*/
|
|
53622
54467
|
async _refreshOAuthCredential(existing) {
|
|
53623
54468
|
if (!existing.refreshToken) return;
|
|
53624
|
-
const
|
|
53625
|
-
const oauthCfg =
|
|
54469
|
+
const profile2 = await getProviderProfile(this.provider);
|
|
54470
|
+
const oauthCfg = profile2?.oauth;
|
|
53626
54471
|
if (oauthCfg?.mode === "pkce") {
|
|
53627
54472
|
await this._refreshViaPkce(
|
|
53628
54473
|
existing,
|
|
@@ -54170,7 +55015,7 @@ var init_error_classifier = __esm({
|
|
|
54170
55015
|
|
|
54171
55016
|
// packages/core/src/llm/catalog-cache.ts
|
|
54172
55017
|
import {
|
|
54173
|
-
existsSync as
|
|
55018
|
+
existsSync as existsSync44,
|
|
54174
55019
|
mkdirSync as mkdirSync17,
|
|
54175
55020
|
readdirSync as readdirSync11,
|
|
54176
55021
|
readFileSync as readFileSync23,
|
|
@@ -54188,7 +55033,7 @@ function getCatalogDir() {
|
|
|
54188
55033
|
return join49(getCleoHome11(), "llm-catalog");
|
|
54189
55034
|
}
|
|
54190
55035
|
function findLatestCacheFile(dir) {
|
|
54191
|
-
if (!
|
|
55036
|
+
if (!existsSync44(dir)) return null;
|
|
54192
55037
|
const files = readdirSync11(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync13(join49(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
54193
55038
|
return files.length > 0 ? join49(dir, files[0].name) : null;
|
|
54194
55039
|
}
|
|
@@ -55573,7 +56418,7 @@ var init_structured_output = __esm({
|
|
|
55573
56418
|
|
|
55574
56419
|
// packages/core/src/llm/transports/anthropic.ts
|
|
55575
56420
|
import Anthropic from "@anthropic-ai/sdk";
|
|
55576
|
-
import { z as
|
|
56421
|
+
import { z as z32 } from "zod";
|
|
55577
56422
|
function isTextBlock(block) {
|
|
55578
56423
|
return block.type === "text";
|
|
55579
56424
|
}
|
|
@@ -55645,8 +56490,8 @@ function mapUsage(usage) {
|
|
|
55645
56490
|
function zodSchemaFrom(responseFormat) {
|
|
55646
56491
|
if (responseFormat == null) return null;
|
|
55647
56492
|
const asAny = responseFormat;
|
|
55648
|
-
if (asAny["schema"] instanceof
|
|
55649
|
-
if (responseFormat instanceof
|
|
56493
|
+
if (asAny["schema"] instanceof z32.ZodType) return asAny["schema"];
|
|
56494
|
+
if (responseFormat instanceof z32.ZodType) return responseFormat;
|
|
55650
56495
|
return null;
|
|
55651
56496
|
}
|
|
55652
56497
|
function getJsonSchemaString(responseFormat) {
|
|
@@ -56052,7 +56897,7 @@ ${schemaJson}`
|
|
|
56052
56897
|
content = typeof validated === "string" ? validated : JSON.stringify(validated);
|
|
56053
56898
|
} catch {
|
|
56054
56899
|
try {
|
|
56055
|
-
const repaired = repairResponseModelJson(rawContent, zodSchema2 ??
|
|
56900
|
+
const repaired = repairResponseModelJson(rawContent, zodSchema2 ?? z32.unknown(), modelName);
|
|
56056
56901
|
content = typeof repaired === "string" ? repaired : JSON.stringify(repaired);
|
|
56057
56902
|
} catch {
|
|
56058
56903
|
content = rawContent || null;
|
|
@@ -57617,7 +58462,7 @@ var init_caching = __esm({
|
|
|
57617
58462
|
|
|
57618
58463
|
// packages/core/src/llm/transports/gemini.ts
|
|
57619
58464
|
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
57620
|
-
import { z as
|
|
58465
|
+
import { z as z33 } from "zod";
|
|
57621
58466
|
function messagesToRaw(messages, system) {
|
|
57622
58467
|
const raw = [];
|
|
57623
58468
|
if (system) {
|
|
@@ -58005,7 +58850,7 @@ var init_gemini2 = __esm({
|
|
|
58005
58850
|
const parsed = response["parsed"];
|
|
58006
58851
|
if (parsed !== null && parsed !== void 0) {
|
|
58007
58852
|
try {
|
|
58008
|
-
const zodResult =
|
|
58853
|
+
const zodResult = z33.string().safeParse(String(parsed));
|
|
58009
58854
|
if (!zodResult.success) {
|
|
58010
58855
|
content = JSON.stringify(parsed);
|
|
58011
58856
|
} else {
|
|
@@ -72402,7 +73247,7 @@ function resolveRef2(ref, ctx) {
|
|
|
72402
73247
|
function convertBaseSchema(schema, ctx) {
|
|
72403
73248
|
if (schema.not !== void 0) {
|
|
72404
73249
|
if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) {
|
|
72405
|
-
return
|
|
73250
|
+
return z34.never();
|
|
72406
73251
|
}
|
|
72407
73252
|
throw new Error("not is not supported in Zod (except { not: {} } for never)");
|
|
72408
73253
|
}
|
|
@@ -72424,7 +73269,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72424
73269
|
return ctx.refs.get(refPath);
|
|
72425
73270
|
}
|
|
72426
73271
|
if (ctx.processing.has(refPath)) {
|
|
72427
|
-
return
|
|
73272
|
+
return z34.lazy(() => {
|
|
72428
73273
|
if (!ctx.refs.has(refPath)) {
|
|
72429
73274
|
throw new Error(`Circular reference not resolved: ${refPath}`);
|
|
72430
73275
|
}
|
|
@@ -72441,25 +73286,25 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72441
73286
|
if (schema.enum !== void 0) {
|
|
72442
73287
|
const enumValues = schema.enum;
|
|
72443
73288
|
if (ctx.version === "openapi-3.0" && schema.nullable === true && enumValues.length === 1 && enumValues[0] === null) {
|
|
72444
|
-
return
|
|
73289
|
+
return z34.null();
|
|
72445
73290
|
}
|
|
72446
73291
|
if (enumValues.length === 0) {
|
|
72447
|
-
return
|
|
73292
|
+
return z34.never();
|
|
72448
73293
|
}
|
|
72449
73294
|
if (enumValues.length === 1) {
|
|
72450
|
-
return
|
|
73295
|
+
return z34.literal(enumValues[0]);
|
|
72451
73296
|
}
|
|
72452
73297
|
if (enumValues.every((v) => typeof v === "string")) {
|
|
72453
|
-
return
|
|
73298
|
+
return z34.enum(enumValues);
|
|
72454
73299
|
}
|
|
72455
|
-
const literalSchemas = enumValues.map((v) =>
|
|
73300
|
+
const literalSchemas = enumValues.map((v) => z34.literal(v));
|
|
72456
73301
|
if (literalSchemas.length < 2) {
|
|
72457
73302
|
return literalSchemas[0];
|
|
72458
73303
|
}
|
|
72459
|
-
return
|
|
73304
|
+
return z34.union([literalSchemas[0], literalSchemas[1], ...literalSchemas.slice(2)]);
|
|
72460
73305
|
}
|
|
72461
73306
|
if (schema.const !== void 0) {
|
|
72462
|
-
return
|
|
73307
|
+
return z34.literal(schema.const);
|
|
72463
73308
|
}
|
|
72464
73309
|
const type = schema.type;
|
|
72465
73310
|
if (Array.isArray(type)) {
|
|
@@ -72468,68 +73313,68 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72468
73313
|
return convertBaseSchema(typeSchema, ctx);
|
|
72469
73314
|
});
|
|
72470
73315
|
if (typeSchemas.length === 0) {
|
|
72471
|
-
return
|
|
73316
|
+
return z34.never();
|
|
72472
73317
|
}
|
|
72473
73318
|
if (typeSchemas.length === 1) {
|
|
72474
73319
|
return typeSchemas[0];
|
|
72475
73320
|
}
|
|
72476
|
-
return
|
|
73321
|
+
return z34.union(typeSchemas);
|
|
72477
73322
|
}
|
|
72478
73323
|
if (!type) {
|
|
72479
|
-
return
|
|
73324
|
+
return z34.any();
|
|
72480
73325
|
}
|
|
72481
73326
|
let zodSchema2;
|
|
72482
73327
|
switch (type) {
|
|
72483
73328
|
case "string": {
|
|
72484
|
-
let stringSchema =
|
|
73329
|
+
let stringSchema = z34.string();
|
|
72485
73330
|
if (schema.format) {
|
|
72486
73331
|
const format = schema.format;
|
|
72487
73332
|
if (format === "email") {
|
|
72488
|
-
stringSchema = stringSchema.check(
|
|
73333
|
+
stringSchema = stringSchema.check(z34.email());
|
|
72489
73334
|
} else if (format === "uri" || format === "uri-reference") {
|
|
72490
|
-
stringSchema = stringSchema.check(
|
|
73335
|
+
stringSchema = stringSchema.check(z34.url());
|
|
72491
73336
|
} else if (format === "uuid" || format === "guid") {
|
|
72492
|
-
stringSchema = stringSchema.check(
|
|
73337
|
+
stringSchema = stringSchema.check(z34.uuid());
|
|
72493
73338
|
} else if (format === "date-time") {
|
|
72494
|
-
stringSchema = stringSchema.check(
|
|
73339
|
+
stringSchema = stringSchema.check(z34.iso.datetime());
|
|
72495
73340
|
} else if (format === "date") {
|
|
72496
|
-
stringSchema = stringSchema.check(
|
|
73341
|
+
stringSchema = stringSchema.check(z34.iso.date());
|
|
72497
73342
|
} else if (format === "time") {
|
|
72498
|
-
stringSchema = stringSchema.check(
|
|
73343
|
+
stringSchema = stringSchema.check(z34.iso.time());
|
|
72499
73344
|
} else if (format === "duration") {
|
|
72500
|
-
stringSchema = stringSchema.check(
|
|
73345
|
+
stringSchema = stringSchema.check(z34.iso.duration());
|
|
72501
73346
|
} else if (format === "ipv4") {
|
|
72502
|
-
stringSchema = stringSchema.check(
|
|
73347
|
+
stringSchema = stringSchema.check(z34.ipv4());
|
|
72503
73348
|
} else if (format === "ipv6") {
|
|
72504
|
-
stringSchema = stringSchema.check(
|
|
73349
|
+
stringSchema = stringSchema.check(z34.ipv6());
|
|
72505
73350
|
} else if (format === "mac") {
|
|
72506
|
-
stringSchema = stringSchema.check(
|
|
73351
|
+
stringSchema = stringSchema.check(z34.mac());
|
|
72507
73352
|
} else if (format === "cidr") {
|
|
72508
|
-
stringSchema = stringSchema.check(
|
|
73353
|
+
stringSchema = stringSchema.check(z34.cidrv4());
|
|
72509
73354
|
} else if (format === "cidr-v6") {
|
|
72510
|
-
stringSchema = stringSchema.check(
|
|
73355
|
+
stringSchema = stringSchema.check(z34.cidrv6());
|
|
72511
73356
|
} else if (format === "base64") {
|
|
72512
|
-
stringSchema = stringSchema.check(
|
|
73357
|
+
stringSchema = stringSchema.check(z34.base64());
|
|
72513
73358
|
} else if (format === "base64url") {
|
|
72514
|
-
stringSchema = stringSchema.check(
|
|
73359
|
+
stringSchema = stringSchema.check(z34.base64url());
|
|
72515
73360
|
} else if (format === "e164") {
|
|
72516
|
-
stringSchema = stringSchema.check(
|
|
73361
|
+
stringSchema = stringSchema.check(z34.e164());
|
|
72517
73362
|
} else if (format === "jwt") {
|
|
72518
|
-
stringSchema = stringSchema.check(
|
|
73363
|
+
stringSchema = stringSchema.check(z34.jwt());
|
|
72519
73364
|
} else if (format === "emoji") {
|
|
72520
|
-
stringSchema = stringSchema.check(
|
|
73365
|
+
stringSchema = stringSchema.check(z34.emoji());
|
|
72521
73366
|
} else if (format === "nanoid") {
|
|
72522
|
-
stringSchema = stringSchema.check(
|
|
73367
|
+
stringSchema = stringSchema.check(z34.nanoid());
|
|
72523
73368
|
} else if (format === "cuid") {
|
|
72524
|
-
stringSchema = stringSchema.check(
|
|
73369
|
+
stringSchema = stringSchema.check(z34.cuid());
|
|
72525
73370
|
} else if (format === "cuid2") {
|
|
72526
|
-
stringSchema = stringSchema.check(
|
|
73371
|
+
stringSchema = stringSchema.check(z34.cuid2());
|
|
72527
73372
|
} else if (format === "ulid") {
|
|
72528
|
-
stringSchema = stringSchema.check(
|
|
73373
|
+
stringSchema = stringSchema.check(z34.ulid());
|
|
72529
73374
|
} else if (format === "xid") {
|
|
72530
|
-
stringSchema = stringSchema.check(
|
|
73375
|
+
stringSchema = stringSchema.check(z34.xid());
|
|
72531
73376
|
} else if (format === "ksuid") {
|
|
72532
|
-
stringSchema = stringSchema.check(
|
|
73377
|
+
stringSchema = stringSchema.check(z34.ksuid());
|
|
72533
73378
|
}
|
|
72534
73379
|
}
|
|
72535
73380
|
if (typeof schema.minLength === "number") {
|
|
@@ -72546,7 +73391,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72546
73391
|
}
|
|
72547
73392
|
case "number":
|
|
72548
73393
|
case "integer": {
|
|
72549
|
-
let numberSchema = type === "integer" ?
|
|
73394
|
+
let numberSchema = type === "integer" ? z34.number().int() : z34.number();
|
|
72550
73395
|
if (typeof schema.minimum === "number") {
|
|
72551
73396
|
numberSchema = numberSchema.min(schema.minimum);
|
|
72552
73397
|
}
|
|
@@ -72570,11 +73415,11 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72570
73415
|
break;
|
|
72571
73416
|
}
|
|
72572
73417
|
case "boolean": {
|
|
72573
|
-
zodSchema2 =
|
|
73418
|
+
zodSchema2 = z34.boolean();
|
|
72574
73419
|
break;
|
|
72575
73420
|
}
|
|
72576
73421
|
case "null": {
|
|
72577
|
-
zodSchema2 =
|
|
73422
|
+
zodSchema2 = z34.null();
|
|
72578
73423
|
break;
|
|
72579
73424
|
}
|
|
72580
73425
|
case "object": {
|
|
@@ -72587,14 +73432,14 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72587
73432
|
}
|
|
72588
73433
|
if (schema.propertyNames) {
|
|
72589
73434
|
const keySchema = convertSchema(schema.propertyNames, ctx);
|
|
72590
|
-
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) :
|
|
73435
|
+
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) : z34.any();
|
|
72591
73436
|
if (Object.keys(shape).length === 0) {
|
|
72592
|
-
zodSchema2 =
|
|
73437
|
+
zodSchema2 = z34.record(keySchema, valueSchema);
|
|
72593
73438
|
break;
|
|
72594
73439
|
}
|
|
72595
|
-
const objectSchema2 =
|
|
72596
|
-
const recordSchema =
|
|
72597
|
-
zodSchema2 =
|
|
73440
|
+
const objectSchema2 = z34.object(shape).passthrough();
|
|
73441
|
+
const recordSchema = z34.looseRecord(keySchema, valueSchema);
|
|
73442
|
+
zodSchema2 = z34.intersection(objectSchema2, recordSchema);
|
|
72598
73443
|
break;
|
|
72599
73444
|
}
|
|
72600
73445
|
if (schema.patternProperties) {
|
|
@@ -72603,28 +73448,28 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72603
73448
|
const looseRecords = [];
|
|
72604
73449
|
for (const pattern of patternKeys) {
|
|
72605
73450
|
const patternValue = convertSchema(patternProps[pattern], ctx);
|
|
72606
|
-
const keySchema =
|
|
72607
|
-
looseRecords.push(
|
|
73451
|
+
const keySchema = z34.string().regex(new RegExp(pattern));
|
|
73452
|
+
looseRecords.push(z34.looseRecord(keySchema, patternValue));
|
|
72608
73453
|
}
|
|
72609
73454
|
const schemasToIntersect = [];
|
|
72610
73455
|
if (Object.keys(shape).length > 0) {
|
|
72611
|
-
schemasToIntersect.push(
|
|
73456
|
+
schemasToIntersect.push(z34.object(shape).passthrough());
|
|
72612
73457
|
}
|
|
72613
73458
|
schemasToIntersect.push(...looseRecords);
|
|
72614
73459
|
if (schemasToIntersect.length === 0) {
|
|
72615
|
-
zodSchema2 =
|
|
73460
|
+
zodSchema2 = z34.object({}).passthrough();
|
|
72616
73461
|
} else if (schemasToIntersect.length === 1) {
|
|
72617
73462
|
zodSchema2 = schemasToIntersect[0];
|
|
72618
73463
|
} else {
|
|
72619
|
-
let result =
|
|
73464
|
+
let result = z34.intersection(schemasToIntersect[0], schemasToIntersect[1]);
|
|
72620
73465
|
for (let i = 2; i < schemasToIntersect.length; i++) {
|
|
72621
|
-
result =
|
|
73466
|
+
result = z34.intersection(result, schemasToIntersect[i]);
|
|
72622
73467
|
}
|
|
72623
73468
|
zodSchema2 = result;
|
|
72624
73469
|
}
|
|
72625
73470
|
break;
|
|
72626
73471
|
}
|
|
72627
|
-
const objectSchema =
|
|
73472
|
+
const objectSchema = z34.object(shape);
|
|
72628
73473
|
if (schema.additionalProperties === false) {
|
|
72629
73474
|
zodSchema2 = objectSchema.strict();
|
|
72630
73475
|
} else if (typeof schema.additionalProperties === "object") {
|
|
@@ -72641,33 +73486,33 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72641
73486
|
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
|
72642
73487
|
const rest = items && typeof items === "object" && !Array.isArray(items) ? convertSchema(items, ctx) : void 0;
|
|
72643
73488
|
if (rest) {
|
|
72644
|
-
zodSchema2 =
|
|
73489
|
+
zodSchema2 = z34.tuple(tupleItems).rest(rest);
|
|
72645
73490
|
} else {
|
|
72646
|
-
zodSchema2 =
|
|
73491
|
+
zodSchema2 = z34.tuple(tupleItems);
|
|
72647
73492
|
}
|
|
72648
73493
|
if (typeof schema.minItems === "number") {
|
|
72649
|
-
zodSchema2 = zodSchema2.check(
|
|
73494
|
+
zodSchema2 = zodSchema2.check(z34.minLength(schema.minItems));
|
|
72650
73495
|
}
|
|
72651
73496
|
if (typeof schema.maxItems === "number") {
|
|
72652
|
-
zodSchema2 = zodSchema2.check(
|
|
73497
|
+
zodSchema2 = zodSchema2.check(z34.maxLength(schema.maxItems));
|
|
72653
73498
|
}
|
|
72654
73499
|
} else if (Array.isArray(items)) {
|
|
72655
73500
|
const tupleItems = items.map((item) => convertSchema(item, ctx));
|
|
72656
73501
|
const rest = schema.additionalItems && typeof schema.additionalItems === "object" ? convertSchema(schema.additionalItems, ctx) : void 0;
|
|
72657
73502
|
if (rest) {
|
|
72658
|
-
zodSchema2 =
|
|
73503
|
+
zodSchema2 = z34.tuple(tupleItems).rest(rest);
|
|
72659
73504
|
} else {
|
|
72660
|
-
zodSchema2 =
|
|
73505
|
+
zodSchema2 = z34.tuple(tupleItems);
|
|
72661
73506
|
}
|
|
72662
73507
|
if (typeof schema.minItems === "number") {
|
|
72663
|
-
zodSchema2 = zodSchema2.check(
|
|
73508
|
+
zodSchema2 = zodSchema2.check(z34.minLength(schema.minItems));
|
|
72664
73509
|
}
|
|
72665
73510
|
if (typeof schema.maxItems === "number") {
|
|
72666
|
-
zodSchema2 = zodSchema2.check(
|
|
73511
|
+
zodSchema2 = zodSchema2.check(z34.maxLength(schema.maxItems));
|
|
72667
73512
|
}
|
|
72668
73513
|
} else if (items !== void 0) {
|
|
72669
73514
|
const element = convertSchema(items, ctx);
|
|
72670
|
-
let arraySchema =
|
|
73515
|
+
let arraySchema = z34.array(element);
|
|
72671
73516
|
if (typeof schema.minItems === "number") {
|
|
72672
73517
|
arraySchema = arraySchema.min(schema.minItems);
|
|
72673
73518
|
}
|
|
@@ -72676,7 +73521,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72676
73521
|
}
|
|
72677
73522
|
zodSchema2 = arraySchema;
|
|
72678
73523
|
} else {
|
|
72679
|
-
zodSchema2 =
|
|
73524
|
+
zodSchema2 = z34.array(z34.any());
|
|
72680
73525
|
}
|
|
72681
73526
|
break;
|
|
72682
73527
|
}
|
|
@@ -72693,37 +73538,37 @@ function convertBaseSchema(schema, ctx) {
|
|
|
72693
73538
|
}
|
|
72694
73539
|
function convertSchema(schema, ctx) {
|
|
72695
73540
|
if (typeof schema === "boolean") {
|
|
72696
|
-
return schema ?
|
|
73541
|
+
return schema ? z34.any() : z34.never();
|
|
72697
73542
|
}
|
|
72698
73543
|
let baseSchema = convertBaseSchema(schema, ctx);
|
|
72699
73544
|
const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
|
|
72700
73545
|
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
72701
73546
|
const options = schema.anyOf.map((s) => convertSchema(s, ctx));
|
|
72702
|
-
const anyOfUnion =
|
|
72703
|
-
baseSchema = hasExplicitType ?
|
|
73547
|
+
const anyOfUnion = z34.union(options);
|
|
73548
|
+
baseSchema = hasExplicitType ? z34.intersection(baseSchema, anyOfUnion) : anyOfUnion;
|
|
72704
73549
|
}
|
|
72705
73550
|
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
72706
73551
|
const options = schema.oneOf.map((s) => convertSchema(s, ctx));
|
|
72707
|
-
const oneOfUnion =
|
|
72708
|
-
baseSchema = hasExplicitType ?
|
|
73552
|
+
const oneOfUnion = z34.xor(options);
|
|
73553
|
+
baseSchema = hasExplicitType ? z34.intersection(baseSchema, oneOfUnion) : oneOfUnion;
|
|
72709
73554
|
}
|
|
72710
73555
|
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
72711
73556
|
if (schema.allOf.length === 0) {
|
|
72712
|
-
baseSchema = hasExplicitType ? baseSchema :
|
|
73557
|
+
baseSchema = hasExplicitType ? baseSchema : z34.any();
|
|
72713
73558
|
} else {
|
|
72714
73559
|
let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
|
|
72715
73560
|
const startIdx = hasExplicitType ? 0 : 1;
|
|
72716
73561
|
for (let i = startIdx; i < schema.allOf.length; i++) {
|
|
72717
|
-
result =
|
|
73562
|
+
result = z34.intersection(result, convertSchema(schema.allOf[i], ctx));
|
|
72718
73563
|
}
|
|
72719
73564
|
baseSchema = result;
|
|
72720
73565
|
}
|
|
72721
73566
|
}
|
|
72722
73567
|
if (schema.nullable === true && ctx.version === "openapi-3.0") {
|
|
72723
|
-
baseSchema =
|
|
73568
|
+
baseSchema = z34.nullable(baseSchema);
|
|
72724
73569
|
}
|
|
72725
73570
|
if (schema.readOnly === true) {
|
|
72726
|
-
baseSchema =
|
|
73571
|
+
baseSchema = z34.readonly(baseSchema);
|
|
72727
73572
|
}
|
|
72728
73573
|
const extraMeta = {};
|
|
72729
73574
|
const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
|
|
@@ -72750,7 +73595,7 @@ function convertSchema(schema, ctx) {
|
|
|
72750
73595
|
}
|
|
72751
73596
|
function fromJSONSchema(schema, params) {
|
|
72752
73597
|
if (typeof schema === "boolean") {
|
|
72753
|
-
return schema ?
|
|
73598
|
+
return schema ? z34.any() : z34.never();
|
|
72754
73599
|
}
|
|
72755
73600
|
const version2 = detectVersion(schema, params?.defaultTarget);
|
|
72756
73601
|
const defs = schema.$defs || schema.definitions || {};
|
|
@@ -72764,14 +73609,14 @@ function fromJSONSchema(schema, params) {
|
|
|
72764
73609
|
};
|
|
72765
73610
|
return convertSchema(schema, ctx);
|
|
72766
73611
|
}
|
|
72767
|
-
var
|
|
73612
|
+
var z34, RECOGNIZED_KEYS;
|
|
72768
73613
|
var init_from_json_schema = __esm({
|
|
72769
73614
|
"node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.js"() {
|
|
72770
73615
|
init_registries();
|
|
72771
73616
|
init_checks2();
|
|
72772
73617
|
init_iso();
|
|
72773
73618
|
init_schemas2();
|
|
72774
|
-
|
|
73619
|
+
z34 = {
|
|
72775
73620
|
...schemas_exports2,
|
|
72776
73621
|
...checks_exports2,
|
|
72777
73622
|
iso: iso_exports
|
|
@@ -86684,15 +87529,15 @@ async function selectBestProvisioned(role, opts) {
|
|
|
86684
87529
|
const ollamaProvisioned = provisionedIds.includes("ollama");
|
|
86685
87530
|
let ollamaAlive = localModels.length > 0;
|
|
86686
87531
|
if (ollamaProvisioned && !ollamaAlive) {
|
|
86687
|
-
const
|
|
86688
|
-
const ollamaBase =
|
|
87532
|
+
const profile2 = await getProviderProfile2("ollama");
|
|
87533
|
+
const ollamaBase = profile2?.baseUrl ?? "http://localhost:11434";
|
|
86689
87534
|
ollamaAlive = await probeOllamaAlive(ollamaBase);
|
|
86690
87535
|
if (ollamaAlive) localModels = await listOllamaModels(ollamaBase);
|
|
86691
87536
|
}
|
|
86692
87537
|
const scored = [];
|
|
86693
87538
|
for (const id of provisionedIds) {
|
|
86694
|
-
const
|
|
86695
|
-
const tier =
|
|
87539
|
+
const profile2 = await getProviderProfile2(id);
|
|
87540
|
+
const tier = profile2?.tier ?? "standard";
|
|
86696
87541
|
const costInput = 0;
|
|
86697
87542
|
const score = scoreProvider(id, tier, taskTier, ollamaAlive, costInput);
|
|
86698
87543
|
const storedCred = await pickCredentialForProvider2(id, { strategy: "priorityOnly" });
|
|
@@ -86887,12 +87732,12 @@ function readLlmBlock(config2) {
|
|
|
86887
87732
|
}
|
|
86888
87733
|
function resolveNamedProfile(llm, name15, source) {
|
|
86889
87734
|
if (!name15) return void 0;
|
|
86890
|
-
const
|
|
86891
|
-
if (!
|
|
87735
|
+
const profile2 = llm?.profiles?.[name15];
|
|
87736
|
+
if (!profile2?.provider || !profile2.model) return void 0;
|
|
86892
87737
|
return {
|
|
86893
|
-
provider:
|
|
86894
|
-
model:
|
|
86895
|
-
credentialLabel:
|
|
87738
|
+
provider: profile2.provider,
|
|
87739
|
+
model: profile2.model,
|
|
87740
|
+
credentialLabel: profile2.credentialLabel,
|
|
86896
87741
|
source
|
|
86897
87742
|
};
|
|
86898
87743
|
}
|
|
@@ -86920,11 +87765,11 @@ function resolveSystemBinding(llm, systemKey) {
|
|
|
86920
87765
|
function resolveRegisteredSystemDefault(llm, systemKey) {
|
|
86921
87766
|
const defaults = getRegisteredSystemDefault(systemKey);
|
|
86922
87767
|
if (!defaults) return void 0;
|
|
86923
|
-
const
|
|
86924
|
-
if (
|
|
87768
|
+
const profile2 = resolveNamedProfile(llm, defaults.profile, "registered-default");
|
|
87769
|
+
if (profile2) {
|
|
86925
87770
|
return {
|
|
86926
|
-
...
|
|
86927
|
-
credentialLabel: defaults.credentialLabel ??
|
|
87771
|
+
...profile2,
|
|
87772
|
+
credentialLabel: defaults.credentialLabel ?? profile2.credentialLabel
|
|
86928
87773
|
};
|
|
86929
87774
|
}
|
|
86930
87775
|
if (defaults.provider && defaults.model) {
|