@amalgm/shell 0.1.143 → 0.1.145
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/PURPOSE.md +7 -4
- package/dist/detection/runtime.js +7 -1
- package/dist/detection/runtime.js.map +1 -1
- package/dist/entity-apply-host.js +14 -3
- package/dist/entity-apply-host.js.map +1 -1
- package/dist/entity-apply-store.js +3 -1
- package/dist/entity-apply-store.js.map +1 -1
- package/dist/git-registration-host.d.ts +2 -1
- package/dist/git-registration-host.js +2 -1
- package/dist/git-registration-host.js.map +1 -1
- package/dist/git-repository-host.js +29 -15
- package/dist/git-repository-host.js.map +1 -1
- package/dist/materialized-graph.js +3 -1
- package/dist/materialized-graph.js.map +1 -1
- package/dist/transfer-instrumentation.d.ts +2 -1
- package/dist/transfer-instrumentation.js +7 -4
- package/dist/transfer-instrumentation.js.map +1 -1
- package/dist/user-ground-host.js +26 -12
- package/dist/user-ground-host.js.map +1 -1
- package/dist/wire-client.js +1 -1
- package/dist/workspace-add-staging.d.ts +9 -5
- package/dist/workspace-add-staging.js +4 -4
- package/dist/workspace-add-staging.js.map +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
package/dist/user-ground-host.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, lstatSync, realpathSync, readFileSync, readdirSync, readlin
|
|
|
3
3
|
import { open, readFile } from "node:fs/promises";
|
|
4
4
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { buildUserHomeManifest, buildUserManifest, liveMachineStateDir, scopedAmalgmDir, shippedUserHomeDeclaration, } from "@amalgm/core/identity";
|
|
6
|
-
import { CHUNK_BYTES, CONTENT_CONTRACT, INLINE_CARGO_MAX_BYTES, ENTITY_CLOUD_CONTRACT, ENTITY_CLOUD_SCHEMA_VERSION, artifactForRecord, canonicalVersion, checkContentManifest, classifyDirectory, classifyFile, classifyRegisteredRoot, containedRecords, createLocalEntityRecord, createEntityRecordAuthorityPort, convergeUserGround, decodeAcceptedEntityRecord, deriveUploadManifest, createUserGroundEnrollmentPolicy, isRepositoryMetadataEntry, indexRepositoryTerritory, downloadAll as downloadAllArtifacts, encodeEntityRecord, EntityApplyRail, EntityRecordRail, membershipHash, materializedSlotNames, pathIsSuspect, CONTENT_REFS_BATCH_OBJECTS, privateEntityResourceId, repositoryIdentityHash, sameRecords, snapshotFromRecords, stableJson, streamCargo, travelingRecords, upload as uploadArtifact, userGroundRecords, GRAPH_HEAD_OPERATION_KIND, } from "@amalgm/live";
|
|
6
|
+
import { CHUNK_BYTES, CONTENT_CONTRACT, INLINE_CARGO_MAX_BYTES, ENTITY_CLOUD_CONTRACT, ENTITY_CLOUD_SCHEMA_VERSION, artifactForRecord, canonicalVersion, checkContentManifest, classifyDirectory, classifyFile, classifyRegisteredRoot, containedRecords, createLocalEntityRecord, createEntityRecordAuthorityPort, convergeUserGround, decodeAcceptedEntityRecord, deriveUploadManifest, createUserGroundEnrollmentPolicy, isRepositoryMetadataEntry, indexRepositoryTerritory, downloadAll as downloadAllArtifacts, encodeEntityRecord, EntityApplyRail, EntityRecordRail, membershipHash, materializedSlotNames, pathIsSuspect, CONTENT_REFS_BATCH_OBJECTS, privateEntityResourceId, repositoryIdentityHash, sameRecords, snapshotFromRecords, stableJson, streamCargo, travelingRecords, upload as uploadArtifact, userGroundRecords, portableFileMode, GRAPH_HEAD_OPERATION_KIND, } from "@amalgm/live";
|
|
7
7
|
import Database from "better-sqlite3";
|
|
8
8
|
import { atomicCopy, atomicWrite, ensurePrivateDir, ensureUserDir } from "./filesystem.js";
|
|
9
9
|
import { emitFilesStage, } from "./files-observability.js";
|
|
@@ -945,7 +945,7 @@ export class UserGroundHost {
|
|
|
945
945
|
// seal inventory; an older gateway cannot say which sealed artifacts are
|
|
946
946
|
// packed, and this shell plans pack-span downloads and repacks against
|
|
947
947
|
// exactly that answer.
|
|
948
|
-
if (this.wire.protocolVersion <
|
|
948
|
+
if (this.wire.protocolVersion < 17) {
|
|
949
949
|
throw new Error("gateway speaks an older wire protocol than this shell");
|
|
950
950
|
}
|
|
951
951
|
this.adoptCloudDeliveryBaseline(identity, this.cloudState.deliveryWatermark);
|
|
@@ -2614,7 +2614,7 @@ export class UserGroundHost {
|
|
|
2614
2614
|
for (const frame of answers) {
|
|
2615
2615
|
if (!Array.isArray(frame.sealed) || !Array.isArray(frame.packed)) {
|
|
2616
2616
|
throw new Error("content authority answered a seal inventory without "
|
|
2617
|
-
+ "placement; protocol
|
|
2617
|
+
+ "placement; protocol 17 requires the gateway to deploy before this machine");
|
|
2618
2618
|
}
|
|
2619
2619
|
for (const hash of frame.sealed)
|
|
2620
2620
|
sealed.add(String(hash));
|
|
@@ -3998,6 +3998,7 @@ function portableRecord(row) {
|
|
|
3998
3998
|
status: row.status,
|
|
3999
3999
|
version: row.version,
|
|
4000
4000
|
payloadVersion: derived ? null : row.payloadVersion,
|
|
4001
|
+
fileMode: portableFileMode(row.type, row.filesystemMode),
|
|
4001
4002
|
transportVersion: derived ? null : row.transportVersion,
|
|
4002
4003
|
};
|
|
4003
4004
|
}
|
|
@@ -4021,11 +4022,18 @@ function coreGroundRecords(file, userEmail) {
|
|
|
4021
4022
|
)
|
|
4022
4023
|
SELECT uuid, type, parent_uuid AS parentUUID, name, status, version,
|
|
4023
4024
|
payload_version AS payloadVersion,
|
|
4025
|
+
filesystem_mode AS filesystemMode,
|
|
4024
4026
|
transport_version AS transportVersion
|
|
4025
4027
|
FROM entities WHERE uuid IN (SELECT uuid FROM core) ORDER BY uuid
|
|
4026
|
-
`).all(userEmail).map((
|
|
4027
|
-
|
|
4028
|
-
|
|
4028
|
+
`).all(userEmail).map(({ filesystemMode, ...record }) => {
|
|
4029
|
+
const derived = record.type === "workspace" || record.type === "folder";
|
|
4030
|
+
return {
|
|
4031
|
+
...record,
|
|
4032
|
+
payloadVersion: derived ? null : record.payloadVersion,
|
|
4033
|
+
fileMode: portableFileMode(record.type, filesystemMode),
|
|
4034
|
+
transportVersion: derived ? null : record.transportVersion,
|
|
4035
|
+
};
|
|
4036
|
+
});
|
|
4029
4037
|
}
|
|
4030
4038
|
finally {
|
|
4031
4039
|
database.close();
|
|
@@ -5112,6 +5120,7 @@ async function reconcileRoot(input) {
|
|
|
5112
5120
|
const existingVersionByUuid = new Map(existingRows.map((row) => [row.uuid, row]));
|
|
5113
5121
|
const rowsFromEntries = () => entries.map((entry) => {
|
|
5114
5122
|
const container = entry.type === "workspace" || entry.type === "folder";
|
|
5123
|
+
const fileMode = portableFileMode(entry.type, entry.filesystemMode);
|
|
5115
5124
|
const stored = container ? undefined : existingVersionByUuid.get(entry.uuid);
|
|
5116
5125
|
const storedVersion = stored !== undefined
|
|
5117
5126
|
&& stored.type === entry.type
|
|
@@ -5119,6 +5128,7 @@ async function reconcileRoot(input) {
|
|
|
5119
5128
|
&& stored.name === entry.name
|
|
5120
5129
|
&& stored.status === "active"
|
|
5121
5130
|
&& stored.payloadVersion === entry.payloadVersion
|
|
5131
|
+
&& portableFileMode(stored.type, stored.filesystemMode) === fileMode
|
|
5122
5132
|
? stored.version
|
|
5123
5133
|
: null;
|
|
5124
5134
|
const record = {
|
|
@@ -5135,8 +5145,10 @@ async function reconcileRoot(input) {
|
|
|
5135
5145
|
payloadVersion: container
|
|
5136
5146
|
? membershipHash(children.get(entry.uuid) ?? [], sha256Hex)
|
|
5137
5147
|
: entry.payloadVersion,
|
|
5148
|
+
fileMode,
|
|
5138
5149
|
}, sha256Hex),
|
|
5139
5150
|
payloadVersion: entry.payloadVersion,
|
|
5151
|
+
fileMode,
|
|
5140
5152
|
transportVersion: entry.transportVersion,
|
|
5141
5153
|
};
|
|
5142
5154
|
return {
|
|
@@ -5880,9 +5892,12 @@ async function materializeRecords(input) {
|
|
|
5880
5892
|
// transport is never its final worktree. Ordinary file bytes are
|
|
5881
5893
|
// the cold Add's mass, and they land exactly once.
|
|
5882
5894
|
if (stagedDestinations && record.type !== "link") {
|
|
5895
|
+
if (record.fileMode === null) {
|
|
5896
|
+
throw new Error(`cloud ordinary file ${record.uuid} has no portable mode`);
|
|
5897
|
+
}
|
|
5883
5898
|
const destination = destinationOf(paths.get(record.uuid));
|
|
5884
5899
|
const list = stagedDestinations.get(artifact.contentHash) ?? [];
|
|
5885
|
-
list.push(destination);
|
|
5900
|
+
list.push({ path: destination, fileMode: record.fileMode });
|
|
5886
5901
|
stagedDestinations.set(artifact.contentHash, list);
|
|
5887
5902
|
}
|
|
5888
5903
|
}
|
|
@@ -5890,8 +5905,9 @@ async function materializeRecords(input) {
|
|
|
5890
5905
|
if (stagedDestinations) {
|
|
5891
5906
|
// A deterministic primary destination keeps resume evidence valid: the
|
|
5892
5907
|
// same first path receives the stream on every attempt.
|
|
5893
|
-
for (const list of stagedDestinations.values())
|
|
5894
|
-
list.sort();
|
|
5908
|
+
for (const list of stagedDestinations.values()) {
|
|
5909
|
+
list.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
|
|
5910
|
+
}
|
|
5895
5911
|
}
|
|
5896
5912
|
const contentStarted = performance.now();
|
|
5897
5913
|
const fileContent = await readContent([...wanted.values()], staged && stagedDestinations
|
|
@@ -6095,9 +6111,7 @@ async function materializeRecords(input) {
|
|
|
6095
6111
|
throw new Error(`cloud materialization conflicts with ${relativePath}`);
|
|
6096
6112
|
}
|
|
6097
6113
|
ensureUserDir(dirname(destination));
|
|
6098
|
-
|
|
6099
|
-
// default Apply gives a fresh target, never the cache's private 0600.
|
|
6100
|
-
atomicCopy(local.file, destination, 0o644);
|
|
6114
|
+
atomicCopy(local.file, destination, record.fileMode);
|
|
6101
6115
|
}
|
|
6102
6116
|
}
|
|
6103
6117
|
else {
|