@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
|
@@ -2009,7 +2009,7 @@ var init_output_contracts_data = __esm({
|
|
|
2009
2009
|
// T12503: the optimistic-concurrency version agents pass to --if-match.
|
|
2010
2010
|
updatedAt: {
|
|
2011
2011
|
type: ["string", "null"],
|
|
2012
|
-
description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`."
|
|
2012
|
+
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)."
|
|
2013
2013
|
},
|
|
2014
2014
|
// T12502: the human assignee and the agent claim lease are separate.
|
|
2015
2015
|
assignee: {
|
|
@@ -13270,6 +13270,7 @@ var init_exit_codes = __esm({
|
|
|
13270
13270
|
ExitCode2[ExitCode2["VERSION_CONFLICT"] = 23] = "VERSION_CONFLICT";
|
|
13271
13271
|
ExitCode2[ExitCode2["SESSION_UNBOUND"] = 24] = "SESSION_UNBOUND";
|
|
13272
13272
|
ExitCode2[ExitCode2["WORKTREE_LOCKED"] = 25] = "WORKTREE_LOCKED";
|
|
13273
|
+
ExitCode2[ExitCode2["TASK_RENAMED"] = 26] = "TASK_RENAMED";
|
|
13273
13274
|
ExitCode2[ExitCode2["SESSION_EXISTS"] = 30] = "SESSION_EXISTS";
|
|
13274
13275
|
ExitCode2[ExitCode2["SESSION_NOT_FOUND"] = 31] = "SESSION_NOT_FOUND";
|
|
13275
13276
|
ExitCode2[ExitCode2["SCOPE_CONFLICT"] = 32] = "SCOPE_CONFLICT";
|
|
@@ -17536,6 +17537,210 @@ var init_nexus_account = __esm({
|
|
|
17536
17537
|
}
|
|
17537
17538
|
});
|
|
17538
17539
|
|
|
17540
|
+
// packages/contracts/src/nexus-cloud.ts
|
|
17541
|
+
import { z as z26 } from "zod";
|
|
17542
|
+
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;
|
|
17543
|
+
var init_nexus_cloud = __esm({
|
|
17544
|
+
"packages/contracts/src/nexus-cloud.ts"() {
|
|
17545
|
+
"use strict";
|
|
17546
|
+
NEXUS_DEVICE_STATES = ["active", "signed-out", "revoked"];
|
|
17547
|
+
NEXUS_CLOUD_PROFILES = ["device", "read-only"];
|
|
17548
|
+
NEXUS_DEVICE_STATE_UNKNOWN = "unknown";
|
|
17549
|
+
isoTime = z26.iso.datetime({ offset: true });
|
|
17550
|
+
profile = z26.enum(NEXUS_CLOUD_PROFILES).nullable().catch(null);
|
|
17551
|
+
deviceState = z26.enum([...NEXUS_DEVICE_STATES, NEXUS_DEVICE_STATE_UNKNOWN]).catch(NEXUS_DEVICE_STATE_UNKNOWN);
|
|
17552
|
+
nexusCloudCredentialSchema = z26.object({
|
|
17553
|
+
kind: z26.enum(["device", "session"]),
|
|
17554
|
+
credentialId: z26.string().nullable().optional(),
|
|
17555
|
+
profile: profile.optional(),
|
|
17556
|
+
scopes: z26.array(z26.string()).default([]),
|
|
17557
|
+
createdAt: isoTime.nullable().optional(),
|
|
17558
|
+
lastUsedAt: isoTime.nullable().optional(),
|
|
17559
|
+
/** When the credential expires if it is not used again; null for sessions. */
|
|
17560
|
+
idleExpiresAt: isoTime.nullable().optional()
|
|
17561
|
+
});
|
|
17562
|
+
nexusCloudDeviceSchema = z26.object({
|
|
17563
|
+
deviceId: z26.string(),
|
|
17564
|
+
name: z26.string(),
|
|
17565
|
+
platform: z26.string().optional(),
|
|
17566
|
+
arch: z26.string().nullable().optional(),
|
|
17567
|
+
cliVersion: z26.string().nullable().optional(),
|
|
17568
|
+
createdAt: isoTime.optional(),
|
|
17569
|
+
lastSeenAt: isoTime.nullable().optional(),
|
|
17570
|
+
state: deviceState,
|
|
17571
|
+
signedOutAt: isoTime.nullable().optional(),
|
|
17572
|
+
/** Base64 device certificate; null until the device holds a key grant. */
|
|
17573
|
+
certificate: z26.string().nullable().optional(),
|
|
17574
|
+
/** The current credential's profile, or null with none (signed out or revoked). */
|
|
17575
|
+
profile: profile.optional(),
|
|
17576
|
+
/** True for the device whose credential made this request. */
|
|
17577
|
+
current: z26.boolean().default(false),
|
|
17578
|
+
projects: z26.number().int().nonnegative().optional(),
|
|
17579
|
+
replicas: z26.number().int().nonnegative().optional(),
|
|
17580
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17581
|
+
lastPresenceAt: isoTime.nullable().optional()
|
|
17582
|
+
});
|
|
17583
|
+
nexusCloudOrganizationSchema = z26.object({
|
|
17584
|
+
id: z26.string(),
|
|
17585
|
+
name: z26.string(),
|
|
17586
|
+
slug: z26.string().nullable().optional(),
|
|
17587
|
+
role: z26.string().optional(),
|
|
17588
|
+
personal: z26.boolean().optional()
|
|
17589
|
+
});
|
|
17590
|
+
nexusCloudUserSchema = z26.object({
|
|
17591
|
+
id: z26.string(),
|
|
17592
|
+
email: z26.string(),
|
|
17593
|
+
name: z26.string().nullable().optional()
|
|
17594
|
+
});
|
|
17595
|
+
nexusCloudWhoamiSchema = z26.object({
|
|
17596
|
+
serverTime: isoTime.optional(),
|
|
17597
|
+
user: nexusCloudUserSchema,
|
|
17598
|
+
organizations: z26.array(nexusCloudOrganizationSchema).default([]),
|
|
17599
|
+
credential: nexusCloudCredentialSchema,
|
|
17600
|
+
/** The calling device; null for a session caller. */
|
|
17601
|
+
device: nexusCloudDeviceSchema.nullable()
|
|
17602
|
+
});
|
|
17603
|
+
nexusCloudDevicePageSchema = z26.object({
|
|
17604
|
+
devices: z26.array(nexusCloudDeviceSchema),
|
|
17605
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17606
|
+
truncated: z26.boolean().default(false)
|
|
17607
|
+
});
|
|
17608
|
+
nexusCloudPresenceSchema = z26.looseObject({
|
|
17609
|
+
observedAt: isoTime.optional(),
|
|
17610
|
+
sync: z26.object({ enabled: z26.boolean() }).optional()
|
|
17611
|
+
});
|
|
17612
|
+
nexusCloudReplicaSchema = z26.object({
|
|
17613
|
+
projectId: z26.string(),
|
|
17614
|
+
replicaId: z26.string(),
|
|
17615
|
+
deviceId: z26.string(),
|
|
17616
|
+
deviceName: z26.string(),
|
|
17617
|
+
deviceState: deviceState.optional(),
|
|
17618
|
+
attachedAt: isoTime.optional(),
|
|
17619
|
+
lastSyncAt: isoTime.nullable(),
|
|
17620
|
+
presence: nexusCloudPresenceSchema.nullable(),
|
|
17621
|
+
presenceAt: isoTime.nullable()
|
|
17622
|
+
});
|
|
17623
|
+
nexusCloudDeviceCountsSchema = z26.object({
|
|
17624
|
+
active: z26.number().int().nonnegative(),
|
|
17625
|
+
total: z26.number().int().nonnegative()
|
|
17626
|
+
});
|
|
17627
|
+
projectFields = {
|
|
17628
|
+
projectId: z26.string(),
|
|
17629
|
+
label: z26.string().nullable(),
|
|
17630
|
+
organizationId: z26.string(),
|
|
17631
|
+
organizationName: z26.string().optional(),
|
|
17632
|
+
remoteUrl: z26.string().nullable().optional(),
|
|
17633
|
+
createdAt: isoTime.optional()
|
|
17634
|
+
};
|
|
17635
|
+
nexusCloudProjectListItemSchema = z26.object({
|
|
17636
|
+
...projectFields,
|
|
17637
|
+
role: z26.string(),
|
|
17638
|
+
streamId: z26.string().optional(),
|
|
17639
|
+
headSeq: z26.number().int().nonnegative().nullable().optional(),
|
|
17640
|
+
openConflicts: z26.number().int().nonnegative().optional(),
|
|
17641
|
+
replicas: z26.array(nexusCloudReplicaSchema).default([]),
|
|
17642
|
+
devices: nexusCloudDeviceCountsSchema.optional(),
|
|
17643
|
+
replicaCount: z26.number().int().nonnegative().optional(),
|
|
17644
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17645
|
+
lastPresenceAt: isoTime.nullable().optional(),
|
|
17646
|
+
/** This project's replica list was cut at 50 (T12858). */
|
|
17647
|
+
replicasTruncated: z26.boolean().default(false)
|
|
17648
|
+
});
|
|
17649
|
+
nexusCloudProjectPageSchema = z26.object({
|
|
17650
|
+
projects: z26.array(nexusCloudProjectListItemSchema),
|
|
17651
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17652
|
+
/** Anything in the page was cut (the project list or a replica list). */
|
|
17653
|
+
truncated: z26.boolean().default(false),
|
|
17654
|
+
/** The project list itself was cut at 1000 (T12858). */
|
|
17655
|
+
projectsTruncated: z26.boolean().default(false)
|
|
17656
|
+
});
|
|
17657
|
+
nexusCloudProjectDetailSchema = z26.object({
|
|
17658
|
+
project: z26.object({ ...projectFields, deletedAt: isoTime.nullable().optional() }),
|
|
17659
|
+
role: z26.string(),
|
|
17660
|
+
canTrash: z26.boolean().optional(),
|
|
17661
|
+
openConflicts: z26.number().int().nonnegative(),
|
|
17662
|
+
/** At most 50, oldest attachment first. */
|
|
17663
|
+
replicas: z26.array(nexusCloudReplicaSchema),
|
|
17664
|
+
devices: nexusCloudDeviceCountsSchema,
|
|
17665
|
+
replicaCount: z26.number().int().nonnegative().optional(),
|
|
17666
|
+
lastSyncAt: isoTime.nullable().optional(),
|
|
17667
|
+
/** `replicas` was cut at 50. */
|
|
17668
|
+
truncated: z26.boolean().default(false),
|
|
17669
|
+
stream: z26.object({
|
|
17670
|
+
streamId: z26.string(),
|
|
17671
|
+
headSeq: z26.number().int().nonnegative(),
|
|
17672
|
+
headCheckpointId: z26.string().nullable()
|
|
17673
|
+
}).nullable()
|
|
17674
|
+
});
|
|
17675
|
+
nexusCloudReplicaPageSchema = z26.object({
|
|
17676
|
+
replicas: z26.array(nexusCloudReplicaSchema),
|
|
17677
|
+
devices: nexusCloudDeviceCountsSchema.optional(),
|
|
17678
|
+
nextCursor: z26.string().max(512).nullable().default(null),
|
|
17679
|
+
truncated: z26.boolean().default(false)
|
|
17680
|
+
});
|
|
17681
|
+
NEXUS_STATUS_CHECK_IDS = [
|
|
17682
|
+
"credential.valid",
|
|
17683
|
+
"device.registered",
|
|
17684
|
+
"device.active",
|
|
17685
|
+
"device.certified",
|
|
17686
|
+
"project.registered",
|
|
17687
|
+
"project.writable",
|
|
17688
|
+
"replica.attached",
|
|
17689
|
+
"presence.fresh",
|
|
17690
|
+
"replica.synced",
|
|
17691
|
+
"conflicts.none"
|
|
17692
|
+
];
|
|
17693
|
+
NEXUS_STATUS_VERDICTS = ["ok", "attention", "not-linked", "not-registered"];
|
|
17694
|
+
CLOUD_STATUS_VERDICTS = [...NEXUS_STATUS_VERDICTS, "not-signed-in"];
|
|
17695
|
+
knownCheckId = z26.enum(NEXUS_STATUS_CHECK_IDS);
|
|
17696
|
+
nexusCloudStatusCheckSchema = z26.object({
|
|
17697
|
+
id: z26.enum(NEXUS_STATUS_CHECK_IDS),
|
|
17698
|
+
ok: z26.boolean(),
|
|
17699
|
+
required: z26.boolean(),
|
|
17700
|
+
detail: z26.string()
|
|
17701
|
+
});
|
|
17702
|
+
nexusCloudStatusSchema = z26.object({
|
|
17703
|
+
serverTime: isoTime.optional(),
|
|
17704
|
+
apiVersion: z26.string().optional(),
|
|
17705
|
+
user: nexusCloudUserSchema,
|
|
17706
|
+
credential: nexusCloudCredentialSchema,
|
|
17707
|
+
device: nexusCloudDeviceSchema.nullable(),
|
|
17708
|
+
project: z26.object({
|
|
17709
|
+
projectId: z26.string(),
|
|
17710
|
+
registered: z26.boolean(),
|
|
17711
|
+
organizationId: z26.string().nullable(),
|
|
17712
|
+
organizationName: z26.string().nullable(),
|
|
17713
|
+
role: z26.string().nullable()
|
|
17714
|
+
}).nullable(),
|
|
17715
|
+
replica: z26.object({
|
|
17716
|
+
replicaId: z26.string(),
|
|
17717
|
+
attached: z26.boolean(),
|
|
17718
|
+
attachedElsewhere: z26.boolean(),
|
|
17719
|
+
attachedAt: isoTime.nullable(),
|
|
17720
|
+
lastSyncAt: isoTime.nullable(),
|
|
17721
|
+
presenceAt: isoTime.nullable(),
|
|
17722
|
+
lastReplicaSeq: z26.number().int().nonnegative().nullable().optional()
|
|
17723
|
+
}).nullable(),
|
|
17724
|
+
stream: z26.object({
|
|
17725
|
+
streamId: z26.string(),
|
|
17726
|
+
headSeq: z26.number().int().nonnegative(),
|
|
17727
|
+
headCheckpointId: z26.string().nullable(),
|
|
17728
|
+
openConflicts: z26.number().int().nonnegative(),
|
|
17729
|
+
devices: nexusCloudDeviceCountsSchema
|
|
17730
|
+
}).nullable(),
|
|
17731
|
+
/** Check ids added by a newer server are dropped, never a parse failure. */
|
|
17732
|
+
checks: z26.array(nexusCloudStatusCheckSchema.extend({ id: z26.string() })).transform(
|
|
17733
|
+
(list) => list.flatMap((c) => {
|
|
17734
|
+
const id = knownCheckId.safeParse(c.id);
|
|
17735
|
+
return id.success ? [{ ...c, id: id.data }] : [];
|
|
17736
|
+
})
|
|
17737
|
+
),
|
|
17738
|
+
/** A verdict added by a newer server reads as `attention`: never `ok` by accident. */
|
|
17739
|
+
verdict: z26.enum(NEXUS_STATUS_VERDICTS).catch("attention")
|
|
17740
|
+
});
|
|
17741
|
+
}
|
|
17742
|
+
});
|
|
17743
|
+
|
|
17539
17744
|
// packages/contracts/src/task-id.ts
|
|
17540
17745
|
var init_task_id = __esm({
|
|
17541
17746
|
"packages/contracts/src/task-id.ts"() {
|
|
@@ -17620,6 +17825,7 @@ var init_src = __esm({
|
|
|
17620
17825
|
init_decide();
|
|
17621
17826
|
init_decide_sites();
|
|
17622
17827
|
init_nexus_account();
|
|
17828
|
+
init_nexus_cloud();
|
|
17623
17829
|
init_task_id();
|
|
17624
17830
|
}
|
|
17625
17831
|
});
|
|
@@ -18059,6 +18265,19 @@ var init_error_catalog = __esm({
|
|
|
18059
18265
|
`Bind a session: run 'cleo session start --scope global --name "<name>"', 'cleo session resume <id>', or set CLEO_SESSION_ID=<id>.`
|
|
18060
18266
|
)
|
|
18061
18267
|
],
|
|
18268
|
+
[
|
|
18269
|
+
26 /* TASK_RENAMED */,
|
|
18270
|
+
def(
|
|
18271
|
+
26 /* TASK_RENAMED */,
|
|
18272
|
+
"TASK_RENAMED",
|
|
18273
|
+
"CONFLICT",
|
|
18274
|
+
"Task was re-numbered by sync",
|
|
18275
|
+
409,
|
|
18276
|
+
true,
|
|
18277
|
+
"E_TASK_RENAMED",
|
|
18278
|
+
"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."
|
|
18279
|
+
)
|
|
18280
|
+
],
|
|
18062
18281
|
[
|
|
18063
18282
|
25 /* WORKTREE_LOCKED */,
|
|
18064
18283
|
def(
|
|
@@ -20006,10 +20225,10 @@ var init_table2 = __esm({
|
|
|
20006
20225
|
[IsDrizzleTable] = true;
|
|
20007
20226
|
/** @internal */
|
|
20008
20227
|
[ExtraConfigBuilder] = void 0;
|
|
20009
|
-
constructor(name15, schema,
|
|
20228
|
+
constructor(name15, schema, baseName2) {
|
|
20010
20229
|
this[TableName] = this[OriginalName] = name15;
|
|
20011
20230
|
this[TableSchema] = schema;
|
|
20012
|
-
this[BaseName] =
|
|
20231
|
+
this[BaseName] = baseName2;
|
|
20013
20232
|
}
|
|
20014
20233
|
};
|
|
20015
20234
|
}
|
|
@@ -21939,9 +22158,9 @@ var init_casing = __esm({
|
|
|
21939
22158
|
});
|
|
21940
22159
|
|
|
21941
22160
|
// 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
|
|
21942
|
-
function sqliteTableBase(name15, columns, extraConfig, schema, casing,
|
|
22161
|
+
function sqliteTableBase(name15, columns, extraConfig, schema, casing, baseName2 = name15) {
|
|
21943
22162
|
const casingFn = getCasingFn(casing);
|
|
21944
|
-
const rawTable = new SQLiteTable(name15, schema,
|
|
22163
|
+
const rawTable = new SQLiteTable(name15, schema, baseName2);
|
|
21945
22164
|
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
21946
22165
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name16, colBuilderBase]) => {
|
|
21947
22166
|
const colBuilder = colBuilderBase;
|
|
@@ -25707,6 +25926,10 @@ function decisionFor(dbPath) {
|
|
|
25707
25926
|
if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
|
|
25708
25927
|
return decisions.get(key) ?? null;
|
|
25709
25928
|
}
|
|
25929
|
+
function schemaWritesAllowed(nativeDb) {
|
|
25930
|
+
const dbPath = nativeDb.location();
|
|
25931
|
+
return !dbPath || decisionFor(dbPath) === null;
|
|
25932
|
+
}
|
|
25710
25933
|
function isWorktreeBuildSchemaError(error48) {
|
|
25711
25934
|
return error48 instanceof Error && error48.message.includes(E_WORKTREE_BUILD_SCHEMA);
|
|
25712
25935
|
}
|
|
@@ -26745,7 +26968,10 @@ var init_row_identity_registry = __esm({
|
|
|
26745
26968
|
key: ["id"],
|
|
26746
26969
|
birth: "recorded_at",
|
|
26747
26970
|
content: ["ac_id", "previous_text", "reason"],
|
|
26748
|
-
|
|
26971
|
+
// v2 (T12802): no @refFp: the criterion's fingerprint is unknowable when
|
|
26972
|
+
// it was gone before this row got its identity, so it made the value
|
|
26973
|
+
// depend on fill timing. ac_id is always known.
|
|
26974
|
+
birthFacts: ["ac_id", "previous_text", "reason"],
|
|
26749
26975
|
storedRefUids: [{ column: "ac_uid", from: "ac_id", table: ACS }],
|
|
26750
26976
|
task: "T12341"
|
|
26751
26977
|
},
|
|
@@ -26754,7 +26980,10 @@ var init_row_identity_registry = __esm({
|
|
|
26754
26980
|
kind: "minted",
|
|
26755
26981
|
key: ["id"],
|
|
26756
26982
|
birth: "created_at",
|
|
26757
|
-
|
|
26983
|
+
// v2 (T12802): ac_id in place of @refFp:ac_uid and ac_text_hash. Both
|
|
26984
|
+
// were filled from the criterion, so a backfilled binding whose
|
|
26985
|
+
// criterion was already gone got a different value (see AC history).
|
|
26986
|
+
birthFacts: ["evidence_atom_id", "binding_type", "ac_id"],
|
|
26758
26987
|
storedRefUids: [
|
|
26759
26988
|
{ column: "ac_uid", from: "ac_id", table: ACS },
|
|
26760
26989
|
{ column: "ac_text_hash", from: "ac_id", table: ACS, source: "text_hash" }
|
|
@@ -26796,7 +27025,9 @@ var init_row_identity_registry = __esm({
|
|
|
26796
27025
|
// The uid IS the primary key: display-id-alias.ts computes it on write.
|
|
26797
27026
|
table: "tasks_display_id_aliases",
|
|
26798
27027
|
kind: "natural",
|
|
26799
|
-
|
|
27028
|
+
// T12800: the reason is part of the key (collision-remint and
|
|
27029
|
+
// remint-assigned of one id and row are distinct facts).
|
|
27030
|
+
key: ["entity_table", "display_id", "entity_uid", "reason"],
|
|
26800
27031
|
task: "T12341"
|
|
26801
27032
|
},
|
|
26802
27033
|
{
|
|
@@ -27378,6 +27609,20 @@ function installRowUidTriggers(db, scope) {
|
|
|
27378
27609
|
);
|
|
27379
27610
|
}
|
|
27380
27611
|
}
|
|
27612
|
+
function v1ReleaseBirthFp(db, table, row) {
|
|
27613
|
+
const col = (c) => row[c] ?? null;
|
|
27614
|
+
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")] : [];
|
|
27615
|
+
if (facts.length === 0) return null;
|
|
27616
|
+
const acUid = col("ac_uid");
|
|
27617
|
+
let ref = "ref:none";
|
|
27618
|
+
if (acUid !== null) {
|
|
27619
|
+
const ac = db.prepare("SELECT birth_fp AS fp FROM main.tasks_task_acceptance_criteria WHERE uid = ?").get(acUid);
|
|
27620
|
+
ref = ac === void 0 ? "ref:missing" : ac.fp;
|
|
27621
|
+
if (ref === null) return null;
|
|
27622
|
+
}
|
|
27623
|
+
const spec = rowIdentitySpec("project", table);
|
|
27624
|
+
return birthFingerprint(table, spec?.birth ? col(spec.birth) : null, [...facts, ref]);
|
|
27625
|
+
}
|
|
27381
27626
|
function hasObject(db, type, name15) {
|
|
27382
27627
|
return db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = ? AND name = ?").get(type, name15) !== void 0;
|
|
27383
27628
|
}
|
|
@@ -27461,24 +27706,41 @@ function preReleaseBirthFp(db, table, row) {
|
|
|
27461
27706
|
function resetStaleIdentity(db, scope, writers) {
|
|
27462
27707
|
if (scope !== "project" || !hasTable(db, ROW_IDENTITY_META_TABLE)) return "none";
|
|
27463
27708
|
if (readMeta(db, ROW_IDENTITY_RECIPE_KEY) === ROW_IDENTITY_RECIPE) return "none";
|
|
27464
|
-
const minted = ROW_IDENTITY.project.filter(
|
|
27465
|
-
(spec) =>
|
|
27709
|
+
const minted = fingerprintOrder("project", ROW_IDENTITY.project).filter(
|
|
27710
|
+
(spec) => hasTable(db, spec.table) && columnsOf(db, spec.table).has(BIRTH_FP_COLUMN)
|
|
27466
27711
|
);
|
|
27467
27712
|
const stale = [];
|
|
27713
|
+
const cleared = /* @__PURE__ */ new Map();
|
|
27714
|
+
const mark = (table, column, value) => {
|
|
27715
|
+
if (value === null || value === void 0) return;
|
|
27716
|
+
const key = `${table}.${column}`;
|
|
27717
|
+
const set2 = cleared.get(key) ?? /* @__PURE__ */ new Set();
|
|
27718
|
+
set2.add(String(value));
|
|
27719
|
+
cleared.set(key, set2);
|
|
27720
|
+
};
|
|
27468
27721
|
for (const spec of minted) {
|
|
27722
|
+
const deps = (spec.birthFacts ?? []).map((fact) => fingerprintRef("project", spec, fact)).filter((d) => d !== null);
|
|
27723
|
+
const keyColumn = targetKey("project", spec.table);
|
|
27469
27724
|
const rows = db.prepare(
|
|
27470
27725
|
`SELECT rowid AS _rowid, * FROM main.${q(spec.table)} WHERE ${q(BIRTH_FP_COLUMN)} IS NOT NULL`
|
|
27471
27726
|
).all();
|
|
27472
27727
|
for (const row of rows) {
|
|
27473
|
-
|
|
27728
|
+
const derivedFromStale = deps.some(
|
|
27729
|
+
(d) => cleared.get(`${d.table}.${d.key}`)?.has(String(row[d.column] ?? ""))
|
|
27730
|
+
);
|
|
27731
|
+
if (derivedFromStale || row[BIRTH_FP_COLUMN] === preReleaseBirthFp(db, spec.table, row) || row[BIRTH_FP_COLUMN] === v1ReleaseBirthFp(db, spec.table, row)) {
|
|
27474
27732
|
stale.push({ table: spec.table, rowid: row._rowid });
|
|
27733
|
+
mark(spec.table, keyColumn, row[keyColumn]);
|
|
27734
|
+
mark(spec.table, UID_COLUMN, row[UID_COLUMN]);
|
|
27475
27735
|
}
|
|
27476
27736
|
}
|
|
27477
27737
|
}
|
|
27478
|
-
|
|
27738
|
+
const graveyardRows = scope === "project" && hasTable(db, AC_UID_GRAVEYARD) ? db.prepare(`SELECT count(*) AS n FROM main.${AC_UID_GRAVEYARD}`).get().n : 0;
|
|
27739
|
+
if (stale.length === 0 && graveyardRows === 0) return "none";
|
|
27479
27740
|
if (readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0) return "refused";
|
|
27480
27741
|
db.exec("SAVEPOINT row_identity_reset");
|
|
27481
27742
|
try {
|
|
27743
|
+
if (graveyardRows > 0) writers.clearAcUidGraveyardNative(db);
|
|
27482
27744
|
for (const { table, rowid } of stale) {
|
|
27483
27745
|
writers.clearBirthFpNative(db, table, rowid);
|
|
27484
27746
|
}
|
|
@@ -27494,6 +27756,106 @@ function writeRecipeMarker(db, writers = requireWriters()) {
|
|
|
27494
27756
|
if (!hasTable(db, ROW_IDENTITY_META_TABLE)) return;
|
|
27495
27757
|
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_RECIPE);
|
|
27496
27758
|
}
|
|
27759
|
+
function rowIdentityShared(db) {
|
|
27760
|
+
return readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0;
|
|
27761
|
+
}
|
|
27762
|
+
function healRowIdentitySchema(db, scope, writers = registeredWriters) {
|
|
27763
|
+
const log15 = getLogger("row-identity");
|
|
27764
|
+
if (ROW_IDENTITY[scope].length === 0) {
|
|
27765
|
+
return [];
|
|
27766
|
+
}
|
|
27767
|
+
if (!schemaWritesAllowed(db)) {
|
|
27768
|
+
log15.debug({ scope }, "row identity schema heal skipped: schema writes refused for this build");
|
|
27769
|
+
return [];
|
|
27770
|
+
}
|
|
27771
|
+
try {
|
|
27772
|
+
db.exec("SAVEPOINT row_identity_heal");
|
|
27773
|
+
try {
|
|
27774
|
+
const healed = [
|
|
27775
|
+
...scope === "project" ? ensureIdentityTables(db) : [],
|
|
27776
|
+
...ensureRowIdentitySchema(db, scope)
|
|
27777
|
+
];
|
|
27778
|
+
if (healed.length > 0) recordHealReceipt(db, scope, healed, writers);
|
|
27779
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27780
|
+
if (healed.length > 0)
|
|
27781
|
+
log15.info({ scope, healed: healed.length }, "row identity schema healed");
|
|
27782
|
+
return healed;
|
|
27783
|
+
} catch (error48) {
|
|
27784
|
+
db.exec("ROLLBACK TO SAVEPOINT row_identity_heal");
|
|
27785
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27786
|
+
throw error48;
|
|
27787
|
+
}
|
|
27788
|
+
} catch (error48) {
|
|
27789
|
+
log15.error({ scope, error: error48 }, "row identity schema heal failed");
|
|
27790
|
+
return [];
|
|
27791
|
+
}
|
|
27792
|
+
}
|
|
27793
|
+
function recordHealReceipt(db, scope, healed, writers) {
|
|
27794
|
+
const table = HEAL_RECEIPT_TABLE[scope];
|
|
27795
|
+
const log15 = getLogger("row-identity");
|
|
27796
|
+
if (table === null || !hasTable(db, table) || !writers) {
|
|
27797
|
+
log15.warn({ scope, healed: healed.length }, "row identity schema healed; no receipt table");
|
|
27798
|
+
return;
|
|
27799
|
+
}
|
|
27800
|
+
const objects = healed.map((stmt) => {
|
|
27801
|
+
const col = /ALTER TABLE main\.("?)(\w+)\1 ADD COLUMN ("?)(\w+)\3/.exec(stmt);
|
|
27802
|
+
if (col) return `${col[2]}.${col[4]}`;
|
|
27803
|
+
const obj = /(TABLE|INDEX|TRIGGER) IF NOT EXISTS main\.("?)(\w+)\2/.exec(stmt);
|
|
27804
|
+
return obj ? `${obj[1].toLowerCase()} ${obj[3]}` : stmt.slice(0, 60);
|
|
27805
|
+
});
|
|
27806
|
+
const receipt2 = {
|
|
27807
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27808
|
+
scope,
|
|
27809
|
+
statements: healed.length,
|
|
27810
|
+
objects
|
|
27811
|
+
};
|
|
27812
|
+
const history = [...readRowIdentityHealHistory(db), receipt2].slice(-HEAL_RECEIPTS_KEPT);
|
|
27813
|
+
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_HEAL_KEY, JSON.stringify(history));
|
|
27814
|
+
}
|
|
27815
|
+
function readRowIdentityHealHistory(db) {
|
|
27816
|
+
const raw = readMeta(db, ROW_IDENTITY_HEAL_KEY);
|
|
27817
|
+
if (raw === void 0) return [];
|
|
27818
|
+
try {
|
|
27819
|
+
const parsed = JSON.parse(raw);
|
|
27820
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
27821
|
+
} catch {
|
|
27822
|
+
return [];
|
|
27823
|
+
}
|
|
27824
|
+
}
|
|
27825
|
+
function missingRowIdentitySchema(db) {
|
|
27826
|
+
if (!hasTable(db, "tasks_task_acceptance_criteria")) return [];
|
|
27827
|
+
const missing = [];
|
|
27828
|
+
for (const table of Object.keys(IDENTITY_TABLE_DDL)) {
|
|
27829
|
+
if (!hasTable(db, table)) missing.push(`table ${table}`);
|
|
27830
|
+
}
|
|
27831
|
+
for (const [table, column] of [
|
|
27832
|
+
["tasks_display_id_aliases", "displaced_hlc"],
|
|
27833
|
+
["tasks_display_id_aliases", "entity_birth_fp"],
|
|
27834
|
+
[AC_UID_GRAVEYARD, "birth_fp"]
|
|
27835
|
+
]) {
|
|
27836
|
+
if (hasTable(db, table) && !columnsOf(db, table).has(column)) {
|
|
27837
|
+
missing.push(`column ${table}.${column}`);
|
|
27838
|
+
}
|
|
27839
|
+
}
|
|
27840
|
+
if (!hasObject(db, "trigger", "trg_tasks_ac_uid_graveyard")) {
|
|
27841
|
+
missing.push("trigger trg_tasks_ac_uid_graveyard");
|
|
27842
|
+
}
|
|
27843
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
27844
|
+
if (!hasTable(db, spec.table)) continue;
|
|
27845
|
+
const cols = columnsOf(db, spec.table);
|
|
27846
|
+
for (const column of rowIdentityColumns("project", spec.table)) {
|
|
27847
|
+
if (!cols.has(column)) missing.push(`column ${spec.table}.${column}`);
|
|
27848
|
+
}
|
|
27849
|
+
if (!uidIsPrimaryKey(db, spec.table) && !hasObject(db, "index", `uq_${spec.table}_uid`)) {
|
|
27850
|
+
missing.push(`index uq_${spec.table}_uid`);
|
|
27851
|
+
}
|
|
27852
|
+
for (const ref of spec.storedRefUids ?? []) {
|
|
27853
|
+
const index2 = `idx_${spec.table}_${ref.column}`;
|
|
27854
|
+
if (!hasObject(db, "index", index2)) missing.push(`index ${index2}`);
|
|
27855
|
+
}
|
|
27856
|
+
}
|
|
27857
|
+
return missing;
|
|
27858
|
+
}
|
|
27497
27859
|
function prepareRowIdentity(db, scope, options = {}) {
|
|
27498
27860
|
if (ROW_IDENTITY[scope].length === 0) return null;
|
|
27499
27861
|
if (!rowUidFillEnabled()) return null;
|
|
@@ -27532,7 +27894,7 @@ function prepareRowIdentity(db, scope, options = {}) {
|
|
|
27532
27894
|
return null;
|
|
27533
27895
|
}
|
|
27534
27896
|
}
|
|
27535
|
-
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;
|
|
27897
|
+
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;
|
|
27536
27898
|
var init_row_identity = __esm({
|
|
27537
27899
|
"packages/core/src/store/row-identity.ts"() {
|
|
27538
27900
|
"use strict";
|
|
@@ -27541,6 +27903,7 @@ var init_row_identity = __esm({
|
|
|
27541
27903
|
init_ac_table();
|
|
27542
27904
|
init_row_identity_flag();
|
|
27543
27905
|
init_row_identity_registry();
|
|
27906
|
+
init_worktree_build_guard();
|
|
27544
27907
|
ROW_UID_DOMAIN = "cleo/row-uid/v1";
|
|
27545
27908
|
ROW_BIRTH_DOMAIN = "cleo/row-birth/v1";
|
|
27546
27909
|
ROW_UID_SQL_FUNCTION = "cleo_row_uid";
|
|
@@ -27550,7 +27913,7 @@ var init_row_identity = __esm({
|
|
|
27550
27913
|
AC_UID_GRAVEYARD = "tasks_ac_uid_graveyard";
|
|
27551
27914
|
STORE_TIMESTAMP = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
27552
27915
|
MAX_UUID_MS = 2 ** 48 - 1;
|
|
27553
|
-
ROW_IDENTITY_RECIPE = "cleo/row-identity/
|
|
27916
|
+
ROW_IDENTITY_RECIPE = "cleo/row-identity/v2";
|
|
27554
27917
|
ROW_IDENTITY_META_TABLE = "tasks_row_identity_meta";
|
|
27555
27918
|
ROW_IDENTITY_RECIPE_KEY = "row_identity_recipe";
|
|
27556
27919
|
ROW_IDENTITY_SYNCED_KEY = "row_identity_synced";
|
|
@@ -27595,6 +27958,15 @@ BEGIN
|
|
|
27595
27958
|
INSERT INTO ${AC_UID_GRAVEYARD} (ac_id, uid, task_id, ordinal, text, birth_fp, deleted_at)
|
|
27596
27959
|
VALUES (OLD.id, OLD.uid, OLD.task_id, OLD.ordinal, OLD.text, OLD.birth_fp, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
27597
27960
|
END`;
|
|
27961
|
+
ROW_IDENTITY_HEAL_KEY = "row_identity_schema_healed";
|
|
27962
|
+
HEAL_RECEIPT_TABLE = {
|
|
27963
|
+
project: ROW_IDENTITY_META_TABLE,
|
|
27964
|
+
// The global store declares no identity table yet (ROW_IDENTITY.global is
|
|
27965
|
+
// empty, so its heal never runs); the change that declares one adds its
|
|
27966
|
+
// meta table here.
|
|
27967
|
+
global: null
|
|
27968
|
+
};
|
|
27969
|
+
HEAL_RECEIPTS_KEPT = 20;
|
|
27598
27970
|
}
|
|
27599
27971
|
});
|
|
27600
27972
|
|
|
@@ -33274,7 +33646,7 @@ var init_task_claim = __esm({
|
|
|
33274
33646
|
});
|
|
33275
33647
|
|
|
33276
33648
|
// packages/core/src/store/converters.ts
|
|
33277
|
-
import { z as
|
|
33649
|
+
import { z as z27 } from "zod";
|
|
33278
33650
|
function readStoredAcceptance(row) {
|
|
33279
33651
|
if (row.acceptanceJson === null || row.acceptanceJson === void 0) return void 0;
|
|
33280
33652
|
try {
|
|
@@ -33432,7 +33804,7 @@ var init_converters = __esm({
|
|
|
33432
33804
|
init_src();
|
|
33433
33805
|
init_parsers();
|
|
33434
33806
|
init_task_claim();
|
|
33435
|
-
storedAcceptanceSchema =
|
|
33807
|
+
storedAcceptanceSchema = z27.custom(
|
|
33436
33808
|
(value) => Array.isArray(value) && value.every((item) => acceptanceItemSchema.safeParse(item).success)
|
|
33437
33809
|
);
|
|
33438
33810
|
}
|
|
@@ -36095,7 +36467,7 @@ import {
|
|
|
36095
36467
|
} from "node:fs";
|
|
36096
36468
|
import { createRequire as createRequire5 } from "node:module";
|
|
36097
36469
|
import { basename as basename7, dirname as dirname13, join as join15 } from "node:path";
|
|
36098
|
-
import { z as
|
|
36470
|
+
import { z as z28 } from "zod";
|
|
36099
36471
|
function formatBackupTimestamp(d) {
|
|
36100
36472
|
const pad = (n, len = 2) => String(n).padStart(len, "0");
|
|
36101
36473
|
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
|
|
@@ -36232,16 +36604,16 @@ var init_backup_sidecar = __esm({
|
|
|
36232
36604
|
init_logger();
|
|
36233
36605
|
PRE_COLLAPSE_BACKUP_TYPE = "migration";
|
|
36234
36606
|
MARKER_PREFIX = "twin_collapse:";
|
|
36235
|
-
backupSidecarSchema =
|
|
36236
|
-
backupId:
|
|
36237
|
-
type:
|
|
36238
|
-
timestamp:
|
|
36239
|
-
note:
|
|
36240
|
-
files:
|
|
36241
|
-
pinned:
|
|
36242
|
-
pinnedReason:
|
|
36243
|
-
releasedAt:
|
|
36244
|
-
releasedReason:
|
|
36607
|
+
backupSidecarSchema = z28.object({
|
|
36608
|
+
backupId: z28.string().min(1),
|
|
36609
|
+
type: z28.string().min(1),
|
|
36610
|
+
timestamp: z28.string().min(1),
|
|
36611
|
+
note: z28.string().optional(),
|
|
36612
|
+
files: z28.array(z28.string()),
|
|
36613
|
+
pinned: z28.boolean().optional(),
|
|
36614
|
+
pinnedReason: z28.string().optional(),
|
|
36615
|
+
releasedAt: z28.string().optional(),
|
|
36616
|
+
releasedReason: z28.string().optional()
|
|
36245
36617
|
}).passthrough();
|
|
36246
36618
|
}
|
|
36247
36619
|
});
|
|
@@ -36413,7 +36785,7 @@ var init_pre_repair_snapshot = __esm({
|
|
|
36413
36785
|
import { createHash as createHash5 } from "node:crypto";
|
|
36414
36786
|
import { basename as basename8, dirname as dirname16 } from "node:path";
|
|
36415
36787
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
36416
|
-
import { z as
|
|
36788
|
+
import { z as z29 } from "zod";
|
|
36417
36789
|
function hasMainTable(db, name15) {
|
|
36418
36790
|
return db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = 'table' AND name = ?").get(name15) !== void 0;
|
|
36419
36791
|
}
|
|
@@ -37546,20 +37918,20 @@ var init_twin_collapse = __esm({
|
|
|
37546
37918
|
SHADOW_WRITE_REFUSED = "E_TWIN_COLLAPSE_FAILED: store is read-only until the twin collapse succeeds; run cleo doctor twin-collapse";
|
|
37547
37919
|
SHADOW_WRITE_OPS = ["INSERT", "UPDATE", "DELETE"];
|
|
37548
37920
|
STICKY_ARCHIVE_KEY = `${TWIN_COLLAPSE_ARCHIVE_PREFIX}sticky_tags`;
|
|
37549
|
-
FocusNotesShape =
|
|
37550
|
-
StickyArchiveShape =
|
|
37551
|
-
RecoveryReceiptShape =
|
|
37552
|
-
task:
|
|
37553
|
-
id:
|
|
37554
|
-
recoveredAt:
|
|
37555
|
-
snapshot:
|
|
37556
|
-
archived:
|
|
37557
|
-
focusNotesAdded:
|
|
37558
|
-
stickyArchived:
|
|
37559
|
-
stickyArchiveKey:
|
|
37560
|
-
before:
|
|
37561
|
-
after:
|
|
37562
|
-
rolledBackAt:
|
|
37921
|
+
FocusNotesShape = z29.object({ sessionNotes: z29.array(z29.unknown()) }).passthrough();
|
|
37922
|
+
StickyArchiveShape = z29.array(z29.string());
|
|
37923
|
+
RecoveryReceiptShape = z29.object({
|
|
37924
|
+
task: z29.literal("T12727"),
|
|
37925
|
+
id: z29.string(),
|
|
37926
|
+
recoveredAt: z29.string(),
|
|
37927
|
+
snapshot: z29.string().nullable(),
|
|
37928
|
+
archived: z29.array(z29.object({ key: z29.string(), archiveKey: z29.string(), sha: z29.string() })),
|
|
37929
|
+
focusNotesAdded: z29.number(),
|
|
37930
|
+
stickyArchived: z29.array(z29.string()),
|
|
37931
|
+
stickyArchiveKey: z29.string(),
|
|
37932
|
+
before: z29.object({ focusState: z29.string().nullable(), stickyArchive: z29.string().nullable() }),
|
|
37933
|
+
after: z29.object({ focusState: z29.string().nullable(), stickyArchive: z29.string().nullable() }),
|
|
37934
|
+
rolledBackAt: z29.string().nullable()
|
|
37563
37935
|
});
|
|
37564
37936
|
}
|
|
37565
37937
|
});
|
|
@@ -41141,12 +41513,12 @@ var init_safety_data_accessor = __esm({
|
|
|
41141
41513
|
this.getSafetyOptions()
|
|
41142
41514
|
);
|
|
41143
41515
|
}
|
|
41144
|
-
async insertNewTask(task) {
|
|
41516
|
+
async insertNewTask(task, identity) {
|
|
41145
41517
|
this.logVerbose(`Inserting new task ${task.id}`);
|
|
41146
41518
|
await safeSingleTaskWrite(
|
|
41147
41519
|
this.inner,
|
|
41148
41520
|
task.id,
|
|
41149
|
-
() => this.inner.insertNewTask(task),
|
|
41521
|
+
() => this.inner.insertNewTask(task, identity),
|
|
41150
41522
|
this.cwd,
|
|
41151
41523
|
this.getSafetyOptions()
|
|
41152
41524
|
);
|
|
@@ -41194,6 +41566,9 @@ var init_safety_data_accessor = __esm({
|
|
|
41194
41566
|
return this.inner.findOrphanAcBindings();
|
|
41195
41567
|
}
|
|
41196
41568
|
// ---- Metadata (pass-through to inner) ----
|
|
41569
|
+
async getTaskIdentities(taskIds) {
|
|
41570
|
+
return await this.inner.getTaskIdentities?.(taskIds) ?? [];
|
|
41571
|
+
}
|
|
41197
41572
|
async getMetaValue(key) {
|
|
41198
41573
|
return this.inner.getMetaValue(key);
|
|
41199
41574
|
}
|
|
@@ -41567,13 +41942,147 @@ var init_cross_db_cleanup = __esm({
|
|
|
41567
41942
|
}
|
|
41568
41943
|
});
|
|
41569
41944
|
|
|
41945
|
+
// packages/core/src/store/dependency-cycles.ts
|
|
41946
|
+
function formatDependencyCycle(cycle) {
|
|
41947
|
+
return cycle.join(" \u2192 ");
|
|
41948
|
+
}
|
|
41949
|
+
function buildAdjacency(edges) {
|
|
41950
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
41951
|
+
for (const { taskId, dependsOn } of edges) {
|
|
41952
|
+
const next = adjacency.get(taskId);
|
|
41953
|
+
if (next) next.push(dependsOn);
|
|
41954
|
+
else adjacency.set(taskId, [dependsOn]);
|
|
41955
|
+
}
|
|
41956
|
+
for (const next of adjacency.values()) next.sort();
|
|
41957
|
+
return adjacency;
|
|
41958
|
+
}
|
|
41959
|
+
function shortestPath(adjacency, from, to) {
|
|
41960
|
+
if (from === to) return [from];
|
|
41961
|
+
const previous = /* @__PURE__ */ new Map([[from, from]]);
|
|
41962
|
+
const queue = [from];
|
|
41963
|
+
for (let head = 0; head < queue.length; head++) {
|
|
41964
|
+
const id = queue[head];
|
|
41965
|
+
for (const next of adjacency.get(id) ?? []) {
|
|
41966
|
+
if (previous.has(next)) continue;
|
|
41967
|
+
previous.set(next, id);
|
|
41968
|
+
if (next === to) {
|
|
41969
|
+
const path = [to];
|
|
41970
|
+
let cursor = id;
|
|
41971
|
+
while (cursor !== from) {
|
|
41972
|
+
path.push(cursor);
|
|
41973
|
+
cursor = previous.get(cursor);
|
|
41974
|
+
}
|
|
41975
|
+
path.push(from);
|
|
41976
|
+
return path.reverse();
|
|
41977
|
+
}
|
|
41978
|
+
queue.push(next);
|
|
41979
|
+
}
|
|
41980
|
+
}
|
|
41981
|
+
return null;
|
|
41982
|
+
}
|
|
41983
|
+
function findClosedCycle(existing, edge) {
|
|
41984
|
+
if (edge.taskId === edge.dependsOn) return [edge.taskId, edge.taskId];
|
|
41985
|
+
const path = shortestPath(buildAdjacency(existing), edge.dependsOn, edge.taskId);
|
|
41986
|
+
return path ? [edge.taskId, ...path] : null;
|
|
41987
|
+
}
|
|
41988
|
+
function dependencyCycleError(edge, cycle) {
|
|
41989
|
+
const self = edge.taskId === edge.dependsOn;
|
|
41990
|
+
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)}`;
|
|
41991
|
+
const closing = cycle.length >= 3 ? cycle[cycle.length - 2] : void 0;
|
|
41992
|
+
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}`;
|
|
41993
|
+
return new CleoError(14 /* CIRCULAR_REFERENCE */, message, {
|
|
41994
|
+
fix,
|
|
41995
|
+
details: {
|
|
41996
|
+
field: "depends",
|
|
41997
|
+
actual: edge.dependsOn,
|
|
41998
|
+
taskId: edge.taskId,
|
|
41999
|
+
cycle: [...cycle]
|
|
42000
|
+
}
|
|
42001
|
+
});
|
|
42002
|
+
}
|
|
42003
|
+
function isDependencyCycleAbort(err) {
|
|
42004
|
+
for (let e = err, depth = 0; e instanceof Error && depth < 8; depth++) {
|
|
42005
|
+
if (e.message.includes(DEPENDENCY_CYCLE_CODE)) return true;
|
|
42006
|
+
e = e.cause;
|
|
42007
|
+
}
|
|
42008
|
+
return false;
|
|
42009
|
+
}
|
|
42010
|
+
function readDependencyEdges(db) {
|
|
42011
|
+
return db.select({
|
|
42012
|
+
taskId: tasksTaskDependencies.taskId,
|
|
42013
|
+
dependsOn: tasksTaskDependencies.dependsOn
|
|
42014
|
+
}).from(tasksTaskDependencies).all();
|
|
42015
|
+
}
|
|
42016
|
+
function rethrowDependencyCycle(db, err, attempted) {
|
|
42017
|
+
if (!isDependencyCycleAbort(err)) throw err;
|
|
42018
|
+
const edges = readDependencyEdges(db);
|
|
42019
|
+
for (const edge of attempted) {
|
|
42020
|
+
const cycle = findClosedCycle(edges, edge);
|
|
42021
|
+
if (cycle) throw dependencyCycleError(edge, cycle);
|
|
42022
|
+
edges.push(edge);
|
|
42023
|
+
}
|
|
42024
|
+
throw err;
|
|
42025
|
+
}
|
|
42026
|
+
var DEPENDENCY_CYCLE_CODE;
|
|
42027
|
+
var init_dependency_cycles = __esm({
|
|
42028
|
+
"packages/core/src/store/dependency-cycles.ts"() {
|
|
42029
|
+
"use strict";
|
|
42030
|
+
init_src();
|
|
42031
|
+
init_errors2();
|
|
42032
|
+
init_tasks_schema();
|
|
42033
|
+
DEPENDENCY_CYCLE_CODE = "E_TASK_DEPENDENCY_CYCLE";
|
|
42034
|
+
}
|
|
42035
|
+
});
|
|
42036
|
+
|
|
41570
42037
|
// packages/core/src/store/db-helpers.ts
|
|
41571
42038
|
import { and as and5, eq as eq7, inArray as inArray3, sql as sql27 } from "drizzle-orm";
|
|
41572
42039
|
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
41573
42040
|
await writeTaskRow(db, row, archiveFields, allowOrphanParent, false);
|
|
41574
42041
|
}
|
|
41575
|
-
async function insertNewTask(db, row) {
|
|
41576
|
-
await writeTaskRow(
|
|
42042
|
+
async function insertNewTask(db, row, identity = { origin: "new" }) {
|
|
42043
|
+
await writeTaskRow(
|
|
42044
|
+
db,
|
|
42045
|
+
{ ...row, ...await importedIdentity(db, identity, row) },
|
|
42046
|
+
void 0,
|
|
42047
|
+
false,
|
|
42048
|
+
true
|
|
42049
|
+
);
|
|
42050
|
+
}
|
|
42051
|
+
async function tableExists2(db, table) {
|
|
42052
|
+
const rows = await db.all(
|
|
42053
|
+
sql27`SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ${table}`
|
|
42054
|
+
);
|
|
42055
|
+
return rows.length > 0;
|
|
42056
|
+
}
|
|
42057
|
+
async function importedIdentity(db, identity, row) {
|
|
42058
|
+
if (identity.origin === "new" || !rowUidFillEnabled()) return {};
|
|
42059
|
+
const fp = identity.birthFp ?? null;
|
|
42060
|
+
const carried2 = identity.uid ?? null;
|
|
42061
|
+
if (carried2 !== null && fp !== null) {
|
|
42062
|
+
let uid = carried2;
|
|
42063
|
+
if (await tableExists2(db, "tasks_uid_aliases")) {
|
|
42064
|
+
for (let hop = 0; hop < 32; hop++) {
|
|
42065
|
+
const found = await db.all(
|
|
42066
|
+
sql27`SELECT new_uid AS uid FROM tasks_uid_aliases
|
|
42067
|
+
WHERE entity_table = 'tasks_tasks' AND old_uid = ${uid} AND old_birth_fp = ${fp}`
|
|
42068
|
+
);
|
|
42069
|
+
const next = found[0];
|
|
42070
|
+
if (!next) break;
|
|
42071
|
+
uid = next.uid;
|
|
42072
|
+
}
|
|
42073
|
+
}
|
|
42074
|
+
const [holder] = await db.select({ id: tasksTasks.id, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(eq7(tasksTasks.uid, uid)).limit(1).all();
|
|
42075
|
+
if (holder && holder.birthFp === fp) throw new SameRowPresentError(row.id, holder.id);
|
|
42076
|
+
if (await tableExists2(db, "tasks_identity_quarantine")) {
|
|
42077
|
+
const [held] = await db.all(
|
|
42078
|
+
sql27`SELECT 1 AS x FROM tasks_identity_quarantine
|
|
42079
|
+
WHERE entity_table = 'tasks_tasks' AND uid = ${uid} AND birth_fp = ${fp}`
|
|
42080
|
+
);
|
|
42081
|
+
if (held) throw new SameRowPresentError(row.id, "held");
|
|
42082
|
+
}
|
|
42083
|
+
if (!holder) return { uid, birthFp: fp };
|
|
42084
|
+
}
|
|
42085
|
+
return { uid: null, birthFp: null };
|
|
41577
42086
|
}
|
|
41578
42087
|
async function writeTaskRow(db, row, archiveFields, allowOrphanParent, insertOnly) {
|
|
41579
42088
|
if (row.parentId && row.parentId === row.id) {
|
|
@@ -41724,7 +42233,11 @@ async function batchUpdateDependencies(db, tasks2, validIds) {
|
|
|
41724
42233
|
for (const depId of want) if (!have.has(depId)) added.push({ taskId, dependsOn: depId });
|
|
41725
42234
|
}
|
|
41726
42235
|
if (added.length > 0) {
|
|
41727
|
-
|
|
42236
|
+
try {
|
|
42237
|
+
await db.insert(tasksTaskDependencies).values(added).onConflictDoNothing().run();
|
|
42238
|
+
} catch (err) {
|
|
42239
|
+
rethrowDependencyCycle(db, err, added);
|
|
42240
|
+
}
|
|
41728
42241
|
}
|
|
41729
42242
|
}
|
|
41730
42243
|
async function loadDependenciesForTasks(db, tasks2, _validationIds) {
|
|
@@ -41769,15 +42282,29 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
41769
42282
|
task.relates = relations && relations.length > 0 ? relations : [];
|
|
41770
42283
|
}
|
|
41771
42284
|
}
|
|
41772
|
-
var log6;
|
|
42285
|
+
var log6, SameRowPresentError;
|
|
41773
42286
|
var init_db_helpers = __esm({
|
|
41774
42287
|
"packages/core/src/store/db-helpers.ts"() {
|
|
41775
42288
|
"use strict";
|
|
41776
42289
|
init_src();
|
|
41777
42290
|
init_errors2();
|
|
41778
42291
|
init_logger();
|
|
42292
|
+
init_dependency_cycles();
|
|
42293
|
+
init_row_identity_flag();
|
|
41779
42294
|
init_tasks_schema();
|
|
41780
42295
|
log6 = getLogger("db-helpers");
|
|
42296
|
+
SameRowPresentError = class extends CleoError {
|
|
42297
|
+
/** Where the row already is: its display id, or `held` when quarantined. */
|
|
42298
|
+
presentAs;
|
|
42299
|
+
constructor(taskId, presentAs) {
|
|
42300
|
+
super(
|
|
42301
|
+
22 /* ID_COLLISION */,
|
|
42302
|
+
`Task ${taskId} is already in this store (${presentAs === "held" ? "held for sync" : `as ${presentAs}`}): same uid and birth fingerprint; not written again`,
|
|
42303
|
+
{ details: { field: "taskId", actual: taskId, expected: presentAs } }
|
|
42304
|
+
);
|
|
42305
|
+
this.presentAs = presentAs;
|
|
42306
|
+
}
|
|
42307
|
+
};
|
|
41781
42308
|
}
|
|
41782
42309
|
});
|
|
41783
42310
|
|
|
@@ -41862,46 +42389,133 @@ function readProcessEntry(pid) {
|
|
|
41862
42389
|
return null;
|
|
41863
42390
|
}
|
|
41864
42391
|
}
|
|
41865
|
-
function
|
|
42392
|
+
function readProcessArgs(pid) {
|
|
42393
|
+
if (process.platform === "win32" || !Number.isInteger(pid) || pid <= 1) return null;
|
|
42394
|
+
try {
|
|
42395
|
+
const out = execFileSync("ps", ["-o", "args=", "-p", String(pid)], {
|
|
42396
|
+
encoding: "utf8",
|
|
42397
|
+
timeout: 1e3,
|
|
42398
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
42399
|
+
env: { ...process.env, ...PS_STABLE_ENV }
|
|
42400
|
+
}).trim();
|
|
42401
|
+
return out === "" ? null : out;
|
|
42402
|
+
} catch {
|
|
42403
|
+
return null;
|
|
42404
|
+
}
|
|
42405
|
+
}
|
|
42406
|
+
function baseName(token) {
|
|
42407
|
+
return token.slice(token.lastIndexOf("/") + 1).replace(/^-/, "");
|
|
42408
|
+
}
|
|
42409
|
+
function programName(commandLine) {
|
|
42410
|
+
const tokens = commandLine.trim().split(/\s+/);
|
|
42411
|
+
const head = baseName(tokens[0] ?? "");
|
|
42412
|
+
if (!RUNTIME_PATTERN.test(head)) return head;
|
|
42413
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
42414
|
+
const token = tokens[i] ?? "";
|
|
42415
|
+
if (token === "-m") return (tokens[i + 1] ?? head).split(".")[0] ?? head;
|
|
42416
|
+
if (token.startsWith("-")) continue;
|
|
42417
|
+
return baseName(token).replace(/\.(c|m)?(js|ts)$|\.py$/, "");
|
|
42418
|
+
}
|
|
42419
|
+
return head;
|
|
42420
|
+
}
|
|
42421
|
+
function isCommandStringShell(args) {
|
|
42422
|
+
const tokens = args.trim().split(/\s+/);
|
|
42423
|
+
const shell = programName(args);
|
|
42424
|
+
let first = 1;
|
|
42425
|
+
if (RUNTIME_PATTERN.test(baseName(tokens[0] ?? ""))) {
|
|
42426
|
+
while (first < tokens.length && (tokens[first] ?? "").startsWith("-")) first++;
|
|
42427
|
+
first++;
|
|
42428
|
+
}
|
|
42429
|
+
const rest = tokens.slice(first);
|
|
42430
|
+
if (shell === "pwsh" || shell === "powershell") {
|
|
42431
|
+
return rest.some((t) => PWSH_COMMAND_SWITCHES.has(t.toLowerCase()));
|
|
42432
|
+
}
|
|
42433
|
+
for (let i = 0; i < rest.length; i++) {
|
|
42434
|
+
const token = rest[i] ?? "";
|
|
42435
|
+
if (token === "--") return false;
|
|
42436
|
+
if (token === "--command" || token === "--commands") return true;
|
|
42437
|
+
if (SHELL_OPTIONS_WITH_ARGUMENT.has(token)) {
|
|
42438
|
+
i++;
|
|
42439
|
+
continue;
|
|
42440
|
+
}
|
|
42441
|
+
if (token.startsWith("--")) continue;
|
|
42442
|
+
if (!/^[-+][A-Za-z]+$/.test(token)) return false;
|
|
42443
|
+
if (token.startsWith("-") && token.slice(1).includes("c")) return true;
|
|
42444
|
+
}
|
|
42445
|
+
return false;
|
|
42446
|
+
}
|
|
42447
|
+
function resolveAncestor(ppid, lookupProcess, lookupArgs, agentId = null) {
|
|
41866
42448
|
let pid = ppid;
|
|
41867
|
-
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH
|
|
42449
|
+
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH; depth++) {
|
|
42450
|
+
if (pid <= 1) return null;
|
|
41868
42451
|
const entry = lookupProcess(pid);
|
|
41869
|
-
if (!entry) return null;
|
|
41870
|
-
|
|
41871
|
-
|
|
42452
|
+
if (!entry || entry.pid <= 1) return null;
|
|
42453
|
+
const args = lookupArgs(entry.pid);
|
|
42454
|
+
const program = programName(args ?? entry.command);
|
|
42455
|
+
if (INIT_PROCESSES.has(program) || INIT_PROCESSES.has(entry.command)) return null;
|
|
42456
|
+
if (OWNER_PROCESS_SHELLS.has(program)) {
|
|
42457
|
+
if (args === null) return null;
|
|
42458
|
+
if (!isCommandStringShell(args)) return { entry, program, type: "shell" };
|
|
42459
|
+
} else if (!ANCESTOR_WRAPPERS.has(program)) {
|
|
42460
|
+
if (KNOWN_HARNESSES.has(program)) return { entry, program, type: "harness" };
|
|
42461
|
+
return agentId ? { entry, program, type: "host" } : null;
|
|
41872
42462
|
}
|
|
41873
42463
|
pid = entry.ppid;
|
|
41874
42464
|
}
|
|
41875
42465
|
return null;
|
|
41876
42466
|
}
|
|
42467
|
+
function anchorKey(anchor, agentId, under) {
|
|
42468
|
+
const proc = `${anchor.entry.pid}@${anchor.entry.startedAt}`;
|
|
42469
|
+
if (anchor.type === "shell" && !agentId) {
|
|
42470
|
+
return { key: `proc:${proc}`, source: "process", kind: "process" };
|
|
42471
|
+
}
|
|
42472
|
+
const agent = agentId ? `#agent=${agentId}` : "";
|
|
42473
|
+
const scope = under ? `|${under.key}` : "";
|
|
42474
|
+
return {
|
|
42475
|
+
key: `harness:${anchor.program}:${proc}${agent}${scope}`,
|
|
42476
|
+
source: "process",
|
|
42477
|
+
kind: "harness"
|
|
42478
|
+
};
|
|
42479
|
+
}
|
|
41877
42480
|
function resolveTerminalKeys(options = {}) {
|
|
41878
42481
|
const env = options.env ?? process.env;
|
|
41879
42482
|
const keys = [];
|
|
41880
42483
|
for (const source of TERMINAL_KEY_SOURCES) {
|
|
41881
42484
|
const value = envValue(env, source.envVar);
|
|
41882
42485
|
if (value === null) continue;
|
|
41883
|
-
const
|
|
42486
|
+
const qualifiers = [source.qualifierEnvVar, ...source.extraQualifierEnvVars ?? []].map((name15) => envValue(env, name15)).filter((q2) => q2 !== null);
|
|
41884
42487
|
keys.push({
|
|
41885
|
-
key: `env:${source.envVar}=${
|
|
42488
|
+
key: `env:${source.envVar}=${[...qualifiers, value].join("|")}`,
|
|
41886
42489
|
source: source.envVar,
|
|
41887
42490
|
kind: source.kind
|
|
41888
42491
|
});
|
|
41889
42492
|
}
|
|
41890
|
-
if (keys.
|
|
41891
|
-
const
|
|
41892
|
-
|
|
42493
|
+
if (keys.some((k) => k.kind === "provider")) return keys;
|
|
42494
|
+
const agentId = envValue(env, "CLEO_AGENT_ID");
|
|
42495
|
+
const live = options.ppid === void 0 && options.lookupProcess === void 0 && options.lookupArgs === void 0;
|
|
42496
|
+
let anchor;
|
|
41893
42497
|
if (live) {
|
|
41894
|
-
|
|
41895
|
-
|
|
42498
|
+
const memoKey2 = agentId ?? "";
|
|
42499
|
+
if (!liveAnchors.has(memoKey2))
|
|
42500
|
+
liveAnchors.set(
|
|
42501
|
+
memoKey2,
|
|
42502
|
+
resolveAncestor(process.ppid, readProcessEntry, readProcessArgs, agentId)
|
|
42503
|
+
);
|
|
42504
|
+
anchor = liveAnchors.get(memoKey2) ?? null;
|
|
41896
42505
|
} else {
|
|
41897
|
-
|
|
42506
|
+
anchor = resolveAncestor(
|
|
41898
42507
|
options.ppid ?? process.ppid,
|
|
41899
|
-
options.lookupProcess ?? readProcessEntry
|
|
42508
|
+
options.lookupProcess ?? readProcessEntry,
|
|
42509
|
+
options.lookupArgs ?? readProcessArgs,
|
|
42510
|
+
agentId
|
|
41900
42511
|
);
|
|
41901
42512
|
}
|
|
41902
|
-
|
|
42513
|
+
if (!anchor) return keys;
|
|
42514
|
+
if (keys.length === 0) return [anchorKey(anchor, agentId, void 0)];
|
|
42515
|
+
if (anchor.type === "shell" && !agentId) return keys;
|
|
42516
|
+
return [...keys, anchorKey(anchor, agentId, keys[0])];
|
|
41903
42517
|
}
|
|
41904
|
-
var TERMINAL_KEY_SOURCES,
|
|
42518
|
+
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;
|
|
41905
42519
|
var init_terminal_identity = __esm({
|
|
41906
42520
|
"packages/core/src/sessions/terminal-identity.ts"() {
|
|
41907
42521
|
"use strict";
|
|
@@ -41933,24 +42547,100 @@ var init_terminal_identity = __esm({
|
|
|
41933
42547
|
kind: "terminal",
|
|
41934
42548
|
origin: "konsole",
|
|
41935
42549
|
qualifierEnvVar: "KONSOLE_DBUS_SERVICE"
|
|
42550
|
+
},
|
|
42551
|
+
// T12864 — non-terminal callers whose platform exports a per-job / per-login id.
|
|
42552
|
+
// GitHub Actions: GITHUB_RUN_ID is per run and shared by its jobs, so it is
|
|
42553
|
+
// qualified by GITHUB_RUN_ATTEMPT and GITHUB_JOB ("Variables reference",
|
|
42554
|
+
// docs.github.com/en/actions/reference/workflows-and-actions/variables).
|
|
42555
|
+
// Every step of one job shares the key; the steps run sequentially.
|
|
42556
|
+
{
|
|
42557
|
+
envVar: "GITHUB_RUN_ID",
|
|
42558
|
+
kind: "terminal",
|
|
42559
|
+
origin: "github-actions",
|
|
42560
|
+
qualifierEnvVar: "GITHUB_RUN_ATTEMPT",
|
|
42561
|
+
extraQualifierEnvVars: ["GITHUB_JOB"]
|
|
42562
|
+
},
|
|
42563
|
+
// GitLab CI: CI_JOB_ID is unique per job across the instance ("Predefined
|
|
42564
|
+
// CI/CD variables reference", docs.gitlab.com/ci/variables/predefined_variables).
|
|
42565
|
+
{ envVar: "CI_JOB_ID", kind: "terminal", origin: "gitlab-ci" },
|
|
42566
|
+
// OpenSSH login with a tty: SSH_TTY names the login's tty and is set only
|
|
42567
|
+
// when one was allocated; SSH_CONNECTION ("client-ip client-port server-ip
|
|
42568
|
+
// server-port", ssh(1) ENVIRONMENT) disambiguates it across connections. A
|
|
42569
|
+
// one-shot `ssh host 'cmd'` has no tty and falls through to the ancestor walk.
|
|
42570
|
+
{
|
|
42571
|
+
envVar: "SSH_TTY",
|
|
42572
|
+
kind: "terminal",
|
|
42573
|
+
origin: "openssh",
|
|
42574
|
+
qualifierEnvVar: "SSH_CONNECTION"
|
|
41936
42575
|
}
|
|
41937
42576
|
];
|
|
41938
|
-
|
|
41939
|
-
|
|
42577
|
+
PPID_CHAIN_MAX_DEPTH = 12;
|
|
42578
|
+
KNOWN_HARNESSES = /* @__PURE__ */ new Set([
|
|
42579
|
+
"claude",
|
|
42580
|
+
"codex",
|
|
42581
|
+
"aider",
|
|
42582
|
+
"gemini",
|
|
42583
|
+
"kimi",
|
|
42584
|
+
"cursor-agent",
|
|
42585
|
+
"amp"
|
|
42586
|
+
]);
|
|
42587
|
+
RUNTIME_PATTERN = /^(node|nodejs|bun|deno|python[0-9.]*|pypy[0-9.]*|ruby|java|php|perl)$/;
|
|
42588
|
+
ANCESTOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
42589
|
+
"env",
|
|
42590
|
+
"timeout",
|
|
42591
|
+
"gtimeout",
|
|
42592
|
+
"nohup",
|
|
42593
|
+
"nice",
|
|
42594
|
+
"time",
|
|
42595
|
+
"xargs",
|
|
42596
|
+
"stdbuf",
|
|
42597
|
+
"sudo",
|
|
42598
|
+
"doas",
|
|
41940
42599
|
"npm",
|
|
42600
|
+
"npm-cli",
|
|
41941
42601
|
"npx",
|
|
42602
|
+
"npx-cli",
|
|
41942
42603
|
"pnpm",
|
|
41943
42604
|
"pnpx",
|
|
41944
42605
|
"yarn",
|
|
41945
|
-
"bun",
|
|
41946
42606
|
"bunx",
|
|
41947
|
-
"tsx",
|
|
41948
42607
|
"corepack",
|
|
41949
42608
|
"mise",
|
|
41950
|
-
"env",
|
|
41951
42609
|
"cleo"
|
|
41952
42610
|
]);
|
|
41953
|
-
|
|
42611
|
+
INIT_PROCESSES = /* @__PURE__ */ new Set(["launchd", "systemd", "init"]);
|
|
42612
|
+
SHELL_OPTIONS_WITH_ARGUMENT = /* @__PURE__ */ new Set([
|
|
42613
|
+
"-o",
|
|
42614
|
+
"+o",
|
|
42615
|
+
"-O",
|
|
42616
|
+
"+O",
|
|
42617
|
+
"--rcfile",
|
|
42618
|
+
"--init-file"
|
|
42619
|
+
]);
|
|
42620
|
+
PWSH_COMMAND_SWITCHES = /* @__PURE__ */ new Set([
|
|
42621
|
+
"-c",
|
|
42622
|
+
"-command",
|
|
42623
|
+
"-commandwithargs",
|
|
42624
|
+
"-cwa",
|
|
42625
|
+
"-e",
|
|
42626
|
+
"-ec",
|
|
42627
|
+
"-encodedcommand"
|
|
42628
|
+
]);
|
|
42629
|
+
OWNER_PROCESS_SHELLS = /* @__PURE__ */ new Set([
|
|
42630
|
+
"sh",
|
|
42631
|
+
"bash",
|
|
42632
|
+
"zsh",
|
|
42633
|
+
"dash",
|
|
42634
|
+
"fish",
|
|
42635
|
+
"ksh",
|
|
42636
|
+
"tcsh",
|
|
42637
|
+
"csh",
|
|
42638
|
+
"pwsh",
|
|
42639
|
+
"powershell",
|
|
42640
|
+
"nu",
|
|
42641
|
+
"xonsh"
|
|
42642
|
+
]);
|
|
42643
|
+
liveAnchors = /* @__PURE__ */ new Map();
|
|
41954
42644
|
}
|
|
41955
42645
|
});
|
|
41956
42646
|
|
|
@@ -41990,7 +42680,8 @@ var init_session_binding_schema = __esm({
|
|
|
41990
42680
|
});
|
|
41991
42681
|
|
|
41992
42682
|
// packages/core/src/store/session-store.ts
|
|
41993
|
-
import {
|
|
42683
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
42684
|
+
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";
|
|
41994
42685
|
async function getSession(sessionId, cwd) {
|
|
41995
42686
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
41996
42687
|
return worktreeScope.run(scope, async () => {
|
|
@@ -42012,8 +42703,9 @@ async function getActiveSession(cwd) {
|
|
|
42012
42703
|
function splitTerminalKeys(keys) {
|
|
42013
42704
|
return {
|
|
42014
42705
|
provider: keys.find((k) => k.kind === "provider"),
|
|
42015
|
-
|
|
42016
|
-
|
|
42706
|
+
// A harness / CLEO_AGENT_ID agent (T12864) is more specific than a pane.
|
|
42707
|
+
pane: keys.find((k) => k.kind === "harness") ?? keys.find((k) => k.kind === "multiplexer"),
|
|
42708
|
+
tab: keys.find((k) => k.kind === "terminal" || k.kind === "process" || k.kind === "ppid")
|
|
42017
42709
|
};
|
|
42018
42710
|
}
|
|
42019
42711
|
async function readBinding(db, key) {
|
|
@@ -42093,6 +42785,7 @@ async function resolveCurrentSession(cwd) {
|
|
|
42093
42785
|
async function resolveBoundSession(cwd) {
|
|
42094
42786
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
42095
42787
|
return worktreeScope.run(scope, async () => {
|
|
42788
|
+
if (!existsSync20(getDbPath(scope.worktreeRoot))) return null;
|
|
42096
42789
|
const connId = getCurrentConnectionSessionId();
|
|
42097
42790
|
if (connId) {
|
|
42098
42791
|
const byConn = await getSession(connId, scope.worktreeRoot);
|
|
@@ -42244,7 +42937,7 @@ __export(registry_exports2, {
|
|
|
42244
42937
|
updateAgentStatus: () => updateAgentStatus
|
|
42245
42938
|
});
|
|
42246
42939
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
42247
|
-
import { and as and7, eq as eq9, inArray as
|
|
42940
|
+
import { and as and7, eq as eq9, inArray as inArray5, lt as lt2, sql as sql29 } from "drizzle-orm";
|
|
42248
42941
|
function generateAgentId() {
|
|
42249
42942
|
const now = /* @__PURE__ */ new Date();
|
|
42250
42943
|
const ts = now.toISOString().replace(/[-:T]/g, "").substring(0, 14);
|
|
@@ -42333,11 +43026,11 @@ async function listAgentInstances(filters, cwd) {
|
|
|
42333
43026
|
const conditions = [];
|
|
42334
43027
|
if (filters?.status) {
|
|
42335
43028
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
42336
|
-
conditions.push(
|
|
43029
|
+
conditions.push(inArray5(agentInstances.status, statuses));
|
|
42337
43030
|
}
|
|
42338
43031
|
if (filters?.agentType) {
|
|
42339
43032
|
const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
|
|
42340
|
-
conditions.push(
|
|
43033
|
+
conditions.push(inArray5(agentInstances.agentType, types));
|
|
42341
43034
|
}
|
|
42342
43035
|
if (filters?.sessionId) {
|
|
42343
43036
|
conditions.push(eq9(agentInstances.sessionId, filters.sessionId));
|
|
@@ -42374,7 +43067,7 @@ async function checkAgentHealth(thresholdMs = 3e4, cwd) {
|
|
|
42374
43067
|
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
42375
43068
|
return db.select().from(agentInstances).where(
|
|
42376
43069
|
and7(
|
|
42377
|
-
|
|
43070
|
+
inArray5(agentInstances.status, ["active", "idle", "starting"]),
|
|
42378
43071
|
lt2(agentInstances.lastHeartbeat, cutoff)
|
|
42379
43072
|
)
|
|
42380
43073
|
).all();
|
|
@@ -42469,12 +43162,14 @@ var init_registry2 = __esm({
|
|
|
42469
43162
|
// packages/core/src/store/sqlite-data-accessor.ts
|
|
42470
43163
|
var sqlite_data_accessor_exports = {};
|
|
42471
43164
|
__export(sqlite_data_accessor_exports, {
|
|
43165
|
+
RENAMED_RECENT_MS: () => RENAMED_RECENT_MS,
|
|
42472
43166
|
addTaskLabelsNative: () => addTaskLabelsNative,
|
|
42473
43167
|
advanceTaskIdSequence: () => advanceTaskIdSequence,
|
|
42474
43168
|
bindTaskAccessorScope: () => bindTaskAccessorScope,
|
|
42475
43169
|
captureTaskAccessorScope: () => captureProjectScope,
|
|
42476
43170
|
clearAcUidGraveyardNative: () => clearAcUidGraveyardNative,
|
|
42477
43171
|
clearBirthFpNative: () => clearBirthFpNative,
|
|
43172
|
+
clearReplacedTaskIdentityNative: () => clearReplacedTaskIdentityNative,
|
|
42478
43173
|
clearRowUidNative: () => clearRowUidNative,
|
|
42479
43174
|
createSqliteDataAccessor: () => createSqliteDataAccessor,
|
|
42480
43175
|
deleteDisplayIdAliasNative: () => deleteDisplayIdAliasNative,
|
|
@@ -42485,6 +43180,7 @@ __export(sqlite_data_accessor_exports, {
|
|
|
42485
43180
|
insertIdentityRowNative: () => insertIdentityRowNative,
|
|
42486
43181
|
insertQuarantineNative: () => insertQuarantineNative,
|
|
42487
43182
|
insertUidAliasNative: () => insertUidAliasNative,
|
|
43183
|
+
readReplacedTaskBirthNative: () => readReplacedTaskBirthNative,
|
|
42488
43184
|
rederiveAcIdsNative: () => rederiveAcIdsNative,
|
|
42489
43185
|
rekeyQuarantineNative: () => rekeyQuarantineNative,
|
|
42490
43186
|
relinkAcUidNative: () => relinkAcUidNative,
|
|
@@ -42501,7 +43197,7 @@ import {
|
|
|
42501
43197
|
and as and8,
|
|
42502
43198
|
eq as eq10,
|
|
42503
43199
|
getTableColumns as getTableColumns2,
|
|
42504
|
-
inArray as
|
|
43200
|
+
inArray as inArray6,
|
|
42505
43201
|
isNull as isNull4,
|
|
42506
43202
|
like as like2,
|
|
42507
43203
|
lte as lte3,
|
|
@@ -42525,8 +43221,8 @@ async function selectAcBindings(db, acIds) {
|
|
|
42525
43221
|
bindingType: b.bindingType,
|
|
42526
43222
|
createdAt: b.createdAt
|
|
42527
43223
|
};
|
|
42528
|
-
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
42529
|
-
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
43224
|
+
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(ac.id, ids)).all();
|
|
43225
|
+
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(b.acId, ids)).all();
|
|
42530
43226
|
const rows = [...byUid, ...byId];
|
|
42531
43227
|
const wanted = new Set(ids);
|
|
42532
43228
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -42619,6 +43315,7 @@ function renameTaskDisplayIdNative(nativeDb, uid, toId, refs, guard = {}) {
|
|
|
42619
43315
|
if (Number(changed) !== 1) {
|
|
42620
43316
|
throw taskConflictError(current.id, taskVersion(current), null);
|
|
42621
43317
|
}
|
|
43318
|
+
recordLocalRename(nativeDb, uid, current.id, toId, taskVersion(current));
|
|
42622
43319
|
const rewritten = {};
|
|
42623
43320
|
const q2 = (name15) => `"${name15.replaceAll('"', '""')}"`;
|
|
42624
43321
|
for (const ref of refs) {
|
|
@@ -42674,23 +43371,39 @@ function rederiveAcIdsNative(nativeDb, fromId, toId) {
|
|
|
42674
43371
|
}
|
|
42675
43372
|
return count;
|
|
42676
43373
|
}
|
|
42677
|
-
function insertDisplayIdAliasNative(nativeDb, row) {
|
|
43374
|
+
function insertDisplayIdAliasNative(nativeDb, row, precedes) {
|
|
43375
|
+
const stored = nativeDb.prepare(
|
|
43376
|
+
`SELECT uid, entity_table AS entityTable, display_id AS displayId, entity_uid AS entityUid,
|
|
43377
|
+
reason, origin, displaced_hlc AS displacedHlc, created_at AS createdAt,
|
|
43378
|
+
entity_birth_fp AS entityBirthFp
|
|
43379
|
+
FROM tasks_display_id_aliases WHERE uid = ?`
|
|
43380
|
+
).get(row.uid);
|
|
43381
|
+
if (!stored) {
|
|
43382
|
+
nativeDb.prepare(
|
|
43383
|
+
`INSERT INTO tasks_display_id_aliases
|
|
43384
|
+
(uid, entity_table, display_id, entity_uid, reason, origin, displaced_hlc, created_at,
|
|
43385
|
+
entity_birth_fp)
|
|
43386
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
43387
|
+
).run(
|
|
43388
|
+
row.uid,
|
|
43389
|
+
row.entityTable,
|
|
43390
|
+
row.displayId,
|
|
43391
|
+
row.entityUid,
|
|
43392
|
+
row.reason,
|
|
43393
|
+
row.origin,
|
|
43394
|
+
row.displacedHlc,
|
|
43395
|
+
row.createdAt,
|
|
43396
|
+
row.entityBirthFp
|
|
43397
|
+
);
|
|
43398
|
+
return;
|
|
43399
|
+
}
|
|
43400
|
+
if (!precedes(row, stored)) return;
|
|
42678
43401
|
nativeDb.prepare(
|
|
42679
|
-
`
|
|
42680
|
-
|
|
42681
|
-
|
|
42682
|
-
|
|
42683
|
-
).run(
|
|
42684
|
-
row.uid,
|
|
42685
|
-
row.entityTable,
|
|
42686
|
-
row.displayId,
|
|
42687
|
-
row.entityUid,
|
|
42688
|
-
row.reason,
|
|
42689
|
-
row.origin,
|
|
42690
|
-
row.displacedHlc,
|
|
42691
|
-
row.createdAt,
|
|
42692
|
-
row.entityBirthFp
|
|
42693
|
-
);
|
|
43402
|
+
`UPDATE tasks_display_id_aliases
|
|
43403
|
+
SET origin = ?, displaced_hlc = ?, created_at = ?,
|
|
43404
|
+
entity_birth_fp = coalesce(entity_birth_fp, ?)
|
|
43405
|
+
WHERE uid = ?`
|
|
43406
|
+
).run(row.origin, row.displacedHlc, row.createdAt, row.entityBirthFp, row.uid);
|
|
42694
43407
|
}
|
|
42695
43408
|
function deleteDisplayIdAliasNative(nativeDb, uid) {
|
|
42696
43409
|
nativeDb.prepare("DELETE FROM tasks_display_id_aliases WHERE uid = ?").run(uid);
|
|
@@ -42752,6 +43465,63 @@ function relinkAcUidNative(nativeDb, acId, uid, birthFp) {
|
|
|
42752
43465
|
function clearAcUidGraveyardNative(nativeDb) {
|
|
42753
43466
|
nativeDb.exec("DELETE FROM tasks_ac_uid_graveyard");
|
|
42754
43467
|
}
|
|
43468
|
+
function readReplacedTaskBirthNative(nativeDb, taskId) {
|
|
43469
|
+
return nativeDb.prepare("SELECT created_at AS createdAt, uid FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43470
|
+
}
|
|
43471
|
+
function clearReplacedTaskIdentityNative(nativeDb, taskId, before) {
|
|
43472
|
+
const row = nativeDb.prepare("SELECT uid, birth_fp AS fp, created_at AS createdAt FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43473
|
+
if (!row || row.uid === null && row.fp === null) return;
|
|
43474
|
+
if (before) {
|
|
43475
|
+
const was = parseStoreTimestamp(before.createdAt);
|
|
43476
|
+
if (was !== null && was === parseStoreTimestamp(row.createdAt)) {
|
|
43477
|
+
return;
|
|
43478
|
+
}
|
|
43479
|
+
}
|
|
43480
|
+
if (rowIdentityShared(nativeDb)) {
|
|
43481
|
+
throw new CleoError(
|
|
43482
|
+
6 /* VALIDATION_ERROR */,
|
|
43483
|
+
`Task ${taskId} cannot be overwritten by an import: its identity is shared with other devices`,
|
|
43484
|
+
{
|
|
43485
|
+
fix: "Import it under a new id (the default duplicate strategy), or edit the task instead of overwriting it.",
|
|
43486
|
+
details: { field: "taskId", actual: taskId }
|
|
43487
|
+
}
|
|
43488
|
+
);
|
|
43489
|
+
}
|
|
43490
|
+
const has = (table) => nativeDb.prepare("SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== void 0;
|
|
43491
|
+
nativeDb.prepare("UPDATE tasks_tasks SET uid = NULL, birth_fp = NULL WHERE id = ?").run(taskId);
|
|
43492
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
43493
|
+
if (spec.kind !== "natural" || !has(spec.table)) continue;
|
|
43494
|
+
const cols = (spec.keyRefs ?? []).filter((r) => r.table === "tasks_tasks").map((r) => r.column);
|
|
43495
|
+
if (cols.length === 0) continue;
|
|
43496
|
+
nativeDb.prepare(
|
|
43497
|
+
`UPDATE main.${quoteIdent2(spec.table)} SET uid = NULL WHERE ${cols.map((c) => `${quoteIdent2(c)} = ?`).join(" OR ")}`
|
|
43498
|
+
).run(...cols.map(() => taskId));
|
|
43499
|
+
}
|
|
43500
|
+
const children = ["tasks_task_acceptance_criteria_history", "tasks_evidence_ac_bindings"].filter(
|
|
43501
|
+
has
|
|
43502
|
+
);
|
|
43503
|
+
const criteria = has("tasks_task_acceptance_criteria") ? nativeDb.prepare("SELECT id, uid FROM tasks_task_acceptance_criteria WHERE task_id = ?").all(taskId) : [];
|
|
43504
|
+
if (criteria.length > 0) {
|
|
43505
|
+
nativeDb.prepare(
|
|
43506
|
+
"UPDATE tasks_task_acceptance_criteria SET uid = NULL, birth_fp = NULL WHERE task_id = ?"
|
|
43507
|
+
).run(taskId);
|
|
43508
|
+
}
|
|
43509
|
+
fillRowUids(nativeDb, "project");
|
|
43510
|
+
const newUid = nativeDb.prepare("SELECT uid FROM tasks_task_acceptance_criteria WHERE id = ?");
|
|
43511
|
+
let rekeyed = 0;
|
|
43512
|
+
for (const ac of criteria) {
|
|
43513
|
+
const now = newUid.get(ac.id)?.uid ?? null;
|
|
43514
|
+
for (const table of children) {
|
|
43515
|
+
rekeyed += Number(
|
|
43516
|
+
nativeDb.prepare(
|
|
43517
|
+
`UPDATE main.${quoteIdent2(table)} SET ac_uid = ?, birth_fp = NULL
|
|
43518
|
+
WHERE ac_id = ? OR (? IS NOT NULL AND ac_uid = ?)`
|
|
43519
|
+
).run(now, ac.id, ac.uid, ac.uid).changes
|
|
43520
|
+
);
|
|
43521
|
+
}
|
|
43522
|
+
}
|
|
43523
|
+
if (rekeyed > 0) fillRowUids(nativeDb, "project");
|
|
43524
|
+
}
|
|
42755
43525
|
function quoteIdent2(name15) {
|
|
42756
43526
|
return `"${name15.replaceAll('"', '""')}"`;
|
|
42757
43527
|
}
|
|
@@ -42839,10 +43609,50 @@ function claimPredicate(guard, allowedHolders) {
|
|
|
42839
43609
|
if (guard.mode === "force") return void 0;
|
|
42840
43610
|
const mine = guard.sessionId === null ? void 0 : eq10(holder, guard.sessionId);
|
|
42841
43611
|
if (guard.mode === "renew" || guard.mode === "release") return mine ?? sql30`0`;
|
|
42842
|
-
const related = allowedHolders.length > 0 ?
|
|
43612
|
+
const related = allowedHolders.length > 0 ? inArray6(holder, [...allowedHolders]) : void 0;
|
|
42843
43613
|
const expired = guard.mode === "take-over" ? or5(isNull4(tasksTasks.leaseExpiresAt), lte3(tasksTasks.leaseExpiresAt, guard.now)) : void 0;
|
|
42844
43614
|
return or5(isNull4(holder), mine, related, expired);
|
|
42845
43615
|
}
|
|
43616
|
+
function renameRecordKey(fromId) {
|
|
43617
|
+
return `renamed_from:tasks_tasks:${fromId}`;
|
|
43618
|
+
}
|
|
43619
|
+
function hasIdentityMeta(nativeDb) {
|
|
43620
|
+
return nativeDb.prepare(
|
|
43621
|
+
"SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = 'tasks_row_identity_meta'"
|
|
43622
|
+
).get() !== void 0;
|
|
43623
|
+
}
|
|
43624
|
+
function recordLocalRename(nativeDb, uid, fromId, toId, fromVersion) {
|
|
43625
|
+
if (!hasIdentityMeta(nativeDb)) return;
|
|
43626
|
+
const record2 = { uid, fromVersion, toId, at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
43627
|
+
writeRowIdentityMetaNative(nativeDb, renameRecordKey(fromId), JSON.stringify(record2));
|
|
43628
|
+
}
|
|
43629
|
+
function assertNotRenamed(nativeDb, taskId, guard, current) {
|
|
43630
|
+
if (!nativeDb || !hasIdentityMeta(nativeDb)) return;
|
|
43631
|
+
const raw = nativeDb.prepare("SELECT value FROM tasks_row_identity_meta WHERE key = ?").get(renameRecordKey(taskId));
|
|
43632
|
+
if (!raw) return;
|
|
43633
|
+
let record2;
|
|
43634
|
+
try {
|
|
43635
|
+
record2 = JSON.parse(raw.value);
|
|
43636
|
+
} catch {
|
|
43637
|
+
return;
|
|
43638
|
+
}
|
|
43639
|
+
if (Date.now() - Date.parse(record2.at) > RENAMED_RECENT_MS) return;
|
|
43640
|
+
const renamed = nativeDb.prepare("SELECT id, claimed_by_session AS claimedBySession FROM tasks_tasks WHERE uid = ?").get(record2.uid);
|
|
43641
|
+
if (!renamed || renamed.id === taskId) return;
|
|
43642
|
+
const expected = guard.expectedUpdatedAt;
|
|
43643
|
+
const session = guard.claim?.sessionId ?? null;
|
|
43644
|
+
const holdsRenamedClaim = session !== null && (guard.claim?.mode === "renew" || guard.claim?.mode === "release") && renamed.claimedBySession === session && current?.claimedBySession !== session;
|
|
43645
|
+
const readRenamed = expected !== void 0 && expected === record2.fromVersion && (current === void 0 || taskVersion(current) !== expected);
|
|
43646
|
+
if (!(current === void 0 || holdsRenamedClaim || readRenamed)) return;
|
|
43647
|
+
throw new CleoError(
|
|
43648
|
+
26 /* TASK_RENAMED */,
|
|
43649
|
+
`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`,
|
|
43650
|
+
{
|
|
43651
|
+
fix: `Re-read it with 'cleo show ${renamed.id}' and retry against ${renamed.id}.`,
|
|
43652
|
+
details: { field: "taskId", actual: taskId, expected: renamed.id }
|
|
43653
|
+
}
|
|
43654
|
+
);
|
|
43655
|
+
}
|
|
42846
43656
|
function assertClaimAllowed(taskId, row, guard, allowedHolders) {
|
|
42847
43657
|
const stored = claimFromColumns(row);
|
|
42848
43658
|
if (claimAllows(stored, guard.mode, guard.sessionId, guard.now, allowedHolders)) return;
|
|
@@ -43017,13 +43827,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43017
43827
|
const db = await getDb(cwd);
|
|
43018
43828
|
const conditions = [];
|
|
43019
43829
|
if (query.ids && query.ids.length > 0) {
|
|
43020
|
-
conditions.push(
|
|
43830
|
+
conditions.push(inArray6(tasksAuditLog.id, [...query.ids]));
|
|
43021
43831
|
}
|
|
43022
43832
|
if (query.taskIds && query.taskIds.length > 0) {
|
|
43023
|
-
conditions.push(
|
|
43833
|
+
conditions.push(inArray6(tasksAuditLog.taskId, [...query.taskIds]));
|
|
43024
43834
|
}
|
|
43025
43835
|
if (query.actions && query.actions.length > 0) {
|
|
43026
|
-
conditions.push(
|
|
43836
|
+
conditions.push(inArray6(tasksAuditLog.action, [...query.actions]));
|
|
43027
43837
|
}
|
|
43028
43838
|
if (query.since) {
|
|
43029
43839
|
conditions.push(sql30`${tasksAuditLog.timestamp} >= ${query.since}`);
|
|
@@ -43056,8 +43866,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43056
43866
|
async upsertSingleTask(task) {
|
|
43057
43867
|
await accessor.transaction((tx) => tx.upsertSingleTask(task));
|
|
43058
43868
|
},
|
|
43059
|
-
async insertNewTask(task) {
|
|
43060
|
-
await accessor.transaction((tx) => tx.insertNewTask(task));
|
|
43869
|
+
async insertNewTask(task, identity) {
|
|
43870
|
+
await accessor.transaction((tx) => tx.insertNewTask(task, identity));
|
|
43871
|
+
},
|
|
43872
|
+
async getTaskIdentities(taskIds) {
|
|
43873
|
+
if (taskIds.length === 0) return [];
|
|
43874
|
+
const db = await getDb(cwd);
|
|
43875
|
+
return db.select({ id: tasksTasks.id, uid: tasksTasks.uid, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
43061
43876
|
},
|
|
43062
43877
|
async addRelation(taskId, relatedTo, relationType, reason) {
|
|
43063
43878
|
return accessor.transaction(async () => {
|
|
@@ -43234,7 +44049,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43234
44049
|
if (!statuses.includes("archived")) {
|
|
43235
44050
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43236
44051
|
}
|
|
43237
|
-
conditions.push(
|
|
44052
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43238
44053
|
} else if (filters.excludeStatus) {
|
|
43239
44054
|
const excluded = Array.isArray(filters.excludeStatus) ? filters.excludeStatus : [filters.excludeStatus];
|
|
43240
44055
|
for (const s of excluded) {
|
|
@@ -43248,11 +44063,11 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43248
44063
|
if (filters.phase) conditions.push(eq10(tasksTasks.phase, filters.phase));
|
|
43249
44064
|
if (filters.severity) {
|
|
43250
44065
|
const severities = Array.isArray(filters.severity) ? filters.severity : [filters.severity];
|
|
43251
|
-
conditions.push(
|
|
44066
|
+
conditions.push(inArray6(tasksTasks.severity, severities));
|
|
43252
44067
|
}
|
|
43253
44068
|
if (filters.kind) {
|
|
43254
44069
|
const kinds = Array.isArray(filters.kind) ? filters.kind : [filters.kind];
|
|
43255
|
-
conditions.push(
|
|
44070
|
+
conditions.push(inArray6(tasksTasks.kind, kinds));
|
|
43256
44071
|
}
|
|
43257
44072
|
if (filters.parentId !== void 0) {
|
|
43258
44073
|
if (filters.parentId === null) {
|
|
@@ -43273,7 +44088,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43273
44088
|
}
|
|
43274
44089
|
if (filters.label) {
|
|
43275
44090
|
const labelMatchIds = db.select({ taskId: tasksTaskLabels.taskId }).from(tasksTaskLabels).where(eq10(tasksTaskLabels.label, filters.label));
|
|
43276
|
-
conditions.push(
|
|
44091
|
+
conditions.push(inArray6(tasksTasks.id, labelMatchIds));
|
|
43277
44092
|
}
|
|
43278
44093
|
const where = conditions.length > 0 ? and8(...conditions) : void 0;
|
|
43279
44094
|
const countResult = await db.select({ count: sql30`count(*)` }).from(tasksTasks).where(where).get();
|
|
@@ -43316,7 +44131,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43316
44131
|
const conditions = [];
|
|
43317
44132
|
if (filters?.status) {
|
|
43318
44133
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
43319
|
-
conditions.push(
|
|
44134
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43320
44135
|
} else {
|
|
43321
44136
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43322
44137
|
}
|
|
@@ -43381,7 +44196,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43381
44196
|
if (idRows.length === 0) return [];
|
|
43382
44197
|
const db = await getDb(cwd);
|
|
43383
44198
|
const ids = idRows.map((r) => r.id);
|
|
43384
|
-
const taskRows = await db.select().from(tasksTasks).where(
|
|
44199
|
+
const taskRows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43385
44200
|
const tasks2 = taskRows.map(rowToTask);
|
|
43386
44201
|
if (tasks2.length > 0) {
|
|
43387
44202
|
const allIds = await getAllTaskIds();
|
|
@@ -43410,7 +44225,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43410
44225
|
if (idRows.length === 0) return [];
|
|
43411
44226
|
const db = await getDb(cwd);
|
|
43412
44227
|
const ids = idRows.map((r) => r.id);
|
|
43413
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44228
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43414
44229
|
const tasks2 = rows.map(rowToTask);
|
|
43415
44230
|
if (tasks2.length > 0) {
|
|
43416
44231
|
const allIds = await getAllTaskIds();
|
|
@@ -43424,7 +44239,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43424
44239
|
const depRows = await db.select().from(tasksTaskDependencies).where(eq10(tasksTaskDependencies.dependsOn, taskId)).all();
|
|
43425
44240
|
if (depRows.length === 0) return [];
|
|
43426
44241
|
const dependentIds = depRows.map((r) => r.taskId);
|
|
43427
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44242
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, dependentIds)).all();
|
|
43428
44243
|
const tasks2 = rows.map(rowToTask);
|
|
43429
44244
|
if (tasks2.length > 0) {
|
|
43430
44245
|
const allIds = await getAllTaskIds();
|
|
@@ -43454,7 +44269,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43454
44269
|
async loadTasks(taskIds) {
|
|
43455
44270
|
if (taskIds.length === 0) return [];
|
|
43456
44271
|
const db = await getDb(cwd);
|
|
43457
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
44272
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
43458
44273
|
const tasks2 = rows.map(rowToTask);
|
|
43459
44274
|
if (tasks2.length > 0) {
|
|
43460
44275
|
const allIds = await getAllTaskIds();
|
|
@@ -43508,6 +44323,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43508
44323
|
createdAt: tasksTasks.createdAt,
|
|
43509
44324
|
...CLAIM_COLUMNS
|
|
43510
44325
|
}).from(tasksTasks).where(eq10(tasksTasks.id, taskId)).limit(1).all();
|
|
44326
|
+
if (guard?.claim || guard?.expectedUpdatedAt !== void 0) {
|
|
44327
|
+
assertNotRenamed(getNativeTasksDb(cwd), taskId, guard, current);
|
|
44328
|
+
}
|
|
43511
44329
|
if (!current) throw new Error(`Task not found: ${taskId}`);
|
|
43512
44330
|
const claimGuard = guard?.claim;
|
|
43513
44331
|
const allowedHolders = claimGuard ? await claimAllowedHolders(db, claimGuard) : [];
|
|
@@ -43585,24 +44403,37 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43585
44403
|
nativeDb.prepare(`SAVEPOINT ${spName}`).run();
|
|
43586
44404
|
}
|
|
43587
44405
|
try {
|
|
44406
|
+
const replacedBirths = /* @__PURE__ */ new Map();
|
|
43588
44407
|
const tx = {
|
|
43589
44408
|
async upsertSingleTask(task) {
|
|
43590
44409
|
scope.assertActive();
|
|
43591
44410
|
return accessor.transaction(async () => {
|
|
43592
44411
|
scope.assertActive();
|
|
44412
|
+
if (rowUidFillEnabled() && !replacedBirths.has(task.id)) {
|
|
44413
|
+
const before = readReplacedTaskBirthNative(nativeDb, task.id);
|
|
44414
|
+
if (before) replacedBirths.set(task.id, before);
|
|
44415
|
+
}
|
|
43593
44416
|
const row = taskToRow(task);
|
|
43594
44417
|
await upsertTask(db, row);
|
|
43595
44418
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43596
44419
|
});
|
|
43597
44420
|
},
|
|
43598
|
-
async insertNewTask(task) {
|
|
44421
|
+
async insertNewTask(task, identity) {
|
|
43599
44422
|
scope.assertActive();
|
|
43600
44423
|
return accessor.transaction(async () => {
|
|
43601
44424
|
scope.assertActive();
|
|
43602
|
-
await insertNewTask(db, taskToRow(task));
|
|
44425
|
+
await insertNewTask(db, taskToRow(task), identity);
|
|
43603
44426
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43604
44427
|
});
|
|
43605
44428
|
},
|
|
44429
|
+
async clearTaskIdentity(taskId) {
|
|
44430
|
+
scope.assertActive();
|
|
44431
|
+
if (!rowUidFillEnabled()) return;
|
|
44432
|
+
return accessor.transaction(async () => {
|
|
44433
|
+
scope.assertActive();
|
|
44434
|
+
clearReplacedTaskIdentityNative(nativeDb, taskId, replacedBirths.get(taskId));
|
|
44435
|
+
});
|
|
44436
|
+
},
|
|
43606
44437
|
async archiveSingleTask(taskId, fields) {
|
|
43607
44438
|
scope.assertActive();
|
|
43608
44439
|
return accessor.transaction(async () => {
|
|
@@ -43749,7 +44580,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43749
44580
|
const owned = await db.select({ id: tasksTaskAcceptanceCriteria.id }).from(tasksTaskAcceptanceCriteria).where(
|
|
43750
44581
|
and8(
|
|
43751
44582
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43752
|
-
|
|
44583
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43753
44584
|
)
|
|
43754
44585
|
).all();
|
|
43755
44586
|
await pruneAcBindingsForAcIds(
|
|
@@ -43762,7 +44593,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43762
44593
|
await db.delete(tasksTaskAcceptanceCriteria).where(
|
|
43763
44594
|
and8(
|
|
43764
44595
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43765
|
-
|
|
44596
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43766
44597
|
)
|
|
43767
44598
|
).run();
|
|
43768
44599
|
});
|
|
@@ -44021,7 +44852,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
44021
44852
|
};
|
|
44022
44853
|
return accessor;
|
|
44023
44854
|
}
|
|
44024
|
-
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS;
|
|
44855
|
+
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS, RENAMED_RECENT_MS;
|
|
44025
44856
|
var init_sqlite_data_accessor = __esm({
|
|
44026
44857
|
"packages/core/src/store/sqlite-data-accessor.ts"() {
|
|
44027
44858
|
"use strict";
|
|
@@ -44035,6 +44866,8 @@ var init_sqlite_data_accessor = __esm({
|
|
|
44035
44866
|
init_cross_db_cleanup();
|
|
44036
44867
|
init_db_helpers();
|
|
44037
44868
|
init_row_identity();
|
|
44869
|
+
init_row_identity_flag();
|
|
44870
|
+
init_row_identity_registry();
|
|
44038
44871
|
init_audit2();
|
|
44039
44872
|
init_session_store();
|
|
44040
44873
|
init_sqlite3();
|
|
@@ -44067,6 +44900,7 @@ var init_sqlite_data_accessor = __esm({
|
|
|
44067
44900
|
claimedAt: tasksTasks.claimedAt,
|
|
44068
44901
|
leaseExpiresAt: tasksTasks.leaseExpiresAt
|
|
44069
44902
|
};
|
|
44903
|
+
RENAMED_RECENT_MS = 24 * 60 * 60 * 1e3;
|
|
44070
44904
|
registerRowIdentityWriters({
|
|
44071
44905
|
relinkAcUidNative,
|
|
44072
44906
|
clearAcUidGraveyardNative,
|
|
@@ -44537,7 +45371,7 @@ __export(governor_exports, {
|
|
|
44537
45371
|
resolveGovernorMode: () => resolveGovernorMode,
|
|
44538
45372
|
slotFileCount: () => slotFileCount
|
|
44539
45373
|
});
|
|
44540
|
-
import { existsSync as
|
|
45374
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync6, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
44541
45375
|
import { availableParallelism, totalmem } from "node:os";
|
|
44542
45376
|
import { join as join27 } from "node:path";
|
|
44543
45377
|
import lockfile2 from "proper-lockfile";
|
|
@@ -44611,11 +45445,11 @@ function governorSlotDir(cls) {
|
|
|
44611
45445
|
return join27(getCleoHome(), "locks", `resource-${cls}`);
|
|
44612
45446
|
}
|
|
44613
45447
|
function ensureSlotFiles(dir, count) {
|
|
44614
|
-
if (!
|
|
45448
|
+
if (!existsSync21(dir)) mkdirSync6(dir, { recursive: true });
|
|
44615
45449
|
const paths = [];
|
|
44616
45450
|
for (let i = 0; i < count; i++) {
|
|
44617
45451
|
const p = join27(dir, `slot-${i}.lock`);
|
|
44618
|
-
if (!
|
|
45452
|
+
if (!existsSync21(p)) writeFileSync5(p, "", { flag: "a" });
|
|
44619
45453
|
paths.push(p);
|
|
44620
45454
|
}
|
|
44621
45455
|
return paths;
|
|
@@ -44655,7 +45489,7 @@ function shuffledIndices(n) {
|
|
|
44655
45489
|
}
|
|
44656
45490
|
async function countHeldSlots(cls, budget) {
|
|
44657
45491
|
const dir = governorSlotDir(cls);
|
|
44658
|
-
if (!
|
|
45492
|
+
if (!existsSync21(dir)) return 0;
|
|
44659
45493
|
const slots = ensureSlotFiles(dir, budget);
|
|
44660
45494
|
let held = 0;
|
|
44661
45495
|
for (const path of slots) {
|
|
@@ -44670,7 +45504,7 @@ async function countHeldSlots(cls, budget) {
|
|
|
44670
45504
|
}
|
|
44671
45505
|
function slotFileCount(cls) {
|
|
44672
45506
|
const dir = governorSlotDir(cls);
|
|
44673
|
-
if (!
|
|
45507
|
+
if (!existsSync21(dir)) return 0;
|
|
44674
45508
|
return readdirSync5(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
|
|
44675
45509
|
}
|
|
44676
45510
|
var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
|
|
@@ -44821,7 +45655,7 @@ var init_governor = __esm({
|
|
|
44821
45655
|
// packages/core/src/store/exodus/recovery.ts
|
|
44822
45656
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
44823
45657
|
import { constants } from "node:sqlite";
|
|
44824
|
-
import { z as
|
|
45658
|
+
import { z as z30 } from "zod";
|
|
44825
45659
|
function identityValues(encoded) {
|
|
44826
45660
|
return identitySchema.parse(JSON.parse(encoded)).map(([kind, value]) => {
|
|
44827
45661
|
if (kind === "null") return null;
|
|
@@ -45157,8 +45991,8 @@ var init_recovery = __esm({
|
|
|
45157
45991
|
"use strict";
|
|
45158
45992
|
init_row_identity_registry();
|
|
45159
45993
|
RECEIPTS = "_exodus_recovery_rows";
|
|
45160
|
-
identitySchema =
|
|
45161
|
-
|
|
45994
|
+
identitySchema = z30.array(
|
|
45995
|
+
z30.tuple([z30.enum(["null", "integer", "real", "text", "blob"]), z30.string()])
|
|
45162
45996
|
);
|
|
45163
45997
|
ExodusRecoveryError = class extends Error {
|
|
45164
45998
|
};
|
|
@@ -45168,7 +46002,7 @@ var init_recovery = __esm({
|
|
|
45168
46002
|
// packages/core/src/store/exodus/archive.ts
|
|
45169
46003
|
import {
|
|
45170
46004
|
copyFileSync as copyFileSync5,
|
|
45171
|
-
existsSync as
|
|
46005
|
+
existsSync as existsSync22,
|
|
45172
46006
|
mkdirSync as mkdirSync7,
|
|
45173
46007
|
readFileSync as readFileSync9,
|
|
45174
46008
|
renameSync as renameSync7,
|
|
@@ -45176,7 +46010,7 @@ import {
|
|
|
45176
46010
|
writeFileSync as writeFileSync6
|
|
45177
46011
|
} from "node:fs";
|
|
45178
46012
|
import { basename as basename9, dirname as dirname20, join as join28, resolve as resolve12 } from "node:path";
|
|
45179
|
-
import { z as
|
|
46013
|
+
import { z as z31 } from "zod";
|
|
45180
46014
|
function scopeBaseDir(scope, cwd, targetDbPath) {
|
|
45181
46015
|
if (targetDbPath !== void 0) return dirname20(targetDbPath);
|
|
45182
46016
|
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
@@ -45196,7 +46030,7 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
|
45196
46030
|
if (targetDbPath) throw error48;
|
|
45197
46031
|
return false;
|
|
45198
46032
|
}
|
|
45199
|
-
if (!
|
|
46033
|
+
if (!existsSync22(markerPath)) return false;
|
|
45200
46034
|
const marker16 = markerIdentity.parse(JSON.parse(readFileSync9(markerPath, "utf8")));
|
|
45201
46035
|
if (nativeDb && (!marker16.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker16.databaseIdentity)))
|
|
45202
46036
|
throw new Error(
|
|
@@ -45226,7 +46060,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
45226
46060
|
function moveFileInto(srcPath, destDir) {
|
|
45227
46061
|
mkdirSync7(destDir, { recursive: true });
|
|
45228
46062
|
let dest = join28(destDir, basename9(srcPath));
|
|
45229
|
-
if (
|
|
46063
|
+
if (existsSync22(dest)) {
|
|
45230
46064
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
45231
46065
|
dest = join28(destDir, `${basename9(srcPath)}.${stamp}`);
|
|
45232
46066
|
}
|
|
@@ -45239,14 +46073,14 @@ function moveFileInto(srcPath, destDir) {
|
|
|
45239
46073
|
return dest;
|
|
45240
46074
|
}
|
|
45241
46075
|
function archiveSourceDb(source, cwd, targetDbPath) {
|
|
45242
|
-
if (!
|
|
46076
|
+
if (!existsSync22(source.path)) {
|
|
45243
46077
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
45244
46078
|
}
|
|
45245
46079
|
const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
|
|
45246
46080
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
45247
46081
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
45248
46082
|
const sidecar = `${source.path}${suffix}`;
|
|
45249
|
-
if (
|
|
46083
|
+
if (existsSync22(sidecar)) {
|
|
45250
46084
|
try {
|
|
45251
46085
|
moveFileInto(sidecar, destDir);
|
|
45252
46086
|
} catch (err) {
|
|
@@ -45294,7 +46128,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
45294
46128
|
const stranded = [];
|
|
45295
46129
|
for (const source of sources) {
|
|
45296
46130
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
45297
|
-
if (
|
|
46131
|
+
if (existsSync22(source.path)) {
|
|
45298
46132
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
45299
46133
|
}
|
|
45300
46134
|
}
|
|
@@ -45319,11 +46153,11 @@ var init_archive2 = __esm({
|
|
|
45319
46153
|
init_ensure_config();
|
|
45320
46154
|
init_recovery();
|
|
45321
46155
|
log8 = getLogger("exodus-archive");
|
|
45322
|
-
markerIdentity =
|
|
45323
|
-
version:
|
|
45324
|
-
scope:
|
|
45325
|
-
targetDbPath:
|
|
45326
|
-
databaseIdentity:
|
|
46156
|
+
markerIdentity = z31.object({
|
|
46157
|
+
version: z31.literal(1),
|
|
46158
|
+
scope: z31.enum(["project", "global"]),
|
|
46159
|
+
targetDbPath: z31.string().optional(),
|
|
46160
|
+
databaseIdentity: z31.string().optional()
|
|
45327
46161
|
});
|
|
45328
46162
|
ARCHIVE_DIR_NAME = "_archive";
|
|
45329
46163
|
MARKER_FILENAME_BY_SCOPE = {
|
|
@@ -45335,13 +46169,13 @@ var init_archive2 = __esm({
|
|
|
45335
46169
|
});
|
|
45336
46170
|
|
|
45337
46171
|
// packages/core/src/store/exodus/count-parity.ts
|
|
45338
|
-
import { existsSync as
|
|
46172
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
45339
46173
|
function listTables2(db) {
|
|
45340
46174
|
return db.prepare(
|
|
45341
46175
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
45342
46176
|
).all().map((r) => r.name);
|
|
45343
46177
|
}
|
|
45344
|
-
function
|
|
46178
|
+
function tableExists3(db, tableName) {
|
|
45345
46179
|
const escaped = tableName.replace(/'/g, "''");
|
|
45346
46180
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
45347
46181
|
}
|
|
@@ -45356,14 +46190,14 @@ function rowCount(db, tableName) {
|
|
|
45356
46190
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
45357
46191
|
const entries = [];
|
|
45358
46192
|
let skipped = 0;
|
|
45359
|
-
if (!
|
|
46193
|
+
if (!existsSync23(projectDbPath) || !existsSync23(globalDbPath)) {
|
|
45360
46194
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45361
46195
|
}
|
|
45362
46196
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
45363
46197
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
45364
46198
|
try {
|
|
45365
46199
|
for (const src of sources) {
|
|
45366
|
-
if (!
|
|
46200
|
+
if (!existsSync23(src.path)) continue;
|
|
45367
46201
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
45368
46202
|
try {
|
|
45369
46203
|
for (const legacyTable of listTables2(srcSnap.db)) {
|
|
@@ -45380,7 +46214,7 @@ function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
|
45380
46214
|
skipped++;
|
|
45381
46215
|
continue;
|
|
45382
46216
|
}
|
|
45383
|
-
const targetCount =
|
|
46217
|
+
const targetCount = tableExists3(targetSnap.db, targetTable) ? rowCount(targetSnap.db, targetTable) ?? 0 : 0;
|
|
45384
46218
|
const deficit = targetCount < sourceCount ? sourceCount - targetCount : 0;
|
|
45385
46219
|
entries.push({
|
|
45386
46220
|
sourceDb: src.name,
|
|
@@ -45421,7 +46255,7 @@ var init_count_parity = __esm({
|
|
|
45421
46255
|
});
|
|
45422
46256
|
|
|
45423
46257
|
// packages/core/src/store/exodus/plan.ts
|
|
45424
|
-
import { existsSync as
|
|
46258
|
+
import { existsSync as existsSync24, readdirSync as readdirSync6, statfsSync as statfsSync2, statSync as statSync6 } from "node:fs";
|
|
45425
46259
|
import { join as join29 } from "node:path";
|
|
45426
46260
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
45427
46261
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
@@ -45523,7 +46357,7 @@ function buildExodusPlan(cwd) {
|
|
|
45523
46357
|
};
|
|
45524
46358
|
}
|
|
45525
46359
|
function sourcesPresent(sources) {
|
|
45526
|
-
return sources.some((s) =>
|
|
46360
|
+
return sources.some((s) => existsSync24(s.path));
|
|
45527
46361
|
}
|
|
45528
46362
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
45529
46363
|
var init_plan2 = __esm({
|
|
@@ -45537,18 +46371,18 @@ var init_plan2 = __esm({
|
|
|
45537
46371
|
});
|
|
45538
46372
|
|
|
45539
46373
|
// packages/core/src/store/exodus/health.ts
|
|
45540
|
-
import { existsSync as
|
|
46374
|
+
import { existsSync as existsSync25, statSync as statSync7 } from "node:fs";
|
|
45541
46375
|
function buildExodusHealth(cwd) {
|
|
45542
46376
|
const plan = buildExodusPlan(cwd);
|
|
45543
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
46377
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync25(s.path));
|
|
45544
46378
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45545
46379
|
const consolidatedExistsByScope = {
|
|
45546
|
-
project:
|
|
45547
|
-
global:
|
|
46380
|
+
project: existsSync25(plan.projectDbPath),
|
|
46381
|
+
global: existsSync25(plan.globalDbPath)
|
|
45548
46382
|
};
|
|
45549
46383
|
const buildScope = (scope) => {
|
|
45550
46384
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
45551
|
-
const present =
|
|
46385
|
+
const present = existsSync25(s.path);
|
|
45552
46386
|
let bytes = 0;
|
|
45553
46387
|
if (present) {
|
|
45554
46388
|
try {
|
|
@@ -45653,7 +46487,7 @@ var init_types = __esm({
|
|
|
45653
46487
|
// packages/core/src/store/exodus/migrate.ts
|
|
45654
46488
|
import {
|
|
45655
46489
|
copyFileSync as copyFileSync6,
|
|
45656
|
-
existsSync as
|
|
46490
|
+
existsSync as existsSync26,
|
|
45657
46491
|
mkdirSync as mkdirSync8,
|
|
45658
46492
|
readFileSync as readFileSync10,
|
|
45659
46493
|
renameSync as renameSync8,
|
|
@@ -45699,7 +46533,7 @@ function writeJournal(stagingDir, journal) {
|
|
|
45699
46533
|
}
|
|
45700
46534
|
function readJournal(stagingDir) {
|
|
45701
46535
|
const journalPath = join30(stagingDir, JOURNAL_FILENAME);
|
|
45702
|
-
if (!
|
|
46536
|
+
if (!existsSync26(journalPath)) return null;
|
|
45703
46537
|
try {
|
|
45704
46538
|
return JSON.parse(readFileSync10(journalPath, "utf8"));
|
|
45705
46539
|
} catch {
|
|
@@ -45709,7 +46543,7 @@ function readJournal(stagingDir) {
|
|
|
45709
46543
|
function clearExodusJournal(stagingDir) {
|
|
45710
46544
|
const journalPath = join30(stagingDir, JOURNAL_FILENAME);
|
|
45711
46545
|
try {
|
|
45712
|
-
if (!
|
|
46546
|
+
if (!existsSync26(journalPath)) return false;
|
|
45713
46547
|
unlinkSync5(journalPath);
|
|
45714
46548
|
log10.info(
|
|
45715
46549
|
{ stagingDir },
|
|
@@ -46005,7 +46839,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
46005
46839
|
mkdirSync8(stagingDir, { recursive: true });
|
|
46006
46840
|
let sqliteVersion = "unknown";
|
|
46007
46841
|
for (const src of sources) {
|
|
46008
|
-
if (
|
|
46842
|
+
if (existsSync26(src.path)) {
|
|
46009
46843
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
46010
46844
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
46011
46845
|
snap.close();
|
|
@@ -46035,7 +46869,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
46035
46869
|
let reseedProject = null;
|
|
46036
46870
|
try {
|
|
46037
46871
|
for (const src of sources) {
|
|
46038
|
-
if (!
|
|
46872
|
+
if (!existsSync26(src.path)) continue;
|
|
46039
46873
|
const backupDest = join30(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
46040
46874
|
const srcBytes = safeStatBytes(src.path);
|
|
46041
46875
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
@@ -46043,7 +46877,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
46043
46877
|
onProgress?.(
|
|
46044
46878
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
46045
46879
|
);
|
|
46046
|
-
} else if (!
|
|
46880
|
+
} else if (!existsSync26(backupDest)) {
|
|
46047
46881
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
46048
46882
|
copyFileSync6(src.path, backupDest);
|
|
46049
46883
|
backupPaths.push(backupDest);
|
|
@@ -46076,8 +46910,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
46076
46910
|
}
|
|
46077
46911
|
prepareExodusRecovery(projectNative, stagingDir);
|
|
46078
46912
|
if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
|
|
46079
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
46080
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
46913
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync26(s.path));
|
|
46914
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync26(s.path));
|
|
46081
46915
|
if (globalNative === null && globalSources.length > 0)
|
|
46082
46916
|
throw new Error("A projectOnly exodus run was given global-scope sources");
|
|
46083
46917
|
await migrateScope(
|
|
@@ -46326,7 +47160,8 @@ var init_migrate = __esm({
|
|
|
46326
47160
|
GRANDFATHERED_GUARD_TRIGGERS = [
|
|
46327
47161
|
"tasks_tasks_parent_type_matrix_insert",
|
|
46328
47162
|
"tasks_task_relations_non_containment_insert",
|
|
46329
|
-
"tasks_task_acceptance_child_target_insert"
|
|
47163
|
+
"tasks_task_acceptance_child_target_insert",
|
|
47164
|
+
"tasks_task_dependencies_cycle_guard_insert"
|
|
46330
47165
|
];
|
|
46331
47166
|
SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
|
|
46332
47167
|
["conduit", "seconds"],
|
|
@@ -46385,7 +47220,7 @@ __export(reconcile_exports, {
|
|
|
46385
47220
|
reconcileSupersededStores: () => reconcileSupersededStores,
|
|
46386
47221
|
unmigratedBareSources: () => unmigratedBareSources
|
|
46387
47222
|
});
|
|
46388
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
47223
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync27, mkdirSync as mkdirSync9, mkdtempSync, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
46389
47224
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
46390
47225
|
import { basename as basename10, join as join31 } from "node:path";
|
|
46391
47226
|
function ident2(name15) {
|
|
@@ -46456,7 +47291,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
|
|
|
46456
47291
|
}
|
|
46457
47292
|
function legacySourcesHoldRows(sources) {
|
|
46458
47293
|
for (const src of sources) {
|
|
46459
|
-
if (!
|
|
47294
|
+
if (!existsSync27(src.path)) continue;
|
|
46460
47295
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
46461
47296
|
try {
|
|
46462
47297
|
for (const table of orderTablesForCopy(snap.db)) {
|
|
@@ -46704,8 +47539,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
46704
47539
|
}
|
|
46705
47540
|
}
|
|
46706
47541
|
async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
|
|
46707
|
-
const fileSources = plan.sources.filter((s) => s.targetScope === "project" &&
|
|
46708
|
-
const bare = !additive &&
|
|
47542
|
+
const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync27(s.path));
|
|
47543
|
+
const bare = !additive && existsSync27(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
|
|
46709
47544
|
const copyResolver = additive ? (sourceName, legacyTable) => {
|
|
46710
47545
|
const r = resolveTarget(sourceName, legacyTable);
|
|
46711
47546
|
return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
|
|
@@ -46724,7 +47559,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
46724
47559
|
stagingDir: null,
|
|
46725
47560
|
receiptPath: null
|
|
46726
47561
|
};
|
|
46727
|
-
if (sources.length === 0 || !
|
|
47562
|
+
if (sources.length === 0 || !existsSync27(liveStorePath)) {
|
|
46728
47563
|
return {
|
|
46729
47564
|
...base,
|
|
46730
47565
|
outcome: "nothing-to-reconcile",
|
|
@@ -46916,11 +47751,11 @@ var init_seal = __esm({
|
|
|
46916
47751
|
});
|
|
46917
47752
|
|
|
46918
47753
|
// packages/core/src/store/exodus/status.ts
|
|
46919
|
-
import { existsSync as
|
|
47754
|
+
import { existsSync as existsSync28, readdirSync as readdirSync7, readFileSync as readFileSync11, statSync as statSync9 } from "node:fs";
|
|
46920
47755
|
import { join as join32 } from "node:path";
|
|
46921
47756
|
function readJournal2(stagingDir) {
|
|
46922
47757
|
const p = join32(stagingDir, JOURNAL_FILENAME2);
|
|
46923
|
-
if (!
|
|
47758
|
+
if (!existsSync28(p)) return null;
|
|
46924
47759
|
try {
|
|
46925
47760
|
return JSON.parse(readFileSync11(p, "utf8"));
|
|
46926
47761
|
} catch {
|
|
@@ -46952,15 +47787,15 @@ function runExodusStatus(cwd) {
|
|
|
46952
47787
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
46953
47788
|
name: s.name,
|
|
46954
47789
|
path: s.path,
|
|
46955
|
-
exists:
|
|
47790
|
+
exists: existsSync28(s.path),
|
|
46956
47791
|
bytes: safeBytes(s.path)
|
|
46957
47792
|
}));
|
|
46958
47793
|
return {
|
|
46959
47794
|
hasStaging: latestStaging !== null,
|
|
46960
47795
|
stagingDir: latestStaging,
|
|
46961
47796
|
journal,
|
|
46962
|
-
projectDbExists:
|
|
46963
|
-
globalDbExists:
|
|
47797
|
+
projectDbExists: existsSync28(projectDbPath),
|
|
47798
|
+
globalDbExists: existsSync28(globalDbPath),
|
|
46964
47799
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
46965
47800
|
sources: sourcesInfo
|
|
46966
47801
|
};
|
|
@@ -46977,7 +47812,7 @@ var init_status = __esm({
|
|
|
46977
47812
|
});
|
|
46978
47813
|
|
|
46979
47814
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
46980
|
-
import { existsSync as
|
|
47815
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
46981
47816
|
import { createRequire as createRequire10 } from "node:module";
|
|
46982
47817
|
function orderByClause(db, tableName) {
|
|
46983
47818
|
try {
|
|
@@ -47092,7 +47927,7 @@ function listTables3(db) {
|
|
|
47092
47927
|
).all();
|
|
47093
47928
|
return rows.map((r) => r.name);
|
|
47094
47929
|
}
|
|
47095
|
-
function
|
|
47930
|
+
function tableExists4(db, tableName) {
|
|
47096
47931
|
try {
|
|
47097
47932
|
const escaped = tableName.replace(/'/g, "''");
|
|
47098
47933
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
@@ -47242,10 +48077,10 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
|
|
|
47242
48077
|
const anyFeeder = (targetTable, probe) => {
|
|
47243
48078
|
for (const feeder of feedersOf(targetTable)) {
|
|
47244
48079
|
const src = sources.find((s) => s.name === feeder.sourceName);
|
|
47245
|
-
if (src === void 0 || !
|
|
48080
|
+
if (src === void 0 || !existsSync29(src.path)) continue;
|
|
47246
48081
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
47247
48082
|
try {
|
|
47248
|
-
if (!
|
|
48083
|
+
if (!tableExists4(snap.db, feeder.legacyTable)) continue;
|
|
47249
48084
|
const cols = new Set(
|
|
47250
48085
|
snap.db.prepare(`PRAGMA table_info("${feeder.legacyTable}")`).all().map((c) => c.name)
|
|
47251
48086
|
);
|
|
@@ -47297,7 +48132,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47297
48132
|
const preExistingForeignKeyViolations = [];
|
|
47298
48133
|
const failureLines = [];
|
|
47299
48134
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
47300
|
-
if (!
|
|
48135
|
+
if (!existsSync29(projectDbPath)) {
|
|
47301
48136
|
return {
|
|
47302
48137
|
ok: false,
|
|
47303
48138
|
tables: [],
|
|
@@ -47308,7 +48143,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47308
48143
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
47309
48144
|
};
|
|
47310
48145
|
}
|
|
47311
|
-
if (!
|
|
48146
|
+
if (!existsSync29(globalDbPath)) {
|
|
47312
48147
|
return {
|
|
47313
48148
|
ok: false,
|
|
47314
48149
|
tables: [],
|
|
@@ -47323,7 +48158,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47323
48158
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
47324
48159
|
try {
|
|
47325
48160
|
for (const src of sources) {
|
|
47326
|
-
if (!
|
|
48161
|
+
if (!existsSync29(src.path)) {
|
|
47327
48162
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
47328
48163
|
continue;
|
|
47329
48164
|
}
|
|
@@ -47448,7 +48283,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47448
48283
|
targetOrphans.push(...foreignKeyCheck(globalSnap.db, "global"));
|
|
47449
48284
|
foreignKeyViolations.push(...targetOrphans);
|
|
47450
48285
|
for (const fk of targetOrphans) {
|
|
47451
|
-
const orphanDb =
|
|
48286
|
+
const orphanDb = tableExists4(projectSnap.db, fk.table) ? projectSnap.db : globalSnap.db;
|
|
47452
48287
|
const sig = orphanSignature(orphanDb, fk);
|
|
47453
48288
|
const preExisting = sourceOrphanSigs.has(sig) || orphanAlreadyInSource(orphanDb, fk, sources, resolveTarget);
|
|
47454
48289
|
if (preExisting) {
|
|
@@ -47614,7 +48449,7 @@ __export(on_open_exports, {
|
|
|
47614
48449
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
|
|
47615
48450
|
withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
|
|
47616
48451
|
});
|
|
47617
|
-
import { existsSync as
|
|
48452
|
+
import { existsSync as existsSync30, mkdtempSync as mkdtempSync2, rmSync as rmSync4 } from "node:fs";
|
|
47618
48453
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
47619
48454
|
import { join as join33, resolve as resolve13 } from "node:path";
|
|
47620
48455
|
async function withExodusOnOpenSuppressed(dbPath, fn) {
|
|
@@ -47656,7 +48491,7 @@ function remedyFor(scope) {
|
|
|
47656
48491
|
}
|
|
47657
48492
|
async function strandedLegacySources(scope, cwd) {
|
|
47658
48493
|
const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
47659
|
-
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope &&
|
|
48494
|
+
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync30(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
|
|
47660
48495
|
}
|
|
47661
48496
|
async function exodusStoreRewriteRefusal(dbPath, cwd) {
|
|
47662
48497
|
const { assertOwnerStoreRewriteConfirmed: assertOwnerStoreRewriteConfirmed2, invocationDirectory: invocationDirectory2 } = await Promise.resolve().then(() => (init_worktree_isolation_guard(), worktree_isolation_guard_exports));
|
|
@@ -47788,7 +48623,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47788
48623
|
};
|
|
47789
48624
|
}
|
|
47790
48625
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
47791
|
-
if (!scopeSources.some((s) =>
|
|
48626
|
+
if (!scopeSources.some((s) => existsSync30(s.path))) {
|
|
47792
48627
|
return {
|
|
47793
48628
|
outcome: "skipped",
|
|
47794
48629
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -47813,7 +48648,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47813
48648
|
{
|
|
47814
48649
|
scope,
|
|
47815
48650
|
dbPath,
|
|
47816
|
-
sources: plan.sources.filter((s) =>
|
|
48651
|
+
sources: plan.sources.filter((s) => existsSync30(s.path)).map((s) => s.name)
|
|
47817
48652
|
},
|
|
47818
48653
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
47819
48654
|
);
|
|
@@ -47826,7 +48661,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47826
48661
|
const bare = scope === "project" ? await unmigratedBareSources2(
|
|
47827
48662
|
dbPath,
|
|
47828
48663
|
resolveTarget,
|
|
47829
|
-
plan.sources.find((s) => s.name === "tasks" &&
|
|
48664
|
+
plan.sources.find((s) => s.name === "tasks" && existsSync30(s.path))?.path,
|
|
47830
48665
|
bareScratch
|
|
47831
48666
|
) : { first: [], last: [] };
|
|
47832
48667
|
const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
|
|
@@ -47890,7 +48725,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47890
48725
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
47891
48726
|
);
|
|
47892
48727
|
try {
|
|
47893
|
-
const consumed = plan.sources.filter((s) =>
|
|
48728
|
+
const consumed = plan.sources.filter((s) => existsSync30(s.path));
|
|
47894
48729
|
const identities = await sealTargets(plan, consumed);
|
|
47895
48730
|
const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
|
|
47896
48731
|
log14.info(
|
|
@@ -47965,7 +48800,7 @@ __export(dual_scope_db_exports, {
|
|
|
47965
48800
|
upsertIdempotent: () => upsertIdempotent,
|
|
47966
48801
|
withStoreSchemaOwnership: () => withStoreSchemaOwnership
|
|
47967
48802
|
});
|
|
47968
|
-
import { existsSync as
|
|
48803
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync10 } from "node:fs";
|
|
47969
48804
|
import { createRequire as createRequire11 } from "node:module";
|
|
47970
48805
|
import { dirname as dirname21, join as join34, resolve as resolve14 } from "node:path";
|
|
47971
48806
|
function getDualScopeNativeDb(handle) {
|
|
@@ -48038,11 +48873,15 @@ async function openDualScopeDb(scope, cwd, options) {
|
|
|
48038
48873
|
open
|
|
48039
48874
|
) : open();
|
|
48040
48875
|
}
|
|
48876
|
+
function identityWorkOnOpen(nativeDb, scope) {
|
|
48877
|
+
if (ROW_IDENTITY[scope].length === 0) return false;
|
|
48878
|
+
return rowUidFillEnabled() || missingRowIdentitySchema(nativeDb).length > 0;
|
|
48879
|
+
}
|
|
48041
48880
|
async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
48042
48881
|
execution?.assertActive();
|
|
48043
48882
|
log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
48044
48883
|
const dir = dirname21(dbPath);
|
|
48045
|
-
if (!
|
|
48884
|
+
if (!existsSync31(dir)) {
|
|
48046
48885
|
mkdirSync10(dir, { recursive: true });
|
|
48047
48886
|
}
|
|
48048
48887
|
execution?.assertActive();
|
|
@@ -48075,9 +48914,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
48075
48914
|
`dual-scope-db[${scope}]`
|
|
48076
48915
|
);
|
|
48077
48916
|
execution?.assertActive();
|
|
48078
|
-
if (
|
|
48917
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
48079
48918
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
48080
|
-
|
|
48919
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
48920
|
+
if (rowUidFillEnabled()) {
|
|
48921
|
+
prepareRowIdentity(nativeDb, scope, { triggers: false });
|
|
48922
|
+
}
|
|
48081
48923
|
}
|
|
48082
48924
|
execution?.assertActive();
|
|
48083
48925
|
log15.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
|
|
@@ -48190,7 +49032,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48190
49032
|
execution?.assertActive();
|
|
48191
49033
|
log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
|
|
48192
49034
|
const dir = dirname21(normalizedPath);
|
|
48193
|
-
if (!
|
|
49035
|
+
if (!existsSync31(dir)) {
|
|
48194
49036
|
mkdirSync10(dir, { recursive: true });
|
|
48195
49037
|
}
|
|
48196
49038
|
execution?.assertActive();
|
|
@@ -48223,9 +49065,12 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48223
49065
|
`dual-scope-db[${scope}]`
|
|
48224
49066
|
);
|
|
48225
49067
|
execution?.assertActive();
|
|
48226
|
-
if (
|
|
49068
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
48227
49069
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
48228
|
-
|
|
49070
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
49071
|
+
if (rowUidFillEnabled()) {
|
|
49072
|
+
prepareRowIdentity(nativeDb, scope);
|
|
49073
|
+
}
|
|
48229
49074
|
}
|
|
48230
49075
|
execution?.assertActive();
|
|
48231
49076
|
log15.debug({ scope, dbPath: normalizedPath }, "dual-scope cleo.db ready");
|
|
@@ -49355,7 +50200,7 @@ __export(nexus_sqlite_exports, {
|
|
|
49355
50200
|
resetNexusDbState: () => resetNexusDbState,
|
|
49356
50201
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
49357
50202
|
});
|
|
49358
|
-
import { copyFileSync as copyFileSync8, existsSync as
|
|
50203
|
+
import { copyFileSync as copyFileSync8, existsSync as existsSync32 } from "node:fs";
|
|
49359
50204
|
import { join as join35 } from "node:path";
|
|
49360
50205
|
function getNexusDbPath(cwd) {
|
|
49361
50206
|
return resolveDualScopeDbPath("project", cwd);
|
|
@@ -49407,7 +50252,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49407
50252
|
} catch {
|
|
49408
50253
|
return false;
|
|
49409
50254
|
}
|
|
49410
|
-
if (!
|
|
50255
|
+
if (!existsSync32(nestedPath)) return false;
|
|
49411
50256
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
49412
50257
|
_warnedNestedPaths.add(nestedPath);
|
|
49413
50258
|
const canonicalPath = getNexusDbPath();
|
|
@@ -49427,7 +50272,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49427
50272
|
function _resetNestedNexusWarningGate() {
|
|
49428
50273
|
_warnedNestedPaths.clear();
|
|
49429
50274
|
}
|
|
49430
|
-
function
|
|
50275
|
+
function tableExists5(nativeDb, tableName) {
|
|
49431
50276
|
const result = nativeDb.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(tableName);
|
|
49432
50277
|
return !!result;
|
|
49433
50278
|
}
|
|
@@ -49436,7 +50281,7 @@ function objectExists(nativeDb, type, name15) {
|
|
|
49436
50281
|
return !!result;
|
|
49437
50282
|
}
|
|
49438
50283
|
function ensureNexusFts5(nativeDb) {
|
|
49439
|
-
if (!
|
|
50284
|
+
if (!tableExists5(nativeDb, "nexus_nodes")) return;
|
|
49440
50285
|
if (!objectExists(nativeDb, "table", "nexus_symbols_fts")) {
|
|
49441
50286
|
nativeDb.exec(`
|
|
49442
50287
|
CREATE VIRTUAL TABLE nexus_symbols_fts USING fts5(
|
|
@@ -49482,7 +50327,7 @@ function ensureNexusFts5(nativeDb) {
|
|
|
49482
50327
|
`);
|
|
49483
50328
|
}
|
|
49484
50329
|
function ensureNexusRelationWeights(nativeDb) {
|
|
49485
|
-
if (!
|
|
50330
|
+
if (!tableExists5(nativeDb, "nexus_relations")) return;
|
|
49486
50331
|
nativeDb.exec(`
|
|
49487
50332
|
CREATE TABLE IF NOT EXISTS nexus_relation_weights (
|
|
49488
50333
|
relation_id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -49564,9 +50409,9 @@ function ensureNexusRelationWeights(nativeDb) {
|
|
|
49564
50409
|
}
|
|
49565
50410
|
function runNexusMigrations(nativeDb, db, dbPath) {
|
|
49566
50411
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
49567
|
-
if (
|
|
50412
|
+
if (tableExists5(nativeDb, "nexus_nodes")) {
|
|
49568
50413
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
49569
|
-
if (!
|
|
50414
|
+
if (!existsSync32(backupPath)) {
|
|
49570
50415
|
try {
|
|
49571
50416
|
copyFileSync8(dbPath, backupPath);
|
|
49572
50417
|
} catch {
|
|
@@ -49696,13 +50541,13 @@ var init_legacy_alias = __esm({
|
|
|
49696
50541
|
|
|
49697
50542
|
// packages/core/src/llm/stable-device-id.ts
|
|
49698
50543
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
49699
|
-
import { existsSync as
|
|
50544
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync11, readFileSync as readFileSync12, renameSync as renameSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
49700
50545
|
import { dirname as dirname22 } from "node:path";
|
|
49701
50546
|
import { resolveStableDeviceIdPath } from "@cleocode/paths";
|
|
49702
50547
|
function getStableDeviceId() {
|
|
49703
50548
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
49704
50549
|
const path = resolveStableDeviceIdPath();
|
|
49705
|
-
if (
|
|
50550
|
+
if (existsSync33(path)) {
|
|
49706
50551
|
try {
|
|
49707
50552
|
const raw = readFileSync12(path, "utf-8").trim();
|
|
49708
50553
|
if (raw.length > 0) {
|
|
@@ -49715,7 +50560,7 @@ function getStableDeviceId() {
|
|
|
49715
50560
|
const fresh = randomUUID3();
|
|
49716
50561
|
try {
|
|
49717
50562
|
const dir = dirname22(path);
|
|
49718
|
-
if (!
|
|
50563
|
+
if (!existsSync33(dir)) {
|
|
49719
50564
|
mkdirSync11(dir, { recursive: true });
|
|
49720
50565
|
}
|
|
49721
50566
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
@@ -49791,11 +50636,11 @@ __export(path_map_exports, {
|
|
|
49791
50636
|
supersededRegistryPath: () => supersededRegistryPath,
|
|
49792
50637
|
touchProjectLocation: () => touchProjectLocation
|
|
49793
50638
|
});
|
|
49794
|
-
import { existsSync as
|
|
50639
|
+
import { existsSync as existsSync34, lstatSync, readdirSync as readdirSync8 } from "node:fs";
|
|
49795
50640
|
import { lstat, readdir as readdir2 } from "node:fs/promises";
|
|
49796
50641
|
import { isAbsolute as isAbsolute5, join as join36, relative as relative3, sep as sep5 } from "node:path";
|
|
49797
50642
|
import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity4 } from "@cleocode/paths";
|
|
49798
|
-
import { and as and9, desc as desc3, eq as eq12, inArray as
|
|
50643
|
+
import { and as and9, desc as desc3, eq as eq12, inArray as inArray7, ne as ne3 } from "drizzle-orm";
|
|
49799
50644
|
function holdingKey(projectId, path) {
|
|
49800
50645
|
return `${projectId}\0${path}`;
|
|
49801
50646
|
}
|
|
@@ -49943,7 +50788,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49943
50788
|
const here = db.select({ state: projectLocations.state, checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49944
50789
|
and9(
|
|
49945
50790
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49946
|
-
|
|
50791
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49947
50792
|
eq12(projectLocations.path, record2.projectPath)
|
|
49948
50793
|
)
|
|
49949
50794
|
).all();
|
|
@@ -49954,7 +50799,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49954
50799
|
const previous = () => db.select({ checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49955
50800
|
and9(
|
|
49956
50801
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49957
|
-
|
|
50802
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49958
50803
|
eq12(projectLocations.path, oldPath)
|
|
49959
50804
|
)
|
|
49960
50805
|
).all();
|
|
@@ -50002,7 +50847,7 @@ function hasOtherLiveLocation(db, record2, deviceId) {
|
|
|
50002
50847
|
ne3(projectLocations.path, record2.projectPath)
|
|
50003
50848
|
)
|
|
50004
50849
|
).all().some(
|
|
50005
|
-
(location) => isStrictlyInside(record2.projectPath, location.path) &&
|
|
50850
|
+
(location) => isStrictlyInside(record2.projectPath, location.path) && existsSync34(location.path) && readDeclaredProjectIdentity4(location.path)?.projectId === record2.projectId
|
|
50006
50851
|
);
|
|
50007
50852
|
}
|
|
50008
50853
|
function demoteProjectLocation(db, record2, state) {
|
|
@@ -50053,7 +50898,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
|
|
|
50053
50898
|
).orderBy(desc3(projectLocations.lastSeen)).all();
|
|
50054
50899
|
const present = (path) => {
|
|
50055
50900
|
const holding = probed?.get(holdingKey(row.projectId, path));
|
|
50056
|
-
return holding === void 0 ?
|
|
50901
|
+
return holding === void 0 ? existsSync34(path) : holding === "yes";
|
|
50057
50902
|
};
|
|
50058
50903
|
const home = candidates.find(
|
|
50059
50904
|
(c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq12(projectRegistry.projectPath, c.path)).all().length === 0
|
|
@@ -50082,7 +50927,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
|
|
|
50082
50927
|
projectHash: generateProjectHash(row.path),
|
|
50083
50928
|
firstSeen: row.firstSeen,
|
|
50084
50929
|
lastSeen: row.lastSeen,
|
|
50085
|
-
exists: local &&
|
|
50930
|
+
exists: local && existsSync34(row.path),
|
|
50086
50931
|
deviceId: local ? deviceId : row.deviceId,
|
|
50087
50932
|
state: row.state
|
|
50088
50933
|
});
|
|
@@ -50115,7 +50960,7 @@ __export(project_activity_exports, {
|
|
|
50115
50960
|
projectLastActivitySql: () => projectLastActivitySql,
|
|
50116
50961
|
projectLastActivitySqlText: () => projectLastActivitySqlText
|
|
50117
50962
|
});
|
|
50118
|
-
import { eq as eq13, inArray as
|
|
50963
|
+
import { eq as eq13, inArray as inArray8, sql as sql32 } from "drizzle-orm";
|
|
50119
50964
|
function normalizeRegistryTimestamp(value) {
|
|
50120
50965
|
if (value === null || value === void 0 || value.length === 0) return null;
|
|
50121
50966
|
const iso = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value) ? `${value.replace(" ", "T")}Z` : value;
|
|
@@ -50144,7 +50989,7 @@ function markProjectsProbed(db, projectIds, now = /* @__PURE__ */ new Date()) {
|
|
|
50144
50989
|
for (let i = 0; i < ids.length; i += PROBED_CHUNK) {
|
|
50145
50990
|
const chunk = ids.slice(i, i + PROBED_CHUNK);
|
|
50146
50991
|
changed += Number(
|
|
50147
|
-
db.update(projectRegistry).set({ lastProbedAt: at }).where(
|
|
50992
|
+
db.update(projectRegistry).set({ lastProbedAt: at }).where(inArray8(projectRegistry.projectId, chunk)).run().changes
|
|
50148
50993
|
);
|
|
50149
50994
|
}
|
|
50150
50995
|
return changed;
|
|
@@ -50177,11 +51022,11 @@ __export(checkout_nonce_exports, {
|
|
|
50177
51022
|
readCheckoutNonce: () => readCheckoutNonce
|
|
50178
51023
|
});
|
|
50179
51024
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
50180
|
-
import { existsSync as
|
|
51025
|
+
import { existsSync as existsSync35, readFileSync as readFileSync13, renameSync as renameSync10, writeFileSync as writeFileSync10 } from "node:fs";
|
|
50181
51026
|
import { join as join37 } from "node:path";
|
|
50182
51027
|
function readInfo(projectRoot) {
|
|
50183
51028
|
const path = join37(projectRoot, ".cleo", "project-info.json");
|
|
50184
|
-
if (!
|
|
51029
|
+
if (!existsSync35(path)) return null;
|
|
50185
51030
|
try {
|
|
50186
51031
|
const parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
50187
51032
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
@@ -50274,7 +51119,7 @@ __export(paths_exports, {
|
|
|
50274
51119
|
validateProjectRoot: () => validateProjectRoot,
|
|
50275
51120
|
worktreeScope: () => worktreeScope
|
|
50276
51121
|
});
|
|
50277
|
-
import { existsSync as
|
|
51122
|
+
import { existsSync as existsSync36, readFileSync as readFileSync14, statSync as statSync10 } from "node:fs";
|
|
50278
51123
|
import { createRequire as createRequire12 } from "node:module";
|
|
50279
51124
|
import { homedir as homedir2 } from "node:os";
|
|
50280
51125
|
import { dirname as dirname23, join as join38, resolve as resolve15 } from "node:path";
|
|
@@ -50300,7 +51145,7 @@ function runWithWorktreeScopeFromEnv(fn) {
|
|
|
50300
51145
|
function isProjectInitialized(projectRoot) {
|
|
50301
51146
|
const root = projectRoot ?? getProjectRoot();
|
|
50302
51147
|
const cleoDir = join38(root, ".cleo");
|
|
50303
|
-
return
|
|
51148
|
+
return existsSync36(cleoDir) && existsSync36(join38(cleoDir, "tasks.db"));
|
|
50304
51149
|
}
|
|
50305
51150
|
function getCleoHome() {
|
|
50306
51151
|
return getPlatformPaths().data;
|
|
@@ -50406,7 +51251,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
50406
51251
|
try {
|
|
50407
51252
|
const cleoHome = getCleoHome();
|
|
50408
51253
|
const globalDbPath = join38(cleoHome, "cleo.db");
|
|
50409
|
-
if (!
|
|
51254
|
+
if (!existsSync36(globalDbPath)) return null;
|
|
50410
51255
|
const start = resolve15(cwd ?? process.cwd());
|
|
50411
51256
|
let current = start;
|
|
50412
51257
|
const DatabaseSync3 = _getDatabaseSyncCtor();
|
|
@@ -50569,7 +51414,7 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
50569
51414
|
while (true) {
|
|
50570
51415
|
const gitMarker = join38(current, ".git");
|
|
50571
51416
|
try {
|
|
50572
|
-
if (
|
|
51417
|
+
if (existsSync36(gitMarker)) {
|
|
50573
51418
|
return true;
|
|
50574
51419
|
}
|
|
50575
51420
|
} catch {
|
|
@@ -50647,7 +51492,7 @@ function getCleoGlobalCantAgentsDir() {
|
|
|
50647
51492
|
function getAgentOutputsDir(cwd) {
|
|
50648
51493
|
const projectRoot = getProjectRoot(cwd);
|
|
50649
51494
|
const configPath = join38(projectRoot, ".cleo", "config.json");
|
|
50650
|
-
if (
|
|
51495
|
+
if (existsSync36(configPath)) {
|
|
50651
51496
|
try {
|
|
50652
51497
|
const config2 = JSON.parse(readFileSync14(configPath, "utf-8"));
|
|
50653
51498
|
if (typeof config2.agentOutputs === "object" && config2.agentOutputs?.directory) {
|
|
@@ -50680,7 +51525,7 @@ function getManifestPath(cwd) {
|
|
|
50680
51525
|
const configPath = join38(projectRoot, ".cleo", "config.json");
|
|
50681
51526
|
const legacyFileName = ["MANIFEST", "jsonl"].join(".");
|
|
50682
51527
|
let manifestFile = legacyFileName;
|
|
50683
|
-
if (
|
|
51528
|
+
if (existsSync36(configPath)) {
|
|
50684
51529
|
try {
|
|
50685
51530
|
const config2 = JSON.parse(readFileSync14(configPath, "utf-8"));
|
|
50686
51531
|
const customFile = config2.agentOutputs?.manifestFile ?? config2.research?.manifestFile;
|
|
@@ -50736,7 +51581,7 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
50736
51581
|
while (current !== home && current !== "/" && current !== "") {
|
|
50737
51582
|
const gitPath = join38(current, ".git");
|
|
50738
51583
|
try {
|
|
50739
|
-
if (
|
|
51584
|
+
if (existsSync36(gitPath)) {
|
|
50740
51585
|
const stat3 = statSync10(gitPath);
|
|
50741
51586
|
if (stat3.isFile()) {
|
|
50742
51587
|
worktreePath = current;
|
|
@@ -50775,7 +51620,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50775
51620
|
}
|
|
50776
51621
|
const tasksDbPath = join38(routing.worktreePath, ".cleo", "tasks.db");
|
|
50777
51622
|
try {
|
|
50778
|
-
if (
|
|
51623
|
+
if (existsSync36(tasksDbPath) && statSync10(tasksDbPath).isFile()) {
|
|
50779
51624
|
return tasksDbPath;
|
|
50780
51625
|
}
|
|
50781
51626
|
} catch {
|
|
@@ -50785,7 +51630,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50785
51630
|
async function resolveProjectById(projectId) {
|
|
50786
51631
|
try {
|
|
50787
51632
|
const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50788
|
-
if (!
|
|
51633
|
+
if (!existsSync36(getNexusRegistryDbPath2())) return null;
|
|
50789
51634
|
const { eq: eq14 } = await import("drizzle-orm");
|
|
50790
51635
|
const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50791
51636
|
const db = await getNexusDb2();
|
|
@@ -50821,7 +51666,7 @@ function _rowToRegistryEntry(row) {
|
|
|
50821
51666
|
}
|
|
50822
51667
|
function _assertProjectInfoReadable(projectRoot) {
|
|
50823
51668
|
const infoPath = join38(projectRoot, ".cleo", "project-info.json");
|
|
50824
|
-
if (
|
|
51669
|
+
if (existsSync36(infoPath)) JSON.parse(readFileSync14(infoPath, "utf-8"));
|
|
50825
51670
|
}
|
|
50826
51671
|
function startProjectEncounter(key, projectRoot, infoProjectId) {
|
|
50827
51672
|
const inFlight2 = _encountersInFlight.get(key);
|
|
@@ -50870,7 +51715,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50870
51715
|
if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
|
|
50871
51716
|
const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
|
|
50872
51717
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50873
|
-
if (
|
|
51718
|
+
if (existsSync36(getNexusRegistryDbPath2(cleoHome))) {
|
|
50874
51719
|
const { and: and10, eq: eq14 } = await import("drizzle-orm");
|
|
50875
51720
|
const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50876
51721
|
const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
|
|
@@ -50896,7 +51741,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50896
51741
|
}
|
|
50897
51742
|
async function markEncounterOpened(cleoHome, projectId) {
|
|
50898
51743
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50899
|
-
if (!
|
|
51744
|
+
if (!existsSync36(getNexusRegistryDbPath2(cleoHome))) return;
|
|
50900
51745
|
const { markProjectOpened: markProjectOpened2 } = await Promise.resolve().then(() => (init_project_activity(), project_activity_exports));
|
|
50901
51746
|
markProjectOpened2(await getNexusRegistryDb2(cleoHome), projectId);
|
|
50902
51747
|
}
|
|
@@ -51139,7 +51984,7 @@ var init_api_mode = __esm({
|
|
|
51139
51984
|
// packages/core/src/store/file-utils.ts
|
|
51140
51985
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
51141
51986
|
import {
|
|
51142
|
-
existsSync as
|
|
51987
|
+
existsSync as existsSync37,
|
|
51143
51988
|
mkdirSync as mkdirSync12,
|
|
51144
51989
|
readdirSync as readdirSync9,
|
|
51145
51990
|
readFileSync as readFileSync15,
|
|
@@ -51154,7 +51999,7 @@ function rotateBackup(filePath, mode) {
|
|
|
51154
51999
|
const name15 = basename11(filePath);
|
|
51155
52000
|
const backupDir = join39(dir, ".backups");
|
|
51156
52001
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
51157
|
-
if (!
|
|
52002
|
+
if (!existsSync37(backupDir)) {
|
|
51158
52003
|
mkdirSync12(backupDir, { recursive: true, mode: dirMode });
|
|
51159
52004
|
}
|
|
51160
52005
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
@@ -51167,7 +52012,7 @@ function rotateBackup(filePath, mode) {
|
|
|
51167
52012
|
} else {
|
|
51168
52013
|
const next = join39(backupDir, `${name15}.${i + 1}`);
|
|
51169
52014
|
try {
|
|
51170
|
-
if (
|
|
52015
|
+
if (existsSync37(current)) renameSync11(current, next);
|
|
51171
52016
|
} catch {
|
|
51172
52017
|
}
|
|
51173
52018
|
}
|
|
@@ -51203,7 +52048,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
51203
52048
|
writeFileSync11(tempPath, content, "utf-8");
|
|
51204
52049
|
}
|
|
51205
52050
|
try {
|
|
51206
|
-
if (
|
|
52051
|
+
if (existsSync37(filePath)) {
|
|
51207
52052
|
rotateBackup(filePath, mode);
|
|
51208
52053
|
}
|
|
51209
52054
|
renameSync11(tempPath, filePath);
|
|
@@ -51229,10 +52074,10 @@ function readJsonFile(filePath) {
|
|
|
51229
52074
|
async function withLock2(filePath, transform2, opts = {}) {
|
|
51230
52075
|
const dir = dirname24(filePath);
|
|
51231
52076
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
51232
|
-
if (!
|
|
52077
|
+
if (!existsSync37(dir)) {
|
|
51233
52078
|
mkdirSync12(dir, { recursive: true, mode: dirMode });
|
|
51234
52079
|
}
|
|
51235
|
-
if (!
|
|
52080
|
+
if (!existsSync37(filePath)) {
|
|
51236
52081
|
if (typeof opts.mode === "number") {
|
|
51237
52082
|
writeFileSync11(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
51238
52083
|
} else {
|
|
@@ -51254,10 +52099,10 @@ async function withLock2(filePath, transform2, opts = {}) {
|
|
|
51254
52099
|
}
|
|
51255
52100
|
async function withFileLock(filePath, operation) {
|
|
51256
52101
|
const dir = dirname24(filePath);
|
|
51257
|
-
if (!
|
|
52102
|
+
if (!existsSync37(dir)) {
|
|
51258
52103
|
mkdirSync12(dir, { recursive: true });
|
|
51259
52104
|
}
|
|
51260
|
-
if (!
|
|
52105
|
+
if (!existsSync37(filePath)) {
|
|
51261
52106
|
writeFileSync11(filePath, "", "utf-8");
|
|
51262
52107
|
}
|
|
51263
52108
|
let release;
|
|
@@ -51614,7 +52459,7 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
51614
52459
|
});
|
|
51615
52460
|
|
|
51616
52461
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
51617
|
-
import { existsSync as
|
|
52462
|
+
import { existsSync as existsSync38, readFileSync as readFileSync18 } from "node:fs";
|
|
51618
52463
|
import { homedir as homedir4 } from "node:os";
|
|
51619
52464
|
import { join as join43 } from "node:path";
|
|
51620
52465
|
function getCodexAuthPath() {
|
|
@@ -51639,7 +52484,7 @@ var init_codex_cli_seeder = __esm({
|
|
|
51639
52484
|
*/
|
|
51640
52485
|
async seed() {
|
|
51641
52486
|
const authPath = getCodexAuthPath();
|
|
51642
|
-
if (!
|
|
52487
|
+
if (!existsSync38(authPath)) {
|
|
51643
52488
|
return { entries: [] };
|
|
51644
52489
|
}
|
|
51645
52490
|
let raw;
|
|
@@ -51834,7 +52679,7 @@ var init_google_pkce = __esm({
|
|
|
51834
52679
|
});
|
|
51835
52680
|
|
|
51836
52681
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
51837
|
-
import { existsSync as
|
|
52682
|
+
import { existsSync as existsSync39, readFileSync as readFileSync19 } from "node:fs";
|
|
51838
52683
|
import { join as join44 } from "node:path";
|
|
51839
52684
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
51840
52685
|
function getGoogleOauthPath() {
|
|
@@ -51883,7 +52728,7 @@ var init_gemini_cli_seeder = __esm({
|
|
|
51883
52728
|
*/
|
|
51884
52729
|
async seed() {
|
|
51885
52730
|
const path = getGoogleOauthPath();
|
|
51886
|
-
if (!
|
|
52731
|
+
if (!existsSync39(path)) {
|
|
51887
52732
|
return { entries: [] };
|
|
51888
52733
|
}
|
|
51889
52734
|
let raw;
|
|
@@ -52108,7 +52953,7 @@ var init_credential_seeders = __esm({
|
|
|
52108
52953
|
|
|
52109
52954
|
// packages/core/src/llm/global-config-migration.ts
|
|
52110
52955
|
import {
|
|
52111
|
-
existsSync as
|
|
52956
|
+
existsSync as existsSync40,
|
|
52112
52957
|
mkdirSync as mkdirSync13,
|
|
52113
52958
|
readFileSync as readFileSync20,
|
|
52114
52959
|
renameSync as renameSync12,
|
|
@@ -52134,12 +52979,12 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
52134
52979
|
const source = legacyGlobalConfigPath();
|
|
52135
52980
|
const target = configDirGlobalConfigPath();
|
|
52136
52981
|
const marker16 = migrationMarkerPath();
|
|
52137
|
-
if (
|
|
52138
|
-
if (!
|
|
52982
|
+
if (existsSync40(marker16)) return false;
|
|
52983
|
+
if (!existsSync40(source)) {
|
|
52139
52984
|
stampMarker(marker16);
|
|
52140
52985
|
return false;
|
|
52141
52986
|
}
|
|
52142
|
-
if (
|
|
52987
|
+
if (existsSync40(target)) {
|
|
52143
52988
|
backupSourceQuiet(source);
|
|
52144
52989
|
stampMarker(marker16);
|
|
52145
52990
|
return false;
|
|
@@ -52172,7 +53017,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
52172
53017
|
} catch (err) {
|
|
52173
53018
|
try {
|
|
52174
53019
|
const temp = tempTargetPath();
|
|
52175
|
-
if (
|
|
53020
|
+
if (existsSync40(temp)) unlinkSync8(temp);
|
|
52176
53021
|
} catch {
|
|
52177
53022
|
}
|
|
52178
53023
|
console.error(
|
|
@@ -52192,7 +53037,7 @@ function stampMarker(markerPath) {
|
|
|
52192
53037
|
function backupSourceQuiet(source) {
|
|
52193
53038
|
try {
|
|
52194
53039
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
52195
|
-
if (
|
|
53040
|
+
if (existsSync40(backup)) return;
|
|
52196
53041
|
renameSync12(source, backup);
|
|
52197
53042
|
} catch {
|
|
52198
53043
|
}
|
|
@@ -52215,7 +53060,7 @@ var init_global_config_migration = __esm({
|
|
|
52215
53060
|
});
|
|
52216
53061
|
|
|
52217
53062
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
52218
|
-
import { existsSync as
|
|
53063
|
+
import { existsSync as existsSync41, readFileSync as readFileSync21, renameSync as renameSync13, writeFileSync as writeFileSync13 } from "node:fs";
|
|
52219
53064
|
import { join as join46 } from "node:path";
|
|
52220
53065
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
52221
53066
|
function migrationPaths() {
|
|
@@ -52244,7 +53089,7 @@ function writeMarker(markerPath) {
|
|
|
52244
53089
|
}
|
|
52245
53090
|
function readFlatKey(flatPath) {
|
|
52246
53091
|
try {
|
|
52247
|
-
if (!
|
|
53092
|
+
if (!existsSync41(flatPath)) return null;
|
|
52248
53093
|
const raw = readFileSync21(flatPath, "utf-8").trim();
|
|
52249
53094
|
return raw || null;
|
|
52250
53095
|
} catch (err) {
|
|
@@ -52257,7 +53102,7 @@ function readFlatKey(flatPath) {
|
|
|
52257
53102
|
}
|
|
52258
53103
|
async function importLegacyFlatAnthropicKey() {
|
|
52259
53104
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
52260
|
-
if (
|
|
53105
|
+
if (existsSync41(markerPath)) {
|
|
52261
53106
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
52262
53107
|
}
|
|
52263
53108
|
let existing = null;
|
|
@@ -52274,7 +53119,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
52274
53119
|
writeMarker(markerPath);
|
|
52275
53120
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
52276
53121
|
}
|
|
52277
|
-
if (!
|
|
53122
|
+
if (!existsSync41(flatPath)) {
|
|
52278
53123
|
writeMarker(markerPath);
|
|
52279
53124
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
52280
53125
|
}
|
|
@@ -52336,7 +53181,7 @@ var init_legacy_flat_key_import = __esm({
|
|
|
52336
53181
|
});
|
|
52337
53182
|
|
|
52338
53183
|
// packages/core/src/llm/credentials.ts
|
|
52339
|
-
import { existsSync as
|
|
53184
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
52340
53185
|
import { join as join47 } from "node:path";
|
|
52341
53186
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
52342
53187
|
function globalConfigPath() {
|
|
@@ -52355,7 +53200,7 @@ function readGlobalProviderKey(provider) {
|
|
|
52355
53200
|
function readFlatAnthropicKey() {
|
|
52356
53201
|
try {
|
|
52357
53202
|
const keyFile = join47(getCleoHome8(), "anthropic-key");
|
|
52358
|
-
if (!
|
|
53203
|
+
if (!existsSync42(keyFile)) return null;
|
|
52359
53204
|
const stored = readFileSync22(keyFile, "utf-8").trim();
|
|
52360
53205
|
return stored || null;
|
|
52361
53206
|
} catch {
|
|
@@ -52364,7 +53209,7 @@ function readFlatAnthropicKey() {
|
|
|
52364
53209
|
}
|
|
52365
53210
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
52366
53211
|
try {
|
|
52367
|
-
if (!
|
|
53212
|
+
if (!existsSync42(configFile)) return null;
|
|
52368
53213
|
const raw = readFileSync22(configFile, "utf-8");
|
|
52369
53214
|
const config2 = JSON.parse(raw);
|
|
52370
53215
|
const llm = config2["llm"];
|
|
@@ -52504,16 +53349,16 @@ __export(credentials_store_exports, {
|
|
|
52504
53349
|
pickCredentialForProviderSync: () => pickCredentialForProviderSync,
|
|
52505
53350
|
removeCredential: () => removeCredential
|
|
52506
53351
|
});
|
|
52507
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
53352
|
+
import { chmodSync as chmodSync2, existsSync as existsSync43, mkdirSync as mkdirSync15, readFileSync as readFileSync23, statSync as statSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
52508
53353
|
import { dirname as dirname25, join as join48 } from "node:path";
|
|
52509
53354
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
52510
53355
|
function credentialsStorePath() {
|
|
52511
53356
|
return join48(getCleoHome9(), "llm-credentials.json");
|
|
52512
53357
|
}
|
|
52513
53358
|
function ensureFileInitialized(path) {
|
|
52514
|
-
if (
|
|
53359
|
+
if (existsSync43(path)) return;
|
|
52515
53360
|
const dir = dirname25(path);
|
|
52516
|
-
if (!
|
|
53361
|
+
if (!existsSync43(dir)) {
|
|
52517
53362
|
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
52518
53363
|
} else {
|
|
52519
53364
|
try {
|
|
@@ -53211,8 +54056,8 @@ async function scanAndLoadPlugins(pluginDir, api) {
|
|
|
53211
54056
|
}
|
|
53212
54057
|
async function runDiscovery(registerProvider2, builtins) {
|
|
53213
54058
|
const api = { registerProvider: registerProvider2 };
|
|
53214
|
-
for (const
|
|
53215
|
-
registerProvider2(
|
|
54059
|
+
for (const profile2 of builtins) {
|
|
54060
|
+
registerProvider2(profile2);
|
|
53216
54061
|
}
|
|
53217
54062
|
await scanAndLoadPlugins(getPluginDir(), api);
|
|
53218
54063
|
}
|
|
@@ -53235,16 +54080,16 @@ __export(provider_registry_exports, {
|
|
|
53235
54080
|
listProviders: () => listProviders,
|
|
53236
54081
|
registerProvider: () => registerProvider
|
|
53237
54082
|
});
|
|
53238
|
-
function registerProvider(
|
|
53239
|
-
const key =
|
|
53240
|
-
_registry.set(key,
|
|
53241
|
-
for (const alias of
|
|
54083
|
+
function registerProvider(profile2) {
|
|
54084
|
+
const key = profile2.name.toLowerCase();
|
|
54085
|
+
_registry.set(key, profile2);
|
|
54086
|
+
for (const alias of profile2.aliases ?? []) {
|
|
53242
54087
|
const aliasKey = alias.toLowerCase();
|
|
53243
54088
|
const existing = _aliases.get(aliasKey);
|
|
53244
54089
|
if (existing !== void 0 && existing !== key) {
|
|
53245
54090
|
if (_registry.has(aliasKey) && aliasKey !== key) {
|
|
53246
54091
|
throw new TypeError(
|
|
53247
|
-
`[provider-registry] Alias "${alias}" for provider "${
|
|
54092
|
+
`[provider-registry] Alias "${alias}" for provider "${profile2.name}" conflicts with the primary name of provider "${_registry.get(aliasKey)?.name ?? aliasKey}".`
|
|
53248
54093
|
);
|
|
53249
54094
|
}
|
|
53250
54095
|
}
|
|
@@ -53309,7 +54154,7 @@ var init_provider_registry = __esm({
|
|
|
53309
54154
|
});
|
|
53310
54155
|
|
|
53311
54156
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
53312
|
-
import { existsSync as
|
|
54157
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9 } from "node:fs";
|
|
53313
54158
|
import { join as join50 } from "node:path";
|
|
53314
54159
|
import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
|
|
53315
54160
|
function sanitize(value) {
|
|
@@ -53365,7 +54210,7 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
53365
54210
|
}
|
|
53366
54211
|
const filePath = rateLimitStatePath(provider, label);
|
|
53367
54212
|
const dir = join50(getCleoHome10(), "rate-limit-state");
|
|
53368
|
-
if (!
|
|
54213
|
+
if (!existsSync44(dir)) {
|
|
53369
54214
|
mkdirSync16(dir, { recursive: true });
|
|
53370
54215
|
}
|
|
53371
54216
|
const state = { resetAt, recordedAt: now, source };
|
|
@@ -53706,8 +54551,8 @@ var init_credential_pool = __esm({
|
|
|
53706
54551
|
*/
|
|
53707
54552
|
async _refreshOAuthCredential(existing) {
|
|
53708
54553
|
if (!existing.refreshToken) return;
|
|
53709
|
-
const
|
|
53710
|
-
const oauthCfg =
|
|
54554
|
+
const profile2 = await getProviderProfile(this.provider);
|
|
54555
|
+
const oauthCfg = profile2?.oauth;
|
|
53711
54556
|
if (oauthCfg?.mode === "pkce") {
|
|
53712
54557
|
await this._refreshViaPkce(
|
|
53713
54558
|
existing,
|
|
@@ -53950,7 +54795,7 @@ var init_local_inference_probe = __esm({
|
|
|
53950
54795
|
|
|
53951
54796
|
// packages/core/src/llm/catalog-cache.ts
|
|
53952
54797
|
import {
|
|
53953
|
-
existsSync as
|
|
54798
|
+
existsSync as existsSync45,
|
|
53954
54799
|
mkdirSync as mkdirSync17,
|
|
53955
54800
|
readdirSync as readdirSync11,
|
|
53956
54801
|
readFileSync as readFileSync24,
|
|
@@ -53968,7 +54813,7 @@ function getCatalogDir() {
|
|
|
53968
54813
|
return join51(getCleoHome11(), "llm-catalog");
|
|
53969
54814
|
}
|
|
53970
54815
|
function findLatestCacheFile(dir) {
|
|
53971
|
-
if (!
|
|
54816
|
+
if (!existsSync45(dir)) return null;
|
|
53972
54817
|
const files = readdirSync11(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync13(join51(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
53973
54818
|
return files.length > 0 ? join51(dir, files[0].name) : null;
|
|
53974
54819
|
}
|
|
@@ -54216,15 +55061,15 @@ async function selectBestProvisioned(role, opts) {
|
|
|
54216
55061
|
const ollamaProvisioned = provisionedIds.includes("ollama");
|
|
54217
55062
|
let ollamaAlive = localModels.length > 0;
|
|
54218
55063
|
if (ollamaProvisioned && !ollamaAlive) {
|
|
54219
|
-
const
|
|
54220
|
-
const ollamaBase =
|
|
55064
|
+
const profile2 = await getProviderProfile2("ollama");
|
|
55065
|
+
const ollamaBase = profile2?.baseUrl ?? "http://localhost:11434";
|
|
54221
55066
|
ollamaAlive = await probeOllamaAlive(ollamaBase);
|
|
54222
55067
|
if (ollamaAlive) localModels = await listOllamaModels(ollamaBase);
|
|
54223
55068
|
}
|
|
54224
55069
|
const scored = [];
|
|
54225
55070
|
for (const id of provisionedIds) {
|
|
54226
|
-
const
|
|
54227
|
-
const tier =
|
|
55071
|
+
const profile2 = await getProviderProfile2(id);
|
|
55072
|
+
const tier = profile2?.tier ?? "standard";
|
|
54228
55073
|
const costInput = 0;
|
|
54229
55074
|
const score = scoreProvider(id, tier, taskTier, ollamaAlive, costInput);
|
|
54230
55075
|
const storedCred = await pickCredentialForProvider2(id, { strategy: "priorityOnly" });
|
|
@@ -54410,12 +55255,12 @@ function readLlmBlock(config2) {
|
|
|
54410
55255
|
}
|
|
54411
55256
|
function resolveNamedProfile(llm, name15, source) {
|
|
54412
55257
|
if (!name15) return void 0;
|
|
54413
|
-
const
|
|
54414
|
-
if (!
|
|
55258
|
+
const profile2 = llm?.profiles?.[name15];
|
|
55259
|
+
if (!profile2?.provider || !profile2.model) return void 0;
|
|
54415
55260
|
return {
|
|
54416
|
-
provider:
|
|
54417
|
-
model:
|
|
54418
|
-
credentialLabel:
|
|
55261
|
+
provider: profile2.provider,
|
|
55262
|
+
model: profile2.model,
|
|
55263
|
+
credentialLabel: profile2.credentialLabel,
|
|
54419
55264
|
source
|
|
54420
55265
|
};
|
|
54421
55266
|
}
|
|
@@ -54443,11 +55288,11 @@ function resolveSystemBinding(llm, systemKey) {
|
|
|
54443
55288
|
function resolveRegisteredSystemDefault(llm, systemKey) {
|
|
54444
55289
|
const defaults = getRegisteredSystemDefault(systemKey);
|
|
54445
55290
|
if (!defaults) return void 0;
|
|
54446
|
-
const
|
|
54447
|
-
if (
|
|
55291
|
+
const profile2 = resolveNamedProfile(llm, defaults.profile, "registered-default");
|
|
55292
|
+
if (profile2) {
|
|
54448
55293
|
return {
|
|
54449
|
-
...
|
|
54450
|
-
credentialLabel: defaults.credentialLabel ??
|
|
55294
|
+
...profile2,
|
|
55295
|
+
credentialLabel: defaults.credentialLabel ?? profile2.credentialLabel
|
|
54451
55296
|
};
|
|
54452
55297
|
}
|
|
54453
55298
|
if (defaults.provider && defaults.model) {
|
|
@@ -54902,13 +55747,13 @@ async function upgradeCatalogDefault(resolved) {
|
|
|
54902
55747
|
return resolved;
|
|
54903
55748
|
}
|
|
54904
55749
|
const { getProviderProfile: getProviderProfile2 } = await Promise.resolve().then(() => (init_provider_registry(), provider_registry_exports));
|
|
54905
|
-
const
|
|
54906
|
-
if (
|
|
55750
|
+
const profile2 = await getProviderProfile2(resolved.provider);
|
|
55751
|
+
if (profile2?.defaultModel && profile2.defaultModel !== resolved.model) {
|
|
54907
55752
|
logger6.debug(
|
|
54908
|
-
{ provider: resolved.provider, from: resolved.model, to:
|
|
55753
|
+
{ provider: resolved.provider, from: resolved.model, to: profile2.defaultModel },
|
|
54909
55754
|
"system-resolver: catalog empty \u2014 degrading to static builtin defaultModel floor"
|
|
54910
55755
|
);
|
|
54911
|
-
return { ...resolved, model:
|
|
55756
|
+
return { ...resolved, model: profile2.defaultModel };
|
|
54912
55757
|
}
|
|
54913
55758
|
return resolved;
|
|
54914
55759
|
} catch (err) {
|
|
@@ -56428,7 +57273,7 @@ var init_structured_output = __esm({
|
|
|
56428
57273
|
|
|
56429
57274
|
// packages/core/src/llm/transports/anthropic.ts
|
|
56430
57275
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
56431
|
-
import { z as
|
|
57276
|
+
import { z as z32 } from "zod";
|
|
56432
57277
|
function isTextBlock(block) {
|
|
56433
57278
|
return block.type === "text";
|
|
56434
57279
|
}
|
|
@@ -56500,8 +57345,8 @@ function mapUsage(usage) {
|
|
|
56500
57345
|
function zodSchemaFrom(responseFormat) {
|
|
56501
57346
|
if (responseFormat == null) return null;
|
|
56502
57347
|
const asAny = responseFormat;
|
|
56503
|
-
if (asAny["schema"] instanceof
|
|
56504
|
-
if (responseFormat instanceof
|
|
57348
|
+
if (asAny["schema"] instanceof z32.ZodType) return asAny["schema"];
|
|
57349
|
+
if (responseFormat instanceof z32.ZodType) return responseFormat;
|
|
56505
57350
|
return null;
|
|
56506
57351
|
}
|
|
56507
57352
|
function getJsonSchemaString(responseFormat) {
|
|
@@ -56907,7 +57752,7 @@ ${schemaJson}`
|
|
|
56907
57752
|
content = typeof validated === "string" ? validated : JSON.stringify(validated);
|
|
56908
57753
|
} catch {
|
|
56909
57754
|
try {
|
|
56910
|
-
const repaired = repairResponseModelJson(rawContent, zodSchema2 ??
|
|
57755
|
+
const repaired = repairResponseModelJson(rawContent, zodSchema2 ?? z32.unknown(), modelName);
|
|
56911
57756
|
content = typeof repaired === "string" ? repaired : JSON.stringify(repaired);
|
|
56912
57757
|
} catch {
|
|
56913
57758
|
content = rawContent || null;
|
|
@@ -58472,7 +59317,7 @@ var init_caching = __esm({
|
|
|
58472
59317
|
|
|
58473
59318
|
// packages/core/src/llm/transports/gemini.ts
|
|
58474
59319
|
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
58475
|
-
import { z as
|
|
59320
|
+
import { z as z33 } from "zod";
|
|
58476
59321
|
function messagesToRaw(messages, system) {
|
|
58477
59322
|
const raw = [];
|
|
58478
59323
|
if (system) {
|
|
@@ -58860,7 +59705,7 @@ var init_gemini2 = __esm({
|
|
|
58860
59705
|
const parsed = response["parsed"];
|
|
58861
59706
|
if (parsed !== null && parsed !== void 0) {
|
|
58862
59707
|
try {
|
|
58863
|
-
const zodResult =
|
|
59708
|
+
const zodResult = z33.string().safeParse(String(parsed));
|
|
58864
59709
|
if (!zodResult.success) {
|
|
58865
59710
|
content = JSON.stringify(parsed);
|
|
58866
59711
|
} else {
|
|
@@ -73257,7 +74102,7 @@ function resolveRef2(ref, ctx) {
|
|
|
73257
74102
|
function convertBaseSchema(schema, ctx) {
|
|
73258
74103
|
if (schema.not !== void 0) {
|
|
73259
74104
|
if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) {
|
|
73260
|
-
return
|
|
74105
|
+
return z34.never();
|
|
73261
74106
|
}
|
|
73262
74107
|
throw new Error("not is not supported in Zod (except { not: {} } for never)");
|
|
73263
74108
|
}
|
|
@@ -73279,7 +74124,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73279
74124
|
return ctx.refs.get(refPath);
|
|
73280
74125
|
}
|
|
73281
74126
|
if (ctx.processing.has(refPath)) {
|
|
73282
|
-
return
|
|
74127
|
+
return z34.lazy(() => {
|
|
73283
74128
|
if (!ctx.refs.has(refPath)) {
|
|
73284
74129
|
throw new Error(`Circular reference not resolved: ${refPath}`);
|
|
73285
74130
|
}
|
|
@@ -73296,25 +74141,25 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73296
74141
|
if (schema.enum !== void 0) {
|
|
73297
74142
|
const enumValues = schema.enum;
|
|
73298
74143
|
if (ctx.version === "openapi-3.0" && schema.nullable === true && enumValues.length === 1 && enumValues[0] === null) {
|
|
73299
|
-
return
|
|
74144
|
+
return z34.null();
|
|
73300
74145
|
}
|
|
73301
74146
|
if (enumValues.length === 0) {
|
|
73302
|
-
return
|
|
74147
|
+
return z34.never();
|
|
73303
74148
|
}
|
|
73304
74149
|
if (enumValues.length === 1) {
|
|
73305
|
-
return
|
|
74150
|
+
return z34.literal(enumValues[0]);
|
|
73306
74151
|
}
|
|
73307
74152
|
if (enumValues.every((v) => typeof v === "string")) {
|
|
73308
|
-
return
|
|
74153
|
+
return z34.enum(enumValues);
|
|
73309
74154
|
}
|
|
73310
|
-
const literalSchemas = enumValues.map((v) =>
|
|
74155
|
+
const literalSchemas = enumValues.map((v) => z34.literal(v));
|
|
73311
74156
|
if (literalSchemas.length < 2) {
|
|
73312
74157
|
return literalSchemas[0];
|
|
73313
74158
|
}
|
|
73314
|
-
return
|
|
74159
|
+
return z34.union([literalSchemas[0], literalSchemas[1], ...literalSchemas.slice(2)]);
|
|
73315
74160
|
}
|
|
73316
74161
|
if (schema.const !== void 0) {
|
|
73317
|
-
return
|
|
74162
|
+
return z34.literal(schema.const);
|
|
73318
74163
|
}
|
|
73319
74164
|
const type = schema.type;
|
|
73320
74165
|
if (Array.isArray(type)) {
|
|
@@ -73323,68 +74168,68 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73323
74168
|
return convertBaseSchema(typeSchema, ctx);
|
|
73324
74169
|
});
|
|
73325
74170
|
if (typeSchemas.length === 0) {
|
|
73326
|
-
return
|
|
74171
|
+
return z34.never();
|
|
73327
74172
|
}
|
|
73328
74173
|
if (typeSchemas.length === 1) {
|
|
73329
74174
|
return typeSchemas[0];
|
|
73330
74175
|
}
|
|
73331
|
-
return
|
|
74176
|
+
return z34.union(typeSchemas);
|
|
73332
74177
|
}
|
|
73333
74178
|
if (!type) {
|
|
73334
|
-
return
|
|
74179
|
+
return z34.any();
|
|
73335
74180
|
}
|
|
73336
74181
|
let zodSchema2;
|
|
73337
74182
|
switch (type) {
|
|
73338
74183
|
case "string": {
|
|
73339
|
-
let stringSchema =
|
|
74184
|
+
let stringSchema = z34.string();
|
|
73340
74185
|
if (schema.format) {
|
|
73341
74186
|
const format = schema.format;
|
|
73342
74187
|
if (format === "email") {
|
|
73343
|
-
stringSchema = stringSchema.check(
|
|
74188
|
+
stringSchema = stringSchema.check(z34.email());
|
|
73344
74189
|
} else if (format === "uri" || format === "uri-reference") {
|
|
73345
|
-
stringSchema = stringSchema.check(
|
|
74190
|
+
stringSchema = stringSchema.check(z34.url());
|
|
73346
74191
|
} else if (format === "uuid" || format === "guid") {
|
|
73347
|
-
stringSchema = stringSchema.check(
|
|
74192
|
+
stringSchema = stringSchema.check(z34.uuid());
|
|
73348
74193
|
} else if (format === "date-time") {
|
|
73349
|
-
stringSchema = stringSchema.check(
|
|
74194
|
+
stringSchema = stringSchema.check(z34.iso.datetime());
|
|
73350
74195
|
} else if (format === "date") {
|
|
73351
|
-
stringSchema = stringSchema.check(
|
|
74196
|
+
stringSchema = stringSchema.check(z34.iso.date());
|
|
73352
74197
|
} else if (format === "time") {
|
|
73353
|
-
stringSchema = stringSchema.check(
|
|
74198
|
+
stringSchema = stringSchema.check(z34.iso.time());
|
|
73354
74199
|
} else if (format === "duration") {
|
|
73355
|
-
stringSchema = stringSchema.check(
|
|
74200
|
+
stringSchema = stringSchema.check(z34.iso.duration());
|
|
73356
74201
|
} else if (format === "ipv4") {
|
|
73357
|
-
stringSchema = stringSchema.check(
|
|
74202
|
+
stringSchema = stringSchema.check(z34.ipv4());
|
|
73358
74203
|
} else if (format === "ipv6") {
|
|
73359
|
-
stringSchema = stringSchema.check(
|
|
74204
|
+
stringSchema = stringSchema.check(z34.ipv6());
|
|
73360
74205
|
} else if (format === "mac") {
|
|
73361
|
-
stringSchema = stringSchema.check(
|
|
74206
|
+
stringSchema = stringSchema.check(z34.mac());
|
|
73362
74207
|
} else if (format === "cidr") {
|
|
73363
|
-
stringSchema = stringSchema.check(
|
|
74208
|
+
stringSchema = stringSchema.check(z34.cidrv4());
|
|
73364
74209
|
} else if (format === "cidr-v6") {
|
|
73365
|
-
stringSchema = stringSchema.check(
|
|
74210
|
+
stringSchema = stringSchema.check(z34.cidrv6());
|
|
73366
74211
|
} else if (format === "base64") {
|
|
73367
|
-
stringSchema = stringSchema.check(
|
|
74212
|
+
stringSchema = stringSchema.check(z34.base64());
|
|
73368
74213
|
} else if (format === "base64url") {
|
|
73369
|
-
stringSchema = stringSchema.check(
|
|
74214
|
+
stringSchema = stringSchema.check(z34.base64url());
|
|
73370
74215
|
} else if (format === "e164") {
|
|
73371
|
-
stringSchema = stringSchema.check(
|
|
74216
|
+
stringSchema = stringSchema.check(z34.e164());
|
|
73372
74217
|
} else if (format === "jwt") {
|
|
73373
|
-
stringSchema = stringSchema.check(
|
|
74218
|
+
stringSchema = stringSchema.check(z34.jwt());
|
|
73374
74219
|
} else if (format === "emoji") {
|
|
73375
|
-
stringSchema = stringSchema.check(
|
|
74220
|
+
stringSchema = stringSchema.check(z34.emoji());
|
|
73376
74221
|
} else if (format === "nanoid") {
|
|
73377
|
-
stringSchema = stringSchema.check(
|
|
74222
|
+
stringSchema = stringSchema.check(z34.nanoid());
|
|
73378
74223
|
} else if (format === "cuid") {
|
|
73379
|
-
stringSchema = stringSchema.check(
|
|
74224
|
+
stringSchema = stringSchema.check(z34.cuid());
|
|
73380
74225
|
} else if (format === "cuid2") {
|
|
73381
|
-
stringSchema = stringSchema.check(
|
|
74226
|
+
stringSchema = stringSchema.check(z34.cuid2());
|
|
73382
74227
|
} else if (format === "ulid") {
|
|
73383
|
-
stringSchema = stringSchema.check(
|
|
74228
|
+
stringSchema = stringSchema.check(z34.ulid());
|
|
73384
74229
|
} else if (format === "xid") {
|
|
73385
|
-
stringSchema = stringSchema.check(
|
|
74230
|
+
stringSchema = stringSchema.check(z34.xid());
|
|
73386
74231
|
} else if (format === "ksuid") {
|
|
73387
|
-
stringSchema = stringSchema.check(
|
|
74232
|
+
stringSchema = stringSchema.check(z34.ksuid());
|
|
73388
74233
|
}
|
|
73389
74234
|
}
|
|
73390
74235
|
if (typeof schema.minLength === "number") {
|
|
@@ -73401,7 +74246,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73401
74246
|
}
|
|
73402
74247
|
case "number":
|
|
73403
74248
|
case "integer": {
|
|
73404
|
-
let numberSchema = type === "integer" ?
|
|
74249
|
+
let numberSchema = type === "integer" ? z34.number().int() : z34.number();
|
|
73405
74250
|
if (typeof schema.minimum === "number") {
|
|
73406
74251
|
numberSchema = numberSchema.min(schema.minimum);
|
|
73407
74252
|
}
|
|
@@ -73425,11 +74270,11 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73425
74270
|
break;
|
|
73426
74271
|
}
|
|
73427
74272
|
case "boolean": {
|
|
73428
|
-
zodSchema2 =
|
|
74273
|
+
zodSchema2 = z34.boolean();
|
|
73429
74274
|
break;
|
|
73430
74275
|
}
|
|
73431
74276
|
case "null": {
|
|
73432
|
-
zodSchema2 =
|
|
74277
|
+
zodSchema2 = z34.null();
|
|
73433
74278
|
break;
|
|
73434
74279
|
}
|
|
73435
74280
|
case "object": {
|
|
@@ -73442,14 +74287,14 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73442
74287
|
}
|
|
73443
74288
|
if (schema.propertyNames) {
|
|
73444
74289
|
const keySchema = convertSchema(schema.propertyNames, ctx);
|
|
73445
|
-
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) :
|
|
74290
|
+
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) : z34.any();
|
|
73446
74291
|
if (Object.keys(shape).length === 0) {
|
|
73447
|
-
zodSchema2 =
|
|
74292
|
+
zodSchema2 = z34.record(keySchema, valueSchema);
|
|
73448
74293
|
break;
|
|
73449
74294
|
}
|
|
73450
|
-
const objectSchema2 =
|
|
73451
|
-
const recordSchema =
|
|
73452
|
-
zodSchema2 =
|
|
74295
|
+
const objectSchema2 = z34.object(shape).passthrough();
|
|
74296
|
+
const recordSchema = z34.looseRecord(keySchema, valueSchema);
|
|
74297
|
+
zodSchema2 = z34.intersection(objectSchema2, recordSchema);
|
|
73453
74298
|
break;
|
|
73454
74299
|
}
|
|
73455
74300
|
if (schema.patternProperties) {
|
|
@@ -73458,28 +74303,28 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73458
74303
|
const looseRecords = [];
|
|
73459
74304
|
for (const pattern of patternKeys) {
|
|
73460
74305
|
const patternValue = convertSchema(patternProps[pattern], ctx);
|
|
73461
|
-
const keySchema =
|
|
73462
|
-
looseRecords.push(
|
|
74306
|
+
const keySchema = z34.string().regex(new RegExp(pattern));
|
|
74307
|
+
looseRecords.push(z34.looseRecord(keySchema, patternValue));
|
|
73463
74308
|
}
|
|
73464
74309
|
const schemasToIntersect = [];
|
|
73465
74310
|
if (Object.keys(shape).length > 0) {
|
|
73466
|
-
schemasToIntersect.push(
|
|
74311
|
+
schemasToIntersect.push(z34.object(shape).passthrough());
|
|
73467
74312
|
}
|
|
73468
74313
|
schemasToIntersect.push(...looseRecords);
|
|
73469
74314
|
if (schemasToIntersect.length === 0) {
|
|
73470
|
-
zodSchema2 =
|
|
74315
|
+
zodSchema2 = z34.object({}).passthrough();
|
|
73471
74316
|
} else if (schemasToIntersect.length === 1) {
|
|
73472
74317
|
zodSchema2 = schemasToIntersect[0];
|
|
73473
74318
|
} else {
|
|
73474
|
-
let result =
|
|
74319
|
+
let result = z34.intersection(schemasToIntersect[0], schemasToIntersect[1]);
|
|
73475
74320
|
for (let i = 2; i < schemasToIntersect.length; i++) {
|
|
73476
|
-
result =
|
|
74321
|
+
result = z34.intersection(result, schemasToIntersect[i]);
|
|
73477
74322
|
}
|
|
73478
74323
|
zodSchema2 = result;
|
|
73479
74324
|
}
|
|
73480
74325
|
break;
|
|
73481
74326
|
}
|
|
73482
|
-
const objectSchema =
|
|
74327
|
+
const objectSchema = z34.object(shape);
|
|
73483
74328
|
if (schema.additionalProperties === false) {
|
|
73484
74329
|
zodSchema2 = objectSchema.strict();
|
|
73485
74330
|
} else if (typeof schema.additionalProperties === "object") {
|
|
@@ -73496,33 +74341,33 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73496
74341
|
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
|
73497
74342
|
const rest = items && typeof items === "object" && !Array.isArray(items) ? convertSchema(items, ctx) : void 0;
|
|
73498
74343
|
if (rest) {
|
|
73499
|
-
zodSchema2 =
|
|
74344
|
+
zodSchema2 = z34.tuple(tupleItems).rest(rest);
|
|
73500
74345
|
} else {
|
|
73501
|
-
zodSchema2 =
|
|
74346
|
+
zodSchema2 = z34.tuple(tupleItems);
|
|
73502
74347
|
}
|
|
73503
74348
|
if (typeof schema.minItems === "number") {
|
|
73504
|
-
zodSchema2 = zodSchema2.check(
|
|
74349
|
+
zodSchema2 = zodSchema2.check(z34.minLength(schema.minItems));
|
|
73505
74350
|
}
|
|
73506
74351
|
if (typeof schema.maxItems === "number") {
|
|
73507
|
-
zodSchema2 = zodSchema2.check(
|
|
74352
|
+
zodSchema2 = zodSchema2.check(z34.maxLength(schema.maxItems));
|
|
73508
74353
|
}
|
|
73509
74354
|
} else if (Array.isArray(items)) {
|
|
73510
74355
|
const tupleItems = items.map((item) => convertSchema(item, ctx));
|
|
73511
74356
|
const rest = schema.additionalItems && typeof schema.additionalItems === "object" ? convertSchema(schema.additionalItems, ctx) : void 0;
|
|
73512
74357
|
if (rest) {
|
|
73513
|
-
zodSchema2 =
|
|
74358
|
+
zodSchema2 = z34.tuple(tupleItems).rest(rest);
|
|
73514
74359
|
} else {
|
|
73515
|
-
zodSchema2 =
|
|
74360
|
+
zodSchema2 = z34.tuple(tupleItems);
|
|
73516
74361
|
}
|
|
73517
74362
|
if (typeof schema.minItems === "number") {
|
|
73518
|
-
zodSchema2 = zodSchema2.check(
|
|
74363
|
+
zodSchema2 = zodSchema2.check(z34.minLength(schema.minItems));
|
|
73519
74364
|
}
|
|
73520
74365
|
if (typeof schema.maxItems === "number") {
|
|
73521
|
-
zodSchema2 = zodSchema2.check(
|
|
74366
|
+
zodSchema2 = zodSchema2.check(z34.maxLength(schema.maxItems));
|
|
73522
74367
|
}
|
|
73523
74368
|
} else if (items !== void 0) {
|
|
73524
74369
|
const element = convertSchema(items, ctx);
|
|
73525
|
-
let arraySchema =
|
|
74370
|
+
let arraySchema = z34.array(element);
|
|
73526
74371
|
if (typeof schema.minItems === "number") {
|
|
73527
74372
|
arraySchema = arraySchema.min(schema.minItems);
|
|
73528
74373
|
}
|
|
@@ -73531,7 +74376,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73531
74376
|
}
|
|
73532
74377
|
zodSchema2 = arraySchema;
|
|
73533
74378
|
} else {
|
|
73534
|
-
zodSchema2 =
|
|
74379
|
+
zodSchema2 = z34.array(z34.any());
|
|
73535
74380
|
}
|
|
73536
74381
|
break;
|
|
73537
74382
|
}
|
|
@@ -73548,37 +74393,37 @@ function convertBaseSchema(schema, ctx) {
|
|
|
73548
74393
|
}
|
|
73549
74394
|
function convertSchema(schema, ctx) {
|
|
73550
74395
|
if (typeof schema === "boolean") {
|
|
73551
|
-
return schema ?
|
|
74396
|
+
return schema ? z34.any() : z34.never();
|
|
73552
74397
|
}
|
|
73553
74398
|
let baseSchema = convertBaseSchema(schema, ctx);
|
|
73554
74399
|
const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
|
|
73555
74400
|
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
73556
74401
|
const options = schema.anyOf.map((s) => convertSchema(s, ctx));
|
|
73557
|
-
const anyOfUnion =
|
|
73558
|
-
baseSchema = hasExplicitType ?
|
|
74402
|
+
const anyOfUnion = z34.union(options);
|
|
74403
|
+
baseSchema = hasExplicitType ? z34.intersection(baseSchema, anyOfUnion) : anyOfUnion;
|
|
73559
74404
|
}
|
|
73560
74405
|
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
73561
74406
|
const options = schema.oneOf.map((s) => convertSchema(s, ctx));
|
|
73562
|
-
const oneOfUnion =
|
|
73563
|
-
baseSchema = hasExplicitType ?
|
|
74407
|
+
const oneOfUnion = z34.xor(options);
|
|
74408
|
+
baseSchema = hasExplicitType ? z34.intersection(baseSchema, oneOfUnion) : oneOfUnion;
|
|
73564
74409
|
}
|
|
73565
74410
|
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
73566
74411
|
if (schema.allOf.length === 0) {
|
|
73567
|
-
baseSchema = hasExplicitType ? baseSchema :
|
|
74412
|
+
baseSchema = hasExplicitType ? baseSchema : z34.any();
|
|
73568
74413
|
} else {
|
|
73569
74414
|
let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
|
|
73570
74415
|
const startIdx = hasExplicitType ? 0 : 1;
|
|
73571
74416
|
for (let i = startIdx; i < schema.allOf.length; i++) {
|
|
73572
|
-
result =
|
|
74417
|
+
result = z34.intersection(result, convertSchema(schema.allOf[i], ctx));
|
|
73573
74418
|
}
|
|
73574
74419
|
baseSchema = result;
|
|
73575
74420
|
}
|
|
73576
74421
|
}
|
|
73577
74422
|
if (schema.nullable === true && ctx.version === "openapi-3.0") {
|
|
73578
|
-
baseSchema =
|
|
74423
|
+
baseSchema = z34.nullable(baseSchema);
|
|
73579
74424
|
}
|
|
73580
74425
|
if (schema.readOnly === true) {
|
|
73581
|
-
baseSchema =
|
|
74426
|
+
baseSchema = z34.readonly(baseSchema);
|
|
73582
74427
|
}
|
|
73583
74428
|
const extraMeta = {};
|
|
73584
74429
|
const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
|
|
@@ -73605,7 +74450,7 @@ function convertSchema(schema, ctx) {
|
|
|
73605
74450
|
}
|
|
73606
74451
|
function fromJSONSchema(schema, params) {
|
|
73607
74452
|
if (typeof schema === "boolean") {
|
|
73608
|
-
return schema ?
|
|
74453
|
+
return schema ? z34.any() : z34.never();
|
|
73609
74454
|
}
|
|
73610
74455
|
const version2 = detectVersion(schema, params?.defaultTarget);
|
|
73611
74456
|
const defs = schema.$defs || schema.definitions || {};
|
|
@@ -73619,14 +74464,14 @@ function fromJSONSchema(schema, params) {
|
|
|
73619
74464
|
};
|
|
73620
74465
|
return convertSchema(schema, ctx);
|
|
73621
74466
|
}
|
|
73622
|
-
var
|
|
74467
|
+
var z34, RECOGNIZED_KEYS;
|
|
73623
74468
|
var init_from_json_schema = __esm({
|
|
73624
74469
|
"node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.js"() {
|
|
73625
74470
|
init_registries();
|
|
73626
74471
|
init_checks2();
|
|
73627
74472
|
init_iso();
|
|
73628
74473
|
init_schemas2();
|
|
73629
|
-
|
|
74474
|
+
z34 = {
|
|
73630
74475
|
...schemas_exports2,
|
|
73631
74476
|
...checks_exports2,
|
|
73632
74477
|
iso: iso_exports
|