@plinth-music/cli 0.21.0 → 0.21.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/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/dist/build-stamp.json +2 -2
- package/dist/cli.js +375 -177
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7584,7 +7584,7 @@ function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
|
7584
7584
|
// package.json
|
|
7585
7585
|
var package_default = {
|
|
7586
7586
|
name: "@plinth-music/cli",
|
|
7587
|
-
version: "0.21.
|
|
7587
|
+
version: "0.21.1",
|
|
7588
7588
|
description: "Plinth capstone sync daemon and CLI",
|
|
7589
7589
|
type: "module",
|
|
7590
7590
|
private: false,
|
|
@@ -26125,6 +26125,27 @@ function isLaterVersion(a, b) {
|
|
|
26125
26125
|
return false;
|
|
26126
26126
|
return ta > tb;
|
|
26127
26127
|
}
|
|
26128
|
+
function committedEntryIfNewer(workspaceSlug, entityType, entry) {
|
|
26129
|
+
let raw;
|
|
26130
|
+
try {
|
|
26131
|
+
raw = readFileSync7(stateFilePath(workspaceSlug), "utf8");
|
|
26132
|
+
} catch {
|
|
26133
|
+
return;
|
|
26134
|
+
}
|
|
26135
|
+
let committed;
|
|
26136
|
+
try {
|
|
26137
|
+
const parsed = JSON.parse(raw);
|
|
26138
|
+
committed = parsed.entries?.[entityType]?.[entry.id];
|
|
26139
|
+
} catch {
|
|
26140
|
+
return;
|
|
26141
|
+
}
|
|
26142
|
+
if (committed === undefined)
|
|
26143
|
+
return;
|
|
26144
|
+
const valid = StateEntrySchema.safeParse(committed);
|
|
26145
|
+
if (!valid.success)
|
|
26146
|
+
return;
|
|
26147
|
+
return isLaterVersion(valid.data, entry) ? valid.data : undefined;
|
|
26148
|
+
}
|
|
26128
26149
|
function mergeKey(fresh, before, after) {
|
|
26129
26150
|
if (before === after)
|
|
26130
26151
|
return { value: fresh, overruled: false };
|
|
@@ -26200,8 +26221,7 @@ function mergeAnchor(fresh, before, after) {
|
|
|
26200
26221
|
return fresh;
|
|
26201
26222
|
return after;
|
|
26202
26223
|
}
|
|
26203
|
-
function
|
|
26204
|
-
const fresh = loadState(after.workspace_slug);
|
|
26224
|
+
function mergeWorkspaceState(fresh, before, after, wantCorrected = true) {
|
|
26205
26225
|
const entityTypes = new Set([
|
|
26206
26226
|
...Object.keys(fresh.entries),
|
|
26207
26227
|
...Object.keys(before.entries),
|
|
@@ -26242,10 +26262,11 @@ function commitState(before, after) {
|
|
|
26242
26262
|
last_trim_at: mergeScalar(fresh.last_trim_at, before.last_trim_at, after.last_trim_at),
|
|
26243
26263
|
memory_facts: mergeScalar(fresh.memory_facts, before.memory_facts, after.memory_facts)
|
|
26244
26264
|
};
|
|
26245
|
-
|
|
26265
|
+
if (!wantCorrected)
|
|
26266
|
+
return { merged, corrected: after };
|
|
26246
26267
|
const singletonOverruled = rules.overruled || memory.overruled || userMemory.overruled || userVoice.overruled;
|
|
26247
26268
|
if (overruledEntries.length === 0 && files.overruled.length === 0 && !singletonOverruled) {
|
|
26248
|
-
return after;
|
|
26269
|
+
return { merged, corrected: after };
|
|
26249
26270
|
}
|
|
26250
26271
|
let corrected = after;
|
|
26251
26272
|
if (rules.overruled)
|
|
@@ -26264,8 +26285,20 @@ function commitState(before, after) {
|
|
|
26264
26285
|
const committed = merged.files?.[path];
|
|
26265
26286
|
corrected = committed ? upsertFileEntry(corrected, committed).state : removeFileEntry(corrected, path).state;
|
|
26266
26287
|
}
|
|
26288
|
+
return { merged, corrected };
|
|
26289
|
+
}
|
|
26290
|
+
function commitState(before, after) {
|
|
26291
|
+
const { merged, corrected } = mergeWorkspaceState(loadState(after.workspace_slug), before, after);
|
|
26292
|
+
writeState(merged);
|
|
26267
26293
|
return corrected;
|
|
26268
26294
|
}
|
|
26295
|
+
function rebaseState(current, base2, next) {
|
|
26296
|
+
if (next === base2)
|
|
26297
|
+
return current;
|
|
26298
|
+
if (current === base2)
|
|
26299
|
+
return next;
|
|
26300
|
+
return mergeWorkspaceState(current, base2, next, false).merged;
|
|
26301
|
+
}
|
|
26269
26302
|
function upsertEntry(state, entityType, entry) {
|
|
26270
26303
|
const bucket = state.entries[entityType] ?? {};
|
|
26271
26304
|
const existing = bucket[entry.id];
|
|
@@ -34324,7 +34357,7 @@ class PerIdMutex {
|
|
|
34324
34357
|
|
|
34325
34358
|
// src/lib/push.ts
|
|
34326
34359
|
var import_gray_matter10 = __toESM(require_gray_matter(), 1);
|
|
34327
|
-
import { readFileSync as readFileSync17, statSync as statSync8 } from "node:fs";
|
|
34360
|
+
import { existsSync as existsSync4, readFileSync as readFileSync17, statSync as statSync8 } from "node:fs";
|
|
34328
34361
|
import { basename as basename5, relative as relative5 } from "node:path";
|
|
34329
34362
|
|
|
34330
34363
|
// src/lib/frontmatter-id.ts
|
|
@@ -34512,6 +34545,10 @@ function writeMirrorWithBodyPreserve(workspaceSlug, strategy, doc2, suppressor,
|
|
|
34512
34545
|
}
|
|
34513
34546
|
|
|
34514
34547
|
// src/lib/push.ts
|
|
34548
|
+
var DELETE_DECLINED_PATH_EXISTS = "the file is on disk again — a newer write owns this row";
|
|
34549
|
+
function deleteDeclinedSentence(relPath) {
|
|
34550
|
+
return `Not deleted: ${relPath} is on disk again, so the row was left alone. If you meant to delete it, remove the file and it will be retried.`;
|
|
34551
|
+
}
|
|
34515
34552
|
function normaliseWireBody(body) {
|
|
34516
34553
|
if (body === undefined)
|
|
34517
34554
|
return;
|
|
@@ -34889,6 +34926,7 @@ async function reconcileContextDocConflict(args) {
|
|
|
34889
34926
|
now,
|
|
34890
34927
|
output
|
|
34891
34928
|
} = args;
|
|
34929
|
+
const base2 = args.state;
|
|
34892
34930
|
let state = args.state;
|
|
34893
34931
|
const existingSlug = existing.slug;
|
|
34894
34932
|
const existingId = existing.id;
|
|
@@ -34938,7 +34976,8 @@ async function reconcileContextDocConflict(args) {
|
|
|
34938
34976
|
entitySlug: fileSlug,
|
|
34939
34977
|
stashPath
|
|
34940
34978
|
},
|
|
34941
|
-
state: nextState
|
|
34979
|
+
state: nextState,
|
|
34980
|
+
base: base2
|
|
34942
34981
|
};
|
|
34943
34982
|
}
|
|
34944
34983
|
const stashPreLandCloudCopy = () => stashConflict({
|
|
@@ -35000,7 +35039,8 @@ async function reconcileContextDocConflict(args) {
|
|
|
35000
35039
|
entitySlug: updated.slug,
|
|
35001
35040
|
stashPath: preLandStash
|
|
35002
35041
|
},
|
|
35003
|
-
state
|
|
35042
|
+
state,
|
|
35043
|
+
base: base2
|
|
35004
35044
|
};
|
|
35005
35045
|
}
|
|
35006
35046
|
if (patchResult.code === 404) {
|
|
@@ -35058,7 +35098,8 @@ async function reconcileContextDocConflict(args) {
|
|
|
35058
35098
|
entitySlug: fileSlug,
|
|
35059
35099
|
stashPath
|
|
35060
35100
|
},
|
|
35061
|
-
state
|
|
35101
|
+
state,
|
|
35102
|
+
base: base2
|
|
35062
35103
|
};
|
|
35063
35104
|
}
|
|
35064
35105
|
if (patchResult.reason === "context_doc_conflict") {
|
|
@@ -35086,10 +35127,11 @@ async function runPushUpsert(args) {
|
|
|
35086
35127
|
const hashBody = hashableBody(strategy, bodyMarkdown);
|
|
35087
35128
|
const newBodyHash = stableHash(hashBody);
|
|
35088
35129
|
const newFrontmatterHash = stableHash({ ...userFm, ...lifted.topLevel });
|
|
35089
|
-
const
|
|
35130
|
+
const snapshotEntry = getEntry(args.state, strategy.type, args.stateEntry.id) ?? args.stateEntry;
|
|
35131
|
+
const liveEntry = committedEntryIfNewer(args.workspaceSlug, strategy.type, snapshotEntry) ?? snapshotEntry;
|
|
35090
35132
|
const bodyChanged = newBodyHash !== liveEntry.body_hash;
|
|
35091
35133
|
const frontmatterChanged = newFrontmatterHash !== liveEntry.frontmatter_hash;
|
|
35092
|
-
let workingState = args.state;
|
|
35134
|
+
let workingState = liveEntry === snapshotEntry ? args.state : upsertEntry(args.state, strategy.type, liveEntry).state;
|
|
35093
35135
|
if (fm["id"] === undefined && workingState.frontmatter_id_backfill_version !== undefined) {
|
|
35094
35136
|
const cleared = clearFrontmatterIdBackfillMarker(workingState);
|
|
35095
35137
|
if (cleared.changed) {
|
|
@@ -35098,6 +35140,69 @@ async function runPushUpsert(args) {
|
|
|
35098
35140
|
} catch {}
|
|
35099
35141
|
}
|
|
35100
35142
|
}
|
|
35143
|
+
const wireProjection = (md) => {
|
|
35144
|
+
try {
|
|
35145
|
+
const p = import_gray_matter10.default(md);
|
|
35146
|
+
const f = p.data ?? {};
|
|
35147
|
+
const l = splitUserFrontmatter(strategy, f);
|
|
35148
|
+
const u = userFrontmatter(strategy, l.frontmatter);
|
|
35149
|
+
return stableHash({
|
|
35150
|
+
body: strategy.bodyToWire(p.content),
|
|
35151
|
+
frontmatter: { ...u, ...l.topLevel }
|
|
35152
|
+
});
|
|
35153
|
+
} catch {
|
|
35154
|
+
return null;
|
|
35155
|
+
}
|
|
35156
|
+
};
|
|
35157
|
+
if (liveEntry !== snapshotEntry) {
|
|
35158
|
+
let onDisk = null;
|
|
35159
|
+
try {
|
|
35160
|
+
onDisk = readFileSync17(args.absolutePath, "utf8");
|
|
35161
|
+
} catch {
|
|
35162
|
+
onDisk = null;
|
|
35163
|
+
}
|
|
35164
|
+
if (onDisk !== null && onDisk !== args.raw) {
|
|
35165
|
+
let disk = null;
|
|
35166
|
+
try {
|
|
35167
|
+
disk = computeMirrorHashes(strategy, onDisk);
|
|
35168
|
+
} catch {
|
|
35169
|
+
disk = null;
|
|
35170
|
+
}
|
|
35171
|
+
if (disk !== null && disk.bodyHash === liveEntry.body_hash && disk.frontmatterHash === liveEntry.frontmatter_hash) {
|
|
35172
|
+
const ours = wireProjection(args.raw);
|
|
35173
|
+
const theirs = wireProjection(onDisk);
|
|
35174
|
+
if (ours !== null && theirs !== null && ours === theirs) {
|
|
35175
|
+
return {
|
|
35176
|
+
outcome: {
|
|
35177
|
+
kind: "noop",
|
|
35178
|
+
entityType: strategy.type,
|
|
35179
|
+
entitySlug: liveEntry.slug
|
|
35180
|
+
},
|
|
35181
|
+
state: workingState,
|
|
35182
|
+
base: workingState
|
|
35183
|
+
};
|
|
35184
|
+
}
|
|
35185
|
+
const stashPath2 = stashConflict({
|
|
35186
|
+
workspaceSlug: args.workspaceSlug,
|
|
35187
|
+
entityType: strategy.type,
|
|
35188
|
+
entitySlug: liveEntry.slug,
|
|
35189
|
+
timestamp: args.now(),
|
|
35190
|
+
contents: args.raw,
|
|
35191
|
+
side: "local"
|
|
35192
|
+
});
|
|
35193
|
+
return {
|
|
35194
|
+
outcome: {
|
|
35195
|
+
kind: "conflict",
|
|
35196
|
+
entityType: strategy.type,
|
|
35197
|
+
entitySlug: liveEntry.slug,
|
|
35198
|
+
stashPath: stashPath2
|
|
35199
|
+
},
|
|
35200
|
+
state: workingState,
|
|
35201
|
+
base: workingState
|
|
35202
|
+
};
|
|
35203
|
+
}
|
|
35204
|
+
}
|
|
35205
|
+
}
|
|
35101
35206
|
if (!bodyChanged && !frontmatterChanged) {
|
|
35102
35207
|
return {
|
|
35103
35208
|
outcome: {
|
|
@@ -35105,7 +35210,8 @@ async function runPushUpsert(args) {
|
|
|
35105
35210
|
entityType: strategy.type,
|
|
35106
35211
|
entitySlug: liveEntry.slug
|
|
35107
35212
|
},
|
|
35108
|
-
state: workingState
|
|
35213
|
+
state: workingState,
|
|
35214
|
+
base: workingState
|
|
35109
35215
|
};
|
|
35110
35216
|
}
|
|
35111
35217
|
const wireBodyFields = bodyChanged ? strategy.bodyToWire(bodyMarkdown) : undefined;
|
|
@@ -35124,7 +35230,8 @@ async function runPushUpsert(args) {
|
|
|
35124
35230
|
entityType: strategy.type,
|
|
35125
35231
|
entitySlug: liveEntry.slug
|
|
35126
35232
|
},
|
|
35127
|
-
state: persistEntry(workingState, strategy.type, updated)
|
|
35233
|
+
state: persistEntry(workingState, strategy.type, updated),
|
|
35234
|
+
base: workingState
|
|
35128
35235
|
};
|
|
35129
35236
|
}
|
|
35130
35237
|
const mergedTopLevel = split || wireBodyFields?.topLevel ? {
|
|
@@ -35160,7 +35267,8 @@ async function runPushUpsert(args) {
|
|
|
35160
35267
|
fields,
|
|
35161
35268
|
pushed: false
|
|
35162
35269
|
},
|
|
35163
|
-
state: nextState2
|
|
35270
|
+
state: nextState2,
|
|
35271
|
+
base: workingState
|
|
35164
35272
|
};
|
|
35165
35273
|
}
|
|
35166
35274
|
let patchResult = await patchEntity({
|
|
@@ -35233,7 +35341,8 @@ async function runPushUpsert(args) {
|
|
|
35233
35341
|
fields,
|
|
35234
35342
|
pushed: true
|
|
35235
35343
|
},
|
|
35236
|
-
state: nextState2
|
|
35344
|
+
state: nextState2,
|
|
35345
|
+
base: workingState
|
|
35237
35346
|
};
|
|
35238
35347
|
}
|
|
35239
35348
|
return {
|
|
@@ -35242,7 +35351,8 @@ async function runPushUpsert(args) {
|
|
|
35242
35351
|
entityType: strategy.type,
|
|
35243
35352
|
entitySlug: updated.slug
|
|
35244
35353
|
},
|
|
35245
|
-
state: nextState2
|
|
35354
|
+
state: nextState2,
|
|
35355
|
+
base: workingState
|
|
35246
35356
|
};
|
|
35247
35357
|
}
|
|
35248
35358
|
if (patchResult.code === 404) {
|
|
@@ -35252,7 +35362,8 @@ async function runPushUpsert(args) {
|
|
|
35252
35362
|
entityType: strategy.type,
|
|
35253
35363
|
entitySlug: liveEntry.slug
|
|
35254
35364
|
},
|
|
35255
|
-
state: workingState
|
|
35365
|
+
state: workingState,
|
|
35366
|
+
base: workingState
|
|
35256
35367
|
};
|
|
35257
35368
|
}
|
|
35258
35369
|
if (patchResult.reason === "slug_conflict") {
|
|
@@ -35322,7 +35433,8 @@ async function runPushUpsert(args) {
|
|
|
35322
35433
|
entitySlug: liveEntry.slug,
|
|
35323
35434
|
stashPath
|
|
35324
35435
|
},
|
|
35325
|
-
state: nextState
|
|
35436
|
+
state: nextState,
|
|
35437
|
+
base: workingState
|
|
35326
35438
|
};
|
|
35327
35439
|
});
|
|
35328
35440
|
}
|
|
@@ -35341,6 +35453,7 @@ async function reconcileTaskConflict(args) {
|
|
|
35341
35453
|
now,
|
|
35342
35454
|
output
|
|
35343
35455
|
} = args;
|
|
35456
|
+
const base2 = args.state;
|
|
35344
35457
|
let state = args.state;
|
|
35345
35458
|
const stashLocalSide = () => stashConflict({
|
|
35346
35459
|
workspaceSlug,
|
|
@@ -35373,7 +35486,8 @@ async function reconcileTaskConflict(args) {
|
|
|
35373
35486
|
entitySlug: liveEntry.slug,
|
|
35374
35487
|
stashPath: stashPath2
|
|
35375
35488
|
},
|
|
35376
|
-
state
|
|
35489
|
+
state,
|
|
35490
|
+
base: base2
|
|
35377
35491
|
};
|
|
35378
35492
|
}
|
|
35379
35493
|
let cloudRow = null;
|
|
@@ -35391,7 +35505,8 @@ async function reconcileTaskConflict(args) {
|
|
|
35391
35505
|
entityType: strategy.type,
|
|
35392
35506
|
entitySlug: liveEntry.slug
|
|
35393
35507
|
},
|
|
35394
|
-
state
|
|
35508
|
+
state,
|
|
35509
|
+
base: base2
|
|
35395
35510
|
};
|
|
35396
35511
|
}
|
|
35397
35512
|
const stashCloudSide = () => stashConflict({
|
|
@@ -35431,7 +35546,8 @@ async function reconcileTaskConflict(args) {
|
|
|
35431
35546
|
entitySlug: patchResult.doc.slug,
|
|
35432
35547
|
stashPath: stashPath2
|
|
35433
35548
|
},
|
|
35434
|
-
state
|
|
35549
|
+
state,
|
|
35550
|
+
base: base2
|
|
35435
35551
|
};
|
|
35436
35552
|
}
|
|
35437
35553
|
if (patchResult.code === 404) {
|
|
@@ -35442,7 +35558,8 @@ async function reconcileTaskConflict(args) {
|
|
|
35442
35558
|
entityType: strategy.type,
|
|
35443
35559
|
entitySlug: liveEntry.slug
|
|
35444
35560
|
},
|
|
35445
|
-
state
|
|
35561
|
+
state,
|
|
35562
|
+
base: base2
|
|
35446
35563
|
};
|
|
35447
35564
|
}
|
|
35448
35565
|
const stashPath = stashLocalSide();
|
|
@@ -35465,7 +35582,8 @@ async function reconcileTaskConflict(args) {
|
|
|
35465
35582
|
entitySlug: liveEntry.slug,
|
|
35466
35583
|
stashPath
|
|
35467
35584
|
},
|
|
35468
|
-
state
|
|
35585
|
+
state,
|
|
35586
|
+
base: base2
|
|
35469
35587
|
};
|
|
35470
35588
|
}
|
|
35471
35589
|
function writeCreatedIdBack(args) {
|
|
@@ -35576,7 +35694,8 @@ async function runPushCreate(args) {
|
|
|
35576
35694
|
fields,
|
|
35577
35695
|
pushed: true
|
|
35578
35696
|
},
|
|
35579
|
-
state: nextState2
|
|
35697
|
+
state: nextState2,
|
|
35698
|
+
base: args.state
|
|
35580
35699
|
};
|
|
35581
35700
|
}
|
|
35582
35701
|
return {
|
|
@@ -35585,7 +35704,8 @@ async function runPushCreate(args) {
|
|
|
35585
35704
|
entityType: strategy.type,
|
|
35586
35705
|
entitySlug: doc2.slug
|
|
35587
35706
|
},
|
|
35588
|
-
state: nextState2
|
|
35707
|
+
state: nextState2,
|
|
35708
|
+
base: args.state
|
|
35589
35709
|
};
|
|
35590
35710
|
}
|
|
35591
35711
|
if (createResult.reason === "context_doc_conflict") {
|
|
@@ -35634,7 +35754,8 @@ async function runPushCreate(args) {
|
|
|
35634
35754
|
entitySlug: args.slug,
|
|
35635
35755
|
stashPath
|
|
35636
35756
|
},
|
|
35637
|
-
state: nextState
|
|
35757
|
+
state: nextState,
|
|
35758
|
+
base: args.state
|
|
35638
35759
|
};
|
|
35639
35760
|
});
|
|
35640
35761
|
}
|
|
@@ -35668,12 +35789,31 @@ async function runPushDelete(args) {
|
|
|
35668
35789
|
absolutePath: args.absolutePath,
|
|
35669
35790
|
reason: "untracked file — no cloud row to delete"
|
|
35670
35791
|
},
|
|
35671
|
-
state: args.state
|
|
35792
|
+
state: args.state,
|
|
35793
|
+
base: args.state
|
|
35672
35794
|
};
|
|
35673
35795
|
}
|
|
35674
35796
|
return args.mutex.run(id, async () => {
|
|
35675
|
-
const
|
|
35797
|
+
const snapshot = getEntry(args.state, strategy.type, id) ?? null;
|
|
35798
|
+
const live = snapshot ? committedEntryIfNewer(args.workspaceSlug, strategy.type, snapshot) ?? snapshot : null;
|
|
35799
|
+
if (existsSync4(args.absolutePath)) {
|
|
35800
|
+
args.output?.log(entityDeleteSuppressedLine({
|
|
35801
|
+
entityType: strategy.type,
|
|
35802
|
+
slug,
|
|
35803
|
+
reason: "path_exists"
|
|
35804
|
+
}));
|
|
35805
|
+
return {
|
|
35806
|
+
outcome: {
|
|
35807
|
+
kind: "ignored",
|
|
35808
|
+
absolutePath: args.absolutePath,
|
|
35809
|
+
reason: DELETE_DECLINED_PATH_EXISTS
|
|
35810
|
+
},
|
|
35811
|
+
state: args.state,
|
|
35812
|
+
base: args.state
|
|
35813
|
+
};
|
|
35814
|
+
}
|
|
35676
35815
|
const effectiveExpected = live?.updated_at ?? expectedUpdatedAt;
|
|
35816
|
+
const workingState = live && live !== snapshot ? upsertEntry(args.state, strategy.type, live).state : args.state;
|
|
35677
35817
|
const result = await deleteEntity({
|
|
35678
35818
|
strategy,
|
|
35679
35819
|
baseUrl: args.baseUrl,
|
|
@@ -35683,7 +35823,7 @@ async function runPushDelete(args) {
|
|
|
35683
35823
|
fetchImpl: args.fetchImpl
|
|
35684
35824
|
});
|
|
35685
35825
|
if (result.ok) {
|
|
35686
|
-
const nextState2 = dropEntry(
|
|
35826
|
+
const nextState2 = dropEntry(workingState, strategy.type, id);
|
|
35687
35827
|
args.output?.log(`[DELETE entityType=${strategy.type} slug=${slug} id=${id}]`);
|
|
35688
35828
|
return {
|
|
35689
35829
|
outcome: {
|
|
@@ -35691,11 +35831,12 @@ async function runPushDelete(args) {
|
|
|
35691
35831
|
entityType: strategy.type,
|
|
35692
35832
|
entitySlug: slug
|
|
35693
35833
|
},
|
|
35694
|
-
state: nextState2
|
|
35834
|
+
state: nextState2,
|
|
35835
|
+
base: workingState
|
|
35695
35836
|
};
|
|
35696
35837
|
}
|
|
35697
35838
|
if (result.code === 404) {
|
|
35698
|
-
const nextState2 = dropEntry(
|
|
35839
|
+
const nextState2 = dropEntry(workingState, strategy.type, id);
|
|
35699
35840
|
args.output?.log(`[DELETE entityType=${strategy.type} slug=${slug} id=${id} note=already_absent]`);
|
|
35700
35841
|
return {
|
|
35701
35842
|
outcome: {
|
|
@@ -35703,7 +35844,8 @@ async function runPushDelete(args) {
|
|
|
35703
35844
|
entityType: strategy.type,
|
|
35704
35845
|
entitySlug: slug
|
|
35705
35846
|
},
|
|
35706
|
-
state: nextState2
|
|
35847
|
+
state: nextState2,
|
|
35848
|
+
base: workingState
|
|
35707
35849
|
};
|
|
35708
35850
|
}
|
|
35709
35851
|
const nextState = await pullAndWriteMirror({
|
|
@@ -35725,7 +35867,8 @@ async function runPushDelete(args) {
|
|
|
35725
35867
|
entitySlug: slug,
|
|
35726
35868
|
stashPath: ""
|
|
35727
35869
|
},
|
|
35728
|
-
state: nextState
|
|
35870
|
+
state: nextState,
|
|
35871
|
+
base: workingState
|
|
35729
35872
|
};
|
|
35730
35873
|
});
|
|
35731
35874
|
}
|
|
@@ -35757,8 +35900,10 @@ async function pushRename(args) {
|
|
|
35757
35900
|
toSlug = basename5(toPath, ".md");
|
|
35758
35901
|
}
|
|
35759
35902
|
return mutex.run(id, async () => {
|
|
35760
|
-
const
|
|
35903
|
+
const snapshot = getEntry(state, entityType, id);
|
|
35904
|
+
const live = snapshot ? committedEntryIfNewer(workspaceSlug, entityType, snapshot) ?? snapshot : undefined;
|
|
35761
35905
|
const effectiveExpected = live?.updated_at ?? expectedUpdatedAt;
|
|
35906
|
+
const workingState = live && live !== snapshot ? upsertEntry(state, entityType, live).state : state;
|
|
35762
35907
|
let patchResult = await patchEntity({
|
|
35763
35908
|
strategy,
|
|
35764
35909
|
baseUrl,
|
|
@@ -35818,7 +35963,7 @@ async function pushRename(args) {
|
|
|
35818
35963
|
updated.body_len = renameHashBody.length;
|
|
35819
35964
|
} catch {}
|
|
35820
35965
|
}
|
|
35821
|
-
const nextState2 = persistEntry(
|
|
35966
|
+
const nextState2 = persistEntry(workingState, entityType, updated);
|
|
35822
35967
|
output?.log(`[RENAME entityType=${entityType} fromSlug=${fromSlug} toSlug=${doc2.slug} id=${doc2.id}]`);
|
|
35823
35968
|
return {
|
|
35824
35969
|
outcome: {
|
|
@@ -35827,13 +35972,15 @@ async function pushRename(args) {
|
|
|
35827
35972
|
fromSlug,
|
|
35828
35973
|
toSlug: doc2.slug
|
|
35829
35974
|
},
|
|
35830
|
-
state: nextState2
|
|
35975
|
+
state: nextState2,
|
|
35976
|
+
base: workingState
|
|
35831
35977
|
};
|
|
35832
35978
|
}
|
|
35833
35979
|
if (patchResult.code === 404) {
|
|
35834
35980
|
return {
|
|
35835
35981
|
outcome: { kind: "not_found", entityType, entitySlug: fromSlug },
|
|
35836
|
-
state
|
|
35982
|
+
state: workingState,
|
|
35983
|
+
base: workingState
|
|
35837
35984
|
};
|
|
35838
35985
|
}
|
|
35839
35986
|
if (patchResult.reason === "slug_conflict") {
|
|
@@ -35855,7 +36002,7 @@ async function pushRename(args) {
|
|
|
35855
36002
|
baseUrl,
|
|
35856
36003
|
pat,
|
|
35857
36004
|
id: patchResult.existing.id,
|
|
35858
|
-
state,
|
|
36005
|
+
state: workingState,
|
|
35859
36006
|
fetchImpl,
|
|
35860
36007
|
echo,
|
|
35861
36008
|
output,
|
|
@@ -35881,7 +36028,8 @@ async function pushRename(args) {
|
|
|
35881
36028
|
toSlug,
|
|
35882
36029
|
stashPath: stashPath2
|
|
35883
36030
|
},
|
|
35884
|
-
state: finalState
|
|
36031
|
+
state: finalState,
|
|
36032
|
+
base: workingState
|
|
35885
36033
|
};
|
|
35886
36034
|
}
|
|
35887
36035
|
let contents = "";
|
|
@@ -35902,7 +36050,7 @@ async function pushRename(args) {
|
|
|
35902
36050
|
baseUrl,
|
|
35903
36051
|
pat,
|
|
35904
36052
|
id,
|
|
35905
|
-
state,
|
|
36053
|
+
state: workingState,
|
|
35906
36054
|
fetchImpl,
|
|
35907
36055
|
echo,
|
|
35908
36056
|
output,
|
|
@@ -35915,7 +36063,8 @@ async function pushRename(args) {
|
|
|
35915
36063
|
entitySlug: fromSlug,
|
|
35916
36064
|
stashPath
|
|
35917
36065
|
},
|
|
35918
|
-
state: nextState
|
|
36066
|
+
state: nextState,
|
|
36067
|
+
base: workingState
|
|
35919
36068
|
};
|
|
35920
36069
|
});
|
|
35921
36070
|
}
|
|
@@ -35951,13 +36100,14 @@ async function applyBatch(batch, deps, mutex) {
|
|
|
35951
36100
|
await applyFileOp(op, deps);
|
|
35952
36101
|
continue;
|
|
35953
36102
|
}
|
|
36103
|
+
const base2 = deps.getState();
|
|
35954
36104
|
const result = await pushFile({
|
|
35955
36105
|
workspaceSlug: deps.workspaceSlug,
|
|
35956
36106
|
baseUrl: deps.baseUrl,
|
|
35957
36107
|
pat: deps.pat,
|
|
35958
36108
|
absolutePath: opPath(deps.workspaceSlug, op),
|
|
35959
36109
|
entityType: op.entityType,
|
|
35960
|
-
state:
|
|
36110
|
+
state: base2,
|
|
35961
36111
|
exists: op.kind === "overwrite",
|
|
35962
36112
|
unlinkContext: op.kind === "delete" ? { id: op.id, slug: op.slug, updated_at: op.updated_at } : null,
|
|
35963
36113
|
deps: {
|
|
@@ -35968,7 +36118,10 @@ async function applyBatch(batch, deps, mutex) {
|
|
|
35968
36118
|
echo: deps.echo
|
|
35969
36119
|
}
|
|
35970
36120
|
});
|
|
35971
|
-
deps.
|
|
36121
|
+
deps.applyState(result.base ?? base2, result.state);
|
|
36122
|
+
if (result.outcome.kind === "ignored" && result.outcome.reason === DELETE_DECLINED_PATH_EXISTS) {
|
|
36123
|
+
deps.output?.warn(deleteDeclinedSentence(opPath(deps.workspaceSlug, op)));
|
|
36124
|
+
}
|
|
35972
36125
|
} catch (err) {
|
|
35973
36126
|
const msg = err instanceof Error ? err.message : "unknown error";
|
|
35974
36127
|
deps.output?.warn(`Apply failed for ${opLabel(op)}: ${msg} (left for the next pull to reconcile).`);
|
|
@@ -35978,27 +36131,29 @@ async function applyBatch(batch, deps, mutex) {
|
|
|
35978
36131
|
async function applyFileOp(op, deps) {
|
|
35979
36132
|
const fileDeps = { fetchImpl: deps.fetchImpl, now: deps.now, output: deps.output };
|
|
35980
36133
|
if (op.kind === "delete") {
|
|
36134
|
+
const base3 = deps.getState();
|
|
35981
36135
|
const result2 = await pushFilesDelete({
|
|
35982
36136
|
workspaceSlug: deps.workspaceSlug,
|
|
35983
36137
|
baseUrl: deps.baseUrl,
|
|
35984
36138
|
pat: deps.pat,
|
|
35985
36139
|
relPath: op.path,
|
|
35986
|
-
state:
|
|
36140
|
+
state: base3,
|
|
35987
36141
|
deps: fileDeps
|
|
35988
36142
|
});
|
|
35989
|
-
deps.
|
|
36143
|
+
deps.applyState(base3, result2.state);
|
|
35990
36144
|
return;
|
|
35991
36145
|
}
|
|
36146
|
+
const base2 = deps.getState();
|
|
35992
36147
|
const result = await pushFilesUpsert({
|
|
35993
36148
|
workspaceSlug: deps.workspaceSlug,
|
|
35994
36149
|
baseUrl: deps.baseUrl,
|
|
35995
36150
|
pat: deps.pat,
|
|
35996
36151
|
absolutePath: filesSubtreePath(deps.workspaceSlug, op.path),
|
|
35997
36152
|
relPath: op.path,
|
|
35998
|
-
state:
|
|
36153
|
+
state: base2,
|
|
35999
36154
|
deps: fileDeps
|
|
36000
36155
|
});
|
|
36001
|
-
deps.
|
|
36156
|
+
deps.applyState(base2, result.state);
|
|
36002
36157
|
}
|
|
36003
36158
|
async function discardBatchOps(batch, deps) {
|
|
36004
36159
|
for (const op of batch.ops) {
|
|
@@ -36027,19 +36182,20 @@ async function discardBatchOps(batch, deps) {
|
|
|
36027
36182
|
});
|
|
36028
36183
|
}
|
|
36029
36184
|
}
|
|
36185
|
+
const base2 = deps.getState();
|
|
36030
36186
|
const next = await pullAndWriteMirror({
|
|
36031
36187
|
strategy,
|
|
36032
36188
|
workspaceSlug: deps.workspaceSlug,
|
|
36033
36189
|
baseUrl: deps.baseUrl,
|
|
36034
36190
|
pat: deps.pat,
|
|
36035
36191
|
id: op.id,
|
|
36036
|
-
state:
|
|
36192
|
+
state: base2,
|
|
36037
36193
|
fetchImpl: deps.fetchImpl,
|
|
36038
36194
|
echo: deps.echo,
|
|
36039
36195
|
output: deps.output,
|
|
36040
36196
|
now: deps.now
|
|
36041
36197
|
});
|
|
36042
|
-
deps.
|
|
36198
|
+
deps.applyState(base2, next);
|
|
36043
36199
|
} catch (err) {
|
|
36044
36200
|
const msg = err instanceof Error ? err.message : "unknown error";
|
|
36045
36201
|
deps.output?.warn(`Discard restore failed for ${opLabel(op)}: ${msg} (the next pull will reconcile).`);
|
|
@@ -36063,17 +36219,18 @@ async function discardFileOp(op, deps) {
|
|
|
36063
36219
|
side: "local"
|
|
36064
36220
|
});
|
|
36065
36221
|
}
|
|
36222
|
+
const base2 = deps.getState();
|
|
36066
36223
|
const next = await restoreFileFromCloud({
|
|
36067
36224
|
workspaceSlug: deps.workspaceSlug,
|
|
36068
36225
|
baseUrl: deps.baseUrl,
|
|
36069
36226
|
pat: deps.pat,
|
|
36070
36227
|
id: op.id,
|
|
36071
36228
|
relPath: op.path,
|
|
36072
|
-
state:
|
|
36229
|
+
state: base2,
|
|
36073
36230
|
fetchImpl: deps.fetchImpl,
|
|
36074
36231
|
output: deps.output
|
|
36075
36232
|
});
|
|
36076
|
-
deps.
|
|
36233
|
+
deps.applyState(base2, next);
|
|
36077
36234
|
}
|
|
36078
36235
|
function opPath(workspaceSlug, op) {
|
|
36079
36236
|
try {
|
|
@@ -36634,7 +36791,7 @@ function recordFileUnsynced(args) {
|
|
|
36634
36791
|
});
|
|
36635
36792
|
}
|
|
36636
36793
|
async function drainUnsyncedOps(args) {
|
|
36637
|
-
const { workspaceSlug, baseUrl, pat, getState,
|
|
36794
|
+
const { workspaceSlug, baseUrl, pat, getState, applyState, fetchImpl, mutex, output, echo } = args;
|
|
36638
36795
|
const now = args.now ?? (() => new Date);
|
|
36639
36796
|
const ops = listUnsynced(getState());
|
|
36640
36797
|
let attempted = 0;
|
|
@@ -36645,7 +36802,7 @@ async function drainUnsyncedOps(args) {
|
|
|
36645
36802
|
const before = getState();
|
|
36646
36803
|
const { state: next, changed } = removeUnsynced(before, target, path5);
|
|
36647
36804
|
if (changed)
|
|
36648
|
-
|
|
36805
|
+
applyState(before, commitState(before, next));
|
|
36649
36806
|
};
|
|
36650
36807
|
for (const op of ops) {
|
|
36651
36808
|
attempted += 1;
|
|
@@ -36658,38 +36815,46 @@ async function drainUnsyncedOps(args) {
|
|
|
36658
36815
|
resolved += 1;
|
|
36659
36816
|
continue;
|
|
36660
36817
|
}
|
|
36818
|
+
const base2 = getState();
|
|
36661
36819
|
const result = await pushFile({
|
|
36662
36820
|
workspaceSlug,
|
|
36663
36821
|
baseUrl,
|
|
36664
36822
|
pat,
|
|
36665
36823
|
absolutePath,
|
|
36666
36824
|
entityType: classified.entityType,
|
|
36667
|
-
state:
|
|
36825
|
+
state: base2,
|
|
36668
36826
|
exists: op.op === "upsert",
|
|
36669
36827
|
unlinkContext: null,
|
|
36670
36828
|
deps: { fetchImpl, now, mutex, output, echo }
|
|
36671
36829
|
});
|
|
36672
|
-
|
|
36830
|
+
applyState(result.base ?? base2, result.state);
|
|
36831
|
+
if (result.outcome.kind === "ignored" && result.outcome.reason === DELETE_DECLINED_PATH_EXISTS) {
|
|
36832
|
+
output?.warn(deleteDeclinedSentence(op.path));
|
|
36833
|
+
}
|
|
36673
36834
|
} else {
|
|
36674
36835
|
const absolutePath = filesSubtreePath(workspaceSlug, op.path);
|
|
36675
|
-
|
|
36676
|
-
|
|
36677
|
-
|
|
36678
|
-
|
|
36679
|
-
|
|
36680
|
-
|
|
36681
|
-
|
|
36682
|
-
|
|
36683
|
-
|
|
36684
|
-
|
|
36685
|
-
|
|
36686
|
-
|
|
36687
|
-
|
|
36688
|
-
|
|
36689
|
-
|
|
36690
|
-
|
|
36836
|
+
let base2;
|
|
36837
|
+
const doFile = () => {
|
|
36838
|
+
base2 = getState();
|
|
36839
|
+
return op.op === "delete" ? pushFilesDelete({
|
|
36840
|
+
workspaceSlug,
|
|
36841
|
+
baseUrl,
|
|
36842
|
+
pat,
|
|
36843
|
+
relPath: op.path,
|
|
36844
|
+
state: base2,
|
|
36845
|
+
deps: { fetchImpl, now, output }
|
|
36846
|
+
}) : pushFilesUpsert({
|
|
36847
|
+
workspaceSlug,
|
|
36848
|
+
baseUrl,
|
|
36849
|
+
pat,
|
|
36850
|
+
absolutePath,
|
|
36851
|
+
relPath: op.path,
|
|
36852
|
+
state: base2,
|
|
36853
|
+
deps: { fetchImpl, now, output }
|
|
36854
|
+
});
|
|
36855
|
+
};
|
|
36691
36856
|
const result = mutex ? await mutex.run(`files:${op.path}`, doFile) : await doFile();
|
|
36692
|
-
|
|
36857
|
+
applyState(base2, result.state);
|
|
36693
36858
|
}
|
|
36694
36859
|
clear(op.target, op.path);
|
|
36695
36860
|
resolved += 1;
|
|
@@ -36709,7 +36874,7 @@ async function drainUnsyncedOps(args) {
|
|
|
36709
36874
|
message: cat.serverMessage,
|
|
36710
36875
|
rejected_at: now().toISOString()
|
|
36711
36876
|
});
|
|
36712
|
-
|
|
36877
|
+
applyState(beforeReject, commitState(beforeReject, next2));
|
|
36713
36878
|
continue;
|
|
36714
36879
|
}
|
|
36715
36880
|
stillFailing += 1;
|
|
@@ -36722,7 +36887,7 @@ async function drainUnsyncedOps(args) {
|
|
|
36722
36887
|
last_reason: cat.reason
|
|
36723
36888
|
});
|
|
36724
36889
|
if (changed)
|
|
36725
|
-
|
|
36890
|
+
applyState(beforeRetry, commitState(beforeRetry, next));
|
|
36726
36891
|
}
|
|
36727
36892
|
}
|
|
36728
36893
|
return { attempted, resolved, stillFailing, rejected };
|
|
@@ -39001,7 +39166,9 @@ async function pushArtistMemory(args) {
|
|
|
39001
39166
|
}
|
|
39002
39167
|
const localHash = stableHash(local);
|
|
39003
39168
|
const runPatch = async () => {
|
|
39004
|
-
|
|
39169
|
+
const snapshotEntry = getEntryBySlug(state, ENTITY_TYPE, slug);
|
|
39170
|
+
const fresher = args.mutex && snapshotEntry ? committedEntryIfNewer(workspaceSlug, ENTITY_TYPE, snapshotEntry) : undefined;
|
|
39171
|
+
let base2 = fresher ? upsertEntry(state, ENTITY_TYPE, fresher).state : state;
|
|
39005
39172
|
const entry2 = getEntryBySlug(base2, ENTITY_TYPE, slug);
|
|
39006
39173
|
if (!entry2)
|
|
39007
39174
|
return { state: base2, outcome: { kind: "ignored", slug } };
|
|
@@ -43877,7 +44044,7 @@ function makeWatchHandler(deps) {
|
|
|
43877
44044
|
spinner,
|
|
43878
44045
|
mutex,
|
|
43879
44046
|
getState,
|
|
43880
|
-
|
|
44047
|
+
applyState,
|
|
43881
44048
|
fetchImpl,
|
|
43882
44049
|
now,
|
|
43883
44050
|
output,
|
|
@@ -43887,6 +44054,10 @@ function makeWatchHandler(deps) {
|
|
|
43887
44054
|
fileGate,
|
|
43888
44055
|
isFileFrozen
|
|
43889
44056
|
} = deps;
|
|
44057
|
+
const applyFromCurrent = (update) => {
|
|
44058
|
+
const base2 = getState();
|
|
44059
|
+
applyState(base2, update(base2));
|
|
44060
|
+
};
|
|
43890
44061
|
const handleFilesEvent = async (relPath, absolutePath, exists) => {
|
|
43891
44062
|
try {
|
|
43892
44063
|
if (isFileFrozen?.(relPath))
|
|
@@ -43896,8 +44067,8 @@ function makeWatchHandler(deps) {
|
|
|
43896
44067
|
} catch (err) {
|
|
43897
44068
|
if (!(err instanceof MirrorSymlinkError))
|
|
43898
44069
|
throw err;
|
|
43899
|
-
|
|
43900
|
-
state:
|
|
44070
|
+
applyFromCurrent((base2) => recordFileSymlinkRefused({
|
|
44071
|
+
state: base2,
|
|
43901
44072
|
relPath,
|
|
43902
44073
|
op: exists ? "upsert" : "delete",
|
|
43903
44074
|
now: now ?? (() => new Date)
|
|
@@ -43923,15 +44094,16 @@ function makeWatchHandler(deps) {
|
|
|
43923
44094
|
}
|
|
43924
44095
|
}
|
|
43925
44096
|
await mutex.run(`files:${relPath}`, async () => {
|
|
44097
|
+
const base2 = getState();
|
|
43926
44098
|
const result = await pushFilesDelete({
|
|
43927
44099
|
workspaceSlug,
|
|
43928
44100
|
baseUrl,
|
|
43929
44101
|
pat,
|
|
43930
44102
|
relPath,
|
|
43931
|
-
state:
|
|
44103
|
+
state: base2,
|
|
43932
44104
|
deps: { fetchImpl, now, output, suppressor }
|
|
43933
44105
|
});
|
|
43934
|
-
|
|
44106
|
+
applyState(base2, clearReportedSafeFileRejected(result.state, relPath));
|
|
43935
44107
|
reportFileOutcome(spinner, workspaceSlug, getState(), result.outcome);
|
|
43936
44108
|
});
|
|
43937
44109
|
return;
|
|
@@ -43956,8 +44128,8 @@ function makeWatchHandler(deps) {
|
|
|
43956
44128
|
max: MAX_WORKSPACE_FILE_BYTES,
|
|
43957
44129
|
source: "client"
|
|
43958
44130
|
}));
|
|
43959
|
-
|
|
43960
|
-
state:
|
|
44131
|
+
applyFromCurrent((base2) => recordFileOverCap({
|
|
44132
|
+
state: base2,
|
|
43961
44133
|
relPath,
|
|
43962
44134
|
size: st.size,
|
|
43963
44135
|
max: MAX_WORKSPACE_FILE_BYTES,
|
|
@@ -43985,17 +44157,18 @@ function makeWatchHandler(deps) {
|
|
|
43985
44157
|
}
|
|
43986
44158
|
}
|
|
43987
44159
|
await mutex.run(`files:${relPath}`, async () => {
|
|
44160
|
+
const base2 = getState();
|
|
43988
44161
|
const result = await pushFilesUpsert({
|
|
43989
44162
|
workspaceSlug,
|
|
43990
44163
|
baseUrl,
|
|
43991
44164
|
pat,
|
|
43992
44165
|
absolutePath,
|
|
43993
44166
|
relPath,
|
|
43994
|
-
state:
|
|
44167
|
+
state: base2,
|
|
43995
44168
|
prepared: { bytes, hash: hash2, size: st.size, inode: st.ino },
|
|
43996
44169
|
deps: { fetchImpl, now, output, suppressor }
|
|
43997
44170
|
});
|
|
43998
|
-
|
|
44171
|
+
applyState(base2, result.outcome.kind === "over_cap" ? result.state : clearFileRejected(result.state, relPath));
|
|
43999
44172
|
reportFileOutcome(spinner, workspaceSlug, getState(), result.outcome);
|
|
44000
44173
|
});
|
|
44001
44174
|
} catch (err) {
|
|
@@ -44003,16 +44176,16 @@ function makeWatchHandler(deps) {
|
|
|
44003
44176
|
output?.log(fileFailedLine({ path: relPath, ...categorizeError(err) }));
|
|
44004
44177
|
spinner.warn(`File push failed for files/${relPath}: ${msg}`);
|
|
44005
44178
|
if (isRecordableFailure(err)) {
|
|
44006
|
-
|
|
44007
|
-
state:
|
|
44179
|
+
applyFromCurrent((base2) => recordFileUnsynced({
|
|
44180
|
+
state: base2,
|
|
44008
44181
|
relPath,
|
|
44009
44182
|
op: exists ? "upsert" : "delete",
|
|
44010
44183
|
err,
|
|
44011
44184
|
now: now ?? (() => new Date)
|
|
44012
44185
|
}));
|
|
44013
44186
|
} else if (isPermanentReject(err)) {
|
|
44014
|
-
|
|
44015
|
-
state:
|
|
44187
|
+
applyFromCurrent((base2) => recordFileRejected({
|
|
44188
|
+
state: base2,
|
|
44016
44189
|
relPath,
|
|
44017
44190
|
op: exists ? "upsert" : "delete",
|
|
44018
44191
|
err,
|
|
@@ -44040,17 +44213,18 @@ function makeWatchHandler(deps) {
|
|
|
44040
44213
|
}
|
|
44041
44214
|
try {
|
|
44042
44215
|
await mutex.run(WORKSPACE_RULES_MUTEX_KEY, async () => {
|
|
44216
|
+
const base2 = getState();
|
|
44043
44217
|
const result = await pushWorkspaceRules({
|
|
44044
44218
|
workspaceSlug,
|
|
44045
44219
|
baseUrl,
|
|
44046
44220
|
pat,
|
|
44047
|
-
state:
|
|
44221
|
+
state: base2,
|
|
44048
44222
|
fetchImpl,
|
|
44049
44223
|
now,
|
|
44050
44224
|
output,
|
|
44051
44225
|
suppressor
|
|
44052
44226
|
});
|
|
44053
|
-
|
|
44227
|
+
applyState(base2, result.state);
|
|
44054
44228
|
reportWorkspaceRulesOutcome(spinner, workspaceSlug, result.state, result.outcome);
|
|
44055
44229
|
});
|
|
44056
44230
|
} catch (err) {
|
|
@@ -44078,17 +44252,18 @@ function makeWatchHandler(deps) {
|
|
|
44078
44252
|
}
|
|
44079
44253
|
try {
|
|
44080
44254
|
await mutex.run(WORKSPACE_MEMORY_MUTEX_KEY, async () => {
|
|
44255
|
+
const base2 = getState();
|
|
44081
44256
|
const result = await pushWorkspaceMemory({
|
|
44082
44257
|
workspaceSlug,
|
|
44083
44258
|
baseUrl,
|
|
44084
44259
|
pat,
|
|
44085
|
-
state:
|
|
44260
|
+
state: base2,
|
|
44086
44261
|
fetchImpl,
|
|
44087
44262
|
now,
|
|
44088
44263
|
output,
|
|
44089
44264
|
suppressor
|
|
44090
44265
|
});
|
|
44091
|
-
|
|
44266
|
+
applyState(base2, result.state);
|
|
44092
44267
|
reportWorkspaceMemoryOutcome(spinner, workspaceSlug, result.state, result.outcome);
|
|
44093
44268
|
});
|
|
44094
44269
|
} catch (err) {
|
|
@@ -44116,17 +44291,18 @@ function makeWatchHandler(deps) {
|
|
|
44116
44291
|
}
|
|
44117
44292
|
try {
|
|
44118
44293
|
await mutex.run(USER_MEMORY_MUTEX_KEY, async () => {
|
|
44294
|
+
const base2 = getState();
|
|
44119
44295
|
const result = await pushUserMemory({
|
|
44120
44296
|
workspaceSlug,
|
|
44121
44297
|
baseUrl,
|
|
44122
44298
|
pat,
|
|
44123
|
-
state:
|
|
44299
|
+
state: base2,
|
|
44124
44300
|
fetchImpl,
|
|
44125
44301
|
now,
|
|
44126
44302
|
output,
|
|
44127
44303
|
suppressor
|
|
44128
44304
|
});
|
|
44129
|
-
|
|
44305
|
+
applyState(base2, result.state);
|
|
44130
44306
|
reportUserMemoryOutcome(spinner, workspaceSlug, result.state, result.outcome);
|
|
44131
44307
|
});
|
|
44132
44308
|
} catch (err) {
|
|
@@ -44154,17 +44330,18 @@ function makeWatchHandler(deps) {
|
|
|
44154
44330
|
}
|
|
44155
44331
|
try {
|
|
44156
44332
|
await mutex.run(VOICE_MUTEX_KEY, async () => {
|
|
44333
|
+
const base2 = getState();
|
|
44157
44334
|
const result = await pushVoice({
|
|
44158
44335
|
workspaceSlug,
|
|
44159
44336
|
baseUrl,
|
|
44160
44337
|
pat,
|
|
44161
|
-
state:
|
|
44338
|
+
state: base2,
|
|
44162
44339
|
fetchImpl,
|
|
44163
44340
|
now,
|
|
44164
44341
|
output,
|
|
44165
44342
|
suppressor
|
|
44166
44343
|
});
|
|
44167
|
-
|
|
44344
|
+
applyState(base2, result.state);
|
|
44168
44345
|
reportVoiceOutcome(spinner, workspaceSlug, result.state, result.outcome);
|
|
44169
44346
|
});
|
|
44170
44347
|
} catch (err) {
|
|
@@ -44191,19 +44368,20 @@ function makeWatchHandler(deps) {
|
|
|
44191
44368
|
}
|
|
44192
44369
|
}
|
|
44193
44370
|
try {
|
|
44371
|
+
const base2 = getState();
|
|
44194
44372
|
const result = await pushArtistMemory({
|
|
44195
44373
|
workspaceSlug,
|
|
44196
44374
|
baseUrl,
|
|
44197
44375
|
pat,
|
|
44198
44376
|
slug,
|
|
44199
|
-
state:
|
|
44377
|
+
state: base2,
|
|
44200
44378
|
fetchImpl,
|
|
44201
44379
|
now,
|
|
44202
44380
|
output,
|
|
44203
44381
|
suppressor,
|
|
44204
44382
|
mutex
|
|
44205
44383
|
});
|
|
44206
|
-
|
|
44384
|
+
applyState(base2, result.state);
|
|
44207
44385
|
reportArtistMemoryOutcome(spinner, workspaceSlug, result.state, result.outcome);
|
|
44208
44386
|
} catch (err) {
|
|
44209
44387
|
const msg = err instanceof Error ? err.message : "unknown push error";
|
|
@@ -44236,6 +44414,7 @@ function makeWatchHandler(deps) {
|
|
|
44236
44414
|
await handle({ kind: "upsert", absolutePath: event.toPath });
|
|
44237
44415
|
return;
|
|
44238
44416
|
}
|
|
44417
|
+
const base3 = getState();
|
|
44239
44418
|
const result2 = await pushRename({
|
|
44240
44419
|
workspaceSlug,
|
|
44241
44420
|
baseUrl,
|
|
@@ -44246,7 +44425,7 @@ function makeWatchHandler(deps) {
|
|
|
44246
44425
|
id: event.id,
|
|
44247
44426
|
expectedUpdatedAt: event.expectedUpdatedAt,
|
|
44248
44427
|
fromSlug: event.fromSlug,
|
|
44249
|
-
state:
|
|
44428
|
+
state: base3,
|
|
44250
44429
|
deps: {
|
|
44251
44430
|
fetchImpl,
|
|
44252
44431
|
now,
|
|
@@ -44255,7 +44434,7 @@ function makeWatchHandler(deps) {
|
|
|
44255
44434
|
echo: suppressor ? { watcher: "live", suppressor } : undefined
|
|
44256
44435
|
}
|
|
44257
44436
|
});
|
|
44258
|
-
|
|
44437
|
+
applyState(base3, result2.state);
|
|
44259
44438
|
reportOutcome(spinner, workspaceSlug, result2.state, result2.outcome);
|
|
44260
44439
|
return;
|
|
44261
44440
|
}
|
|
@@ -44314,8 +44493,8 @@ function makeWatchHandler(deps) {
|
|
|
44314
44493
|
if (!classified) {
|
|
44315
44494
|
const key = entitySymlinkRefusalKey({ workspaceSlug, absolutePath });
|
|
44316
44495
|
if (key) {
|
|
44317
|
-
|
|
44318
|
-
state:
|
|
44496
|
+
applyFromCurrent((base3) => recordEntitySymlinkRefused({
|
|
44497
|
+
state: base3,
|
|
44319
44498
|
mirrorRelativePath: key,
|
|
44320
44499
|
op: event.kind === "unlink" ? "delete" : "upsert",
|
|
44321
44500
|
now: now ?? (() => new Date)
|
|
@@ -44372,13 +44551,14 @@ function makeWatchHandler(deps) {
|
|
|
44372
44551
|
return;
|
|
44373
44552
|
}
|
|
44374
44553
|
}
|
|
44554
|
+
const base2 = getState();
|
|
44375
44555
|
const result = await pushFile({
|
|
44376
44556
|
workspaceSlug,
|
|
44377
44557
|
baseUrl,
|
|
44378
44558
|
pat,
|
|
44379
44559
|
absolutePath,
|
|
44380
44560
|
entityType: classified.entityType,
|
|
44381
|
-
state:
|
|
44561
|
+
state: base2,
|
|
44382
44562
|
exists: event.kind === "upsert",
|
|
44383
44563
|
unlinkContext: event.kind === "unlink" && event.stateEntry ? {
|
|
44384
44564
|
id: event.stateEntry.id,
|
|
@@ -44394,7 +44574,7 @@ function makeWatchHandler(deps) {
|
|
|
44394
44574
|
echo: suppressor ? { watcher: "live", suppressor } : undefined
|
|
44395
44575
|
}
|
|
44396
44576
|
});
|
|
44397
|
-
|
|
44577
|
+
applyState(result.base ?? base2, clearEntityRejected(result.state, workspaceSlug, absolutePath));
|
|
44398
44578
|
reportOutcome(spinner, workspaceSlug, getState(), result.outcome);
|
|
44399
44579
|
} catch (err) {
|
|
44400
44580
|
const msg = err instanceof Error ? err.message : "unknown push error";
|
|
@@ -44410,8 +44590,8 @@ function makeWatchHandler(deps) {
|
|
|
44410
44590
|
}));
|
|
44411
44591
|
}
|
|
44412
44592
|
if (classified && event.kind !== "renamed" && isRecordableFailure(err)) {
|
|
44413
|
-
|
|
44414
|
-
state:
|
|
44593
|
+
applyFromCurrent((base2) => recordEntityUnsynced({
|
|
44594
|
+
state: base2,
|
|
44415
44595
|
workspaceSlug,
|
|
44416
44596
|
absolutePath: path5,
|
|
44417
44597
|
op: event.kind === "unlink" ? "delete" : "upsert",
|
|
@@ -44419,8 +44599,8 @@ function makeWatchHandler(deps) {
|
|
|
44419
44599
|
now: now ?? (() => new Date)
|
|
44420
44600
|
}));
|
|
44421
44601
|
} else if (classified && event.kind !== "renamed" && isPermanentReject(err)) {
|
|
44422
|
-
|
|
44423
|
-
state:
|
|
44602
|
+
applyFromCurrent((base2) => recordEntityRejected({
|
|
44603
|
+
state: base2,
|
|
44424
44604
|
workspaceSlug,
|
|
44425
44605
|
absolutePath: path5,
|
|
44426
44606
|
op: event.kind === "unlink" ? "delete" : "upsert",
|
|
@@ -44439,6 +44619,7 @@ function discardSink() {
|
|
|
44439
44619
|
}
|
|
44440
44620
|
async function flushHeldEntityOp(deps) {
|
|
44441
44621
|
const now = deps.now ?? (() => new Date);
|
|
44622
|
+
const base2 = deps.getState();
|
|
44442
44623
|
try {
|
|
44443
44624
|
const result = await pushFile({
|
|
44444
44625
|
workspaceSlug: deps.workspaceSlug,
|
|
@@ -44446,7 +44627,7 @@ async function flushHeldEntityOp(deps) {
|
|
|
44446
44627
|
pat: deps.pat,
|
|
44447
44628
|
absolutePath: deps.op.absolutePath,
|
|
44448
44629
|
entityType: deps.op.entityType,
|
|
44449
|
-
state:
|
|
44630
|
+
state: base2,
|
|
44450
44631
|
exists: deps.op.kind === "overwrite",
|
|
44451
44632
|
unlinkContext: deps.op.kind === "delete" ? { id: deps.op.id, slug: deps.op.slug, updated_at: deps.op.updatedAt } : null,
|
|
44452
44633
|
deps: {
|
|
@@ -44457,7 +44638,10 @@ async function flushHeldEntityOp(deps) {
|
|
|
44457
44638
|
echo: deps.echo
|
|
44458
44639
|
}
|
|
44459
44640
|
});
|
|
44460
|
-
deps.
|
|
44641
|
+
deps.applyState(result.base ?? base2, result.state);
|
|
44642
|
+
if (result.outcome.kind === "ignored" && result.outcome.reason === DELETE_DECLINED_PATH_EXISTS) {
|
|
44643
|
+
deps.spinner.warn(deleteDeclinedSentence(deps.op.absolutePath));
|
|
44644
|
+
}
|
|
44461
44645
|
reportOutcome(deps.spinner, deps.workspaceSlug, deps.getState(), result.outcome);
|
|
44462
44646
|
} catch (err) {
|
|
44463
44647
|
const msg = err instanceof Error ? err.message : "unknown push error";
|
|
@@ -44469,8 +44653,8 @@ async function flushHeldEntityOp(deps) {
|
|
|
44469
44653
|
}));
|
|
44470
44654
|
deps.spinner.warn(`Push failed for ${deps.op.entityType}/${deps.op.slug}: ${msg}`);
|
|
44471
44655
|
if (isRecordableFailure(err)) {
|
|
44472
|
-
deps.
|
|
44473
|
-
state:
|
|
44656
|
+
deps.applyState(base2, recordEntityUnsynced({
|
|
44657
|
+
state: base2,
|
|
44474
44658
|
workspaceSlug: deps.workspaceSlug,
|
|
44475
44659
|
absolutePath: deps.op.absolutePath,
|
|
44476
44660
|
op: deps.op.kind === "delete" ? "delete" : "upsert",
|
|
@@ -44488,14 +44672,16 @@ async function flushHeldFileOpImpl(deps) {
|
|
|
44488
44672
|
output: deps.output,
|
|
44489
44673
|
suppressor: deps.suppressor
|
|
44490
44674
|
};
|
|
44675
|
+
let base2;
|
|
44491
44676
|
const run = async () => {
|
|
44677
|
+
base2 = deps.getState();
|
|
44492
44678
|
try {
|
|
44493
44679
|
const result = deps.op.kind === "delete" ? await pushFilesDelete({
|
|
44494
44680
|
workspaceSlug: deps.workspaceSlug,
|
|
44495
44681
|
baseUrl: deps.baseUrl,
|
|
44496
44682
|
pat: deps.pat,
|
|
44497
44683
|
relPath: deps.op.relPath,
|
|
44498
|
-
state:
|
|
44684
|
+
state: base2,
|
|
44499
44685
|
deps: fileDeps
|
|
44500
44686
|
}) : await pushFilesUpsert({
|
|
44501
44687
|
workspaceSlug: deps.workspaceSlug,
|
|
@@ -44503,18 +44689,18 @@ async function flushHeldFileOpImpl(deps) {
|
|
|
44503
44689
|
pat: deps.pat,
|
|
44504
44690
|
absolutePath: deps.op.absolutePath,
|
|
44505
44691
|
relPath: deps.op.relPath,
|
|
44506
|
-
state:
|
|
44692
|
+
state: base2,
|
|
44507
44693
|
deps: fileDeps
|
|
44508
44694
|
});
|
|
44509
|
-
deps.
|
|
44695
|
+
deps.applyState(base2, result.state);
|
|
44510
44696
|
reportFileOutcome(deps.spinner, deps.workspaceSlug, deps.getState(), result.outcome);
|
|
44511
44697
|
} catch (err) {
|
|
44512
44698
|
const msg = err instanceof Error ? err.message : "unknown push error";
|
|
44513
44699
|
deps.output?.log(fileFailedLine({ path: deps.op.relPath, ...categorizeError(err) }));
|
|
44514
44700
|
deps.spinner.warn(`File push failed for files/${deps.op.relPath}: ${msg}`);
|
|
44515
44701
|
if (isRecordableFailure(err)) {
|
|
44516
|
-
deps.
|
|
44517
|
-
state:
|
|
44702
|
+
deps.applyState(base2, recordFileUnsynced({
|
|
44703
|
+
state: base2,
|
|
44518
44704
|
relPath: deps.op.relPath,
|
|
44519
44705
|
op: deps.op.kind === "delete" ? "delete" : "upsert",
|
|
44520
44706
|
err,
|
|
@@ -44809,8 +44995,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
44809
44995
|
baseUrl: entry2.api_base_url,
|
|
44810
44996
|
pat,
|
|
44811
44997
|
getState: () => state,
|
|
44812
|
-
|
|
44813
|
-
state =
|
|
44998
|
+
applyState: (base2, next) => {
|
|
44999
|
+
state = rebaseState(state, base2, next);
|
|
44814
45000
|
},
|
|
44815
45001
|
fetchImpl,
|
|
44816
45002
|
now: deps.now,
|
|
@@ -44827,8 +45013,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
44827
45013
|
baseUrl: entry2.api_base_url,
|
|
44828
45014
|
pat,
|
|
44829
45015
|
getState: () => state,
|
|
44830
|
-
|
|
44831
|
-
state =
|
|
45016
|
+
applyState: (base2, next) => {
|
|
45017
|
+
state = rebaseState(state, base2, next);
|
|
44832
45018
|
},
|
|
44833
45019
|
fetchImpl,
|
|
44834
45020
|
now: deps.now,
|
|
@@ -44866,8 +45052,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
44866
45052
|
pat,
|
|
44867
45053
|
op,
|
|
44868
45054
|
getState: () => state,
|
|
44869
|
-
|
|
44870
|
-
state =
|
|
45055
|
+
applyState: (base2, next) => {
|
|
45056
|
+
state = rebaseState(state, base2, next);
|
|
44871
45057
|
},
|
|
44872
45058
|
mutex,
|
|
44873
45059
|
fetchImpl,
|
|
@@ -44930,8 +45116,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
44930
45116
|
pat,
|
|
44931
45117
|
op,
|
|
44932
45118
|
getState: () => state,
|
|
44933
|
-
|
|
44934
|
-
state =
|
|
45119
|
+
applyState: (base2, next) => {
|
|
45120
|
+
state = rebaseState(state, base2, next);
|
|
44935
45121
|
},
|
|
44936
45122
|
mutex,
|
|
44937
45123
|
fetchImpl,
|
|
@@ -44987,8 +45173,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
44987
45173
|
spinner,
|
|
44988
45174
|
mutex,
|
|
44989
45175
|
getState: () => state,
|
|
44990
|
-
|
|
44991
|
-
state =
|
|
45176
|
+
applyState: (base2, next) => {
|
|
45177
|
+
state = rebaseState(state, base2, next);
|
|
44992
45178
|
},
|
|
44993
45179
|
fetchImpl,
|
|
44994
45180
|
now: deps.now,
|
|
@@ -45053,8 +45239,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
45053
45239
|
baseUrl: entry2.api_base_url,
|
|
45054
45240
|
pat,
|
|
45055
45241
|
getState: () => state,
|
|
45056
|
-
|
|
45057
|
-
state =
|
|
45242
|
+
applyState: (base2, next) => {
|
|
45243
|
+
state = rebaseState(state, base2, next);
|
|
45058
45244
|
},
|
|
45059
45245
|
fetchImpl,
|
|
45060
45246
|
now: deps.now,
|
|
@@ -45071,8 +45257,8 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
45071
45257
|
baseUrl: entry2.api_base_url,
|
|
45072
45258
|
pat,
|
|
45073
45259
|
getState: () => state,
|
|
45074
|
-
|
|
45075
|
-
state =
|
|
45260
|
+
applyState: (base2, next) => {
|
|
45261
|
+
state = rebaseState(state, base2, next);
|
|
45076
45262
|
},
|
|
45077
45263
|
fetchImpl,
|
|
45078
45264
|
now: deps.now,
|
|
@@ -45087,58 +45273,70 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
45087
45273
|
spinner.warn(`${redriven.rejected} write${redriven.rejected === 1 ? "" : "s"} permanently rejected — see \`plinth status\``);
|
|
45088
45274
|
spinner.update(`Watching ${slug} · ${watchingSummary(state)}`);
|
|
45089
45275
|
}
|
|
45090
|
-
|
|
45091
|
-
|
|
45092
|
-
|
|
45093
|
-
|
|
45094
|
-
|
|
45095
|
-
|
|
45096
|
-
|
|
45097
|
-
|
|
45098
|
-
|
|
45099
|
-
|
|
45100
|
-
|
|
45101
|
-
|
|
45276
|
+
let rulesBase = state;
|
|
45277
|
+
const rulesRecon = await mutex.run(WORKSPACE_RULES_MUTEX_KEY, () => {
|
|
45278
|
+
rulesBase = state;
|
|
45279
|
+
return reconcileWorkspaceRules({
|
|
45280
|
+
workspaceSlug: slug,
|
|
45281
|
+
baseUrl: entry2.api_base_url,
|
|
45282
|
+
pat,
|
|
45283
|
+
state: rulesBase,
|
|
45284
|
+
fetchImpl,
|
|
45285
|
+
now: deps.now,
|
|
45286
|
+
output: out,
|
|
45287
|
+
suppressor
|
|
45288
|
+
});
|
|
45289
|
+
});
|
|
45290
|
+
state = rebaseState(state, rulesBase, rulesRecon.state);
|
|
45102
45291
|
reportSingletonReconcile(spinner, slug, state, WORKSPACE_RULES_FILENAME, rulesRecon.outcome);
|
|
45103
|
-
|
|
45104
|
-
|
|
45105
|
-
|
|
45106
|
-
|
|
45107
|
-
|
|
45108
|
-
|
|
45109
|
-
|
|
45110
|
-
|
|
45111
|
-
|
|
45112
|
-
|
|
45113
|
-
|
|
45114
|
-
|
|
45292
|
+
let memoryBase = state;
|
|
45293
|
+
const memoryRecon = await mutex.run(WORKSPACE_MEMORY_MUTEX_KEY, () => {
|
|
45294
|
+
memoryBase = state;
|
|
45295
|
+
return reconcileWorkspaceMemory({
|
|
45296
|
+
workspaceSlug: slug,
|
|
45297
|
+
baseUrl: entry2.api_base_url,
|
|
45298
|
+
pat,
|
|
45299
|
+
state: memoryBase,
|
|
45300
|
+
fetchImpl,
|
|
45301
|
+
now: deps.now,
|
|
45302
|
+
output: out,
|
|
45303
|
+
suppressor
|
|
45304
|
+
});
|
|
45305
|
+
});
|
|
45306
|
+
state = rebaseState(state, memoryBase, memoryRecon.state);
|
|
45115
45307
|
reportSingletonReconcile(spinner, slug, state, WORKSPACE_MEMORY_FILENAME, memoryRecon.outcome);
|
|
45116
|
-
|
|
45117
|
-
|
|
45118
|
-
|
|
45119
|
-
|
|
45120
|
-
state,
|
|
45121
|
-
fetchImpl,
|
|
45122
|
-
now: deps.now,
|
|
45123
|
-
output: out,
|
|
45124
|
-
suppressor
|
|
45125
|
-
}));
|
|
45126
|
-
if (userMemoryRecon.state !== state)
|
|
45127
|
-
state = userMemoryRecon.state;
|
|
45128
|
-
reportSingletonReconcile(spinner, slug, state, USER_MEMORY_FILENAME, userMemoryRecon.outcome);
|
|
45129
|
-
try {
|
|
45130
|
-
const voiceRecon = await mutex.run(VOICE_MUTEX_KEY, () => reconcileVoice({
|
|
45308
|
+
let userMemoryBase = state;
|
|
45309
|
+
const userMemoryRecon = await mutex.run(USER_MEMORY_MUTEX_KEY, () => {
|
|
45310
|
+
userMemoryBase = state;
|
|
45311
|
+
return reconcileUserMemory({
|
|
45131
45312
|
workspaceSlug: slug,
|
|
45132
45313
|
baseUrl: entry2.api_base_url,
|
|
45133
45314
|
pat,
|
|
45134
|
-
state,
|
|
45315
|
+
state: userMemoryBase,
|
|
45135
45316
|
fetchImpl,
|
|
45136
45317
|
now: deps.now,
|
|
45137
45318
|
output: out,
|
|
45138
45319
|
suppressor
|
|
45139
|
-
})
|
|
45140
|
-
|
|
45141
|
-
|
|
45320
|
+
});
|
|
45321
|
+
});
|
|
45322
|
+
state = rebaseState(state, userMemoryBase, userMemoryRecon.state);
|
|
45323
|
+
reportSingletonReconcile(spinner, slug, state, USER_MEMORY_FILENAME, userMemoryRecon.outcome);
|
|
45324
|
+
try {
|
|
45325
|
+
let voiceBase = state;
|
|
45326
|
+
const voiceRecon = await mutex.run(VOICE_MUTEX_KEY, () => {
|
|
45327
|
+
voiceBase = state;
|
|
45328
|
+
return reconcileVoice({
|
|
45329
|
+
workspaceSlug: slug,
|
|
45330
|
+
baseUrl: entry2.api_base_url,
|
|
45331
|
+
pat,
|
|
45332
|
+
state: voiceBase,
|
|
45333
|
+
fetchImpl,
|
|
45334
|
+
now: deps.now,
|
|
45335
|
+
output: out,
|
|
45336
|
+
suppressor
|
|
45337
|
+
});
|
|
45338
|
+
});
|
|
45339
|
+
state = rebaseState(state, voiceBase, voiceRecon.state);
|
|
45142
45340
|
reportSingletonReconcile(spinner, slug, state, VOICE_FILENAME, voiceRecon.outcome);
|
|
45143
45341
|
const reconWarning = voiceMalformedWarning(state, slug);
|
|
45144
45342
|
if (reconWarning)
|
|
@@ -45146,19 +45344,19 @@ async function runStart(workspaceSlug, deps = {}) {
|
|
|
45146
45344
|
} catch (err) {
|
|
45147
45345
|
out.log(`[VOICE_RECONCILE_FAILED ${categorizeError(err).reason}]`);
|
|
45148
45346
|
}
|
|
45347
|
+
const memBase = state;
|
|
45149
45348
|
const memRecon = await reconcileArtistMemory({
|
|
45150
45349
|
workspaceSlug: slug,
|
|
45151
45350
|
baseUrl: entry2.api_base_url,
|
|
45152
45351
|
pat,
|
|
45153
|
-
state,
|
|
45352
|
+
state: memBase,
|
|
45154
45353
|
fetchImpl,
|
|
45155
45354
|
now: deps.now,
|
|
45156
45355
|
output: out,
|
|
45157
45356
|
suppressor,
|
|
45158
45357
|
mutex
|
|
45159
45358
|
});
|
|
45160
|
-
|
|
45161
|
-
state = memRecon.state;
|
|
45359
|
+
state = rebaseState(state, memBase, memRecon.state);
|
|
45162
45360
|
if (memRecon.pushed > 0) {
|
|
45163
45361
|
spinner.success(`↑ synced ${memRecon.pushed} memory file${memRecon.pushed === 1 ? "" : "s"}`);
|
|
45164
45362
|
spinner.update(`Watching ${slug} · ${watchingSummary(state)}`);
|